Ken Thomases : winemac: Allow the user to attempt to resize a maximized window and try to restore it if they do.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Mar 24 10:00:43 CDT 2015


Module: wine
Branch: master
Commit: 8d581d0e489c6bf7d54674adc0ea695e8adc978f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8d581d0e489c6bf7d54674adc0ea695e8adc978f

Author: Ken Thomases <ken at codeweavers.com>
Date:   Mon Mar 23 18:58:06 2015 -0500

winemac: Allow the user to attempt to resize a maximized window and try to restore it if they do.

OS X doesn't have the same concept of maximized windows as Windows does.
There's no mode that prevents a normally-resizable window from being resized.
If a window is "zoomed", it mostly fills the screen but the user can still
move or resize it, at which point it ceases to be in the zoomed state.  So,
users are confused and frustrated when they can't resize a window that's
maximized.

To get similar behavior while still respecting Win32 semantics, we now let the
user try to resize maximized windows.  (The resize cursors are shown at the
edges of the window frame.)  When they start, a request is submitted to the app
to restore the window.  Unless and until the window is restored, we don't
actually allow the window to change its size.

The user expects to resize the window from its current (maximized) position.
It should not jump to its normal position upon being restored.  So, we set the
window's normal position to its current position before restoring it.

---

 dlls/winemac.drv/cocoa_window.m | 46 +++++++++++++++++++++++++++++++++--------
 dlls/winemac.drv/event.c        |  2 +-
 dlls/winemac.drv/macdrv.h       |  2 +-
 dlls/winemac.drv/macdrv_cocoa.h |  4 ++++
 dlls/winemac.drv/window.c       | 22 +++++++++++++++++++-
 5 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index 7f71fea..1bb99a9 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -650,7 +650,7 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
     - (BOOL) preventResizing
     {
         BOOL preventForClipping = cursor_clipping_locks_windows && [[WineApplicationController sharedController] clippingCursor];
-        return ([self styleMask] & NSResizableWindowMask) && (disabled || !resizable || maximized || preventForClipping);
+        return ([self styleMask] & NSResizableWindowMask) && (disabled || !resizable || preventForClipping);
     }
 
     - (void) adjustFeaturesForState
@@ -814,6 +814,16 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
         macdrv_release_event(event);
     }
 
+    - (void) sendResizeStartQuery
+    {
+        macdrv_query* query = macdrv_create_query();
+        query->type = QUERY_RESIZE_START;
+        query->window = (macdrv_window)[self retain];
+
+        [self.queue query:query timeout:0.3];
+        macdrv_release_query(query);
+    }
+
     - (void) setMacDrvState:(const struct macdrv_window_state*)state
     {
         NSWindowCollectionBehavior behavior;
@@ -892,6 +902,9 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
         {
             maximized = state->maximized;
             [self adjustFeaturesForState];
+
+            if (!maximized && [self inLiveResize])
+                [self sendResizeStartQuery];
         }
 
         behavior = NSWindowCollectionBehaviorDefault;
@@ -1797,9 +1810,12 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
 
     - (void) windowDidEndLiveResize:(NSNotification *)notification
     {
-        macdrv_event* event = macdrv_create_event(WINDOW_RESIZE_ENDED, self);
-        [queue postEvent:event];
-        macdrv_release_event(event);
+        if (!maximized)
+        {
+            macdrv_event* event = macdrv_create_event(WINDOW_RESIZE_ENDED, self);
+            [queue postEvent:event];
+            macdrv_release_event(event);
+        }
 
         self.liveResizeDisplayTimer = nil;
     }
@@ -1958,6 +1974,9 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
     {
         if ([self inLiveResize])
         {
+            if (maximized)
+                return self.frame.size;
+
             NSRect rect;
             macdrv_query* query;
 
@@ -1992,12 +2011,21 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
 
     - (void) windowWillStartLiveResize:(NSNotification *)notification
     {
-        macdrv_query* query = macdrv_create_query();
-        query->type = QUERY_RESIZE_START;
-        query->window = (macdrv_window)[self retain];
+        if (maximized)
+        {
+            macdrv_event* event;
+            NSRect frame = [self contentRectForFrameRect:self.frame];
 
-        [self.queue query:query timeout:0.3];
-        macdrv_release_query(query);
+            [[WineApplicationController sharedController] flipRect:&frame];
+
+            event = macdrv_create_event(WINDOW_RESTORE_REQUESTED, self);
+            event->window_restore_requested.keep_frame = TRUE;
+            event->window_restore_requested.frame = NSRectToCGRect(frame);
+            [queue postEvent:event];
+            macdrv_release_event(event);
+        }
+        else
+            [self sendResizeStartQuery];
 
         frameAtResizeStart = [self frame];
         resizingFromLeft = resizingFromTop = FALSE;
diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c
index 8e03080..58b507c 100644
--- a/dlls/winemac.drv/event.c
+++ b/dlls/winemac.drv/event.c
@@ -280,7 +280,7 @@ void macdrv_handle_event(const macdrv_event *event)
         macdrv_window_resize_ended(hwnd);
         break;
     case WINDOW_RESTORE_REQUESTED:
-        macdrv_window_restore_requested(hwnd);
+        macdrv_window_restore_requested(hwnd, event);
         break;
     default:
         TRACE("    ignoring\n");
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index cf0fc64..a874dfb 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -172,7 +172,7 @@ extern void macdrv_window_minimize_requested(HWND hwnd) DECLSPEC_HIDDEN;
 extern void macdrv_window_did_unminimize(HWND hwnd) DECLSPEC_HIDDEN;
 extern void macdrv_window_brought_forward(HWND hwnd) DECLSPEC_HIDDEN;
 extern void macdrv_window_resize_ended(HWND hwnd) DECLSPEC_HIDDEN;
-extern void macdrv_window_restore_requested(HWND hwnd) DECLSPEC_HIDDEN;
+extern void macdrv_window_restore_requested(HWND hwnd, const macdrv_event *event) DECLSPEC_HIDDEN;
 extern void macdrv_window_drag_begin(HWND hwnd) DECLSPEC_HIDDEN;
 extern void macdrv_window_drag_end(HWND hwnd) DECLSPEC_HIDDEN;
 extern BOOL query_resize_size(HWND hwnd, macdrv_query *query) DECLSPEC_HIDDEN;
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h
index 30b6b64..4b68adc 100644
--- a/dlls/winemac.drv/macdrv_cocoa.h
+++ b/dlls/winemac.drv/macdrv_cocoa.h
@@ -291,6 +291,10 @@ typedef struct macdrv_event {
             unsigned long   serial;
             void           *tried_windows;
         }                                           window_got_focus;
+        struct {
+            int     keep_frame;
+            CGRect  frame;
+        }                                           window_restore_requested;
     };
 } macdrv_event;
 
diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c
index 54bd56e..7a777e6 100644
--- a/dlls/winemac.drv/window.c
+++ b/dlls/winemac.drv/window.c
@@ -2139,8 +2139,28 @@ void macdrv_window_resize_ended(HWND hwnd)
  * Handler for WINDOW_RESTORE_REQUESTED events.  This is specifically
  * for restoring from maximized, not from minimized.
  */
-void macdrv_window_restore_requested(HWND hwnd)
+void macdrv_window_restore_requested(HWND hwnd, const macdrv_event *event)
 {
+    if (event->window_restore_requested.keep_frame && hwnd)
+    {
+        DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
+        struct macdrv_win_data *data;
+
+        if ((style & WS_MAXIMIZE) && (style & WS_VISIBLE) && (data = get_win_data(hwnd)))
+        {
+            RECT rect;
+            HWND parent = GetAncestor(hwnd, GA_PARENT);
+
+            rect = rect_from_cgrect(event->window_restore_requested.frame);
+            macdrv_mac_to_window_rect(data, &rect);
+            MapWindowPoints(0, parent, (POINT *)&rect, 2);
+
+            release_win_data(data);
+
+            SetInternalWindowPos(hwnd, SW_SHOW, &rect, NULL);
+        }
+    }
+
     perform_window_command(hwnd, WS_MAXIMIZE, 0, SC_RESTORE, HTMAXBUTTON);
 }
 




More information about the wine-cvs mailing list