[mutter] window: Properly end grab ops started from a keybind / menu



commit cef2745bc02a72e5397f78969b413324bad0afe1
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sun Apr 20 12:45:40 2014 -0400

    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.

 src/core/events.c |   19 +++-------
 src/core/window.c |  101 ++++++++++++++++++++++++++++++++---------------------
 2 files changed, 66 insertions(+), 54 deletions(-)
---
diff --git a/src/core/events.c b/src/core/events.c
index d18d131..72e6017 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -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;
diff --git a/src/core/window.c b/src/core/window.c
index 042d103..4306fb8 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -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;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]