compositor: Handle keyboard events in window drag operations
This is code largely copied from src/core/keybindings.c, taking care of keyboard interaction during window drag operations. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2683>
This commit is contained in:
parent
d8f6b4be9b
commit
dd3e5d2b52
@ -24,6 +24,7 @@
|
|||||||
#include "meta-window-drag.h"
|
#include "meta-window-drag.h"
|
||||||
|
|
||||||
#include "compositor/compositor-private.h"
|
#include "compositor/compositor-private.h"
|
||||||
|
#include "core/edge-resistance.h"
|
||||||
#include "core/window-private.h"
|
#include "core/window-private.h"
|
||||||
#include "meta/meta-enum-types.h"
|
#include "meta/meta-enum-types.h"
|
||||||
|
|
||||||
@ -399,6 +400,636 @@ warp_grab_pointer (MetaWindowDrag *window_drag,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_keyboard_resize (MetaWindowDrag *window_drag,
|
||||||
|
gboolean update_cursor)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
warp_grab_pointer (window_drag,
|
||||||
|
window_drag->effective_grab_window,
|
||||||
|
window_drag->grab_op,
|
||||||
|
&x, &y);
|
||||||
|
|
||||||
|
if (update_cursor)
|
||||||
|
meta_window_drag_update_cursor (window_drag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_keyboard_move (MetaWindowDrag *window_drag)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
warp_grab_pointer (window_drag,
|
||||||
|
window_drag->effective_grab_window,
|
||||||
|
window_drag->grab_op,
|
||||||
|
&x, &y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_modifier (xkb_keysym_t keysym)
|
||||||
|
{
|
||||||
|
switch (keysym)
|
||||||
|
{
|
||||||
|
case XKB_KEY_Shift_L:
|
||||||
|
case XKB_KEY_Shift_R:
|
||||||
|
case XKB_KEY_Control_L:
|
||||||
|
case XKB_KEY_Control_R:
|
||||||
|
case XKB_KEY_Caps_Lock:
|
||||||
|
case XKB_KEY_Shift_Lock:
|
||||||
|
case XKB_KEY_Meta_L:
|
||||||
|
case XKB_KEY_Meta_R:
|
||||||
|
case XKB_KEY_Alt_L:
|
||||||
|
case XKB_KEY_Alt_R:
|
||||||
|
case XKB_KEY_Super_L:
|
||||||
|
case XKB_KEY_Super_R:
|
||||||
|
case XKB_KEY_Hyper_L:
|
||||||
|
case XKB_KEY_Hyper_R:
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
process_mouse_move_resize_grab (MetaWindowDrag *window_drag,
|
||||||
|
MetaWindow *window,
|
||||||
|
ClutterKeyEvent *event)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_window_get_display (window);
|
||||||
|
|
||||||
|
/* don't care about releases, but eat them, don't end grab */
|
||||||
|
if (event->type == CLUTTER_KEY_RELEASE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (event->keyval == CLUTTER_KEY_Escape)
|
||||||
|
{
|
||||||
|
MetaTileMode tile_mode;
|
||||||
|
|
||||||
|
/* Hide the tiling preview if necessary */
|
||||||
|
if (display->preview_tile_mode != META_TILE_NONE)
|
||||||
|
meta_display_hide_tile_preview (display);
|
||||||
|
|
||||||
|
/* Restore the original tile mode */
|
||||||
|
tile_mode = window_drag->tile_mode;
|
||||||
|
window->tile_monitor_number = window_drag->tile_monitor_number;
|
||||||
|
|
||||||
|
/* End move or resize and restore to original state. If the
|
||||||
|
* window was a maximized window that had been "shaken loose" we
|
||||||
|
* need to remaximize it. In normal cases, we need to do a
|
||||||
|
* moveresize now to get the position back to the original.
|
||||||
|
*/
|
||||||
|
if (window->shaken_loose || tile_mode == META_TILE_MAXIMIZED)
|
||||||
|
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||||
|
else if (tile_mode != META_TILE_NONE)
|
||||||
|
meta_window_restore_tile (window,
|
||||||
|
tile_mode,
|
||||||
|
window_drag->initial_window_pos.width,
|
||||||
|
window_drag->initial_window_pos.height);
|
||||||
|
else
|
||||||
|
meta_window_move_resize_frame (window_drag->effective_grab_window,
|
||||||
|
TRUE,
|
||||||
|
window_drag->initial_window_pos.x,
|
||||||
|
window_drag->initial_window_pos.y,
|
||||||
|
window_drag->initial_window_pos.width,
|
||||||
|
window_drag->initial_window_pos.height);
|
||||||
|
|
||||||
|
/* End grab */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
process_keyboard_move_grab (MetaWindowDrag *window_drag,
|
||||||
|
MetaWindow *window,
|
||||||
|
ClutterKeyEvent *event)
|
||||||
|
{
|
||||||
|
MetaEdgeResistanceFlags flags;
|
||||||
|
gboolean handled;
|
||||||
|
MetaRectangle frame_rect;
|
||||||
|
int x, y;
|
||||||
|
int incr;
|
||||||
|
|
||||||
|
handled = FALSE;
|
||||||
|
|
||||||
|
/* don't care about releases, but eat them, don't end grab */
|
||||||
|
if (event->type == CLUTTER_KEY_RELEASE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* don't end grab on modifier key presses */
|
||||||
|
if (is_modifier (event->keyval))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
meta_window_get_frame_rect (window, &frame_rect);
|
||||||
|
x = frame_rect.x;
|
||||||
|
y = frame_rect.y;
|
||||||
|
|
||||||
|
flags = META_EDGE_RESISTANCE_KEYBOARD_OP | META_EDGE_RESISTANCE_WINDOWS;
|
||||||
|
|
||||||
|
if ((event->modifier_state & CLUTTER_SHIFT_MASK) != 0)
|
||||||
|
flags |= META_EDGE_RESISTANCE_SNAP;
|
||||||
|
|
||||||
|
#define SMALL_INCREMENT 1
|
||||||
|
#define NORMAL_INCREMENT 10
|
||||||
|
|
||||||
|
if (flags & META_EDGE_RESISTANCE_SNAP)
|
||||||
|
incr = 1;
|
||||||
|
else if (event->modifier_state & CLUTTER_CONTROL_MASK)
|
||||||
|
incr = SMALL_INCREMENT;
|
||||||
|
else
|
||||||
|
incr = NORMAL_INCREMENT;
|
||||||
|
|
||||||
|
if (event->keyval == CLUTTER_KEY_Escape)
|
||||||
|
{
|
||||||
|
/* End move and restore to original state. If the window was a
|
||||||
|
* maximized window that had been "shaken loose" we need to
|
||||||
|
* remaximize it. In normal cases, we need to do a moveresize
|
||||||
|
* now to get the position back to the original.
|
||||||
|
*/
|
||||||
|
if (window->shaken_loose)
|
||||||
|
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||||
|
else
|
||||||
|
meta_window_move_resize_frame (window_drag->effective_grab_window,
|
||||||
|
TRUE,
|
||||||
|
window_drag->initial_window_pos.x,
|
||||||
|
window_drag->initial_window_pos.y,
|
||||||
|
window_drag->initial_window_pos.width,
|
||||||
|
window_drag->initial_window_pos.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When moving by increments, we still snap to edges if the move
|
||||||
|
* to the edge is smaller than the increment. This is because
|
||||||
|
* Shift + arrow to snap is sort of a hidden feature. This way
|
||||||
|
* people using just arrows shouldn't get too frustrated.
|
||||||
|
*/
|
||||||
|
switch (event->keyval)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_KP_Home:
|
||||||
|
case CLUTTER_KEY_KP_Prior:
|
||||||
|
case CLUTTER_KEY_Up:
|
||||||
|
case CLUTTER_KEY_KP_Up:
|
||||||
|
y -= incr;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_KP_End:
|
||||||
|
case CLUTTER_KEY_KP_Next:
|
||||||
|
case CLUTTER_KEY_Down:
|
||||||
|
case CLUTTER_KEY_KP_Down:
|
||||||
|
y += incr;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event->keyval)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_KP_Home:
|
||||||
|
case CLUTTER_KEY_KP_End:
|
||||||
|
case CLUTTER_KEY_Left:
|
||||||
|
case CLUTTER_KEY_KP_Left:
|
||||||
|
x -= incr;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_KP_Prior:
|
||||||
|
case CLUTTER_KEY_KP_Next:
|
||||||
|
case CLUTTER_KEY_Right:
|
||||||
|
case CLUTTER_KEY_KP_Right:
|
||||||
|
x += incr;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
|
"Computed new window location %d,%d due to keypress",
|
||||||
|
x, y);
|
||||||
|
|
||||||
|
meta_window_edge_resistance_for_move (window,
|
||||||
|
&x,
|
||||||
|
&y,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
meta_window_move_frame (window, TRUE, x, y);
|
||||||
|
update_keyboard_move (window_drag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
process_keyboard_resize_grab_op_change (MetaWindowDrag *window_drag,
|
||||||
|
MetaWindow *window,
|
||||||
|
ClutterKeyEvent *event)
|
||||||
|
{
|
||||||
|
gboolean handled;
|
||||||
|
|
||||||
|
handled = FALSE;
|
||||||
|
switch (window_drag->grab_op)
|
||||||
|
{
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
|
||||||
|
switch (event->keyval)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_Up:
|
||||||
|
case CLUTTER_KEY_KP_Up:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_Down:
|
||||||
|
case CLUTTER_KEY_KP_Down:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_Left:
|
||||||
|
case CLUTTER_KEY_KP_Left:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_Right:
|
||||||
|
case CLUTTER_KEY_KP_Right:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
||||||
|
switch (event->keyval)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_Left:
|
||||||
|
case CLUTTER_KEY_KP_Left:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_Right:
|
||||||
|
case CLUTTER_KEY_KP_Right:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
||||||
|
switch (event->keyval)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_Left:
|
||||||
|
case CLUTTER_KEY_KP_Left:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_Right:
|
||||||
|
case CLUTTER_KEY_KP_Right:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
||||||
|
switch (event->keyval)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_Up:
|
||||||
|
case CLUTTER_KEY_KP_Up:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_Down:
|
||||||
|
case CLUTTER_KEY_KP_Down:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
||||||
|
switch (event->keyval)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_Up:
|
||||||
|
case CLUTTER_KEY_KP_Up:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_Down:
|
||||||
|
case CLUTTER_KEY_KP_Down:
|
||||||
|
window_drag->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
||||||
|
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled)
|
||||||
|
{
|
||||||
|
update_keyboard_resize (window_drag, TRUE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
process_keyboard_resize_grab (MetaWindowDrag *window_drag,
|
||||||
|
MetaWindow *window,
|
||||||
|
ClutterKeyEvent *event)
|
||||||
|
{
|
||||||
|
MetaRectangle frame_rect;
|
||||||
|
gboolean handled;
|
||||||
|
int height_inc;
|
||||||
|
int width_inc;
|
||||||
|
int width, height;
|
||||||
|
MetaEdgeResistanceFlags flags;
|
||||||
|
MetaGravity gravity;
|
||||||
|
|
||||||
|
handled = FALSE;
|
||||||
|
|
||||||
|
/* don't care about releases, but eat them, don't end grab */
|
||||||
|
if (event->type == CLUTTER_KEY_RELEASE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* don't end grab on modifier key presses */
|
||||||
|
if (is_modifier (event->keyval))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (event->keyval == CLUTTER_KEY_Escape)
|
||||||
|
{
|
||||||
|
/* End resize and restore to original state. */
|
||||||
|
meta_window_move_resize_frame (window_drag->effective_grab_window,
|
||||||
|
TRUE,
|
||||||
|
window_drag->initial_window_pos.x,
|
||||||
|
window_drag->initial_window_pos.y,
|
||||||
|
window_drag->initial_window_pos.width,
|
||||||
|
window_drag->initial_window_pos.height);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process_keyboard_resize_grab_op_change (window_drag, window, event))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
width = window->rect.width;
|
||||||
|
height = window->rect.height;
|
||||||
|
|
||||||
|
meta_window_get_frame_rect (window, &frame_rect);
|
||||||
|
width = frame_rect.width;
|
||||||
|
height = frame_rect.height;
|
||||||
|
|
||||||
|
gravity = meta_resize_gravity_from_grab_op (window_drag->grab_op);
|
||||||
|
|
||||||
|
flags = META_EDGE_RESISTANCE_KEYBOARD_OP;
|
||||||
|
|
||||||
|
if ((event->modifier_state & CLUTTER_SHIFT_MASK) != 0)
|
||||||
|
flags |= META_EDGE_RESISTANCE_SNAP;
|
||||||
|
|
||||||
|
#define SMALL_INCREMENT 1
|
||||||
|
#define NORMAL_INCREMENT 10
|
||||||
|
|
||||||
|
if (flags & META_EDGE_RESISTANCE_SNAP)
|
||||||
|
{
|
||||||
|
height_inc = 1;
|
||||||
|
width_inc = 1;
|
||||||
|
}
|
||||||
|
else if (event->modifier_state & CLUTTER_CONTROL_MASK)
|
||||||
|
{
|
||||||
|
width_inc = SMALL_INCREMENT;
|
||||||
|
height_inc = SMALL_INCREMENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width_inc = NORMAL_INCREMENT;
|
||||||
|
height_inc = NORMAL_INCREMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is a resize increment window, make the amount we resize
|
||||||
|
* the window by match that amount (well, unless snap resizing...)
|
||||||
|
*/
|
||||||
|
if (window->size_hints.width_inc > 1)
|
||||||
|
width_inc = window->size_hints.width_inc;
|
||||||
|
if (window->size_hints.height_inc > 1)
|
||||||
|
height_inc = window->size_hints.height_inc;
|
||||||
|
|
||||||
|
switch (event->keyval)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_Up:
|
||||||
|
case CLUTTER_KEY_KP_Up:
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case META_GRAVITY_NORTH:
|
||||||
|
case META_GRAVITY_NORTH_WEST:
|
||||||
|
case META_GRAVITY_NORTH_EAST:
|
||||||
|
/* Move bottom edge up */
|
||||||
|
height -= height_inc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAVITY_SOUTH:
|
||||||
|
case META_GRAVITY_SOUTH_WEST:
|
||||||
|
case META_GRAVITY_SOUTH_EAST:
|
||||||
|
/* Move top edge up */
|
||||||
|
height += height_inc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAVITY_EAST:
|
||||||
|
case META_GRAVITY_WEST:
|
||||||
|
case META_GRAVITY_CENTER:
|
||||||
|
case META_GRAVITY_NONE:
|
||||||
|
case META_GRAVITY_STATIC:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_KEY_Down:
|
||||||
|
case CLUTTER_KEY_KP_Down:
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case META_GRAVITY_NORTH:
|
||||||
|
case META_GRAVITY_NORTH_WEST:
|
||||||
|
case META_GRAVITY_NORTH_EAST:
|
||||||
|
/* Move bottom edge down */
|
||||||
|
height += height_inc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAVITY_SOUTH:
|
||||||
|
case META_GRAVITY_SOUTH_WEST:
|
||||||
|
case META_GRAVITY_SOUTH_EAST:
|
||||||
|
/* Move top edge down */
|
||||||
|
height -= height_inc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAVITY_EAST:
|
||||||
|
case META_GRAVITY_WEST:
|
||||||
|
case META_GRAVITY_CENTER:
|
||||||
|
case META_GRAVITY_NONE:
|
||||||
|
case META_GRAVITY_STATIC:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_KEY_Left:
|
||||||
|
case CLUTTER_KEY_KP_Left:
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case META_GRAVITY_EAST:
|
||||||
|
case META_GRAVITY_SOUTH_EAST:
|
||||||
|
case META_GRAVITY_NORTH_EAST:
|
||||||
|
/* Move left edge left */
|
||||||
|
width += width_inc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAVITY_WEST:
|
||||||
|
case META_GRAVITY_SOUTH_WEST:
|
||||||
|
case META_GRAVITY_NORTH_WEST:
|
||||||
|
/* Move right edge left */
|
||||||
|
width -= width_inc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAVITY_NORTH:
|
||||||
|
case META_GRAVITY_SOUTH:
|
||||||
|
case META_GRAVITY_CENTER:
|
||||||
|
case META_GRAVITY_NONE:
|
||||||
|
case META_GRAVITY_STATIC:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_KEY_Right:
|
||||||
|
case CLUTTER_KEY_KP_Right:
|
||||||
|
switch (gravity)
|
||||||
|
{
|
||||||
|
case META_GRAVITY_EAST:
|
||||||
|
case META_GRAVITY_SOUTH_EAST:
|
||||||
|
case META_GRAVITY_NORTH_EAST:
|
||||||
|
/* Move left edge right */
|
||||||
|
width -= width_inc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAVITY_WEST:
|
||||||
|
case META_GRAVITY_SOUTH_WEST:
|
||||||
|
case META_GRAVITY_NORTH_WEST:
|
||||||
|
/* Move right edge right */
|
||||||
|
width += width_inc;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_GRAVITY_NORTH:
|
||||||
|
case META_GRAVITY_SOUTH:
|
||||||
|
case META_GRAVITY_CENTER:
|
||||||
|
case META_GRAVITY_NONE:
|
||||||
|
case META_GRAVITY_STATIC:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fixup hack (just paranoia, not sure it's required) */
|
||||||
|
if (height < 1)
|
||||||
|
height = 1;
|
||||||
|
if (width < 1)
|
||||||
|
width = 1;
|
||||||
|
|
||||||
|
if (handled)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
|
"Computed new window size due to keypress: "
|
||||||
|
"%dx%d, gravity %s",
|
||||||
|
width, height, meta_gravity_to_string (gravity));
|
||||||
|
|
||||||
|
/* Do any edge resistance/snapping */
|
||||||
|
meta_window_edge_resistance_for_resize (window,
|
||||||
|
&width,
|
||||||
|
&height,
|
||||||
|
gravity,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
meta_window_resize_frame_with_gravity (window,
|
||||||
|
TRUE,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
gravity);
|
||||||
|
|
||||||
|
update_keyboard_resize (window_drag, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_key_event (MetaWindowDrag *window_drag,
|
||||||
|
ClutterKeyEvent *event)
|
||||||
|
{
|
||||||
|
MetaWindow *window;
|
||||||
|
gboolean keep_grab = TRUE;
|
||||||
|
|
||||||
|
window = window_drag->effective_grab_window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (window_drag->grab_op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD)
|
||||||
|
{
|
||||||
|
if (window_drag->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
|
"Processing event for keyboard move");
|
||||||
|
keep_grab = process_keyboard_move_grab (window_drag, window, event);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
|
"Processing event for keyboard resize");
|
||||||
|
keep_grab = process_keyboard_resize_grab (window_drag, window, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (window_drag->grab_op & META_GRAB_OP_MOVING)
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||||
|
"Processing event for mouse-only move/resize");
|
||||||
|
keep_grab = process_mouse_move_resize_grab (window_drag, window, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!keep_grab)
|
||||||
|
meta_window_drag_end (window_drag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_window_drag_event (MetaWindowDrag *window_drag,
|
||||||
|
ClutterEvent *event)
|
||||||
|
{
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_KEY_PRESS:
|
||||||
|
case CLUTTER_KEY_RELEASE:
|
||||||
|
process_key_event (window_drag, &event->key);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_window_drag_begin (MetaWindowDrag *window_drag,
|
meta_window_drag_begin (MetaWindowDrag *window_drag,
|
||||||
uint32_t timestamp)
|
uint32_t timestamp)
|
||||||
@ -466,6 +1097,8 @@ meta_window_drag_begin (MetaWindowDrag *window_drag,
|
|||||||
window_drag->handler = clutter_actor_new ();
|
window_drag->handler = clutter_actor_new ();
|
||||||
clutter_actor_set_name (window_drag->handler,
|
clutter_actor_set_name (window_drag->handler,
|
||||||
"Window drag helper");
|
"Window drag helper");
|
||||||
|
g_signal_connect_swapped (window_drag->handler, "event",
|
||||||
|
G_CALLBACK (on_window_drag_event), window_drag);
|
||||||
clutter_actor_add_child (stage, window_drag->handler);
|
clutter_actor_add_child (stage, window_drag->handler);
|
||||||
|
|
||||||
window_drag->grab = clutter_stage_grab (CLUTTER_STAGE (stage),
|
window_drag->grab = clutter_stage_grab (CLUTTER_STAGE (stage),
|
||||||
|
Loading…
Reference in New Issue
Block a user