Rework the click-client-area-to-focus support to use synchronous grabs,

2001-12-10  Havoc Pennington  <hp@pobox.com>

        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
This commit is contained in:
Havoc Pennington 2001-12-11 04:03:58 +00:00 committed by Havoc Pennington
parent ac7524508b
commit 69dae32c37
7 changed files with 92 additions and 95 deletions

View File

@ -1,3 +1,19 @@
2001-12-10 Havoc Pennington <hp@pobox.com>
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 <hp@pobox.com> 2001-12-10 Havoc Pennington <hp@pobox.com>
* src/window.c (meta_window_update_unfocused_button_grabs): oops, * src/window.c (meta_window_update_unfocused_button_grabs): oops,

View File

@ -704,24 +704,58 @@ event_callback (XEvent *event,
if (g_getenv ("METACITY_DEBUG_BUTTON_GRABS")) if (g_getenv ("METACITY_DEBUG_BUTTON_GRABS"))
grab_mask |= ControlMask; grab_mask |= ControlMask;
if (!window->unfocused_buttons_grabbed && if ((event->xbutton.state & grab_mask) == 0 &&
(event->xbutton.state & grab_mask) == 0) event->xbutton.button != 1)
{ {
; /* nothing, not getting event from our button grabs, /* Two possible sources of an unmodified event;
* rather from a client that just let button presses * one is a client that's letting button presses
* pass through to our frame, and we don't have * pass through to the frame, the other is
* the click-to-focus first-click-to-raise grab * 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) 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); 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 /* 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; begin_move = TRUE;
} }
else if (event->xbutton.button == 2) else if (event->xbutton.button == 2)
@ -769,7 +803,9 @@ event_callback (XEvent *event,
{ {
case META_FOCUS_MODE_SLOPPY: case META_FOCUS_MODE_SLOPPY:
case META_FOCUS_MODE_MOUSE: 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; break;
case META_FOCUS_MODE_CLICK: case META_FOCUS_MODE_CLICK:
break; break;
@ -1644,9 +1680,14 @@ static void
meta_change_button_grab (MetaDisplay *display, meta_change_button_grab (MetaDisplay *display,
Window xwindow, Window xwindow,
gboolean grab, gboolean grab,
gboolean sync,
int button, int button,
int modmask) 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; int ignored_mask;
g_return_if_fail ((modmask & INTERESTING_MODIFIERS) == modmask); g_return_if_fail ((modmask & INTERESTING_MODIFIERS) == modmask);
@ -1671,7 +1712,8 @@ meta_change_button_grab (MetaDisplay *display,
xwindow, False, xwindow, False,
ButtonPressMask | ButtonReleaseMask | ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | PointerMotionHintMask, PointerMotionMask | PointerMotionHintMask,
GrabModeAsync, GrabModeAsync, sync ? GrabModeSync : GrabModeAsync,
GrabModeAsync,
False, None); False, None);
else else
XUngrabButton (display->xdisplay, button, modmask | ignored_mask, XUngrabButton (display->xdisplay, button, modmask | ignored_mask,
@ -1709,6 +1751,7 @@ meta_display_grab_window_buttons (MetaDisplay *display,
meta_change_button_grab (display, meta_change_button_grab (display,
xwindow, xwindow,
TRUE, TRUE,
FALSE,
i, Mod1Mask); i, Mod1Mask);
@ -1718,6 +1761,7 @@ meta_display_grab_window_buttons (MetaDisplay *display,
if (debug) if (debug)
meta_change_button_grab (display, xwindow, meta_change_button_grab (display, xwindow,
TRUE, TRUE,
FALSE,
i, ControlMask); i, ControlMask);
++i; ++i;
@ -1734,10 +1778,10 @@ meta_display_ungrab_window_buttons (MetaDisplay *display,
while (i < 4) while (i < 4)
{ {
meta_change_button_grab (display, xwindow, meta_change_button_grab (display, xwindow,
FALSE, i, Mod1Mask); FALSE, FALSE, i, Mod1Mask);
if (debug) if (debug)
meta_change_button_grab (display, xwindow, meta_change_button_grab (display, xwindow,
FALSE, i, ControlMask); FALSE, FALSE, i, ControlMask);
++i; ++i;
} }
@ -1745,8 +1789,8 @@ meta_display_ungrab_window_buttons (MetaDisplay *display,
/* Grab buttons we only grab while unfocused in click-to-focus mode */ /* Grab buttons we only grab while unfocused in click-to-focus mode */
void void
meta_display_grab_unfocused_window_buttons (MetaDisplay *display, meta_display_grab_focus_window_button (MetaDisplay *display,
Window xwindow) Window xwindow)
{ {
/* Grab button 1 for activating unfocused windows */ /* Grab button 1 for activating unfocused windows */
meta_verbose ("Grabbing unfocused window buttons for 0x%lx\n", xwindow); 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, meta_change_button_grab (display,
xwindow, xwindow,
TRUE, i, 0); TRUE, TRUE, i, 0);
++i; ++i;
} }
@ -1770,8 +1814,8 @@ meta_display_grab_unfocused_window_buttons (MetaDisplay *display,
} }
void void
meta_display_ungrab_unfocused_window_buttons (MetaDisplay *display, meta_display_ungrab_focus_window_button (MetaDisplay *display,
Window xwindow) Window xwindow)
{ {
meta_verbose ("Ungrabbing unfocused window buttons for 0x%lx\n", 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) while (i < 2)
{ {
meta_change_button_grab (display, xwindow, meta_change_button_grab (display, xwindow,
FALSE, i, 0); FALSE, TRUE, i, 0);
++i; ++i;
} }

View File

@ -195,11 +195,10 @@ void meta_display_grab_window_buttons (MetaDisplay *display,
void meta_display_ungrab_window_buttons (MetaDisplay *display, void meta_display_ungrab_window_buttons (MetaDisplay *display,
Window xwindow); Window xwindow);
void meta_display_grab_unfocused_window_buttons (MetaDisplay *display, void meta_display_grab_focus_window_button (MetaDisplay *display,
Window xwindow); Window xwindow);
void meta_display_ungrab_unfocused_window_buttons (MetaDisplay *display, void meta_display_ungrab_focus_window_button (MetaDisplay *display,
Window xwindow); Window xwindow);
/* make a request to ensure the event serial has changed */ /* make a request to ensure the event serial has changed */
void meta_display_increment_event_serial (MetaDisplay *display); void meta_display_increment_event_serial (MetaDisplay *display);

View File

@ -169,7 +169,11 @@ meta_change_keygrab (MetaDisplay *display,
* all combinations of IGNORED_MODIFIERS. * all combinations of IGNORED_MODIFIERS.
* X provides no better way to do this. * 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 */ /* modmask can't contain any non-interesting modifiers */
g_return_if_fail ((modmask & INTERESTING_MODIFIERS) == modmask); g_return_if_fail ((modmask & INTERESTING_MODIFIERS) == modmask);

View File

@ -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 static void
update_focus_mode (MetaScreen *screen) update_focus_mode (MetaScreen *screen)
{ {
meta_screen_foreach_window (screen, update_grabs_func, NULL); /* nothing to do anymore */ ;
} }
void void

View File

@ -304,7 +304,6 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->keys_grabbed = FALSE; window->keys_grabbed = FALSE;
window->grab_on_frame = FALSE; window->grab_on_frame = FALSE;
window->all_keys_grabbed = FALSE; window->all_keys_grabbed = FALSE;
window->unfocused_buttons_grabbed = FALSE;
window->withdrawn = FALSE; window->withdrawn = FALSE;
window->initial_workspace_set = FALSE; window->initial_workspace_set = FALSE;
window->calc_placement = FALSE; window->calc_placement = FALSE;
@ -423,7 +422,7 @@ meta_window_new (MetaDisplay *display, Window xwindow,
meta_window_grab_keys (window); meta_window_grab_keys (window);
meta_display_grab_window_buttons (window->display, window->xwindow); 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, /* For the workspace, first honor hints,
* if that fails put transients with parents, * if that fails put transients with parents,
@ -696,6 +695,7 @@ meta_window_free (MetaWindow *window)
meta_window_ungrab_keys (window); meta_window_ungrab_keys (window);
meta_display_ungrab_window_buttons (window->display, window->xwindow); 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); 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 void
meta_window_change_workspace (MetaWindow *window, meta_window_change_workspace (MetaWindow *window,
MetaWorkspace *workspace) MetaWorkspace *workspace)
@ -2665,7 +2612,6 @@ meta_window_notify_focus (MetaWindow *window,
window->has_focus = TRUE; window->has_focus = TRUE;
if (window->frame) if (window->frame)
meta_frame_queue_draw (window->frame); meta_frame_queue_draw (window->frame);
meta_window_update_unfocused_button_grabs (window);
} }
else if (event->type == FocusOut || else if (event->type == FocusOut ||
event->type == UnmapNotify) event->type == UnmapNotify)
@ -2681,7 +2627,6 @@ meta_window_notify_focus (MetaWindow *window,
window->has_focus = FALSE; window->has_focus = FALSE;
if (window->frame) if (window->frame)
meta_frame_queue_draw (window->frame); meta_frame_queue_draw (window->frame);
meta_window_update_unfocused_button_grabs (window);
} }
/* Now set _NET_ACTIVE_WINDOW hint */ /* Now set _NET_ACTIVE_WINDOW hint */

View File

@ -173,9 +173,6 @@ struct _MetaWindow
guint keys_grabbed : 1; /* normal keybindings grabbed */ guint keys_grabbed : 1; /* normal keybindings grabbed */
guint grab_on_frame : 1; /* grabs are on the frame */ guint grab_on_frame : 1; /* grabs are on the frame */
guint all_keys_grabbed : 1; /* AnyKey grabbed */ 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 /* Set if the reason for unmanaging the window is that
* it was withdrawn * it was withdrawn