diff --git a/src/common.h b/src/common.h index 3be2665..fd6273e 100644 --- a/src/common.h +++ b/src/common.h @@ -279,6 +279,17 @@ typedef struct { int y; } geometry_t; +/// A structure representing margins around a rectangle. +typedef struct { + int top; + int left; + int bottom; + int right; +} margin_t; + +// Or use cmemzero(). +#define MARGIN_INIT { 0, 0, 0, 0 } + /// Enumeration type of window painting mode. typedef enum { WMODE_TRANS, @@ -1174,8 +1185,8 @@ typedef struct _win { // Frame-opacity-related members /// Current window frame opacity. Affected by window opacity. double frame_opacity; - /// Frame widths. Determined by client window attributes. - unsigned int left_width, right_width, top_width, bottom_width; + /// Frame extents. Acquired from _NET_FRAME_EXTENTS. + margin_t frame_extents; // Shadow-related members /// Whether a window has shadow. Calculated. @@ -1343,6 +1354,13 @@ allocchk_(const char *func_name, void *ptr) { /// @brief Wrapper of ealloc(). #define crealloc(ptr, nmemb, type) ((type *) allocchk(realloc((ptr), (nmemb) * sizeof(type)))) +/// @brief Zero out the given memory block. +#define cmemzero(ptr, size) memset((ptr), 0, (size)) + +/// @brief Wrapper of cmemzero() that handles a pointer to a single item, for +/// convenience. +#define cmemzero_one(ptr) cmemzero((ptr), sizeof(*(ptr))) + /** * Return whether a struct timeval value is empty. */ diff --git a/src/compton.c b/src/compton.c index 19de07a..79f412a 100644 --- a/src/compton.c +++ b/src/compton.c @@ -903,10 +903,10 @@ static XserverRegion win_get_region_noframe(session_t *ps, win *w, bool use_offset) { XRectangle r; - r.x = (use_offset ? w->a.x: 0) + w->a.border_width + w->left_width; - r.y = (use_offset ? w->a.y: 0) + w->a.border_width + w->top_width; - r.width = max_i(w->a.width - w->left_width - w->right_width, 0); - r.height = max_i(w->a.height - w->top_width - w->bottom_width, 0); + r.x = (use_offset ? w->a.x: 0) + w->a.border_width + w->frame_extents.left; + r.y = (use_offset ? w->a.y: 0) + w->a.border_width + w->frame_extents.top; + r.width = max_i(w->a.width - w->frame_extents.left - w->frame_extents.right, 0); + r.height = max_i(w->a.height - w->frame_extents.top - w->frame_extents.bottom, 0); if (r.width > 0 && r.height > 0) return XFixesCreateRegion(ps->dpy, &r, 1); @@ -1033,20 +1033,17 @@ find_client_win(session_t *ps, Window w) { */ static void get_frame_extents(session_t *ps, win *w, Window client) { - w->left_width = 0; - w->right_width = 0; - w->top_width = 0; - w->bottom_width = 0; + cmemzero_one(&w->frame_extents); winprop_t prop = wid_get_prop(ps, client, ps->atom_frame_extents, 4L, XA_CARDINAL, 32); if (4 == prop.nitems) { const long * const extents = prop.data.p32; - w->left_width = extents[0]; - w->right_width = extents[1]; - w->top_width = extents[2]; - w->bottom_width = extents[3]; + w->frame_extents.left = extents[0]; + w->frame_extents.right = extents[1]; + w->frame_extents.top = extents[2]; + w->frame_extents.bottom = extents[3]; if (ps->o.frame_opacity) update_reg_ignore_expire(ps, w); @@ -1054,7 +1051,8 @@ get_frame_extents(session_t *ps, win *w, Window client) { #ifdef DEBUG_FRAME printf_dbgf("(%#010lx): %d, %d, %d, %d\n", w->id, - w->left_width, w->right_width, w->top_width, w->bottom_width); + w->frame_extents.left, w->frame_extents.right, + w->frame_extents.top, w->frame_extents.bottom); #endif free_winprop(&prop); @@ -1634,10 +1632,10 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint, } else { // Painting parameters - const int t = w->a.border_width + w->top_width; - const int l = w->a.border_width + w->left_width; - const int b = w->a.border_width + w->bottom_width; - const int r = w->a.border_width + w->right_width; + const int t = w->a.border_width + w->frame_extents.top; + const int l = w->a.border_width + w->frame_extents.left; + const int b = w->a.border_width + w->frame_extents.bottom; + const int r = w->a.border_width + w->frame_extents.right; #define COMP_BDR(cx, cy, cwid, chei) \ win_render(ps, w, (cx), (cy), (cwid), (chei), w->frame_opacity, \ @@ -2898,10 +2896,7 @@ add_win(session_t *ps, Window id, Window prev) { .fade_callback = NULL, .frame_opacity = 0.0, - .left_width = 0, - .right_width = 0, - .top_width = 0, - .bottom_width = 0, + .frame_extents = MARGIN_INIT, .shadow = false, .shadow_force = UNSET, diff --git a/src/compton.h b/src/compton.h index 4844c9c..59d6f5b 100644 --- a/src/compton.h +++ b/src/compton.h @@ -503,7 +503,8 @@ update_reg_ignore_expire(session_t *ps, const win *w) { static inline bool __attribute__((const)) win_has_frame(const win *w) { return w->a.border_width - || w->top_width || w->left_width || w->right_width || w->bottom_width; + || w->frame_extents.top || w->frame_extents.left + || w->frame_extents.right || w->frame_extents.bottom; } static inline void diff --git a/src/dbus.c b/src/dbus.c index 874f565..2ea1b86 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -723,10 +723,22 @@ cdbus_process_win_get(session_t *ps, DBusMessage *msg) { cdbus_m_win_get_do(opacity_set, cdbus_reply_uint32); cdbus_m_win_get_do(frame_opacity, cdbus_reply_double); - cdbus_m_win_get_do(left_width, cdbus_reply_uint32); - cdbus_m_win_get_do(right_width, cdbus_reply_uint32); - cdbus_m_win_get_do(top_width, cdbus_reply_uint32); - cdbus_m_win_get_do(bottom_width, cdbus_reply_uint32); + if (!strcmp("left_width", target)) { + cdbus_reply_uint32(ps, msg, w->frame_extents.left); + return true; + } + if (!strcmp("right_width", target)) { + cdbus_reply_uint32(ps, msg, w->frame_extents.right); + return true; + } + if (!strcmp("top_width", target)) { + cdbus_reply_uint32(ps, msg, w->frame_extents.top); + return true; + } + if (!strcmp("bottom_width", target)) { + cdbus_reply_uint32(ps, msg, w->frame_extents.bottom); + return true; + } cdbus_m_win_get_do(shadow, cdbus_reply_bool); cdbus_m_win_get_do(fade, cdbus_reply_bool);