From 69dae32c37ff7771775068f24499b374e433f8bd Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 11 Dec 2001 04:03:58 +0000 Subject: [PATCH] Rework the click-client-area-to-focus support to use synchronous grabs, 2001-12-10 Havoc Pennington Rework the click-client-area-to-focus support to use synchronous grabs, avoids a big mess, lets us pass through click when required (for dock/desktop). Disadvantage is all left-button clicks now require window manager approval. ;-) * src/display.c (event_callback): don't focus dock/desktop when the mouse enters them; require a click. (meta_change_button_grab): allow sync grabs (meta_display_grab_unfocused_window_buttons): establish a synchronous grab and maintain it all the time, rename to meta_display_grab_focus_window_button * src/window.c: change to reflect display.c --- ChangeLog | 16 +++++++++ src/display.c | 84 ++++++++++++++++++++++++++++++++++++----------- src/display.h | 9 +++-- src/keybindings.c | 6 +++- src/screen.c | 10 +----- src/window.c | 59 ++------------------------------- src/window.h | 3 -- 7 files changed, 92 insertions(+), 95 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad234494a..39622026c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2001-12-10 Havoc Pennington + + Rework the click-client-area-to-focus support to use synchronous + grabs, avoids a big mess, lets us pass through click when + required (for dock/desktop). Disadvantage is all left-button + clicks now require window manager approval. ;-) + + * src/display.c (event_callback): don't focus dock/desktop when + the mouse enters them; require a click. + (meta_change_button_grab): allow sync grabs + (meta_display_grab_unfocused_window_buttons): establish a + synchronous grab and maintain it all the time, rename to + meta_display_grab_focus_window_button + + * src/window.c: change to reflect display.c + 2001-12-10 Havoc Pennington * src/window.c (meta_window_update_unfocused_button_grabs): oops, diff --git a/src/display.c b/src/display.c index d0e604935..d1218932e 100644 --- a/src/display.c +++ b/src/display.c @@ -704,24 +704,58 @@ event_callback (XEvent *event, if (g_getenv ("METACITY_DEBUG_BUTTON_GRABS")) grab_mask |= ControlMask; - if (!window->unfocused_buttons_grabbed && - (event->xbutton.state & grab_mask) == 0) + if ((event->xbutton.state & grab_mask) == 0 && + event->xbutton.button != 1) { - ; /* nothing, not getting event from our button grabs, - * rather from a client that just let button presses - * pass through to our frame, and we don't have - * the click-to-focus first-click-to-raise grab - */ + /* Two possible sources of an unmodified event; + * one is a client that's letting button presses + * pass through to the frame, the other is + * our focus_window_grab on unmodified button 1. + * In this case, we are not button 1, so we just + * ignore the whole thing. + */ + ; } else if (event->xbutton.button == 1) { - meta_window_raise (window); + /* We always raise in click-to-focus, and + * raise only if Alt is down for sloppy/mouse + * (sloppy/mouse allow left-click without raising). + * I'm not sure I have a rationale for this. + */ + if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK || + ((event->xbutton.state & grab_mask) != 0)) + meta_window_raise (window); + meta_window_focus (window, event->xbutton.time); + if (!frame_was_receiver && + (event->xbutton.state & grab_mask) == 0) + { + /* This is from our synchronous grab since + * it has no modifiers and was on the client window + */ + int mode; + + /* Eat clicks used to focus a window, except + * pass through when focusing a dock/desktop + */ + if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK && + !window->has_focus && + window->type != META_WINDOW_DOCK && + window->type != META_WINDOW_DESKTOP) + mode = AsyncPointer; /* eat focus click */ + else + mode = ReplayPointer; /* give event back */ + + XAllowEvents (display->xdisplay, + mode, event->xbutton.time); + } + /* you can move on alt-click but not on - * first-unmodified-click + * the click-to-focus */ - if (!window->unfocused_buttons_grabbed) + if ((event->xbutton.state & grab_mask) != 0) begin_move = TRUE; } else if (event->xbutton.button == 2) @@ -769,7 +803,9 @@ event_callback (XEvent *event, { case META_FOCUS_MODE_SLOPPY: case META_FOCUS_MODE_MOUSE: - meta_window_focus (window, event->xcrossing.time); + if (window->type != META_WINDOW_DOCK && + window->type != META_WINDOW_DESKTOP) + meta_window_focus (window, event->xcrossing.time); break; case META_FOCUS_MODE_CLICK: break; @@ -1644,9 +1680,14 @@ static void meta_change_button_grab (MetaDisplay *display, Window xwindow, gboolean grab, + gboolean sync, int button, int modmask) { + /* Instead of this hacky mess copied from fvwm, WindowMaker just + * grabs with all numlock/scrolllock combinations and doesn't grab + * for other weird bits. + */ int ignored_mask; g_return_if_fail ((modmask & INTERESTING_MODIFIERS) == modmask); @@ -1671,7 +1712,8 @@ meta_change_button_grab (MetaDisplay *display, xwindow, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | PointerMotionHintMask, - GrabModeAsync, GrabModeAsync, + sync ? GrabModeSync : GrabModeAsync, + GrabModeAsync, False, None); else XUngrabButton (display->xdisplay, button, modmask | ignored_mask, @@ -1709,6 +1751,7 @@ meta_display_grab_window_buttons (MetaDisplay *display, meta_change_button_grab (display, xwindow, TRUE, + FALSE, i, Mod1Mask); @@ -1718,6 +1761,7 @@ meta_display_grab_window_buttons (MetaDisplay *display, if (debug) meta_change_button_grab (display, xwindow, TRUE, + FALSE, i, ControlMask); ++i; @@ -1734,10 +1778,10 @@ meta_display_ungrab_window_buttons (MetaDisplay *display, while (i < 4) { meta_change_button_grab (display, xwindow, - FALSE, i, Mod1Mask); + FALSE, FALSE, i, Mod1Mask); if (debug) meta_change_button_grab (display, xwindow, - FALSE, i, ControlMask); + FALSE, FALSE, i, ControlMask); ++i; } @@ -1745,8 +1789,8 @@ meta_display_ungrab_window_buttons (MetaDisplay *display, /* Grab buttons we only grab while unfocused in click-to-focus mode */ void -meta_display_grab_unfocused_window_buttons (MetaDisplay *display, - Window xwindow) +meta_display_grab_focus_window_button (MetaDisplay *display, + Window xwindow) { /* Grab button 1 for activating unfocused windows */ meta_verbose ("Grabbing unfocused window buttons for 0x%lx\n", xwindow); @@ -1762,7 +1806,7 @@ meta_display_grab_unfocused_window_buttons (MetaDisplay *display, { meta_change_button_grab (display, xwindow, - TRUE, i, 0); + TRUE, TRUE, i, 0); ++i; } @@ -1770,8 +1814,8 @@ meta_display_grab_unfocused_window_buttons (MetaDisplay *display, } void -meta_display_ungrab_unfocused_window_buttons (MetaDisplay *display, - Window xwindow) +meta_display_ungrab_focus_window_button (MetaDisplay *display, + Window xwindow) { meta_verbose ("Ungrabbing unfocused window buttons for 0x%lx\n", xwindow); @@ -1780,7 +1824,7 @@ meta_display_ungrab_unfocused_window_buttons (MetaDisplay *display, while (i < 2) { meta_change_button_grab (display, xwindow, - FALSE, i, 0); + FALSE, TRUE, i, 0); ++i; } diff --git a/src/display.h b/src/display.h index 6416cffe6..dc8164ac5 100644 --- a/src/display.h +++ b/src/display.h @@ -195,11 +195,10 @@ void meta_display_grab_window_buttons (MetaDisplay *display, void meta_display_ungrab_window_buttons (MetaDisplay *display, Window xwindow); -void meta_display_grab_unfocused_window_buttons (MetaDisplay *display, - Window xwindow); -void meta_display_ungrab_unfocused_window_buttons (MetaDisplay *display, - Window xwindow); - +void meta_display_grab_focus_window_button (MetaDisplay *display, + Window xwindow); +void meta_display_ungrab_focus_window_button (MetaDisplay *display, + Window xwindow); /* make a request to ensure the event serial has changed */ void meta_display_increment_event_serial (MetaDisplay *display); diff --git a/src/keybindings.c b/src/keybindings.c index 9d00f6ec4..e8c550c18 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -169,7 +169,11 @@ meta_change_keygrab (MetaDisplay *display, * all combinations of IGNORED_MODIFIERS. * X provides no better way to do this. */ - + /* Instead of this hacky mess copied from fvwm, WindowMaker just + * grabs with all numlock/scrolllock combinations and doesn't grab + * for other weird bits. + */ + /* modmask can't contain any non-interesting modifiers */ g_return_if_fail ((modmask & INTERESTING_MODIFIERS) == modmask); diff --git a/src/screen.c b/src/screen.c index cfcfaeba6..3584248fc 100644 --- a/src/screen.c +++ b/src/screen.c @@ -545,18 +545,10 @@ update_num_workspaces (MetaScreen *screen) } } -static void -update_grabs_func (MetaScreen *screen, MetaWindow *window, - gpointer user_data) -{ - meta_window_update_unfocused_button_grabs (window); -} - - static void update_focus_mode (MetaScreen *screen) { - meta_screen_foreach_window (screen, update_grabs_func, NULL); + /* nothing to do anymore */ ; } void diff --git a/src/window.c b/src/window.c index a487a692c..3825dbf8d 100644 --- a/src/window.c +++ b/src/window.c @@ -304,7 +304,6 @@ meta_window_new (MetaDisplay *display, Window xwindow, window->keys_grabbed = FALSE; window->grab_on_frame = FALSE; window->all_keys_grabbed = FALSE; - window->unfocused_buttons_grabbed = FALSE; window->withdrawn = FALSE; window->initial_workspace_set = FALSE; window->calc_placement = FALSE; @@ -423,7 +422,7 @@ meta_window_new (MetaDisplay *display, Window xwindow, meta_window_grab_keys (window); meta_display_grab_window_buttons (window->display, window->xwindow); - meta_window_update_unfocused_button_grabs (window); + meta_display_grab_focus_window_button (window->display, window->xwindow); /* For the workspace, first honor hints, * if that fails put transients with parents, @@ -696,6 +695,7 @@ meta_window_free (MetaWindow *window) meta_window_ungrab_keys (window); meta_display_ungrab_window_buttons (window->display, window->xwindow); + meta_display_ungrab_focus_window_button (window->display, window->xwindow); meta_display_unregister_x_window (window->display, window->xwindow); @@ -2024,59 +2024,6 @@ meta_window_focus (MetaWindow *window, } } -void -meta_window_update_unfocused_button_grabs (MetaWindow *window) -{ - /* Grab buttons if we're unfocused and in click-to-focus mode, - * ungrab otherwise, never grab on panels, menus, etc. - */ - if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK) - { - if (window->unfocused_buttons_grabbed) - { - if (window->has_focus) - { - /* Focused so undo grab */ - meta_verbose ("Ungrabbing on focused window %s\n", - window->desc); - meta_display_ungrab_unfocused_window_buttons (window->display, - window->xwindow); - window->unfocused_buttons_grabbed = FALSE; - } - } - else - { - /* FIXME This type thing is a temporary hack; what we need to - * do is focus these windows, but pass thru click. What we - * do now is ignore clicks on them. - */ - if (!window->has_focus && - window->type != META_WINDOW_DOCK && - window->type != META_WINDOW_DESKTOP) - { - /* Not focused so grab */ - meta_verbose ("Grabbing on unfocused window %s since mode is click-to-focus\n", - window->desc); - meta_display_grab_unfocused_window_buttons (window->display, - window->xwindow); - window->unfocused_buttons_grabbed = TRUE; - } - } - } - else - { - if (window->unfocused_buttons_grabbed) - { - /* Not in click-to-focus so undo grab */ - meta_verbose ("Ungrabbing on window %s since mode is not click-to-focus\n", - window->desc); - meta_display_ungrab_unfocused_window_buttons (window->display, - window->xwindow); - window->unfocused_buttons_grabbed = FALSE; - } - } -} - void meta_window_change_workspace (MetaWindow *window, MetaWorkspace *workspace) @@ -2665,7 +2612,6 @@ meta_window_notify_focus (MetaWindow *window, window->has_focus = TRUE; if (window->frame) meta_frame_queue_draw (window->frame); - meta_window_update_unfocused_button_grabs (window); } else if (event->type == FocusOut || event->type == UnmapNotify) @@ -2681,7 +2627,6 @@ meta_window_notify_focus (MetaWindow *window, window->has_focus = FALSE; if (window->frame) meta_frame_queue_draw (window->frame); - meta_window_update_unfocused_button_grabs (window); } /* Now set _NET_ACTIVE_WINDOW hint */ diff --git a/src/window.h b/src/window.h index edc528de3..974465678 100644 --- a/src/window.h +++ b/src/window.h @@ -173,9 +173,6 @@ struct _MetaWindow guint keys_grabbed : 1; /* normal keybindings grabbed */ guint grab_on_frame : 1; /* grabs are on the frame */ guint all_keys_grabbed : 1; /* AnyKey grabbed */ - - /* Used by display.c */ - guint unfocused_buttons_grabbed : 1; /* have the unmodified buttons grabbed */ /* Set if the reason for unmanaging the window is that * it was withdrawn