keybindings: Move the button grabs to here as well

This commit is contained in:
Jasper St. Pierre 2014-08-14 15:04:00 -04:00
parent 31081e5dac
commit 586f118279
2 changed files with 257 additions and 258 deletions

View File

@ -145,7 +145,6 @@ static const char *gnome_wm_keybindings = "Mutter";
static const char *net_wm_name = "Mutter";
static void update_cursor_theme (void);
static void update_window_grab_modifiers (MetaDisplay *display);
static void prefs_changed_callback (MetaPreference pref,
void *data);
@ -586,8 +585,6 @@ meta_display_open (void)
meta_display_init_keys (display);
update_window_grab_modifiers (display);
meta_prefs_add_listener (prefs_changed_callback, display);
meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
@ -1989,221 +1986,6 @@ meta_display_check_threshold_reached (MetaDisplay *display,
display->grab_threshold_movement_reached = TRUE;
}
static void
meta_change_button_grab (MetaDisplay *display,
Window xwindow,
gboolean grab,
gboolean sync,
int button,
int modmask)
{
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
unsigned int ignored_mask;
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Motion);
ignored_mask = 0;
while (ignored_mask <= display->ignored_modifier_mask)
{
XIGrabModifiers mods;
if (ignored_mask & ~(display->ignored_modifier_mask))
{
/* Not a combination of ignored modifiers
* (it contains some non-ignored modifiers)
*/
++ignored_mask;
continue;
}
mods = (XIGrabModifiers) { modmask | ignored_mask, 0 };
/* GrabModeSync means freeze until XAllowEvents */
if (grab)
XIGrabButton (xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
button, xwindow, None,
sync ? XIGrabModeSync : XIGrabModeAsync,
XIGrabModeAsync, False,
&mask, 1, &mods);
else
XIUngrabButton (xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
button, xwindow, 1, &mods);
++ignored_mask;
}
}
void
meta_display_grab_window_buttons (MetaDisplay *display,
Window xwindow)
{
if (meta_is_wayland_compositor ())
return;
/* Grab Alt + button1 for moving window.
* Grab Alt + button2 for resizing window.
* Grab Alt + button3 for popping up window menu.
* Grab Alt + Shift + button1 for snap-moving window.
*/
meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow);
/* FIXME If we ignored errors here instead of spewing, we could
* put one big error trap around the loop and avoid a bunch of
* XSync()
*/
if (display->window_grab_modifiers != 0)
{
gboolean debug = g_getenv ("MUTTER_DEBUG_BUTTON_GRABS") != NULL;
int i;
for (i = 1; i < 4; i++)
{
meta_change_button_grab (display, xwindow,
TRUE,
FALSE,
i, display->window_grab_modifiers);
/* This is for debugging, since I end up moving the Xnest
* otherwise ;-)
*/
if (debug)
meta_change_button_grab (display, xwindow,
TRUE,
FALSE,
i, ControlMask);
}
/* In addition to grabbing Alt+Button1 for moving the window,
* grab Alt+Shift+Button1 for snap-moving the window. See bug
* 112478. Unfortunately, this doesn't work with
* Shift+Alt+Button1 for some reason; so at least part of the
* order still matters, which sucks (please FIXME).
*/
meta_change_button_grab (display, xwindow,
TRUE,
FALSE,
1, display->window_grab_modifiers | ShiftMask);
}
}
void
meta_display_ungrab_window_buttons (MetaDisplay *display,
Window xwindow)
{
gboolean debug;
int i;
if (meta_is_wayland_compositor ())
return;
if (display->window_grab_modifiers == 0)
return;
debug = g_getenv ("MUTTER_DEBUG_BUTTON_GRABS") != NULL;
i = 1;
while (i < 4)
{
meta_change_button_grab (display, xwindow,
FALSE, FALSE, i,
display->window_grab_modifiers);
if (debug)
meta_change_button_grab (display, xwindow,
FALSE, FALSE, i, ControlMask);
++i;
}
}
/* Grab buttons we only grab while unfocused in click-to-focus mode */
#define MAX_FOCUS_BUTTON 4
void
meta_display_grab_focus_window_button (MetaDisplay *display,
MetaWindow *window)
{
if (meta_is_wayland_compositor ())
return;
/* Grab button 1 for activating unfocused windows */
meta_verbose ("Grabbing unfocused window buttons for %s\n", window->desc);
#if 0
/* FIXME:115072 */
/* Don't grab at all unless in click to focus mode. In click to
* focus, we may sometimes be clever about intercepting and eating
* the focus click. But in mouse focus, we never do that since the
* focus window may not be raised, and who wants to think about
* mouse focus anyway.
*/
if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK)
{
meta_verbose (" (well, not grabbing since not in click to focus mode)\n");
return;
}
#endif
if (window->have_focus_click_grab)
{
meta_verbose (" (well, not grabbing since we already have the grab)\n");
return;
}
/* FIXME If we ignored errors here instead of spewing, we could
* put one big error trap around the loop and avoid a bunch of
* XSync()
*/
{
int i = 1;
while (i < MAX_FOCUS_BUTTON)
{
meta_change_button_grab (display,
window->xwindow,
TRUE, TRUE,
i, 0);
++i;
}
window->have_focus_click_grab = TRUE;
}
}
void
meta_display_ungrab_focus_window_button (MetaDisplay *display,
MetaWindow *window)
{
if (meta_is_wayland_compositor ())
return;
meta_verbose ("Ungrabbing unfocused window buttons for %s\n", window->desc);
if (!window->have_focus_click_grab)
return;
{
int i = 1;
while (i < MAX_FOCUS_BUTTON)
{
meta_change_button_grab (display, window->xwindow,
FALSE, FALSE, i, 0);
++i;
}
window->have_focus_click_grab = FALSE;
}
}
void
meta_display_increment_event_serial (MetaDisplay *display)
{
@ -2853,48 +2635,13 @@ meta_display_sort_windows_by_stacking (MetaDisplay *display,
return copy;
}
static void
update_window_grab_modifiers (MetaDisplay *display)
{
MetaVirtualModifier virtual_mods;
unsigned int mods;
virtual_mods = meta_prefs_get_mouse_button_mods ();
meta_display_devirtualize_modifiers (display, virtual_mods,
&mods);
display->window_grab_modifiers = mods;
}
static void
prefs_changed_callback (MetaPreference pref,
void *data)
{
MetaDisplay *display = data;
if (pref == META_PREF_MOUSE_BUTTON_MODS)
{
GSList *windows, *l;
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
for (l = windows; l; l = l->next)
{
MetaWindow *w = l->data;
meta_display_ungrab_window_buttons (display, w->xwindow);
}
update_window_grab_modifiers (display);
for (l = windows; l; l = l->next)
{
MetaWindow *w = l->data;
if (w->type != META_WINDOW_DOCK)
meta_display_grab_window_buttons (display, w->xwindow);
}
g_slist_free (windows);
}
else if (pref == META_PREF_FOCUS_MODE)
if (pref == META_PREF_FOCUS_MODE)
{
GSList *windows, *l;
windows = meta_display_list_windows (display, META_LIST_DEFAULT);

View File

@ -963,8 +963,236 @@ meta_display_process_mapping_event (MetaDisplay *display,
}
static void
bindings_changed_callback (MetaPreference pref,
void *data)
meta_change_button_grab (MetaDisplay *display,
Window xwindow,
gboolean grab,
gboolean sync,
int button,
int modmask)
{
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
unsigned int ignored_mask;
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
XISetMask (mask.mask, XI_ButtonPress);
XISetMask (mask.mask, XI_ButtonRelease);
XISetMask (mask.mask, XI_Motion);
ignored_mask = 0;
while (ignored_mask <= display->ignored_modifier_mask)
{
XIGrabModifiers mods;
if (ignored_mask & ~(display->ignored_modifier_mask))
{
/* Not a combination of ignored modifiers
* (it contains some non-ignored modifiers)
*/
++ignored_mask;
continue;
}
mods = (XIGrabModifiers) { modmask | ignored_mask, 0 };
/* GrabModeSync means freeze until XAllowEvents */
if (grab)
XIGrabButton (xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
button, xwindow, None,
sync ? XIGrabModeSync : XIGrabModeAsync,
XIGrabModeAsync, False,
&mask, 1, &mods);
else
XIUngrabButton (xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
button, xwindow, 1, &mods);
++ignored_mask;
}
}
void
meta_display_grab_window_buttons (MetaDisplay *display,
Window xwindow)
{
if (meta_is_wayland_compositor ())
return;
/* Grab Alt + button1 for moving window.
* Grab Alt + button2 for resizing window.
* Grab Alt + button3 for popping up window menu.
* Grab Alt + Shift + button1 for snap-moving window.
*/
meta_verbose ("Grabbing window buttons for 0x%lx\n", xwindow);
/* FIXME If we ignored errors here instead of spewing, we could
* put one big error trap around the loop and avoid a bunch of
* XSync()
*/
if (display->window_grab_modifiers != 0)
{
gboolean debug = g_getenv ("MUTTER_DEBUG_BUTTON_GRABS") != NULL;
int i;
for (i = 1; i < 4; i++)
{
meta_change_button_grab (display, xwindow,
TRUE,
FALSE,
i, display->window_grab_modifiers);
/* This is for debugging, since I end up moving the Xnest
* otherwise ;-)
*/
if (debug)
meta_change_button_grab (display, xwindow,
TRUE,
FALSE,
i, ControlMask);
}
/* In addition to grabbing Alt+Button1 for moving the window,
* grab Alt+Shift+Button1 for snap-moving the window. See bug
* 112478. Unfortunately, this doesn't work with
* Shift+Alt+Button1 for some reason; so at least part of the
* order still matters, which sucks (please FIXME).
*/
meta_change_button_grab (display, xwindow,
TRUE,
FALSE,
1, display->window_grab_modifiers | ShiftMask);
}
}
void
meta_display_ungrab_window_buttons (MetaDisplay *display,
Window xwindow)
{
gboolean debug;
int i;
if (meta_is_wayland_compositor ())
return;
if (display->window_grab_modifiers == 0)
return;
debug = g_getenv ("MUTTER_DEBUG_BUTTON_GRABS") != NULL;
i = 1;
while (i < 4)
{
meta_change_button_grab (display, xwindow,
FALSE, FALSE, i,
display->window_grab_modifiers);
if (debug)
meta_change_button_grab (display, xwindow,
FALSE, FALSE, i, ControlMask);
++i;
}
}
static void
update_window_grab_modifiers (MetaDisplay *display)
{
MetaVirtualModifier virtual_mods;
unsigned int mods;
virtual_mods = meta_prefs_get_mouse_button_mods ();
meta_display_devirtualize_modifiers (display, virtual_mods,
&mods);
display->window_grab_modifiers = mods;
}
/* Grab buttons we only grab while unfocused in click-to-focus mode */
#define MAX_FOCUS_BUTTON 4
void
meta_display_grab_focus_window_button (MetaDisplay *display,
MetaWindow *window)
{
if (meta_is_wayland_compositor ())
return;
/* Grab button 1 for activating unfocused windows */
meta_verbose ("Grabbing unfocused window buttons for %s\n", window->desc);
#if 0
/* FIXME:115072 */
/* Don't grab at all unless in click to focus mode. In click to
* focus, we may sometimes be clever about intercepting and eating
* the focus click. But in mouse focus, we never do that since the
* focus window may not be raised, and who wants to think about
* mouse focus anyway.
*/
if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK)
{
meta_verbose (" (well, not grabbing since not in click to focus mode)\n");
return;
}
#endif
if (window->have_focus_click_grab)
{
meta_verbose (" (well, not grabbing since we already have the grab)\n");
return;
}
/* FIXME If we ignored errors here instead of spewing, we could
* put one big error trap around the loop and avoid a bunch of
* XSync()
*/
{
int i = 1;
while (i < MAX_FOCUS_BUTTON)
{
meta_change_button_grab (display,
window->xwindow,
TRUE, TRUE,
i, 0);
++i;
}
window->have_focus_click_grab = TRUE;
}
}
void
meta_display_ungrab_focus_window_button (MetaDisplay *display,
MetaWindow *window)
{
if (meta_is_wayland_compositor ())
return;
meta_verbose ("Ungrabbing unfocused window buttons for %s\n", window->desc);
if (!window->have_focus_click_grab)
return;
{
int i = 1;
while (i < MAX_FOCUS_BUTTON)
{
meta_change_button_grab (display, window->xwindow,
FALSE, FALSE, i, 0);
++i;
}
window->have_focus_click_grab = FALSE;
}
}
static void
prefs_changed_callback (MetaPreference pref,
void *data)
{
MetaDisplay *display;
@ -981,6 +1209,28 @@ bindings_changed_callback (MetaPreference pref,
rebuild_binding_index (display);
grab_key_bindings (display);
break;
case META_PREF_MOUSE_BUTTON_MODS:
{
GSList *windows, *l;
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
for (l = windows; l; l = l->next)
{
MetaWindow *w = l->data;
meta_display_ungrab_window_buttons (display, w->xwindow);
}
update_window_grab_modifiers (display);
for (l = windows; l; l = l->next)
{
MetaWindow *w = l->data;
if (w->type != META_WINDOW_DOCK)
meta_display_grab_window_buttons (display, w->xwindow);
}
g_slist_free (windows);
}
default:
break;
}
@ -990,7 +1240,7 @@ bindings_changed_callback (MetaPreference pref,
void
meta_display_shutdown_keys (MetaDisplay *display)
{
meta_prefs_remove_listener (bindings_changed_callback, display);
meta_prefs_remove_listener (prefs_changed_callback, display);
if (display->keymap)
meta_XFree (display->keymap);
@ -3943,9 +4193,11 @@ meta_display_init_keys (MetaDisplay *display)
reload_modifiers (display);
rebuild_binding_index (display);
update_window_grab_modifiers (display);
/* Keys are actually grabbed in meta_screen_grab_keys() */
meta_prefs_add_listener (bindings_changed_callback, display);
meta_prefs_add_listener (prefs_changed_callback, display);
/* meta_display_init_keys() should have already called XkbQueryExtension() */
if (display->xkb_base_event_type != -1)