[gtk+] quartz: Implement CSD drag resize for all edges/corners



commit 6eaf5bd0f2f432ced83fbc4f379e1d289873d400
Author: Christoph Reiter <reiter christoph gmail com>
Date:   Thu Aug 6 21:36:57 2015 +0200

    quartz: Implement CSD drag resize for all edges/corners
    
    Manual resizing for CSD windows only worked with the bottom
    right corner. This extends it to work for all corners and edges.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=753329

 gdk/quartz/GdkQuartzNSWindow.c |   88 ++++++++++++++++++++++++++++-----------
 gdk/quartz/GdkQuartzNSWindow.h |    4 +-
 gdk/quartz/gdkwindow-quartz.c  |    8 +---
 3 files changed, 67 insertions(+), 33 deletions(-)
---
diff --git a/gdk/quartz/GdkQuartzNSWindow.c b/gdk/quartz/GdkQuartzNSWindow.c
index 155dec9..f757d29 100644
--- a/gdk/quartz/GdkQuartzNSWindow.c
+++ b/gdk/quartz/GdkQuartzNSWindow.c
@@ -406,9 +406,9 @@
 
 - (BOOL)trackManualResize
 {
-  NSPoint currentLocation;
-  NSRect newFrame;
-  float dx, dy;
+  NSPoint mouse_location;
+  NSRect new_frame;
+  float mdx, mdy, dw, dh, dx, dy;
   NSSize min_size;
 
   if (!inManualResize || inTrackManualResize)
@@ -416,33 +416,72 @@
 
   inTrackManualResize = YES;
 
-  currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
-  currentLocation.x -= initialResizeFrame.origin.x;
-  currentLocation.y -= initialResizeFrame.origin.y;
+  mouse_location = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
+  mdx = initialResizeLocation.x - mouse_location.x;
+  mdy = initialResizeLocation.y - mouse_location.y;
 
-  dx = currentLocation.x - initialResizeLocation.x;
-  dy = -(currentLocation.y - initialResizeLocation.y);
+  /* Set how a mouse location delta translates to changes in width,
+   * height and position.
+   */
+  dw = dh = dx = dy = 0.0;
+  if (resizeEdge == GDK_WINDOW_EDGE_EAST ||
+      resizeEdge == GDK_WINDOW_EDGE_NORTH_EAST ||
+      resizeEdge == GDK_WINDOW_EDGE_SOUTH_EAST)
+    {
+      dw = -1.0;
+    }
+  if (resizeEdge == GDK_WINDOW_EDGE_NORTH ||
+      resizeEdge == GDK_WINDOW_EDGE_NORTH_WEST ||
+      resizeEdge == GDK_WINDOW_EDGE_NORTH_EAST)
+    {
+      dh = -1.0;
+    }
+  if (resizeEdge == GDK_WINDOW_EDGE_SOUTH ||
+      resizeEdge == GDK_WINDOW_EDGE_SOUTH_WEST ||
+      resizeEdge == GDK_WINDOW_EDGE_SOUTH_EAST)
+    {
+      dh = 1.0;
+      dy = -1.0;
+    }
+  if (resizeEdge == GDK_WINDOW_EDGE_WEST ||
+      resizeEdge == GDK_WINDOW_EDGE_NORTH_WEST ||
+      resizeEdge == GDK_WINDOW_EDGE_SOUTH_WEST)
+    {
+      dw = 1.0;
+      dx = -1.0;
+    }
 
-  newFrame = initialResizeFrame;
-  newFrame.size.width = initialResizeFrame.size.width + dx;
-  newFrame.size.height = initialResizeFrame.size.height + dy;
+  /* Apply changes to the frame captured when we started resizing */
+  new_frame = initialResizeFrame;
+  new_frame.origin.x += mdx * dx;
+  new_frame.origin.y += mdy * dy;
+  new_frame.size.width += mdx * dw;
+  new_frame.size.height += mdy * dh;
 
+  /* In case the resulting window would be too small reduce the
+   * change to both size and position.
+   */
   min_size = [self contentMinSize];
-  if (newFrame.size.width < min_size.width)
-    newFrame.size.width = min_size.width;
-  if (newFrame.size.height < min_size.height)
-    newFrame.size.height = min_size.height;
 
-  /* We could also apply aspect ratio:
-     newFrame.size.height = newFrame.size.width / [self aspectRatio].width * [self aspectRatio].height;
-  */
+  if (new_frame.size.width < min_size.width)
+    {
+      if (dx)
+        new_frame.origin.x -= min_size.width - new_frame.size.width;
+      new_frame.size.width = min_size.width;
+    }
 
-  dy = newFrame.size.height - initialResizeFrame.size.height;
+  if (new_frame.size.height < min_size.height)
+    {
+      if (dy)
+        new_frame.origin.y -= min_size.height - new_frame.size.height;
+      new_frame.size.height = min_size.height;
+    }
 
-  newFrame.origin.x = initialResizeFrame.origin.x;
-  newFrame.origin.y = initialResizeFrame.origin.y - dy;
+  /* We could also apply aspect ratio:
+     new_frame.size.height = new_frame.size.width / [self aspectRatio].width * [self aspectRatio].height;
+  */
 
-  [self setFrame:newFrame display:YES];
+  [self setFrame:new_frame display:YES];
 
   /* Let the resizing be handled by GTK+. */
   if (g_main_context_pending (NULL))
@@ -453,17 +492,16 @@
   return YES;
 }
 
--(void)beginManualResize
+-(void)beginManualResize:(GdkWindowEdge)edge
 {
   if (inMove || inManualMove || inManualResize)
     return;
 
   inManualResize = YES;
+  resizeEdge = edge;
 
   initialResizeFrame = [self frame];
   initialResizeLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
-  initialResizeLocation.x -= initialResizeFrame.origin.x;
-  initialResizeLocation.y -= initialResizeFrame.origin.y;
 }
 
 
diff --git a/gdk/quartz/GdkQuartzNSWindow.h b/gdk/quartz/GdkQuartzNSWindow.h
index a274ee9..31175da 100644
--- a/gdk/quartz/GdkQuartzNSWindow.h
+++ b/gdk/quartz/GdkQuartzNSWindow.h
@@ -19,6 +19,7 @@
 #import <AppKit/AppKit.h>
 #import <Foundation/Foundation.h>
 #include <glib.h>
+#include <gdk.h>
 
 @interface GdkQuartzNSWindow : NSWindow {
   BOOL    inMove;
@@ -32,6 +33,7 @@
   NSPoint initialMoveLocation;
   NSPoint initialResizeLocation;
   NSRect  initialResizeFrame;
+  GdkWindowEdge resizeEdge;
 
   NSRect  lastUnmaximizedFrame;
   NSRect  lastMaximizedFrame;
@@ -42,7 +44,7 @@
 -(void)beginManualMove;
 -(BOOL)trackManualMove;
 -(BOOL)isInManualResizeOrMove;
--(void)beginManualResize;
+-(void)beginManualResize:(GdkWindowEdge)edge;
 -(BOOL)trackManualResize;
 -(void)showAndMakeKey:(BOOL)makeKey;
 -(void)hide;
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index ff759d0..62710a2 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -2224,12 +2224,6 @@ gdk_quartz_window_begin_resize_drag (GdkWindow     *window,
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  if (edge != GDK_WINDOW_EDGE_SOUTH_EAST)
-    {
-      g_warning ("Resizing is only implemented for GDK_WINDOW_EDGE_SOUTH_EAST on Mac OS");
-      return;
-    }
-
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
@@ -2241,7 +2235,7 @@ gdk_quartz_window_begin_resize_drag (GdkWindow     *window,
       return;
     }
 
-  [(GdkQuartzNSWindow *)impl->toplevel beginManualResize];
+  [(GdkQuartzNSWindow *)impl->toplevel beginManualResize:edge];
 }
 
 static void


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