[mutter/wip/gbsneto/tiling-improvements: 4/9] window: Split tile mode into preview and actual



commit 91d1f12d71c454cc6e5da3a998f6b6ca3c7c5477
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Jun 14 20:31:19 2017 -0300

    window: Split tile mode into preview and actual
    
    After the introduction of the ability to resize tiled
    windows, the tiling field became stateful and should
    be treated carefuly, in order to keep the state valid.
    
    When dragging windows around, however, the actual tile
    mode is changed in order to retrieve a meaningful preview,
    causing many visual glitches and issues when changing
    tiling after dragging the window.
    
    Because of that, it is now required to track the preview
    tile mode differently than the actual tile mode. This
    patch does that, and updates the function that calculates
    the tile area to consider the preview tile mode as well.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=645153

 src/core/keybindings.c    |    2 +-
 src/core/screen.c         |    4 +-
 src/core/stack.c          |    4 +-
 src/core/window-private.h |    4 +-
 src/core/window.c         |   93 +++++++++++++++++++++++++++++++++------------
 5 files changed, 77 insertions(+), 30 deletions(-)
---
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index b161e1e..7366aa7 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -2030,7 +2030,7 @@ process_mouse_move_resize_grab (MetaDisplay     *display,
   if (event->keyval == CLUTTER_KEY_Escape)
     {
       /* Hide the tiling preview if necessary */
-      if (window->tile_mode != META_TILE_NONE)
+      if (window->preview_tile_mode != META_TILE_NONE)
         meta_screen_hide_tile_preview (screen);
 
       /* Restore the original tile mode */
diff --git a/src/core/screen.c b/src/core/screen.c
index 83a0e9d..e9a3b7f 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -1407,7 +1407,7 @@ meta_screen_update_tile_preview_timeout (gpointer data)
 
   if (window)
     {
-      switch (window->tile_mode)
+      switch (window->preview_tile_mode)
         {
           case META_TILE_LEFT:
           case META_TILE_RIGHT:
@@ -1435,8 +1435,6 @@ meta_screen_update_tile_preview_timeout (gpointer data)
       meta_window_get_current_tile_area (window, &tile_rect);
       meta_compositor_show_tile_preview (screen->display->compositor,
                                          window, &tile_rect, monitor);
-
-      window->tile_mode = META_TILE_NONE;
     }
   else
     meta_compositor_hide_tile_preview (screen->display->compositor);
diff --git a/src/core/stack.c b/src/core/stack.c
index 5895b89..3ee5c74 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -267,7 +267,9 @@ meta_stack_update_window_tile_matches (MetaStack     *stack,
   tmp = windows;
   while (tmp)
     {
-      meta_window_compute_tile_match ((MetaWindow *) tmp->data);
+      MetaWindow *window = tmp->data;
+
+      window->tile_match = meta_window_compute_tile_match (window, FALSE);
       tmp = tmp->next;
     }
 
diff --git a/src/core/window-private.h b/src/core/window-private.h
index c993174..cc94469 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -211,6 +211,7 @@ struct _MetaWindow
   /* Keep track of the previous tile mode so when changing between left and
    * right tiles we can resize the window with the complementary width */
   guint previous_tile_mode : 2;
+  guint preview_tile_mode : 2;
   MetaRectangle tile_rect;
 
   int preferred_output_winsys_id;
@@ -702,7 +703,8 @@ void meta_window_on_all_workspaces_changed (MetaWindow *window);
 gboolean meta_window_should_attach_to_parent (MetaWindow *window);
 gboolean meta_window_can_tile_side_by_side   (MetaWindow *window);
 
-void meta_window_compute_tile_match (MetaWindow *window);
+MetaWindow* meta_window_compute_tile_match (MetaWindow *window,
+                                            gboolean    preview);
 
 gboolean meta_window_updates_are_frozen (MetaWindow *window);
 
diff --git a/src/core/window.c b/src/core/window.c
index bc2fa13..99ad4db 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -5695,7 +5695,7 @@ update_move (MetaWindow  *window,
     {
       /* We don't want to tile while snapping. Also, clear any previous tile
          request. */
-      window->tile_mode = META_TILE_NONE;
+      window->preview_tile_mode = META_TILE_NONE;
       window->tile_monitor_number = -1;
     }
   else if (meta_prefs_get_edge_tiling () &&
@@ -5732,18 +5732,18 @@ update_move (MetaWindow  *window,
        */
       if (meta_window_can_tile_side_by_side (window) &&
           x >= monitor->rect.x && x < (work_area.x + shake_threshold))
-        window->tile_mode = META_TILE_LEFT;
+        window->preview_tile_mode = META_TILE_LEFT;
       else if (meta_window_can_tile_side_by_side (window) &&
                x >= work_area.x + work_area.width - shake_threshold &&
                x < (monitor->rect.x + monitor->rect.width))
-        window->tile_mode = META_TILE_RIGHT;
+        window->preview_tile_mode = META_TILE_RIGHT;
       else if (meta_window_can_tile_maximized (window) &&
                y >= monitor->rect.y && y <= work_area.y)
-        window->tile_mode = META_TILE_MAXIMIZED;
+        window->preview_tile_mode = META_TILE_MAXIMIZED;
       else
-        window->tile_mode = META_TILE_NONE;
+        window->preview_tile_mode = META_TILE_NONE;
 
-      if (window->tile_mode != META_TILE_NONE)
+      if (window->preview_tile_mode != META_TILE_NONE)
         window->tile_monitor_number = monitor->number;
     }
 
@@ -5802,7 +5802,7 @@ update_move (MetaWindow  *window,
       MetaRectangle work_area;
       int monitor;
 
-      window->tile_mode = META_TILE_NONE;
+      window->preview_tile_mode = META_TILE_NONE;
       wmonitor = window->monitor;
       n_logical_monitors =
         meta_monitor_manager_get_num_logical_monitors (monitor_manager);
@@ -5854,7 +5854,7 @@ update_move (MetaWindow  *window,
    * it to another monitor.
    */
   meta_screen_update_tile_preview (window->screen,
-                                   window->tile_mode != META_TILE_NONE);
+                                   window->preview_tile_mode != META_TILE_NONE);
 
   meta_window_get_frame_rect (window, &old);
 
@@ -6121,8 +6121,11 @@ end_grab_op (MetaWindow *window,
     {
       if (meta_grab_op_is_moving (window->display->grab_op))
         {
-          if (window->tile_mode != META_TILE_NONE)
-            meta_window_tile (window);
+          if (window->preview_tile_mode != META_TILE_NONE)
+            {
+              meta_window_set_tile_mode (window, window->preview_tile_mode);
+              meta_window_tile (window);
+            }
           else
             update_move (window,
                          modifiers & CLUTTER_SHIFT_MASK,
@@ -6351,12 +6354,52 @@ void
 meta_window_get_current_tile_area (MetaWindow    *window,
                                    MetaRectangle *tile_area)
 {
-  g_return_if_fail (window->tile_mode != META_TILE_NONE);
+  MetaRectangle monitor_area;
+  MetaTileMode tile_mode;
+  gint borders_height = 0;
+  gint borders_width = 0;
+
+  g_return_if_fail (window->tile_mode != META_TILE_NONE || window->preview_tile_mode != META_TILE_NONE);
+
+  /* If we are previewing, don't change the actual tile mode */
+  if (window->preview_tile_mode != META_TILE_NONE)
+    tile_mode = window->preview_tile_mode;
+  else
+    tile_mode = window->tile_mode;
 
-  if (window->tile_mode != window->previous_tile_mode)
-    meta_window_update_tile_state_internal (window);
+  meta_window_get_work_area_current_monitor (window, &monitor_area);
 
+  /* Initially assume the tile area */
   *tile_area = window->tile_rect;
+
+  /* window->tile_rect must consider the visible borders */
+  if (window->frame)
+    {
+      MetaFrameBorders borders;
+
+      meta_frame_calc_borders (window->frame, &borders);
+
+      borders_height = borders.visible.top + borders.visible.bottom;
+      borders_width = borders.visible.left + borders.visible.right;
+    }
+
+  tile_area->x = monitor_area.x;
+  tile_area->y = monitor_area.y;
+  tile_area->height = monitor_area.height + borders_height;
+
+  if (tile_mode == META_TILE_MAXIMIZED)
+    {
+      /* When maximized, cover the entire width*/
+      tile_area->width = monitor_area.width;
+    }
+  else
+    {
+      /* Assume half of the work area of the current monitor */
+      tile_area->width = monitor_area.width / 2 + borders_width;
+    }
+
+  if (tile_mode == META_TILE_RIGHT)
+    tile_area->x = monitor_area.x + monitor_area.width - tile_area->width - borders_width;
 }
 
 gboolean
@@ -7461,24 +7504,26 @@ meta_window_get_tile_match (MetaWindow *window)
   return window->tile_match;
 }
 
-void
-meta_window_compute_tile_match (MetaWindow *window)
+MetaWindow *
+meta_window_compute_tile_match (MetaWindow *window,
+                                gboolean    preview)
 {
   MetaWindow *match;
   MetaStack *stack;
+  MetaTileMode current_mode;
   MetaTileMode match_tile_mode = META_TILE_NONE;
 
-  window->tile_match = NULL;
-
   if (window->shaded || window->minimized)
-    return;
+    return NULL;
 
-  if (META_WINDOW_TILED_LEFT (window))
+  current_mode = preview ? window->preview_tile_mode : window->tile_mode;
+
+  if (current_mode == META_TILE_LEFT)
     match_tile_mode = META_TILE_RIGHT;
-  else if (META_WINDOW_TILED_RIGHT (window))
+  else if (current_mode == META_TILE_RIGHT)
     match_tile_mode = META_TILE_LEFT;
   else
-    return;
+    return NULL;
 
   stack = window->screen->stack;
 
@@ -7529,11 +7574,11 @@ meta_window_compute_tile_match (MetaWindow *window)
 
           if (meta_rectangle_overlap (&above_rect, &bottommost_rect) &&
               meta_rectangle_overlap (&above_rect, &topmost_rect))
-            return;
+            return NULL;
         }
-
-      window->tile_match = match;
     }
+
+  return match;
 }
 
 void


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