From dc4b32b091309e82cab69eb9ad184c8199b8b8b0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 12 Jan 2014 22:06:59 -0500 Subject: [PATCH] X11: Support keyboard-initiated move and resize operations The EWMH defines _NET_WM_MOVERESIZE_SIZE_KEYBOARD and _NET_WM_MOVERESIZE_MOVE_KEYBOARD for operations that are not initiated by a button-press event. Allow using these by passing a button of 0 to gdk_window_begin_move/resize_drag. --- gdk/gdkwindow.c | 8 ++-- gdk/x11/gdkwindow-x11.c | 91 ++++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 9407bb0eb6..5f3a1e1242 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -10154,7 +10154,7 @@ gdk_window_set_functions (GdkWindow *window, * @window: a toplevel #GdkWindow * @edge: the edge or corner from which the drag is started * @device: the device used for the operation - * @button: the button being used to drag + * @button: the button being used to drag, or 0 for a keyboard-initiated drag * @root_x: root window X coordinate of mouse click that began the drag * @root_y: root window Y coordinate of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time()) @@ -10183,7 +10183,7 @@ gdk_window_begin_resize_drag_for_device (GdkWindow *window, * gdk_window_begin_resize_drag: * @window: a toplevel #GdkWindow * @edge: the edge or corner from which the drag is started - * @button: the button being used to drag + * @button: the button being used to drag, or 0 for a keyboard-initiated drag * @root_x: root window X coordinate of mouse click that began the drag * @root_y: root window Y coordinate of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time()) @@ -10215,7 +10215,7 @@ gdk_window_begin_resize_drag (GdkWindow *window, * gdk_window_begin_move_drag_for_device: * @window: a toplevel #GdkWindow * @device: the device used for the operation - * @button: the button being used to drag + * @button: the button being used to drag, or 0 for a keyboard-initiated drag * @root_x: root window X coordinate of mouse click that began the drag * @root_y: root window Y coordinate of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag @@ -10244,7 +10244,7 @@ gdk_window_begin_move_drag_for_device (GdkWindow *window, /** * gdk_window_begin_move_drag: * @window: a toplevel #GdkWindow - * @button: the button being used to drag + * @button: the button being used to drag, or 0 for a keyboard-initiated drag * @root_x: root window X coordinate of mouse click that began the drag * @root_y: root window Y coordinate of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index e9980451cc..e61cac1ca5 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -4757,8 +4757,8 @@ wmspec_moveresize (GdkWindow *window, { GdkDisplay *display = GDK_WINDOW_DISPLAY (window); - /* Release passive grab */ - gdk_device_ungrab (device, timestamp); + if (button != 0) + gdk_device_ungrab (device, timestamp); /* Release passive grab */ GDK_X11_DISPLAY (display)->wm_moveresize_button = button; wmspec_send_message (display, window, root_x, root_y, direction, button); @@ -4775,48 +4775,51 @@ wmspec_resize_drag (GdkWindow *window, { gint direction; - /* Let the compiler turn a switch into a table, instead - * of doing the table manually, this way is easier to verify. - */ - switch (edge) - { - case GDK_WINDOW_EDGE_NORTH_WEST: - direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; - break; + if (button == 0) + direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD; + else + switch (edge) + { + /* Let the compiler turn a switch into a table, instead + * of doing the table manually, this way is easier to verify. + */ + case GDK_WINDOW_EDGE_NORTH_WEST: + direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; + break; - case GDK_WINDOW_EDGE_NORTH: - direction = _NET_WM_MOVERESIZE_SIZE_TOP; - break; + case GDK_WINDOW_EDGE_NORTH: + direction = _NET_WM_MOVERESIZE_SIZE_TOP; + break; - case GDK_WINDOW_EDGE_NORTH_EAST: - direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; - break; + case GDK_WINDOW_EDGE_NORTH_EAST: + direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; + break; - case GDK_WINDOW_EDGE_WEST: - direction = _NET_WM_MOVERESIZE_SIZE_LEFT; - break; + case GDK_WINDOW_EDGE_WEST: + direction = _NET_WM_MOVERESIZE_SIZE_LEFT; + break; - case GDK_WINDOW_EDGE_EAST: - direction = _NET_WM_MOVERESIZE_SIZE_RIGHT; - break; + case GDK_WINDOW_EDGE_EAST: + direction = _NET_WM_MOVERESIZE_SIZE_RIGHT; + break; - case GDK_WINDOW_EDGE_SOUTH_WEST: - direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; - break; + case GDK_WINDOW_EDGE_SOUTH_WEST: + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; + break; - case GDK_WINDOW_EDGE_SOUTH: - direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM; - break; + case GDK_WINDOW_EDGE_SOUTH: + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM; + break; - case GDK_WINDOW_EDGE_SOUTH_EAST: - direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; - break; + case GDK_WINDOW_EDGE_SOUTH_EAST: + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; + break; - default: - g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!", - edge); - return; - } + default: + g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!", + edge); + return; + } wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp); } @@ -5033,7 +5036,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event) impl = GDK_WINDOW_IMPL_X11 (mv_resize->moveresize_window->impl); - button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1); + if (mv_resize->moveresize_button != 0) + button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1); switch (event->xany.type) { @@ -5327,14 +5331,19 @@ gdk_x11_window_begin_move_drag (GdkWindow *window, gint root_y, guint32 timestamp) { - if (GDK_WINDOW_DESTROYED (window) || - !WINDOW_IS_TOPLEVEL (window)) + gint direction; + + if (GDK_WINDOW_DESTROYED (window) || !WINDOW_IS_TOPLEVEL (window)) return; + if (button == 0) + direction = _NET_WM_MOVERESIZE_MOVE_KEYBOARD; + else + direction = _NET_WM_MOVERESIZE_MOVE; + if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE"))) - wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, - device, button, root_x, root_y, timestamp); + wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp); else emulate_move_drag (window, device, button, root_x, root_y, timestamp); }