summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Wong <gtw@gnu.org>2009-09-01 14:48:01 -0600
committerGary Wong <gtw@gnu.org>2009-09-01 14:48:01 -0600
commit86c8dfa5b8017f7a940ed2e7333ee27a4af199a8 (patch)
treeba4a17ca0804df2c89eab84dd21508158cfad531
parentcf1b6f1e83b798ad54bdf6147dc3557220d7312a (diff)
Replace passive_grab with pointer_demux (redirecting events on client side).
-rw-r--r--ChangeLog19
-rw-r--r--button.c31
-rw-r--r--frame.c18
-rw-r--r--gwm.c39
-rw-r--r--gwm.h10
-rw-r--r--window-table.c3
6 files changed, 70 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 8e1981a..ec8610d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,27 @@
+Tue Sep 1 14:40:15 2009 Gary Wong <gtw@gnu.org>
+
+ * gwm.c (handle_events): Replace passive_grab with pointer_demux,
+ which redirects events on the client side.
+ (start_managing_window): Set initial event mask for
+ the frame button window, instead of an explicit GrabButton.
+ * button.c (button_button_press, button_button_release): Use
+ pointer_demux instead of GrabButton.
+ (button_enter_notify, button_leave_notify): Inspect event parameters
+ to determine which window is entered/left.
+ * frame.c (frame_button_press, frame_button_release): Use
+ pointer_demux instead of passive_grab.
+ (frame_motion_notify, frame_destroy_notify): Likewise.
+ (frame_enter_notify): Ignore events when pointer_demux is set.
+ * window-table.c (forget_window): Remove pointer_demux from
+ forgotten windows.
+
2009-08-31 Gary Wong <gtw@gnu.org>
* gwm.c (show_atom): Declare predefined_names[] as const.
(show_error): Declare render_strings[] as const.
(show_event): Declare event_names[] as const.
(setup_display): Use auto storage class for wm_atom_str.
-
+
2009-08-31 Gary Wong <gtw@gnu.org>
* gwm.c (start_managing_window): Create "border region" input-only
diff --git a/button.c b/button.c
index 7abcc96..bfcfda5 100644
--- a/button.c
+++ b/button.c
@@ -69,12 +69,16 @@ static void set_button_active( struct gwm_window *window, int new ) {
static void button_button_press( struct gwm_window *window,
xcb_button_press_event_t *ev ) {
- if( initial_press( ev ) )
- /* No buttons were pressed; grab initiates. */
- set_button_active( window, TRUE );
+ if( !pointer_demux ) {
+ /* Initiate grab. */
+ pointer_demux = window->w;
- if( ev->detail == 3 && ( window->u.button.frame->u.frame.child->
- u.managed.protocols & PROTOCOL_DELETE_WINDOW ) )
+ set_button_active( window, TRUE );
+ }
+
+ if( ( window->u.button.frame->u.frame.child->u.managed.protocols &
+ PROTOCOL_DELETE_WINDOW ) && ( ev->detail == 3 ||
+ ( ev->state & XCB_BUTTON_MASK_3 ) ) )
/* Button 3 will kill the client, even if it supports WM_DELETE_WINDOW.
Change to CURSOR_DESTROY to indicate the distinction. */
xcb_change_active_pointer_grab( c, cursors[ CURSOR_DESTROY ],
@@ -87,6 +91,9 @@ static void button_button_press( struct gwm_window *window,
static void button_button_release( struct gwm_window *window,
xcb_button_release_event_t *ev ) {
+ if( !pointer_demux )
+ return;
+
if( final_release( ev ) ) {
/* Final button released; grab terminates. */
if( button_active ) {
@@ -115,6 +122,8 @@ static void button_button_release( struct gwm_window *window,
set_button_active( window, FALSE );
}
+
+ pointer_demux = XCB_NONE;
} else if( ev->detail == 3 && ( window->u.button.frame->u.frame.child->
u.managed.protocols &
PROTOCOL_DELETE_WINDOW ) )
@@ -130,13 +139,21 @@ static void button_button_release( struct gwm_window *window,
static void button_enter_notify( struct gwm_window *window,
xcb_enter_notify_event_t *ev ) {
- set_button_active( window, TRUE );
+ if( !pointer_demux )
+ return;
+
+ if( ev->event == window->w )
+ set_button_active( window, TRUE );
}
static void button_leave_notify( struct gwm_window *window,
xcb_leave_notify_event_t *ev ) {
- set_button_active( window, FALSE );
+ if( !pointer_demux )
+ return;
+
+ if( ev->event == window->w )
+ set_button_active( window, FALSE );
}
const event_handler button_handlers[] = {
diff --git a/frame.c b/frame.c
index e750211..793bace 100644
--- a/frame.c
+++ b/frame.c
@@ -731,14 +731,10 @@ static void recalc_size( struct gwm_window *window, int x, int y,
static void frame_button_press( struct gwm_window *window,
xcb_button_press_event_t *ev ) {
- if( !initial_press( ev ) )
+ if( pointer_demux || ev->child == window->u.frame.child->w )
return;
- if( ev->child == window->u.frame.child->w ) {
- passive_grab = XCB_NONE;
-
- return;
- }
+ pointer_demux = window->w;
window_op = ( ev->detail > 1 ) ==
( ( window->u.frame.decoration & DEC_TITLE ) &&
@@ -768,7 +764,7 @@ static void frame_motion_notify( struct gwm_window *window,
uint32_t values[ 2 ];
- if( window->w != passive_grab )
+ if( !pointer_demux )
return;
/* Hint to the server that we're ready for further motion events. */
@@ -841,7 +837,7 @@ static void frame_motion_notify( struct gwm_window *window,
static void frame_button_release( struct gwm_window *window,
xcb_button_release_event_t *ev ) {
- if( !final_release( ev ) || window->w != passive_grab )
+ if( !final_release( ev ) || !pointer_demux )
return;
if( moved )
@@ -859,13 +855,15 @@ static void frame_button_release( struct gwm_window *window,
forget_window( feedback );
feedback = NULL;
}
+
+ pointer_demux = XCB_NONE;
}
static void frame_enter_notify( struct gwm_window *window,
xcb_enter_notify_event_t *ev ) {
uint32_t n;
- if( focus_frame == window )
+ if( pointer_demux || focus_frame == window )
/* We have the focus already -- probably an inferior change or
ungrab. */
return;
@@ -929,7 +927,7 @@ static void frame_enter_notify( struct gwm_window *window,
static void frame_destroy_notify( struct gwm_window *window,
xcb_destroy_notify_event_t *ev ) {
- if( window->w != passive_grab )
+ if( window->w != pointer_demux )
return;
if( moved )
diff --git a/gwm.c b/gwm.c
index 9ef47e6..4b699e2 100644
--- a/gwm.c
+++ b/gwm.c
@@ -1141,7 +1141,9 @@ static void start_managing_window( struct gwm_window *window,
values[ 1 ] = gwm_screens[ frame->screen ].pixels[
COL_BORDER ]; /* border pixel */
values[ 2 ] = TRUE; /* override redirect */
- values[ 3 ] = XCB_EVENT_MASK_EXPOSURE;
+ values[ 3 ] = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
+ XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_OWNER_GRAB_BUTTON;
xcb_create_window( c, XCB_COPY_FROM_PARENT, button->w, frame->w,
2, 1, button_size( button, FALSE ),
button_size( button, FALSE ), button_xb( button ),
@@ -1149,12 +1151,6 @@ static void start_managing_window( struct gwm_window *window,
XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL |
XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, values );
- xcb_grab_button( c, FALSE, button->w, XCB_EVENT_MASK_BUTTON_PRESS |
- XCB_EVENT_MASK_BUTTON_RELEASE |
- 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 );
-
if( frame->u.frame.decoration & DEC_TITLE )
xcb_map_window( c, button->w );
@@ -1441,8 +1437,7 @@ extern void generic_expose( struct gwm_window *window,
queue_window_update( window, ev->x, ev->y, ev->width, ev->height, TRUE );
}
-xcb_window_t passive_grab; /* the window which has the pointer automatically
- grabbed via a button press, or XCB_NONE */
+xcb_window_t pointer_demux;
static void handle_fake_change_property( unsigned int sequence, void *reply,
xcb_generic_error_t *error,
@@ -2219,23 +2214,27 @@ static void handle_events( void ) {
break;
case XCB_BUTTON_PRESS:
- w = ( (xcb_button_press_event_t *) ev )->event;
+ w = pointer_demux ?
+ pointer_demux : ( (xcb_button_press_event_t *) ev )->event;
latest_timestamp = ( (xcb_button_press_event_t *) ev )->time;
break;
case XCB_BUTTON_RELEASE:
- w = ( (xcb_button_release_event_t *) ev )->event;
+ w = pointer_demux ?
+ pointer_demux : ( (xcb_button_release_event_t *) ev )->event;
latest_timestamp = ( (xcb_button_release_event_t *) ev )->time;
break;
case XCB_MOTION_NOTIFY:
- w = ( (xcb_motion_notify_event_t *) ev )->event;
+ w = pointer_demux ?
+ pointer_demux : ( (xcb_motion_notify_event_t *) ev )->event;
latest_timestamp = ( (xcb_motion_notify_event_t *) ev )->time;
break;
case XCB_ENTER_NOTIFY:
case XCB_LEAVE_NOTIFY:
- w = ( (xcb_enter_notify_event_t *) ev )->event;
+ w = pointer_demux ?
+ pointer_demux : ( (xcb_enter_notify_event_t *) ev )->event;
latest_timestamp = ( (xcb_enter_notify_event_t *) ev )->time;
break;
@@ -2358,12 +2357,6 @@ static void handle_events( void ) {
warning( "handle_events: received reply message" );
break;
- case XCB_BUTTON_PRESS:
- if( initial_press( (xcb_button_press_event_t *) ev )
- && !passive_grab )
- passive_grab = w;
- break;
-
case XCB_KEYMAP_NOTIFY:
break;
@@ -2393,14 +2386,6 @@ static void handle_events( void ) {
handler( window, ev );
}
- /* Global handling for events (after specific window handler). */
- switch( event_type ) {
- case XCB_BUTTON_RELEASE:
- if( final_release( (xcb_button_release_event_t *) ev ) )
- passive_grab = XCB_NONE;
- break;
- }
-
/* FIXME other features:
- make override-redirect windows translucent
- desktop menu & other key/pointer bindings
diff --git a/gwm.h b/gwm.h
index ca80a36..d1d17ca 100644
--- a/gwm.h
+++ b/gwm.h
@@ -306,17 +306,17 @@ extern void show_error( xcb_generic_error_t *error );
typedef void ( *event_handler )( struct gwm_window *window,
xcb_generic_event_t *ev );
-/* Return TRUE iff an event is the only button pressed (and so would
- initiate a passive grab). */
+/* Return TRUE iff an event is the only button pressed. */
extern CONST int initial_press( xcb_button_press_event_t *ev );
/* Return TRUE iff an event is the release of the last button (and so would
terminate a passive grab). */
extern CONST int final_release( xcb_button_release_event_t *ev );
-/* The window which has the pointer automatically grabbed via a button
- press, or XCB_NONE. */
-extern xcb_window_t passive_grab;
+/* The window whose event handler(s) should be invoked for pointer events.
+ Unlike pointer grabs, this mechanism is implemented entirely on the
+ client side, and has no effect on the contents of events. */
+extern xcb_window_t pointer_demux;
/* Install a window's colormap on a screen, or the default colormap if
unspecified. */
diff --git a/window-table.c b/window-table.c
index 1ab65f7..6970171 100644
--- a/window-table.c
+++ b/window-table.c
@@ -317,6 +317,9 @@ extern MALLOC struct gwm_window *add_window( xcb_window_t w ) {
extern void forget_window( struct gwm_window *window ) {
+ if( pointer_demux == window->w )
+ pointer_demux = XCB_NONE;
+
table_delete( &windows, window->w );
table_delete( &update_windows, window->w );
free( window );