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.
This commit is contained in:
Matthias Clasen 2014-01-12 22:06:59 -05:00
parent 2232430a5a
commit 7125cdc5ff
2 changed files with 54 additions and 45 deletions

View File

@ -10205,7 +10205,7 @@ gdk_window_set_functions (GdkWindow *window,
* @window: a toplevel #GdkWindow * @window: a toplevel #GdkWindow
* @edge: the edge or corner from which the drag is started * @edge: the edge or corner from which the drag is started
* @device: the device used for the operation * @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_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 * @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()) * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
@ -10234,7 +10234,7 @@ gdk_window_begin_resize_drag_for_device (GdkWindow *window,
* gdk_window_begin_resize_drag: * gdk_window_begin_resize_drag:
* @window: a toplevel #GdkWindow * @window: a toplevel #GdkWindow
* @edge: the edge or corner from which the drag is started * @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_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 * @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()) * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
@ -10266,7 +10266,7 @@ gdk_window_begin_resize_drag (GdkWindow *window,
* gdk_window_begin_move_drag_for_device: * gdk_window_begin_move_drag_for_device:
* @window: a toplevel #GdkWindow * @window: a toplevel #GdkWindow
* @device: the device used for the operation * @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_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 * @root_y: root window Y coordinate of mouse click that began the drag
* @timestamp: timestamp of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag
@ -10295,7 +10295,7 @@ gdk_window_begin_move_drag_for_device (GdkWindow *window,
/** /**
* gdk_window_begin_move_drag: * gdk_window_begin_move_drag:
* @window: a toplevel #GdkWindow * @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_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 * @root_y: root window Y coordinate of mouse click that began the drag
* @timestamp: timestamp of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag

View File

@ -4760,8 +4760,8 @@ wmspec_moveresize (GdkWindow *window,
{ {
GdkDisplay *display = GDK_WINDOW_DISPLAY (window); GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
/* Release passive grab */ if (button != 0)
gdk_device_ungrab (device, timestamp); gdk_device_ungrab (device, timestamp); /* Release passive grab */
GDK_X11_DISPLAY (display)->wm_moveresize_button = button; GDK_X11_DISPLAY (display)->wm_moveresize_button = button;
wmspec_send_message (display, window, root_x, root_y, direction, button); wmspec_send_message (display, window, root_x, root_y, direction, button);
@ -4778,48 +4778,51 @@ wmspec_resize_drag (GdkWindow *window,
{ {
gint direction; gint direction;
/* Let the compiler turn a switch into a table, instead if (button == 0)
* of doing the table manually, this way is easier to verify. direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
*/ else
switch (edge) switch (edge)
{ {
case GDK_WINDOW_EDGE_NORTH_WEST: /* Let the compiler turn a switch into a table, instead
direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; * of doing the table manually, this way is easier to verify.
break; */
case GDK_WINDOW_EDGE_NORTH_WEST:
direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
break;
case GDK_WINDOW_EDGE_NORTH: case GDK_WINDOW_EDGE_NORTH:
direction = _NET_WM_MOVERESIZE_SIZE_TOP; direction = _NET_WM_MOVERESIZE_SIZE_TOP;
break; break;
case GDK_WINDOW_EDGE_NORTH_EAST: case GDK_WINDOW_EDGE_NORTH_EAST:
direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
break; break;
case GDK_WINDOW_EDGE_WEST: case GDK_WINDOW_EDGE_WEST:
direction = _NET_WM_MOVERESIZE_SIZE_LEFT; direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
break; break;
case GDK_WINDOW_EDGE_EAST: case GDK_WINDOW_EDGE_EAST:
direction = _NET_WM_MOVERESIZE_SIZE_RIGHT; direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
break; break;
case GDK_WINDOW_EDGE_SOUTH_WEST: case GDK_WINDOW_EDGE_SOUTH_WEST:
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
break; break;
case GDK_WINDOW_EDGE_SOUTH: case GDK_WINDOW_EDGE_SOUTH:
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM; direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
break; break;
case GDK_WINDOW_EDGE_SOUTH_EAST: case GDK_WINDOW_EDGE_SOUTH_EAST:
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
break; break;
default: default:
g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!", g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
edge); edge);
return; return;
} }
wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp); wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp);
} }
@ -5036,7 +5039,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event)
impl = GDK_WINDOW_IMPL_X11 (mv_resize->moveresize_window->impl); 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) switch (event->xany.type)
{ {
@ -5330,14 +5334,19 @@ gdk_x11_window_begin_move_drag (GdkWindow *window,
gint root_y, gint root_y,
guint32 timestamp) guint32 timestamp)
{ {
if (GDK_WINDOW_DESTROYED (window) || gint direction;
!WINDOW_IS_TOPLEVEL (window))
if (GDK_WINDOW_DESTROYED (window) || !WINDOW_IS_TOPLEVEL (window))
return; 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), if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE"))) gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp);
device, button, root_x, root_y, timestamp);
else else
emulate_move_drag (window, device, button, root_x, root_y, timestamp); emulate_move_drag (window, device, button, root_x, root_y, timestamp);
} }