summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Wong <gtw@gnu.org>2009-08-31 15:26:01 -0600
committerGary Wong <gtw@gnu.org>2009-08-31 15:26:01 -0600
commit69b03632ad36228490e30e79852f8b922fb22c74 (patch)
treeaf4e2529c470e812db3a0f3be86a0a8703fb9a1e
parent49b9141e117ff21451619399cee6b18d653c619c (diff)
Make frame decorations optional (selected by _MOTIF_WM_HINTS property).
-rw-r--r--ChangeLog18
-rw-r--r--actions.c1
-rw-r--r--decorate-core.c1
-rw-r--r--decorate-render.c1
-rw-r--r--frame.c78
-rw-r--r--frame.h5
-rw-r--r--gwm.c47
-rw-r--r--gwm.h14
-rw-r--r--managed.c142
-rw-r--r--managed.h2
-rw-r--r--root.c1
11 files changed, 252 insertions, 58 deletions
diff --git a/ChangeLog b/ChangeLog
index 085935c..f13da1d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2009-08-31 Gary Wong <gtw@gnu.org>
+ * frame.c (frame_t, frame_xb): Make window decorations optional.
+ (frame_blr): New function.
+ (frame_b, frame_l, frame_r): Invoke frame_blr().
+ (deactivate_focus_frame): Moved from gwm.c.
+ (frame_button_press, frame_enter_notify): Make window decorations
+ optional.
+ * gwm.c (start_managing_window): Likewise.
+ (setup_display): Add _MOTIF_WM_HINTS property.
+ * managed.c (managed_property_change): Handle _MOTIF_WM_HINTS property.
+ (match_managed_shape): Retrieve _MOTIF_WM_HINTS when a client
+ window is no longer bounding shaped.
+
+2009-08-31 Gary Wong <gtw@gnu.org>
+
* button.c (button_size, button_xb): New functions. All references
to former constants updated.
* frame.c (frame_t, frame_b, frame_l, frame_r, frame_xb): New
@@ -36,7 +50,7 @@
(managed_property_notify): Use async_get_property.
* gwm.c (start_managing_window): Initialise net_wm_name.
(setup_display): Add _NET_WM_NAME property.
-
+
2009-08-28 Gary Wong <gtw@gnu.org>
* frame.c (recalc_size): Initialise feedback->u.feedback.
@@ -57,7 +71,7 @@
to (FcChar8 *).
2009-08-28 Gary Wong <gtw@gnu.org>
-
+
* gwm.c (shutdown_display): Reparent the windows in strict stacking
order.
diff --git a/actions.c b/actions.c
index dc6f426..81c0b86 100644
--- a/actions.c
+++ b/actions.c
@@ -33,6 +33,7 @@
#include "gwm.h"
#include "actions.h"
+#include "frame.h"
#include "window-table.h"
static void external_command( char *name, ... ) {
diff --git a/decorate-core.c b/decorate-core.c
index c3c3b73..52f5837 100644
--- a/decorate-core.c
+++ b/decorate-core.c
@@ -33,6 +33,7 @@
#include "button.h"
#include "decorate-core.h"
+#include "frame.h"
#define FONT_SIZE 12
#define STRING2(x) #x
diff --git a/decorate-render.c b/decorate-render.c
index b30f25a..b844973 100644
--- a/decorate-render.c
+++ b/decorate-render.c
@@ -38,6 +38,7 @@
#include "button.h"
#include "decorate-render.h"
+#include "frame.h"
enum style_id {
STYLE_TITLE, STYLE_MENU, NUM_STYLES
diff --git a/frame.c b/frame.c
index 969733d..f6a6bcc 100644
--- a/frame.c
+++ b/frame.c
@@ -43,37 +43,57 @@
extern int frame_t( struct gwm_window *window, int include_x_border ) {
+ int base, border;
+
assert( window->type == WINDOW_FRAME );
+
+ if( window->u.frame.decoration & DEC_BORDER ) {
+ base = FRAME_BORDER_WIDTH;
+ border = FRAME_X_BORDER;
+ } else
+ base = border = 0;
+
+ if( window->u.frame.decoration & DEC_TITLE )
+ base = FRAME_TITLE_HEIGHT;
- return FRAME_TITLE_HEIGHT + ( include_x_border ? FRAME_X_BORDER : 0 );
+ return base + ( include_x_border ? border : 0 );
}
-extern int frame_b( struct gwm_window *window, int include_x_border ) {
+static int frame_blr( struct gwm_window *window, int include_x_border ) {
- assert( window->type == WINDOW_FRAME );
+ int base, border;
- return FRAME_BORDER_WIDTH + ( include_x_border ? FRAME_X_BORDER : 0 );
+ assert( window->type == WINDOW_FRAME );
+
+ if( window->u.frame.decoration & DEC_BORDER ) {
+ base = FRAME_BORDER_WIDTH;
+ border = FRAME_X_BORDER;
+ } else
+ base = border = 0;
+
+ return base + ( include_x_border ? border : 0 );
+}
+
+extern int frame_b( struct gwm_window *window, int include_x_border ) {
+
+ return frame_blr( window, include_x_border );
}
extern int frame_l( struct gwm_window *window, int include_x_border ) {
- assert( window->type == WINDOW_FRAME );
-
- return FRAME_BORDER_WIDTH + ( include_x_border ? FRAME_X_BORDER : 0 );
+ return frame_blr( window, include_x_border );
}
extern int frame_r( struct gwm_window *window, int include_x_border ) {
- assert( window->type == WINDOW_FRAME );
-
- return FRAME_BORDER_WIDTH + ( include_x_border ? FRAME_X_BORDER : 0 );
+ return frame_blr( window, include_x_border );
}
extern int frame_xb( struct gwm_window *window ) {
assert( window->type == WINDOW_FRAME );
- return FRAME_X_BORDER;
+ return window->u.frame.decoration & DEC_BORDER ? FRAME_X_BORDER : 0;
}
extern void translate_child_to_frame( struct gwm_window *frame,
@@ -292,6 +312,26 @@ extern void apply_size_constraints( struct gwm_window *window, int *width,
}
}
+struct gwm_window *focus_frame;
+
+extern void deactivate_focus_frame( void ) {
+
+ uint32_t n;
+
+ if( !focus_frame )
+ return;
+
+ if( focus_frame->u.frame.decoration & ( DEC_TITLE | DEC_BORDER ) ) {
+ n = gwm_screens[ focus_frame->screen ].pixels[ COL_FRAME_INACTIVE ];
+ xcb_change_window_attributes( c, focus_frame->w, XCB_CW_BACK_PIXEL,
+ &n );
+ }
+
+ if( focus_frame->u.frame.decoration & DEC_TITLE )
+ queue_window_update( focus_frame, 0, 0, focus_frame->u.frame.width,
+ focus_frame->u.frame.height, FALSE );
+}
+
static enum _window_operation {
OP_NONE, OP_MOVE, OP_RESIZE
} window_op;
@@ -695,7 +735,8 @@ static void frame_button_press( struct gwm_window *window,
return;
window_op = ( ev->detail > 1 ) ==
- ( ev->event_y < frame_t( window, FALSE ) ) ? OP_RESIZE : OP_MOVE;
+ ( ( window->u.frame.decoration & DEC_TITLE ) &&
+ ev->event_y < frame_t( window, FALSE ) ) ? OP_RESIZE : OP_MOVE;
init_x = ev->root_x;
init_y = ev->root_y;
@@ -827,11 +868,14 @@ static void frame_enter_notify( struct gwm_window *window,
focus_frame = window;
- n = gwm_screens[ window->screen ].pixels[ COL_FRAME_ACTIVE ];
- xcb_change_window_attributes( c, window->w, XCB_CW_BACK_PIXEL, &n );
-
- queue_window_update( window, 0, 0, window->u.frame.width,
- window->u.frame.height, FALSE );
+ if( window->u.frame.decoration & ( DEC_TITLE | DEC_BORDER ) ) {
+ n = gwm_screens[ window->screen ].pixels[ COL_FRAME_ACTIVE ];
+ xcb_change_window_attributes( c, window->w, XCB_CW_BACK_PIXEL, &n );
+ }
+
+ if( window->u.frame.decoration & DEC_TITLE )
+ queue_window_update( window, 0, 0, window->u.frame.width,
+ window->u.frame.height, FALSE );
/* FIXME Defer all this focus stuff in case of multiple enter/leave
notifies. */
diff --git a/frame.h b/frame.h
index 21ce61b..b02b15d 100644
--- a/frame.h
+++ b/frame.h
@@ -1,6 +1,9 @@
#ifndef FRAME_H
#define FRAME_H
+extern struct gwm_window *focus_frame; /* the WINDOW_FRAME which has the
+ focus, if any */
+
extern int frame_t( struct gwm_window *window, int include_x_border );
extern int frame_b( struct gwm_window *window, int include_x_border );
extern int frame_l( struct gwm_window *window, int include_x_border );
@@ -20,6 +23,8 @@ extern void translate_frame_to_child( struct gwm_window *frame,
extern void apply_size_constraints( struct gwm_window *window, int *width,
int *height );
+extern void deactivate_focus_frame( void );
+
extern void synthetic_configure_notify( struct gwm_window *window );
extern event_handler frame_handlers[], childless_handlers[];
diff --git a/gwm.c b/gwm.c
index 4d9cbf0..2a3585b 100644
--- a/gwm.c
+++ b/gwm.c
@@ -89,6 +89,7 @@ xcb_atom_t atoms[ NUM_ATOMS ];
static const char *atom_names[ NUM_ATOMS ] = {
"COMPOUND_TEXT",
"MANAGER",
+ "_MOTIF_WM_HINTS",
"_NET_WM_NAME",
"UTF8_STRING",
"VERSION",
@@ -137,7 +138,7 @@ xcb_render_directformat_t dfmt_rgba8, dfmt_a8;
xcb_cursor_t cursors[ NUM_CURSORS ];
-struct gwm_window *fake_window, *focus_frame;
+struct gwm_window *fake_window;
const char *argv0;
static int flag_replace, flag_force;
@@ -1063,14 +1064,19 @@ static void start_managing_window( struct gwm_window *window,
window->u.managed.name = NULL;
window->u.managed.net_wm_name = 0;
window->u.managed.state = STATE_WITHDRAWN;
+#if USE_SHAPE
+ window->u.managed.shaped = have_extension[ EXT_SHAPE ] && shape &&
+ shape->bounding_shaped;
+#endif
frame->screen = window->screen;
frame->type = WINDOW_FRAME;
frame->u.frame.child = window;
frame->u.frame.button = button;
+ frame->u.frame.decoration = DEC_DEFAULT;
button->screen = window->screen;
button->type = WINDOW_BUTTON;
button->u.button.frame = frame;
-
+
for( i = 0; i < NUM_PROPS; i++ )
managed_property_change( window, i, props[ i ] );
@@ -1121,8 +1127,9 @@ static void start_managing_window( struct gwm_window *window,
xcb_create_window( c, XCB_COPY_FROM_PARENT, frame->w, geom->root,
frame->u.frame.x, frame->u.frame.y,
- frame->u.frame.width, frame->u.frame.height, 1,
- XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT,
+ frame->u.frame.width, frame->u.frame.height,
+ frame_xb( frame ), XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ XCB_COPY_FROM_PARENT,
XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL |
XCB_CW_BIT_GRAVITY | XCB_CW_OVERRIDE_REDIRECT |
XCB_CW_EVENT_MASK, values );
@@ -1145,8 +1152,9 @@ static void start_managing_window( struct gwm_window *window,
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE,
XCB_NONE, XCB_BUTTON_INDEX_ANY, 0x8000 );
-
- xcb_map_window( c, button->w );
+
+ if( frame->u.frame.decoration & DEC_TITLE )
+ xcb_map_window( c, button->w );
xcb_change_save_set( c, XCB_SET_MODE_INSERT, w );
@@ -1163,6 +1171,7 @@ static void start_managing_window( struct gwm_window *window,
xcb_reparent_window( c, w, frame->w, frame_l( frame, FALSE ),
frame_t( frame, FALSE ) );
+
if( !map_request ) {
values[ 0 ] = XCB_EVENT_MASK_STRUCTURE_NOTIFY |
XCB_EVENT_MASK_PROPERTY_CHANGE |
@@ -1178,8 +1187,8 @@ static void start_managing_window( struct gwm_window *window,
}
#if USE_SHAPE
- if( have_extension[ EXT_SHAPE ] && shape && shape->bounding_shaped )
- match_managed_shape( window, TRUE );
+ if( window->u.managed.shaped )
+ match_managed_shape( window );
#endif
/* Tell the client we've relocated their window with respect to the
@@ -1415,20 +1424,6 @@ extern void iconic_to_normal( struct gwm_window *window ) {
xcb_map_window( c, window->u.managed.frame->w );
}
-extern void deactivate_focus_frame( void ) {
-
- uint32_t n;
-
- if( !focus_frame )
- return;
-
- n = gwm_screens[ focus_frame->screen ].pixels[ COL_FRAME_INACTIVE ];
- xcb_change_window_attributes( c, focus_frame->w, XCB_CW_BACK_PIXEL, &n );
-
- queue_window_update( focus_frame, 0, 0, focus_frame->u.frame.width,
- focus_frame->u.frame.height, FALSE );
-}
-
extern void generic_expose( struct gwm_window *window,
xcb_expose_event_t *ev ) {
@@ -1683,11 +1678,8 @@ static void setup_display( void ) {
free( r );
}
- /* FIXME Also monitor EWMH client window properties:
- _MOTIF_WM_HINTS, to see what decoration clients want
- _NET_WM_NAME, UTF-8 in preference to WM_NAME
- _NET_WM_ICON, ARGB icon(s)
- and set _NET_FRAME_EXTENTS. */
+ /* FIXME Also monitor _NET_WM_ICON and set _NET_FRAME_EXTENTS. */
+ prop_atoms[ PROP__MOTIF_WM_HINTS ] = atoms[ ATOM__MOTIF_WM_HINTS ];
prop_atoms[ PROP__NET_WM_NAME ] = atoms[ ATOM__NET_WM_NAME ];
prop_atoms[ PROP_WM_COLORMAP_WINDOWS ] = atoms[ ATOM_WM_COLORMAP_WINDOWS ];
prop_atoms[ PROP_WM_HINTS ] = WM_HINTS;
@@ -1695,6 +1687,7 @@ static void setup_display( void ) {
prop_atoms[ PROP_WM_NORMAL_HINTS ] = WM_NORMAL_HINTS;
prop_atoms[ PROP_WM_PROTOCOLS ] = atoms[ ATOM_WM_PROTOCOLS ];
+ prop_types[ PROP__MOTIF_WM_HINTS ] = atoms[ ATOM__MOTIF_WM_HINTS ];
prop_types[ PROP__NET_WM_NAME ] = atoms[ ATOM_UTF8_STRING ];
prop_types[ PROP_WM_COLORMAP_WINDOWS ] = WINDOW;
prop_types[ PROP_WM_HINTS ] = WM_HINTS;
diff --git a/gwm.h b/gwm.h
index 03d2d9c..9cf219c 100644
--- a/gwm.h
+++ b/gwm.h
@@ -65,6 +65,7 @@ enum x_atom {
enum gwm_atom {
ATOM_COMPOUND_TEXT,
ATOM_MANAGER,
+ ATOM__MOTIF_WM_HINTS,
ATOM__NET_WM_NAME,
ATOM_UTF8_STRING,
ATOM_VERSION,
@@ -81,6 +82,7 @@ enum gwm_atom {
extern xcb_atom_t atoms[ NUM_ATOMS ];
enum gwm_property_type {
+ PROP__MOTIF_WM_HINTS,
PROP__NET_WM_NAME,
PROP_WM_COLORMAP_WINDOWS,
PROP_WM_HINTS,
@@ -186,6 +188,10 @@ extern xcb_cursor_t cursors[ NUM_CURSORS ];
#define STATE_NORMAL 1
#define STATE_ICONIC 3
+#define DEC_BORDER 0x1
+#define DEC_TITLE 0x2
+#define DEC_DEFAULT ( DEC_BORDER | DEC_TITLE )
+
struct gwm_window {
xcb_window_t w;
int screen;
@@ -200,6 +206,9 @@ struct gwm_window {
struct gwm_window *frame;
uint16_t border_width;
xcb_colormap_t cmap;
+#if USE_SHAPE
+ int shaped;
+#endif
/* from WM_COLORMAP_WINDOWS: */
xcb_window_t cmap_window;
/* from WM_HINTS: */
@@ -219,6 +228,7 @@ struct gwm_window {
struct _gwm_frame {
struct gwm_window *child, *button;
int x, y, width, height;
+ int decoration; /* see DEC_* above */
} frame;
struct _gwm_button {
struct gwm_window *frame;
@@ -237,8 +247,6 @@ struct gwm_window {
extern struct gwm_window *fake_window; /* a window created solely to hold the
WM_Sn selections */
-extern struct gwm_window *focus_frame; /* the WINDOW_FRAME which has the
- focus, if any */
extern const char *argv0;
@@ -305,8 +313,6 @@ extern void install_window_colormap( int screen, struct gwm_window *window,
extern void generic_expose( struct gwm_window *window,
xcb_expose_event_t *ev );
-extern void deactivate_focus_frame( void );
-
extern void iconic_to_normal( struct gwm_window *window );
extern void manage_window( xcb_window_t w, int map_request );
diff --git a/managed.c b/managed.c
index c98d47e..25525c0 100644
--- a/managed.c
+++ b/managed.c
@@ -117,6 +117,16 @@ static void async_get_property( struct gwm_window *window,
handle_managed_get_property, cp );
}
+#define MOTIF_WM_HINTS_DECORATIONS 0x2
+
+#define MOTIF_WM_HINTS_FLAGS_OFF 0
+#define MOTIF_WM_HINTS_DECORATIONS_OFF 2
+#define MOTIF_WM_HINTS_MIN_SIZE 3 /* ignore hint properties smaller than this */
+
+#define MOTIF_WM_HINTS_DEC_ALL 0x1
+#define MOTIF_WM_HINTS_DEC_BORDER 0x2
+#define MOTIF_WM_HINTS_DEC_TITLE 0x8
+
#define WM_HINTS_INPUT 0x1
#define WM_HINTS_STATE 0x2
@@ -152,11 +162,120 @@ extern void managed_property_change( struct gwm_window *window, int prop,
int i;
struct xcb_screen_t *screen;
int value_len;
-
+ int old_decoration;
+
assert( window->type == WINDOW_MANAGED );
switch( prop ) {
+ case PROP__MOTIF_WM_HINTS:
+ /* _MOTIF_WM_HINTS property. */
+ old_decoration = window->u.managed.frame->u.frame.decoration;
+
+ window->u.managed.frame->u.frame.decoration = DEC_DEFAULT;
+
+ if( p->format == 32 && p->value_len >= MOTIF_WM_HINTS_MIN_SIZE ) {
+ p32 = xcb_get_property_value( p );
+
+ if( p32[ MOTIF_WM_HINTS_FLAGS_OFF ] &
+ MOTIF_WM_HINTS_DECORATIONS ) {
+ if( p32[ MOTIF_WM_HINTS_DECORATIONS_OFF ] &
+ MOTIF_WM_HINTS_DEC_ALL ) {
+ window->u.managed.frame->u.frame.decoration =
+ DEC_BORDER | DEC_TITLE;
+
+ if( p32[ MOTIF_WM_HINTS_DECORATIONS_OFF ] &
+ MOTIF_WM_HINTS_DEC_BORDER )
+ window->u.managed.frame->u.frame.decoration &=
+ ~DEC_BORDER;
+
+ if( p32[ MOTIF_WM_HINTS_DECORATIONS_OFF ] &
+ MOTIF_WM_HINTS_DEC_TITLE )
+ window->u.managed.frame->u.frame.decoration &=
+ ~DEC_TITLE;
+ } else {
+ window->u.managed.frame->u.frame.decoration = 0;
+
+ if( p32[ MOTIF_WM_HINTS_DECORATIONS_OFF ] &
+ MOTIF_WM_HINTS_DEC_BORDER )
+ window->u.managed.frame->u.frame.decoration |=
+ DEC_BORDER;
+
+ if( p32[ MOTIF_WM_HINTS_DECORATIONS_OFF ] &
+ MOTIF_WM_HINTS_DEC_TITLE )
+ window->u.managed.frame->u.frame.decoration |=
+ DEC_TITLE;
+ }
+ }
+ }
+
+#if USE_SHAPE
+ if( window->u.managed.shaped )
+ /* Never apply borders to shaped windows. */
+ window->u.managed.frame->u.frame.decoration &= ~DEC_BORDER;
+#endif
+
+ if( window->u.managed.state == STATE_NORMAL &&
+ window->u.managed.frame->u.frame.decoration != old_decoration ) {
+ int new_decoration = window->u.managed.frame->u.frame.decoration;
+ int x, y, width, height;
+ uint32_t n[ 5 ];
+
+ window->u.managed.frame->u.frame.decoration = old_decoration;
+
+ translate_frame_to_child( window->u.managed.frame, &x, &y,
+ window->u.managed.frame->u.frame.x,
+ window->u.managed.frame->u.frame.y,
+ window->u.managed.border_width,
+ window->u.managed.win_gravity );
+
+ window->u.managed.frame->u.frame.decoration = new_decoration;
+
+ translate_child_to_frame( window->u.managed.frame, &x, &y,
+ &width, &height, x, y,
+ window->u.managed.frame->u.frame.width -
+ frame_l( window->u.managed.frame,
+ FALSE ) -
+ frame_r( window->u.managed.frame,
+ FALSE ),
+ window->u.managed.frame->u.frame.height -
+ frame_t( window->u.managed.frame,
+ FALSE ) -
+ frame_b( window->u.managed.frame,
+ FALSE ),
+ window->u.managed.border_width,
+ window->u.managed.win_gravity );
+
+ if( new_decoration & DEC_TITLE )
+ xcb_map_window( c,
+ window->u.managed.frame->u.frame.button->w );
+ else
+ xcb_unmap_window( c,
+ window->u.managed.frame->u.frame.button->w );
+
+ n[ 0 ] = frame_l( window->u.managed.frame, FALSE );
+ n[ 1 ] = frame_l( window->u.managed.frame, FALSE );
+ xcb_configure_window( c, window->w, XCB_CONFIG_WINDOW_X |
+ XCB_CONFIG_WINDOW_Y, n );
+
+ n[ 0 ] = x;
+ n[ 1 ] = y;
+ n[ 2 ] = width;
+ n[ 3 ] = height;
+ n[ 4 ] = frame_xb( window->u.managed.frame );
+ /* We'll also notify the client of any changes, in the
+ ConfigureNotify handler for the event we expect to receive in
+ response to this request. */
+ xcb_configure_window( c, window->u.managed.frame->w,
+ XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
+ XCB_CONFIG_WINDOW_WIDTH |
+ XCB_CONFIG_WINDOW_HEIGHT |
+ XCB_CONFIG_WINDOW_BORDER_WIDTH, n );
+ }
+
+ break;
+
case PROP__NET_WM_NAME:
+ /* _NET_WM_NAME property (see EMWH "Application Window Properties". */
if( window->u.managed.name )
free( window->u.managed.name );
@@ -167,7 +286,8 @@ extern void managed_property_change( struct gwm_window *window, int prop,
window->u.managed.name[ p->value_len ] = 0;
window->u.managed.net_wm_name = 1;
- if( window->u.managed.state == STATE_NORMAL )
+ if( window->u.managed.state == STATE_NORMAL &&
+ ( window->u.managed.frame->u.frame.decoration & DEC_TITLE ) )
queue_window_update( window->u.managed.frame, 0, 0,
window->u.managed.frame->u.frame.width,
frame_t( window->u.managed.frame, FALSE ),
@@ -243,7 +363,8 @@ extern void managed_property_change( struct gwm_window *window, int prop,
else
window->u.managed.name = NULL;
- if( window->u.managed.state == STATE_NORMAL )
+ if( window->u.managed.state == STATE_NORMAL &&
+ ( window->u.managed.frame->u.frame.decoration & DEC_TITLE ) )
queue_window_update( window->u.managed.frame, 0, 0,
window->u.managed.frame->u.frame.width,
frame_t( window->u.managed.frame, FALSE ),
@@ -474,9 +595,9 @@ static void managed_colormap_notify( struct gwm_window *window,
}
#if USE_SHAPE
-extern void match_managed_shape( struct gwm_window *window, int shaped ) {
+extern void match_managed_shape( struct gwm_window *window ) {
- if( shaped ) {
+ if( window->u.managed.shaped ) {
xcb_rectangle_t rect;
rect.x = rect.y = 0;
@@ -498,8 +619,15 @@ extern void match_managed_shape( struct gwm_window *window, int shaped ) {
static void managed_shape_notify( struct gwm_window *window,
xcb_shape_notify_event_t *ev ) {
- if( ev->shape_kind == XCB_SHAPE_SK_BOUNDING )
- match_managed_shape( window, ev->shaped );
+ if( ev->shape_kind == XCB_SHAPE_SK_BOUNDING ) {
+ if( window->u.managed.shaped != ev->shaped &&
+ !( window->u.managed.shaped = ev->shaped ) )
+ /* The client is no longer shaped. Retrieve its original
+ _MOTIF_WM_HINTS, since we might now want to apply a border. */
+ async_get_property( window, PROP__MOTIF_WM_HINTS );
+
+ match_managed_shape( window );
+ }
}
#endif
diff --git a/managed.h b/managed.h
index d366ac8..8dc1ec2 100644
--- a/managed.h
+++ b/managed.h
@@ -2,7 +2,7 @@
#define MANAGED_H
#if USE_SHAPE
-extern void match_managed_shape( struct gwm_window *window, int shaped );
+extern void match_managed_shape( struct gwm_window *window );
#endif
extern void managed_property_change( struct gwm_window *window, int prop,
diff --git a/root.c b/root.c
index 39a09a9..dead2ed 100644
--- a/root.c
+++ b/root.c
@@ -28,6 +28,7 @@
#include "gwm.h"
#include "actions.h"
+#include "frame.h"
#include "keyboard.h"
#include "managed.h"
#include "root.h"