window: Properly end grab ops started from a keybind / menu
If we start a grab op from a keybind / menu, we'll handle the ButtonPress and drop the grab then, never giving the window a chance to handle what it needs to do before the grab is dropped. This means that if you use Alt+F7 to move a window around, move it to a side-tiling or maximization area, and then left-click, it will just hang there in the sky.
This commit is contained in:
parent
064ef09c99
commit
cef2745bc0
@ -1949,24 +1949,15 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
display->overlay_key_only_pressed = FALSE;
|
||||
|
||||
if ((window &&
|
||||
meta_grab_op_is_mouse (display->grab_op) &&
|
||||
(event->button.modifier_state & display->window_grab_modifiers) &&
|
||||
display->grab_button != (int) event->button.button &&
|
||||
display->grab_window == window) ||
|
||||
meta_grab_op_is_keyboard (display->grab_op))
|
||||
if (display->grab_window == window &&
|
||||
meta_grab_op_is_moving_or_resizing (display->grab_op))
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Ending grab op %u on window %s due to button press\n",
|
||||
display->grab_op,
|
||||
(display->grab_window ?
|
||||
display->grab_window->desc :
|
||||
"none"));
|
||||
meta_display_end_grab_op (display, event->any.time);
|
||||
meta_window_handle_mouse_grab_op_event (window, event);
|
||||
bypass_clutter = TRUE;
|
||||
bypass_wayland = TRUE;
|
||||
}
|
||||
else if (window && display->grab_op == META_GRAB_OP_NONE)
|
||||
|
||||
if (window && display->grab_op == META_GRAB_OP_NONE)
|
||||
{
|
||||
ClutterModifierType grab_mask;
|
||||
gboolean unmodified;
|
||||
|
@ -7518,56 +7518,77 @@ meta_window_update_sync_request_counter (MetaWindow *window,
|
||||
}
|
||||
#endif /* HAVE_XSYNC */
|
||||
|
||||
static void
|
||||
end_grab_op (MetaWindow *window,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
meta_display_check_threshold_reached (window->display,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
/* If the user was snap moving then ignore the button
|
||||
* release because they may have let go of shift before
|
||||
* releasing the mouse button and they almost certainly do
|
||||
* not want a non-snapped movement to occur from the button
|
||||
* release.
|
||||
*/
|
||||
if (!window->display->grab_last_user_action_was_snap)
|
||||
{
|
||||
if (meta_grab_op_is_moving (window->display->grab_op))
|
||||
{
|
||||
if (window->tile_mode != META_TILE_NONE)
|
||||
meta_window_tile (window);
|
||||
else
|
||||
update_move (window,
|
||||
event->button.modifier_state & CLUTTER_SHIFT_MASK,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
}
|
||||
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
||||
{
|
||||
update_resize (window,
|
||||
event->button.modifier_state & CLUTTER_SHIFT_MASK,
|
||||
event->button.x,
|
||||
event->button.y,
|
||||
TRUE);
|
||||
|
||||
/* If a tiled window has been dragged free with a
|
||||
* mouse resize without snapping back to the tiled
|
||||
* state, it will end up with an inconsistent tile
|
||||
* mode on mouse release; cleaning the mode earlier
|
||||
* would break the ability to snap back to the tiled
|
||||
* state, so we wait until mouse release.
|
||||
*/
|
||||
update_tile_mode (window);
|
||||
}
|
||||
}
|
||||
meta_display_end_grab_op (window->display, event->any.time);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
/* This is the keybinding or menu case where we've
|
||||
* been dragging around the window without the button
|
||||
* pressed. */
|
||||
|
||||
if ((meta_grab_op_is_mouse (window->display->grab_op) &&
|
||||
(event->button.modifier_state & window->display->window_grab_modifiers) &&
|
||||
window->display->grab_button != (int) event->button.button) ||
|
||||
meta_grab_op_is_keyboard (window->display->grab_op))
|
||||
{
|
||||
end_grab_op (window, event);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
if (event->button.button == 1 ||
|
||||
event->button.button == (unsigned int) meta_prefs_get_mouse_button_resize ())
|
||||
{
|
||||
meta_display_check_threshold_reached (window->display,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
/* If the user was snap moving then ignore the button
|
||||
* release because they may have let go of shift before
|
||||
* releasing the mouse button and they almost certainly do
|
||||
* not want a non-snapped movement to occur from the button
|
||||
* release.
|
||||
*/
|
||||
if (!window->display->grab_last_user_action_was_snap)
|
||||
{
|
||||
if (meta_grab_op_is_moving (window->display->grab_op))
|
||||
{
|
||||
if (window->tile_mode != META_TILE_NONE)
|
||||
meta_window_tile (window);
|
||||
else
|
||||
update_move (window,
|
||||
event->button.modifier_state & CLUTTER_SHIFT_MASK,
|
||||
event->button.x,
|
||||
event->button.y);
|
||||
}
|
||||
else if (meta_grab_op_is_resizing (window->display->grab_op))
|
||||
{
|
||||
update_resize (window,
|
||||
event->button.modifier_state & CLUTTER_SHIFT_MASK,
|
||||
event->button.x,
|
||||
event->button.y,
|
||||
TRUE);
|
||||
|
||||
/* If a tiled window has been dragged free with a
|
||||
* mouse resize without snapping back to the tiled
|
||||
* state, it will end up with an inconsistent tile
|
||||
* mode on mouse release; cleaning the mode earlier
|
||||
* would break the ability to snap back to the tiled
|
||||
* state, so we wait until mouse release.
|
||||
*/
|
||||
update_tile_mode (window);
|
||||
}
|
||||
}
|
||||
meta_display_end_grab_op (window->display, event->any.time);
|
||||
end_grab_op (window, event);
|
||||
}
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user