[mutter/wip/focus] display: move more event handling to clutter



commit 5b3ed980f5608e47096d94c42d2b097aacaa53d7
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Thu Feb 27 00:51:07 2014 +0100

    display: move more event handling to clutter
    
    Mouse event handling was duplicated, resulting in weird interactions
    if clutter was allowed to see certain events (for example under
    wayland, where it gets all events). Because now clutter sees all
    X events, even when running as an x11 compositor, we can handle
    everything using the clutter variants.
    At the same time, rewrite a little the passive button grab code,
    to make it clear what is being matched on what and why.

 src/core/display.c |  343 +++++++++-------------------------------------------
 1 files changed, 60 insertions(+), 283 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index 4d5631f..1859c13 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -2040,9 +2040,6 @@ meta_display_handle_event (MetaDisplay        *display,
   gboolean bypass_clutter = FALSE, bypass_wayland = FALSE;
   MetaWaylandCompositor *compositor = NULL;
 
-  /* XXX -- we need to fill this in properly at some point... */
-  gboolean frame_was_receiver = FALSE;
-
   if (meta_is_wayland_compositor ())
     {
       compositor = meta_wayland_compositor_get_default ();
@@ -2116,57 +2113,61 @@ meta_display_handle_event (MetaDisplay        *display,
           gboolean begin_move = FALSE;
           ClutterModifierType grab_mask;
           gboolean unmodified;
+          gboolean fully_modified;
 
           grab_mask = display->window_grab_modifiers;
           if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS"))
             grab_mask |= CLUTTER_CONTROL_MASK;
 
-          /* Two possible sources of an unmodified event; one is a
-           * client that's letting button presses pass through to the
-           * frame, the other is our focus_window_grab on unmodified
-           * button 1.  So for all such events we focus the window.
+          /* We have three passive button grabs:
+           * - on any button, without modifiers => focuses and maybe raises the window
+           * - on resize button, with modifiers => start an interactive resizing
+           *   (normally <Super>middle)
+           * - on move button, with modifiers => start an interactive move
+           *   (normally <Super>left)
+           * - on menu button, with modifiers => show the window menu
+           *   (normally <Super>right)
+           *
+           * We may get here because we actually have a button
+           * grab on the window, or because we're a wayland
+           * compositor and thus we see all the events, so we
+           * need to check if the event is interesting.
+           * We want an event that is not modified, for a window
+           * that has (or would have, the wayland case) the
+           * button grab active.
+           *
+           * We may have other events on the window, for example
+           * a click on a frame button, but that's not for us to
+           * care about. Just let the event through.
            */
           unmodified = (event->button.modifier_state & grab_mask) == 0;
+          fully_modified = (event->button.modifier_state & grab_mask) == grab_mask;
 
-          if (unmodified ||
-              event->button.button == 1)
+          if (unmodified && window && window->have_focus_click_grab)
             {
-              /* don't focus if frame received, will be lowered in
-               * frames.c or special-cased if the click was on a
-               * minimize/close button.
+              if (meta_prefs_get_raise_on_click ())
+                meta_window_raise (window);
+              else
+                meta_topic (META_DEBUG_FOCUS,
+                            "Not raising window on click due to don't-raise-on-click option\n");
+
+              /* Don't focus panels--they must explicitly request focus.
+               * See bug 160470
                */
-              if (!frame_was_receiver)
+              if (window->type != META_WINDOW_DOCK)
                 {
-                  if (meta_prefs_get_raise_on_click ())
-                    meta_window_raise (window);
-                  else
-                    meta_topic (META_DEBUG_FOCUS,
-                                "Not raising window on click due to don't-raise-on-click option\n");
-
-                  /* Don't focus panels--they must explicitly request focus.
-                   * See bug 160470
-                   */
-                  if (window->type != META_WINDOW_DOCK)
-                    {
-                      meta_topic (META_DEBUG_FOCUS,
-                                  "Focusing %s due to unmodified button %u press (display.c)\n",
-                                  window->desc, event->button.button);
-                      meta_window_focus (window, event->any.time);
-                    }
-                  else
-                    /* However, do allow terminals to lose focus due to new
-                     * window mappings after the user clicks on a panel.
-                     */
-                    display->allow_terminal_deactivation = TRUE;
+                  meta_topic (META_DEBUG_FOCUS,
+                              "Focusing %s due to unmodified button %u press (display.c)\n",
+                              window->desc, event->button.button);
+                  meta_window_focus (window, event->any.time);
                 }
-
-              /* you can move on alt-click but not on
-               * the click-to-focus
-               */
-              if (!unmodified)
-                begin_move = TRUE;
+              else
+                /* However, do allow terminals to lose focus due to new
+                 * window mappings after the user clicks on a panel.
+                 */
+                display->allow_terminal_deactivation = TRUE;
             }
-          else if (!unmodified && ((int) event->button.button == meta_prefs_get_mouse_button_resize ()))
+          else if (fully_modified && event->button.button == meta_prefs_get_mouse_button_resize ())
             {
               if (window->has_resize_func)
                 {
@@ -2214,8 +2215,10 @@ meta_display_handle_event (MetaDisplay        *display,
                                                 event->button.x,
                                                 event->button.y);
                 }
+              bypass_clutter = TRUE;
+              bypass_wayland = TRUE;
             }
-          else if ((int) event->button.button == meta_prefs_get_mouse_button_menu ())
+          else if (fully_modified && (int) event->button.button == meta_prefs_get_mouse_button_menu ())
             {
               if (meta_prefs_get_raise_on_click ())
                 meta_window_raise (window);
@@ -2227,20 +2230,22 @@ meta_display_handle_event (MetaDisplay        *display,
               bypass_clutter = TRUE;
               bypass_wayland = TRUE;
             }
-
-          if (begin_move && window->has_move_func)
+          else if (fully_modified && (int) event->button.button == 1)
             {
-              meta_display_begin_grab_op (display,
-                                          window->screen,
-                                          window,
-                                          META_GRAB_OP_MOVING,
-                                          TRUE,
-                                          FALSE,
-                                          event->button.button,
-                                          0,
-                                          event->any.time,
-                                          event->button.x,
-                                          event->button.y);
+              if (window->has_move_func)
+                {
+                  meta_display_begin_grab_op (display,
+                                              window->screen,
+                                              window,
+                                              META_GRAB_OP_MOVING,
+                                              TRUE,
+                                              FALSE,
+                                              event->button.button,
+                                              0,
+                                              event->any.time,
+                                              event->button.x,
+                                              event->button.y);
+                }
               bypass_clutter = TRUE;
               bypass_wayland = TRUE;
             }
@@ -2338,236 +2343,8 @@ handle_input_xevent (MetaDisplay *display,
                   window->desc);
     }
 
-  if (window && !window->override_redirect &&
-      (input_event->evtype == XI_KeyPress || input_event->evtype == XI_ButtonPress))
-    {
-      if (CurrentTime == display->current_time)
-        {
-          /* We can't use missing (i.e. invalid) timestamps to set user time,
-           * nor do we want to use them to sanity check other timestamps.
-           * See bug 313490 for more details.
-           */
-          meta_warning ("Event has no timestamp! You may be using a broken "
-                        "program such as xse.  Please ask the authors of that "
-                        "program to fix it.\n");
-        }
-      else
-        {
-          meta_window_set_user_time (window, display->current_time);
-          sanity_check_timestamps (display, display->current_time);
-        }
-    }
-
   switch (input_event->evtype)
     {
-    case XI_ButtonPress:
-      if (display->grab_op == META_GRAB_OP_COMPOSITOR)
-        break;
-
-      display->overlay_key_only_pressed = FALSE;
-
-      if (device_event->detail == 4 || device_event->detail == 5)
-        /* Scrollwheel event, do nothing and deliver event to compositor below */
-        break;
-
-      if ((window &&
-           meta_grab_op_is_mouse (display->grab_op) &&
-           (device_event->mods.effective & display->window_grab_modifiers) &&
-           display->grab_button != device_event->detail &&
-           display->grab_window == window) ||
-          grab_op_is_keyboard (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"));
-          if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
-            {
-              meta_topic (META_DEBUG_WINDOW_OPS,
-                          "Syncing to old stack positions.\n");
-
-              if (device_event->root == device_event->event)
-                meta_stack_set_positions (screen->stack,
-                                          display->grab_old_window_stacking);
-            }
-          meta_display_end_grab_op (display,
-                                    device_event->time);
-        }
-      else if (window && display->grab_op == META_GRAB_OP_NONE)
-        {
-          gboolean begin_move = FALSE;
-          unsigned int grab_mask;
-          gboolean unmodified;
-
-          grab_mask = display->window_grab_modifiers;
-          if (g_getenv ("MUTTER_DEBUG_BUTTON_GRABS"))
-            grab_mask |= ControlMask;
-
-          /* Two possible sources of an unmodified event; one is a
-           * client that's letting button presses pass through to the
-           * frame, the other is our focus_window_grab on unmodified
-           * button 1.  So for all such events we focus the window.
-           */
-          unmodified = (device_event->mods.effective & grab_mask) == 0;
-
-          if (unmodified ||
-              device_event->detail == 1)
-            {
-              /* don't focus if frame received, will be lowered in
-               * frames.c or special-cased if the click was on a
-               * minimize/close button.
-               */
-              if (!frame_was_receiver)
-                {
-                  if (meta_prefs_get_raise_on_click ())
-                    meta_window_raise (window);
-                  else
-                    meta_topic (META_DEBUG_FOCUS,
-                                "Not raising window on click due to don't-raise-on-click option\n");
-
-                  /* Don't focus panels--they must explicitly request focus.
-                   * See bug 160470
-                   */
-                  if (window->type != META_WINDOW_DOCK)
-                    {
-                      meta_topic (META_DEBUG_FOCUS,
-                                  "Focusing %s due to unmodified button %u press (display.c)\n",
-                                  window->desc, device_event->detail);
-                      meta_window_focus (window, device_event->time);
-                    }
-                  else
-                    /* However, do allow terminals to lose focus due to new
-                     * window mappings after the user clicks on a panel.
-                     */
-                    display->allow_terminal_deactivation = TRUE;
-                }
-
-              /* you can move on alt-click but not on
-               * the click-to-focus
-               */
-              if (!unmodified)
-                begin_move = TRUE;
-            }
-          else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize())
-            {
-              if (window->has_resize_func)
-                {
-                  gboolean north, south;
-                  gboolean west, east;
-                  MetaRectangle frame_rect;
-                  MetaGrabOp op;
-
-                  meta_window_get_frame_rect (window, &frame_rect);
-
-                  west = device_event->root_x <  (frame_rect.x + 1 * frame_rect.width  / 3);
-                  east = device_event->root_x >  (frame_rect.x + 2 * frame_rect.width  / 3);
-                  north = device_event->root_y < (frame_rect.y + 1 * frame_rect.height / 3);
-                  south = device_event->root_y > (frame_rect.y + 2 * frame_rect.height / 3);
-
-                  if (north && west)
-                    op = META_GRAB_OP_RESIZING_NW;
-                  else if (north && east)
-                    op = META_GRAB_OP_RESIZING_NE;
-                  else if (south && west)
-                    op = META_GRAB_OP_RESIZING_SW;
-                  else if (south && east)
-                    op = META_GRAB_OP_RESIZING_SE;
-                  else if (north)
-                    op = META_GRAB_OP_RESIZING_N;
-                  else if (west)
-                    op = META_GRAB_OP_RESIZING_W;
-                  else if (east)
-                    op = META_GRAB_OP_RESIZING_E;
-                  else if (south)
-                    op = META_GRAB_OP_RESIZING_S;
-                  else /* Middle region is no-op to avoid user triggering wrong action */
-                    op = META_GRAB_OP_NONE;
-
-                  if (op != META_GRAB_OP_NONE)
-                    {
-                      meta_display_begin_grab_op (display,
-                                                  window->screen,
-                                                  window,
-                                                  op,
-                                                  TRUE,
-                                                  FALSE,
-                                                  device_event->detail,
-                                                  0,
-                                                  device_event->time,
-                                                  device_event->root_x,
-                                                  device_event->root_y);
-                      return TRUE;
-                    }
-                }
-            }
-          else if (device_event->detail == meta_prefs_get_mouse_button_menu())
-            {
-              if (meta_prefs_get_raise_on_click ())
-                meta_window_raise (window);
-              meta_window_show_menu (window,
-                                     device_event->root_x,
-                                     device_event->root_y,
-                                     device_event->detail,
-                                     device_event->time);
-              return TRUE;
-            }
-
-          if (!frame_was_receiver && unmodified)
-            {
-              /* This is from our synchronous grab since
-               * it has no modifiers and was on the client window
-               */
-
-              meta_verbose ("Allowing events time %u\n",
-                            (unsigned int)device_event->time);
-
-              XIAllowEvents (display->xdisplay, device_event->deviceid,
-                             XIReplayDevice, device_event->time);
-            }
-
-          if (begin_move && window->has_move_func)
-            {
-              meta_display_begin_grab_op (display,
-                                          window->screen,
-                                          window,
-                                          META_GRAB_OP_MOVING,
-                                          TRUE,
-                                          FALSE,
-                                          device_event->detail,
-                                          0,
-                                          device_event->time,
-                                          device_event->root_x,
-                                          device_event->root_y);
-              return TRUE;
-            }
-        }
-      break;
-    case XI_ButtonRelease:
-      if (display->grab_op == META_GRAB_OP_COMPOSITOR)
-        break;
-
-      display->overlay_key_only_pressed = FALSE;
-
-      if (display->grab_window == window &&
-          meta_grab_op_is_mouse (display->grab_op))
-        {
-          meta_window_handle_mouse_grab_op_xevent (window, device_event);
-          return TRUE;
-        }
-      break;
-    case XI_Motion:
-      if (display->grab_op == META_GRAB_OP_COMPOSITOR)
-        break;
-
-      if (display->grab_window == window &&
-          meta_grab_op_is_mouse (display->grab_op))
-        {
-          meta_window_handle_mouse_grab_op_xevent (window, device_event);
-          return TRUE;
-        }
-      break;
     case XI_Enter:
       if (display->grab_op == META_GRAB_OP_COMPOSITOR)
         break;


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