[mutter] common: Create a better encoding for MetaGrabOp



commit 517e8f6fbd731d4c1a067050f9d9bc1725a51e91
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Aug 15 14:05:04 2014 -0400

    common: Create a better encoding for MetaGrabOp
    
    MetaGrabOp is painful and tedious to work with, because it's a
    sequential series of values, meaning we have to use a giant unreadable
    switch statement to figure out some basic things about the value.
    
    To solve this, modify the encoding for MetaGrabOp and for the specific
    window grab operations so that they're a set of bitflags that we can
    easily check.

 src/core/display.c                 |   99 +++-------------
 src/core/keybindings.c             |   56 +++------
 src/core/window.c                  |  236 ++++++++---------------------------
 src/meta/common.h                  |   85 +++++++++----
 src/wayland/meta-wayland-surface.c |   64 +++++------
 5 files changed, 175 insertions(+), 365 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index 14a3015..d6cc582 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1170,94 +1170,43 @@ meta_get_display (void)
 gboolean
 meta_grab_op_is_mouse (MetaGrabOp op)
 {
-  switch (op)
-    {
-    case META_GRAB_OP_MOVING:
-    case META_GRAB_OP_RESIZING_SE:
-    case META_GRAB_OP_RESIZING_S:
-    case META_GRAB_OP_RESIZING_SW:
-    case META_GRAB_OP_RESIZING_N:
-    case META_GRAB_OP_RESIZING_NE:
-    case META_GRAB_OP_RESIZING_NW:
-    case META_GRAB_OP_RESIZING_W:
-    case META_GRAB_OP_RESIZING_E:
-      return TRUE;
+  if (GRAB_OP_GET_BASE_TYPE (op) != META_GRAB_OP_WINDOW_BASE)
+    return FALSE;
 
-    default:
-      return FALSE;
-    }
+  return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) == 0;
 }
 
 gboolean
 meta_grab_op_is_keyboard (MetaGrabOp op)
 {
-  switch (op)
-    {
-    case META_GRAB_OP_KEYBOARD_MOVING:
-    case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
-    case META_GRAB_OP_KEYBOARD_RESIZING_S:
-    case META_GRAB_OP_KEYBOARD_RESIZING_N:
-    case META_GRAB_OP_KEYBOARD_RESIZING_W:
-    case META_GRAB_OP_KEYBOARD_RESIZING_E:
-    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:
-      return TRUE;
+  if (GRAB_OP_GET_BASE_TYPE (op) == META_GRAB_OP_WINDOW_BASE)
+    return FALSE;
 
-    default:
-      return FALSE;
-    }
+  return (op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD) != 0;
 }
 
 gboolean
 meta_grab_op_is_resizing (MetaGrabOp op)
 {
-  switch (op)
-    {
-    case META_GRAB_OP_RESIZING_SE:
-    case META_GRAB_OP_RESIZING_S:
-    case META_GRAB_OP_RESIZING_SW:
-    case META_GRAB_OP_RESIZING_N:
-    case META_GRAB_OP_RESIZING_NE:
-    case META_GRAB_OP_RESIZING_NW:
-    case META_GRAB_OP_RESIZING_W:
-    case META_GRAB_OP_RESIZING_E:
-    case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
-    case META_GRAB_OP_KEYBOARD_RESIZING_S:
-    case META_GRAB_OP_KEYBOARD_RESIZING_N:
-    case META_GRAB_OP_KEYBOARD_RESIZING_W:
-    case META_GRAB_OP_KEYBOARD_RESIZING_E:
-    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:
-      return TRUE;
+  if (GRAB_OP_GET_BASE_TYPE (op) != META_GRAB_OP_WINDOW_BASE)
+    return FALSE;
 
-    default:
-      return FALSE;
-    }
+  return (op & 0xF000) != 0;
 }
 
 gboolean
 meta_grab_op_is_moving (MetaGrabOp op)
 {
-  switch (op)
-    {
-    case META_GRAB_OP_MOVING:
-    case META_GRAB_OP_KEYBOARD_MOVING:
-      return TRUE;
+  if (GRAB_OP_GET_BASE_TYPE (op) != META_GRAB_OP_WINDOW_BASE)
+    return FALSE;
 
-    default:
-      return FALSE;
-    }
+  return (op & 0xF000) != 0;
 }
 
 gboolean
 meta_grab_op_is_moving_or_resizing (MetaGrabOp op)
 {
-  return (meta_grab_op_is_moving (op) ||
-          meta_grab_op_is_resizing (op));
+  return GRAB_OP_GET_BASE_TYPE (op) == META_GRAB_OP_WINDOW_BASE;
 }
 
 /**
@@ -1756,31 +1705,13 @@ get_first_freefloating_window (MetaWindow *window)
 static MetaEventRoute
 get_event_route_from_grab_op (MetaGrabOp op)
 {
-  switch (op)
+  switch (GRAB_OP_GET_BASE_TYPE (op))
     {
     case META_GRAB_OP_NONE:
       /* begin_grab_op shouldn't be called with META_GRAB_OP_NONE. */
       g_assert_not_reached ();
 
-    case META_GRAB_OP_MOVING:
-    case META_GRAB_OP_RESIZING_SE:
-    case META_GRAB_OP_RESIZING_S:
-    case META_GRAB_OP_RESIZING_SW:
-    case META_GRAB_OP_RESIZING_N:
-    case META_GRAB_OP_RESIZING_NE:
-    case META_GRAB_OP_RESIZING_NW:
-    case META_GRAB_OP_RESIZING_W:
-    case META_GRAB_OP_RESIZING_E:
-    case META_GRAB_OP_KEYBOARD_MOVING:
-    case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
-    case META_GRAB_OP_KEYBOARD_RESIZING_S:
-    case META_GRAB_OP_KEYBOARD_RESIZING_N:
-    case META_GRAB_OP_KEYBOARD_RESIZING_W:
-    case META_GRAB_OP_KEYBOARD_RESIZING_E:
-    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:
+    case META_GRAB_OP_WINDOW_BASE:
       return META_EVENT_ROUTE_WINDOW_OP;
 
     case META_GRAB_OP_COMPOSITOR:
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index 4a31275..23aa355 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -1998,53 +1998,33 @@ process_key_event (MetaDisplay     *display,
     {
       if (display->grab_op == META_GRAB_OP_NONE)
         return TRUE;
+
       /* If we get here we have a global grab, because
        * we're in some special keyboard mode such as window move
        * mode.
        */
-      if ((window && window == display->grab_window) || !window)
+      if (window == display->grab_window)
         {
-          switch (display->grab_op)
+          if (display->grab_op & META_GRAB_OP_WINDOW_FLAG_KEYBOARD)
+            {
+              if (display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
+                {
+                  meta_topic (META_DEBUG_KEYBINDINGS,
+                              "Processing event for keyboard move\n");
+                  keep_grab = process_keyboard_move_grab (display, screen, window, event);
+                }
+              else
+                {
+                  meta_topic (META_DEBUG_KEYBINDINGS,
+                              "Processing event for keyboard resize\n");
+                  keep_grab = process_keyboard_resize_grab (display, screen, window, event);
+                }
+            }
+          else
             {
-            case META_GRAB_OP_MOVING:
-            case META_GRAB_OP_RESIZING_SE:
-            case META_GRAB_OP_RESIZING_S:
-            case META_GRAB_OP_RESIZING_SW:
-            case META_GRAB_OP_RESIZING_N:
-            case META_GRAB_OP_RESIZING_NE:
-            case META_GRAB_OP_RESIZING_NW:
-            case META_GRAB_OP_RESIZING_W:
-            case META_GRAB_OP_RESIZING_E:
               meta_topic (META_DEBUG_KEYBINDINGS,
                           "Processing event for mouse-only move/resize\n");
-              g_assert (window != NULL);
               keep_grab = process_mouse_move_resize_grab (display, screen, window, event);
-              break;
-
-            case META_GRAB_OP_KEYBOARD_MOVING:
-              meta_topic (META_DEBUG_KEYBINDINGS,
-                          "Processing event for keyboard move\n");
-              g_assert (window != NULL);
-              keep_grab = process_keyboard_move_grab (display, screen, window, event);
-              break;
-
-            case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
-            case META_GRAB_OP_KEYBOARD_RESIZING_S:
-            case META_GRAB_OP_KEYBOARD_RESIZING_N:
-            case META_GRAB_OP_KEYBOARD_RESIZING_W:
-            case META_GRAB_OP_KEYBOARD_RESIZING_E:
-            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:
-              meta_topic (META_DEBUG_KEYBINDINGS,
-                          "Processing event for keyboard resize\n");
-              g_assert (window != NULL);
-              keep_grab = process_keyboard_resize_grab (display, screen, window, event);
-              break;
-
-            default:
-              break;
             }
         }
       if (!keep_grab)
diff --git a/src/core/window.c b/src/core/window.c
index c9d19d2..fcb06ac 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -5741,26 +5741,10 @@ check_resize_unmaximize(MetaWindow *window,
        * monitor. If we wanted to only allow resizing smaller than the
        * monitor, we'd use - dx for NE/E/SE and dx for SW/W/NW.
        */
-      switch (window->display->grab_op)
-        {
-        case META_GRAB_OP_RESIZING_NE:
-        case META_GRAB_OP_KEYBOARD_RESIZING_NE:
-        case META_GRAB_OP_RESIZING_E:
-        case META_GRAB_OP_KEYBOARD_RESIZING_E:
-        case META_GRAB_OP_RESIZING_SE:
-        case META_GRAB_OP_KEYBOARD_RESIZING_SE:
-        case META_GRAB_OP_RESIZING_SW:
-        case META_GRAB_OP_KEYBOARD_RESIZING_SW:
-        case META_GRAB_OP_RESIZING_W:
-        case META_GRAB_OP_KEYBOARD_RESIZING_W:
-        case META_GRAB_OP_RESIZING_NW:
-        case META_GRAB_OP_KEYBOARD_RESIZING_NW:
-          x_amount = dx < 0 ? - dx : dx;
-          break;
-        default:
-          x_amount = 0;
-          break;
-        }
+      if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_WEST | META_GRAB_OP_WINDOW_DIR_EAST)) != 0)
+        x_amount = dx < 0 ? - dx : dx;
+      else
+        x_amount = 0;
 
       if (x_amount > threshold)
         new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
@@ -5771,26 +5755,10 @@ check_resize_unmaximize(MetaWindow *window,
     {
       int y_amount;
 
-      switch (window->display->grab_op)
-        {
-        case META_GRAB_OP_RESIZING_N:
-        case META_GRAB_OP_KEYBOARD_RESIZING_N:
-        case META_GRAB_OP_RESIZING_NE:
-        case META_GRAB_OP_KEYBOARD_RESIZING_NE:
-        case META_GRAB_OP_RESIZING_NW:
-        case META_GRAB_OP_KEYBOARD_RESIZING_NW:
-        case META_GRAB_OP_RESIZING_SE:
-        case META_GRAB_OP_KEYBOARD_RESIZING_SE:
-        case META_GRAB_OP_RESIZING_S:
-        case META_GRAB_OP_KEYBOARD_RESIZING_S:
-        case META_GRAB_OP_RESIZING_SW:
-        case META_GRAB_OP_KEYBOARD_RESIZING_SW:
-          y_amount = dy < 0 ? - dy : dy;
-          break;
-        default:
-          y_amount = 0;
-          break;
-        }
+      if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_NORTH | META_GRAB_OP_WINDOW_DIR_SOUTH)) != 0)
+        y_amount = dy < 0 ? - dy : dy;
+      else
+        y_amount = 0;
 
       if (y_amount > threshold)
         new_unmaximize |= META_MAXIMIZE_VERTICAL;
@@ -5870,73 +5838,34 @@ update_resize (MetaWindow *window,
 
   if (window->display->grab_op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)
     {
-      if ((dx > 0) && (dy > 0))
-        window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE;
-      else if ((dx < 0) && (dy > 0))
-        window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW;
-      else if ((dx > 0) && (dy < 0))
-        window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE;
-      else if ((dx < 0) && (dy < 0))
-        window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW;
+      MetaGrabOp op = META_GRAB_OP_WINDOW_BASE | META_GRAB_OP_WINDOW_FLAG_KEYBOARD;
+
+      if (dx > 0)
+        op |= META_GRAB_OP_WINDOW_DIR_EAST;
       else if (dx < 0)
-        window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
-      else if (dx > 0)
-        window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
-      else if (dy > 0)
-        window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
+        op |= META_GRAB_OP_WINDOW_DIR_WEST;
+
+      if (dy > 0)
+        op |= META_GRAB_OP_WINDOW_DIR_SOUTH;
       else if (dy < 0)
-        window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
+        op |= META_GRAB_OP_WINDOW_DIR_NORTH;
+
+      window->display->grab_op = op;
 
       meta_window_update_keyboard_resize (window, TRUE);
     }
 
   new_unmaximize = check_resize_unmaximize (window, dx, dy);
 
-  switch (window->display->grab_op)
-    {
-    case META_GRAB_OP_RESIZING_SE:
-    case META_GRAB_OP_RESIZING_NE:
-    case META_GRAB_OP_RESIZING_E:
-    case META_GRAB_OP_KEYBOARD_RESIZING_SE:
-    case META_GRAB_OP_KEYBOARD_RESIZING_NE:
-    case META_GRAB_OP_KEYBOARD_RESIZING_E:
-      new_w += dx;
-      break;
-
-    case META_GRAB_OP_RESIZING_NW:
-    case META_GRAB_OP_RESIZING_SW:
-    case META_GRAB_OP_RESIZING_W:
-    case META_GRAB_OP_KEYBOARD_RESIZING_NW:
-    case META_GRAB_OP_KEYBOARD_RESIZING_SW:
-    case META_GRAB_OP_KEYBOARD_RESIZING_W:
-      new_w -= dx;
-      break;
-    default:
-      break;
-    }
-
-  switch (window->display->grab_op)
-    {
-    case META_GRAB_OP_RESIZING_SE:
-    case META_GRAB_OP_RESIZING_S:
-    case META_GRAB_OP_RESIZING_SW:
-    case META_GRAB_OP_KEYBOARD_RESIZING_SE:
-    case META_GRAB_OP_KEYBOARD_RESIZING_S:
-    case META_GRAB_OP_KEYBOARD_RESIZING_SW:
-      new_h += dy;
-      break;
+  if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_EAST)
+    new_w += dx;
+  else if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_WEST)
+    new_w -= dx;
 
-    case META_GRAB_OP_RESIZING_N:
-    case META_GRAB_OP_RESIZING_NE:
-    case META_GRAB_OP_RESIZING_NW:
-    case META_GRAB_OP_KEYBOARD_RESIZING_N:
-    case META_GRAB_OP_KEYBOARD_RESIZING_NE:
-    case META_GRAB_OP_KEYBOARD_RESIZING_NW:
-      new_h -= dy;
-      break;
-    default:
-      break;
-    }
+  if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_SOUTH)
+    new_h += dy;
+  else if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_NORTH)
+    new_h -= dy;
 
   /* If we're waiting for a request for _NET_WM_SYNC_REQUEST, we'll
    * resize the window when the window responds, or when we time
@@ -5976,21 +5905,12 @@ update_resize (MetaWindow *window,
    * aspect ratio windows don't interact nicely with the above stuff.  So,
    * to avoid some nasty flicker, we enforce that.
    */
-  switch (window->display->grab_op)
-    {
-    case META_GRAB_OP_RESIZING_S:
-    case META_GRAB_OP_RESIZING_N:
-      new_w = old.width;
-      break;
 
-    case META_GRAB_OP_RESIZING_E:
-    case META_GRAB_OP_RESIZING_W:
-      new_h = old.height;
-      break;
+  if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_WEST | META_GRAB_OP_WINDOW_DIR_EAST)) == 0)
+    new_w = old.width;
 
-    default:
-      break;
-    }
+  if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_NORTH | META_GRAB_OP_WINDOW_DIR_SOUTH)) == 0)
+    new_h = old.height;
 
   /* compute gravity of client during operation */
   gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
@@ -6499,57 +6419,19 @@ warp_grab_pointer (MetaWindow          *window,
 
   meta_window_get_frame_rect (window, &rect);
 
-  switch (grab_op)
-    {
-      case META_GRAB_OP_KEYBOARD_MOVING:
-      case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
-        *x = rect.width / 2;
-        *y = rect.height / 2;
-        break;
-
-      case META_GRAB_OP_KEYBOARD_RESIZING_S:
-        *x = rect.width / 2;
-        *y = rect.height - 1;
-        break;
-
-      case META_GRAB_OP_KEYBOARD_RESIZING_N:
-        *x = rect.width / 2;
-        *y = 0;
-        break;
-
-      case META_GRAB_OP_KEYBOARD_RESIZING_W:
-        *x = 0;
-        *y = rect.height / 2;
-        break;
-
-      case META_GRAB_OP_KEYBOARD_RESIZING_E:
-        *x = rect.width - 1;
-        *y = rect.height / 2;
-        break;
-
-      case META_GRAB_OP_KEYBOARD_RESIZING_SE:
-        *x = rect.width - 1;
-        *y = rect.height - 1;
-        break;
-
-      case META_GRAB_OP_KEYBOARD_RESIZING_NE:
-        *x = rect.width - 1;
-        *y = 0;
-        break;
-
-      case META_GRAB_OP_KEYBOARD_RESIZING_SW:
-        *x = 0;
-        *y = rect.height - 1;
-        break;
-
-      case META_GRAB_OP_KEYBOARD_RESIZING_NW:
-        *x = 0;
-        *y = 0;
-        break;
+  if (grab_op & META_GRAB_OP_WINDOW_DIR_WEST)
+    *x = 0;
+  else if (grab_op & META_GRAB_OP_WINDOW_DIR_EAST)
+    *x = rect.width - 1;
+  else
+    *x = rect.width / 2;
 
-      default:
-        return FALSE;
-    }
+  if (grab_op & META_GRAB_OP_WINDOW_DIR_SOUTH)
+    *y = 0;
+  else if (grab_op & META_GRAB_OP_WINDOW_DIR_NORTH)
+    *y = rect.height - 1;
+  else
+    *y = rect.height / 2;
 
   *x += rect.x;
   *y += rect.y;
@@ -7944,7 +7826,7 @@ meta_window_handle_ungrabbed_event (MetaWindow         *window,
           gboolean north, south;
           gboolean west, east;
           MetaRectangle frame_rect;
-          MetaGrabOp op;
+          MetaGrabOp op = META_GRAB_OP_WINDOW_BASE;
 
           meta_window_get_frame_rect (window, &frame_rect);
 
@@ -7953,26 +7835,16 @@ meta_window_handle_ungrabbed_event (MetaWindow         *window,
           north = event->button.y < (frame_rect.y + 1 * frame_rect.height / 3);
           south = event->button.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)
+          if (west)
+            op |= META_GRAB_OP_WINDOW_DIR_WEST;
+          if (east)
+            op |= META_GRAB_OP_WINDOW_DIR_EAST;
+          if (north)
+            op |= META_GRAB_OP_WINDOW_DIR_NORTH;
+          if (south)
+            op |= META_GRAB_OP_WINDOW_DIR_SOUTH;
+
+          if (op != META_GRAB_OP_WINDOW_BASE)
             meta_display_begin_grab_op (display,
                                         window->screen,
                                         window,
diff --git a/src/meta/common.h b/src/meta/common.h
index 9fc0297..776dc1a 100644
--- a/src/meta/common.h
+++ b/src/meta/common.h
@@ -111,41 +111,76 @@ typedef enum
  * @META_GRAB_OP_COMPOSITOR: Compositor asked for grab
  */
 
-/* when changing this enum, there are various switch statements
- * you have to update
+/* The lower 16 bits of the grab operation is its type.
+ *
+ * Window grab operations have the following layout:
+ *
+ * 0000  0000  | 0000 0011
+ * NSEW  flags | type
+ *
+ * Flags contains whether the operation is a keyboard operation,
+ * and whether the keyboard operation is "unknown".
+ *
+ * The rest of the flags tell you which direction the resize is
+ * going in.
+ *
+ * If the directions field is 0000, then the operation is a move,
+ * not a resize.
+ * If the directions field is 1111, then it's an unknown direction.
  */
+enum
+{
+  META_GRAB_OP_WINDOW_FLAG_KEYBOARD = 0x0100,
+  META_GRAB_OP_WINDOW_DIR_WEST      = 0x1000,
+  META_GRAB_OP_WINDOW_DIR_EAST      = 0x2000,
+  META_GRAB_OP_WINDOW_DIR_SOUTH     = 0x4000,
+  META_GRAB_OP_WINDOW_DIR_NORTH     = 0x8000,
+  META_GRAB_OP_WINDOW_DIR_UNKNOWN   = 0xF000,
+
+  /* WGO = "window grab op". shorthand for below */
+  _WGO_K = META_GRAB_OP_WINDOW_FLAG_KEYBOARD,
+  _WGO_W = META_GRAB_OP_WINDOW_DIR_WEST,
+  _WGO_E = META_GRAB_OP_WINDOW_DIR_EAST,
+  _WGO_S = META_GRAB_OP_WINDOW_DIR_SOUTH,
+  _WGO_N = META_GRAB_OP_WINDOW_DIR_NORTH,
+  _WGO_U = META_GRAB_OP_WINDOW_DIR_UNKNOWN,
+};
+
+#define GRAB_OP_GET_BASE_TYPE(op) (op & 0x00FF)
+
 typedef enum
 {
   META_GRAB_OP_NONE,
 
-  /* Mouse ops */
-  META_GRAB_OP_MOVING,
-  META_GRAB_OP_RESIZING_SE,
-  META_GRAB_OP_RESIZING_S,
-  META_GRAB_OP_RESIZING_SW,
-  META_GRAB_OP_RESIZING_N,
-  META_GRAB_OP_RESIZING_NE,
-  META_GRAB_OP_RESIZING_NW,
-  META_GRAB_OP_RESIZING_W,
-  META_GRAB_OP_RESIZING_E,
-
-  /* Keyboard ops */
-  META_GRAB_OP_KEYBOARD_MOVING,
-  META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
-  META_GRAB_OP_KEYBOARD_RESIZING_S,
-  META_GRAB_OP_KEYBOARD_RESIZING_N,
-  META_GRAB_OP_KEYBOARD_RESIZING_W,
-  META_GRAB_OP_KEYBOARD_RESIZING_E,
-  META_GRAB_OP_KEYBOARD_RESIZING_SE,
-  META_GRAB_OP_KEYBOARD_RESIZING_NE,
-  META_GRAB_OP_KEYBOARD_RESIZING_SW,
-  META_GRAB_OP_KEYBOARD_RESIZING_NW,
-
   /* Special grab op when the compositor asked for a grab */
   META_GRAB_OP_COMPOSITOR,
 
   /* For when a Wayland client takes a popup grab */
   META_GRAB_OP_WAYLAND_POPUP,
+
+  /* Window grab ops. */
+  META_GRAB_OP_WINDOW_BASE,
+
+  _WGO_BASE = META_GRAB_OP_WINDOW_BASE,
+  META_GRAB_OP_MOVING                     = _WGO_BASE,
+  META_GRAB_OP_RESIZING_NW                = _WGO_BASE | _WGO_N | _WGO_W,
+  META_GRAB_OP_RESIZING_N                 = _WGO_BASE | _WGO_N,
+  META_GRAB_OP_RESIZING_NE                = _WGO_BASE | _WGO_N | _WGO_E,
+  META_GRAB_OP_RESIZING_E                 = _WGO_BASE |          _WGO_E,
+  META_GRAB_OP_RESIZING_SW                = _WGO_BASE | _WGO_S | _WGO_W,
+  META_GRAB_OP_RESIZING_S                 = _WGO_BASE | _WGO_S,
+  META_GRAB_OP_RESIZING_SE                = _WGO_BASE | _WGO_S | _WGO_E,
+  META_GRAB_OP_RESIZING_W                 = _WGO_BASE |          _WGO_W,
+  META_GRAB_OP_KEYBOARD_MOVING            = _WGO_BASE |                   _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN  = _WGO_BASE | _WGO_U |          _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_NW       = _WGO_BASE | _WGO_N | _WGO_W | _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_N        = _WGO_BASE | _WGO_N |          _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_NE       = _WGO_BASE | _WGO_N | _WGO_E | _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_E        = _WGO_BASE |          _WGO_E | _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_SW       = _WGO_BASE | _WGO_S | _WGO_W | _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_S        = _WGO_BASE | _WGO_S |          _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_SE       = _WGO_BASE | _WGO_S | _WGO_E | _WGO_K,
+  META_GRAB_OP_KEYBOARD_RESIZING_W        = _WGO_BASE |          _WGO_W | _WGO_K,
 } MetaGrabOp;
 
 /**
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 9963353..d6f386d 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -867,28 +867,24 @@ xdg_surface_move (struct wl_client *client,
 static MetaGrabOp
 grab_op_for_xdg_surface_resize_edge (int edge)
 {
-  switch (edge)
+  MetaGrabOp op = META_GRAB_OP_WINDOW_BASE;
+
+  if (edge & XDG_SURFACE_RESIZE_EDGE_TOP)
+    op |= META_GRAB_OP_WINDOW_DIR_NORTH;
+  if (edge & XDG_SURFACE_RESIZE_EDGE_BOTTOM)
+    op |= META_GRAB_OP_WINDOW_DIR_SOUTH;
+  if (edge & XDG_SURFACE_RESIZE_EDGE_LEFT)
+    op |= META_GRAB_OP_WINDOW_DIR_WEST;
+  if (edge & XDG_SURFACE_RESIZE_EDGE_RIGHT)
+    op |= META_GRAB_OP_WINDOW_DIR_EAST;
+
+  if (op == META_GRAB_OP_WINDOW_BASE)
     {
-    case XDG_SURFACE_RESIZE_EDGE_TOP_LEFT:
-      return META_GRAB_OP_RESIZING_NW;
-    case XDG_SURFACE_RESIZE_EDGE_TOP:
-      return META_GRAB_OP_RESIZING_N;
-    case XDG_SURFACE_RESIZE_EDGE_TOP_RIGHT:
-      return META_GRAB_OP_RESIZING_NE;
-    case XDG_SURFACE_RESIZE_EDGE_RIGHT:
-      return META_GRAB_OP_RESIZING_E;
-    case XDG_SURFACE_RESIZE_EDGE_BOTTOM_RIGHT:
-      return META_GRAB_OP_RESIZING_SE;
-    case XDG_SURFACE_RESIZE_EDGE_BOTTOM:
-      return META_GRAB_OP_RESIZING_S;
-    case XDG_SURFACE_RESIZE_EDGE_BOTTOM_LEFT:
-      return META_GRAB_OP_RESIZING_SW;
-    case XDG_SURFACE_RESIZE_EDGE_LEFT:
-      return META_GRAB_OP_RESIZING_W;
-    default:
       g_warning ("invalid edge: %d", edge);
       return META_GRAB_OP_NONE;
     }
+
+  return op;
 }
 
 static void
@@ -1177,28 +1173,24 @@ wl_shell_surface_move (struct wl_client *client,
 static MetaGrabOp
 grab_op_for_wl_shell_surface_resize_edge (int edge)
 {
-  switch (edge)
+  MetaGrabOp op = META_GRAB_OP_WINDOW_BASE;
+
+  if (edge & WL_SHELL_SURFACE_RESIZE_TOP)
+    op |= META_GRAB_OP_WINDOW_DIR_NORTH;
+  if (edge & WL_SHELL_SURFACE_RESIZE_BOTTOM)
+    op |= META_GRAB_OP_WINDOW_DIR_SOUTH;
+  if (edge & WL_SHELL_SURFACE_RESIZE_LEFT)
+    op |= META_GRAB_OP_WINDOW_DIR_WEST;
+  if (edge & WL_SHELL_SURFACE_RESIZE_RIGHT)
+    op |= META_GRAB_OP_WINDOW_DIR_EAST;
+
+  if (op == META_GRAB_OP_WINDOW_BASE)
     {
-    case WL_SHELL_SURFACE_RESIZE_TOP_LEFT:
-      return META_GRAB_OP_RESIZING_NW;
-    case WL_SHELL_SURFACE_RESIZE_TOP:
-      return META_GRAB_OP_RESIZING_N;
-    case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
-      return META_GRAB_OP_RESIZING_NE;
-    case WL_SHELL_SURFACE_RESIZE_RIGHT:
-      return META_GRAB_OP_RESIZING_E;
-    case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
-      return META_GRAB_OP_RESIZING_SE;
-    case WL_SHELL_SURFACE_RESIZE_BOTTOM:
-      return META_GRAB_OP_RESIZING_S;
-    case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
-      return META_GRAB_OP_RESIZING_SW;
-    case WL_SHELL_SURFACE_RESIZE_LEFT:
-      return META_GRAB_OP_RESIZING_W;
-    default:
       g_warning ("invalid edge: %d", edge);
       return META_GRAB_OP_NONE;
     }
+
+  return op;
 }
 
 static void


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