[mutter] tiling: Add new "maximized" tile



commit 07c047190251e8e335119de8437ec09455cf3d58
Author: Ray Strode <rstrode redhat com>
Date:   Fri Sep 24 15:35:00 2010 -0400

    tiling: Add new "maximized" tile
    
    In addition to the existing side-by-side tiling modes, this commit
    adds a new "maximize" tiling mode.  It allows the user to maximize
    their windows (in other words, tile with the edge panels) by dragging
    their window to the top edge of the monitor.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=630548

 src/core/screen.c         |   26 +++++++++++-
 src/core/window-private.h |    3 +-
 src/core/window.c         |   91 ++++++++++++++++++++++++++++++++++++---------
 3 files changed, 98 insertions(+), 22 deletions(-)
---
diff --git a/src/core/screen.c b/src/core/screen.c
index c3a4f03..1dbd982 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -1758,6 +1758,7 @@ meta_screen_tile_preview_update_timeout (gpointer data)
   MetaScreen *screen = data;
   MetaWindow *window = screen->display->grab_window;
   gboolean composited = screen->display->compositor != NULL;
+  gboolean needs_preview = FALSE;
 
   screen->tile_preview_timeout_id = 0;
 
@@ -1775,9 +1776,28 @@ meta_screen_tile_preview_update_timeout (gpointer data)
                                      create_serial);
     }
 
-  if (window
-      && !META_WINDOW_TILED_SIDE_BY_SIDE (window)
-      && window->tile_mode != META_TILE_NONE)
+  if (window)
+    {
+      switch (window->tile_mode)
+        {
+          case META_TILE_LEFT:
+          case META_TILE_RIGHT:
+              if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
+                needs_preview = TRUE;
+              break;
+
+          case META_TILE_MAXIMIZED:
+              if (!META_WINDOW_MAXIMIZED (window))
+                needs_preview = TRUE;
+              break;
+
+          default:
+              needs_preview = FALSE;
+              break;
+        }
+    }
+
+  if (needs_preview)
     {
       MetaRectangle tile_rect;
 
diff --git a/src/core/window-private.h b/src/core/window-private.h
index cc8a3b3..0c6276e 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -64,7 +64,8 @@ typedef enum {
 typedef enum {
   META_TILE_NONE,
   META_TILE_LEFT,
-  META_TILE_RIGHT
+  META_TILE_RIGHT,
+  META_TILE_MAXIMIZED
 } MetaTileMode;
 
 struct _MetaWindow
diff --git a/src/core/window.c b/src/core/window.c
index ec3dadd..f8d64e5 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -3187,11 +3187,18 @@ meta_window_is_fullscreen (MetaWindow *window)
 static void
 meta_window_tile (MetaWindow *window)
 {
+  MetaMaximizeFlags directions;
+
   /* Don't do anything if no tiling is requested */
   if (window->tile_mode == META_TILE_NONE)
     return;
 
-  meta_window_maximize_internal (window, META_MAXIMIZE_VERTICAL, NULL);
+  if (window->tile_mode == META_TILE_MAXIMIZED)
+    directions = META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL;
+  else
+    directions = META_MAXIMIZE_VERTICAL;
+
+  meta_window_maximize_internal (window, directions, NULL);
   meta_screen_tile_preview_update (window->screen, FALSE);
 
   if (window->display->compositor)
@@ -3249,6 +3256,18 @@ meta_window_can_tile_side_by_side (MetaWindow *window)
          tile_area.height >= window->size_hints.min_height;
 }
 
+static gboolean
+meta_window_can_tile_maximized (MetaWindow *window)
+{
+  if (!META_WINDOW_ALLOWS_RESIZE (window))
+    return FALSE;
+
+  if (!window->has_maximize_func)
+    return FALSE;
+
+  return TRUE;
+}
+
 static void
 unmaximize_window_before_freeing (MetaWindow        *window)
 {
@@ -7799,14 +7818,13 @@ update_move (MetaWindow  *window,
   shake_threshold = meta_ui_get_drag_threshold (window->screen->ui) *
     DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR;
 
-  if (meta_prefs_get_edge_tiling () &&
-      meta_window_can_tile_side_by_side (window))
+  if (meta_prefs_get_edge_tiling ())
     {
       const MetaMonitorInfo *monitor;
       MetaRectangle work_area;
 
-      /* For tiling we are interested in the work area of the monitor where
-       * the pointer is located.
+      /* For side-by-side tiling we are interested in the inside vertical
+       * edges of the work area of the monitor where the pointer is located.
        * Also see comment in meta_window_get_current_tile_area()
        */
       monitor = meta_screen_get_current_monitor (window->screen);
@@ -7814,17 +7832,38 @@ update_move (MetaWindow  *window,
                                              monitor->number,
                                              &work_area);
 
-      if (y >= monitor->rect.y &&
-          y < (monitor->rect.y + monitor->rect.height))
+      if (meta_window_can_tile_side_by_side (window))
         {
-          /* check if cursor is near an edge of the work area */
-          if (x >= monitor->rect.x && x < (work_area.x + shake_threshold))
-            window->tile_mode = META_TILE_LEFT;
-          else if (x >= work_area.x + work_area.width - shake_threshold &&
-                   x < (monitor->rect.x + monitor->rect.width))
-            window->tile_mode = META_TILE_RIGHT;
-          else
-            window->tile_mode = META_TILE_NONE;
+          if (y >= monitor->rect.y &&
+              y < (monitor->rect.y + monitor->rect.height))
+            {
+              /* check if cursor is near an edge of the work area */
+              if (x >= monitor->rect.x && x < (work_area.x + shake_threshold))
+                window->tile_mode = META_TILE_LEFT;
+              else if (x >= work_area.x + work_area.width - shake_threshold &&
+                       x < (monitor->rect.x + monitor->rect.width))
+                window->tile_mode = META_TILE_RIGHT;
+              else
+                window->tile_mode = META_TILE_NONE;
+            }
+        }
+
+      /* For maximized tiling we are interested in the outside top edge
+       * of the work area of the monitor where the pointer is located.
+       *
+       * We use the outside edge instead of the inside edge, because we
+       * don't want to force users to maximize windows they are placing
+       * near the top of their screens.
+       */
+      if (meta_window_can_tile_maximized (window))
+        {
+          if (x >= monitor->rect.x &&
+              x < (monitor->rect.x + monitor->rect.width))
+            {
+              /* check if cursor is on the top edge of the monitor*/
+              if (y >= monitor->rect.y && y < work_area.y)
+                  window->tile_mode = META_TILE_MAXIMIZED;
+            }
         }
     }
 
@@ -7872,12 +7911,13 @@ update_move (MetaWindow  *window,
    * loose or it is still maximized (then move straight)
    */
   else if ((window->shaken_loose || META_WINDOW_MAXIMIZED (window)) &&
-           window->tile_mode == META_TILE_NONE)
+           window->tile_mode != META_TILE_LEFT && window->tile_mode != META_TILE_RIGHT)
     {
       const MetaMonitorInfo *wmonitor;
       MetaRectangle work_area;
       int monitor;
 
+      window->tile_mode = META_TILE_NONE;
       wmonitor = meta_screen_get_monitor_for_window (window->screen, window);
 
       for (monitor = 0; monitor < window->screen->n_monitor_infos; monitor++)
@@ -8372,6 +8412,22 @@ check_use_this_motion_notify (MetaWindow *window,
     }
 }
 
+static void
+update_tile_mode (MetaWindow *window)
+{
+  switch (window->tile_mode)
+    {
+      case META_TILE_LEFT:
+      case META_TILE_RIGHT:
+          if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
+              window->tile_mode = META_TILE_NONE;
+      case META_TILE_MAXIMIZED:
+          if (!META_WINDOW_MAXIMIZED (window))
+              window->tile_mode = META_TILE_NONE;
+          break;
+    }
+}
+
 void
 meta_window_handle_mouse_grab_op_event (MetaWindow *window,
                                         XEvent     *event)
@@ -8464,8 +8520,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
                * would break the ability to snap back to the tiled
                * state, so we wait until mouse release.
                */
-              if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
-                window->tile_mode = META_TILE_NONE;
+              update_tile_mode (window);
             }
         }
 



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