Ken Thomases : winemac: Allow ordering a window into Cocoa' s window list even if it's positioned outside of the desktop.

Alexandre Julliard julliard at winehq.org
Fri Nov 15 13:14:29 CST 2013


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

Author: Ken Thomases <ken at codeweavers.com>
Date:   Thu Nov 14 20:52:04 2013 -0600

winemac: Allow ordering a window into Cocoa's window list even if it's positioned outside of the desktop.

Some programs minimize windows which are outside of the desktop.  The Mac
driver had been leaving such windows ordered out, which prevented them from
minimizing and appearing on the Dock.  That, in turn, made it difficult for
the user to restore them.

---

 dlls/winemac.drv/cocoa_window.m |   64 +++++++++++---------------------------
 dlls/winemac.drv/macdrv_cocoa.h |    4 +-
 dlls/winemac.drv/window.c       |   20 ++++++------
 3 files changed, 31 insertions(+), 57 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index dbac40a..f7c2cd0 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -1045,11 +1045,10 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
 
     /* Returns whether or not the window was ordered in, which depends on if
        its frame intersects any screen. */
-    - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next activate:(BOOL)activate
+    - (void) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next activate:(BOOL)activate
     {
         WineApplicationController* controller = [WineApplicationController sharedController];
-        BOOL on_screen = frame_intersects_screens([self frame], [NSScreen screens]);
-        if (on_screen && ![self isMiniaturized])
+        if (![self isMiniaturized])
         {
             BOOL needAdjustWindowLevels = FALSE;
             BOOL wasVisible = [self isVisible];
@@ -1128,8 +1127,6 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
             if (![self isExcludedFromWindowsMenu])
                 [NSApp addWindowsItem:self title:[self title] filename:NO];
         }
-
-        return on_screen;
     }
 
     - (void) doOrderOut
@@ -1173,24 +1170,12 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
         }
     }
 
-    - (BOOL) setFrameIfOnScreen:(NSRect)contentRect
+    - (void) setFrameFromWine:(NSRect)contentRect
     {
-        NSArray* screens = [NSScreen screens];
-        BOOL on_screen = [self isOrderedIn];
-
-        if (![screens count]) return on_screen;
-
         /* Origin is (left, top) in a top-down space.  Need to convert it to
            (left, bottom) in a bottom-up space. */
         [[WineApplicationController sharedController] flipRect:&contentRect];
 
-        if (on_screen)
-        {
-            on_screen = frame_intersects_screens(contentRect, screens);
-            if (!on_screen)
-                [self doOrderOut];
-        }
-
         /* The back end is establishing a new window size and position.  It's
            not interested in any stale events regarding those that may be sitting
            in the queue. */
@@ -1219,7 +1204,7 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
 
                 [self updateFullscreen];
 
-                if (on_screen)
+                if ([self isOrderedIn])
                 {
                     /* In case Cocoa adjusted the frame we tried to set, generate a frame-changed
                        event.  The back end will ignore it if nothing actually changed. */
@@ -1227,8 +1212,6 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
                 }
             }
         }
-
-        return on_screen;
     }
 
     - (void) setMacDrvParentWindow:(WineWindow*)parent
@@ -1415,8 +1398,10 @@ static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modif
         // If a window is sized to completely cover a screen, then it's in
         // full-screen mode.  In that case, we don't allow NSWindow to constrain
         // it.
+        NSArray* screens = [NSScreen screens];
         NSRect contentRect = [self contentRectForFrameRect:frameRect];
-        if (!screen_covered_by_rect(contentRect, [NSScreen screens]))
+        if (!screen_covered_by_rect(contentRect, screens) &&
+            frame_intersects_screens(frameRect, screens))
             frameRect = [super constrainFrameRect:frameRect toScreen:screen];
         return frameRect;
     }
@@ -2042,23 +2027,19 @@ void macdrv_set_cocoa_window_title(macdrv_window w, const unsigned short* title,
  * non-NULL, it is ordered below that window.  Else, if next is non-NULL,
  * it is ordered above that window.  Otherwise, it is ordered to the
  * front.
- *
- * Returns true if the window has actually been ordered onto the screen
- * (i.e. if its frame intersects with a screen).  Otherwise, false.
  */
-int macdrv_order_cocoa_window(macdrv_window w, macdrv_window prev,
-        macdrv_window next, int activate)
+void macdrv_order_cocoa_window(macdrv_window w, macdrv_window p,
+        macdrv_window n, int activate)
 {
     WineWindow* window = (WineWindow*)w;
-    __block BOOL on_screen;
+    WineWindow* prev = (WineWindow*)p;
+    WineWindow* next = (WineWindow*)n;
 
-    OnMainThread(^{
-        on_screen = [window orderBelow:(WineWindow*)prev
-                               orAbove:(WineWindow*)next
-                              activate:activate];
+    OnMainThreadAsync(^{
+        [window orderBelow:prev
+                   orAbove:next
+                  activate:activate];
     });
-
-    return on_screen;
 }
 
 /***********************************************************************
@@ -2078,22 +2059,15 @@ void macdrv_hide_cocoa_window(macdrv_window w)
 /***********************************************************************
  *              macdrv_set_cocoa_window_frame
  *
- * Move a Cocoa window.  If the window has been moved out of the bounds
- * of the desktop, it is ordered out.  (This routine won't ever order a
- * window in, though.)
- *
- * Returns true if the window is on screen; false otherwise.
+ * Move a Cocoa window.
  */
-int macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame)
+void macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame)
 {
     WineWindow* window = (WineWindow*)w;
-    __block BOOL on_screen;
 
-    OnMainThread(^{
-        on_screen = [window setFrameIfOnScreen:NSRectFromCGRect(*new_frame)];
+    OnMainThreadAsync(^{
+        [window setFrameFromWine:NSRectFromCGRect(*new_frame)];
     });
-
-    return on_screen;
 }
 
 /***********************************************************************
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h
index e0c4f29..b452461 100644
--- a/dlls/winemac.drv/macdrv_cocoa.h
+++ b/dlls/winemac.drv/macdrv_cocoa.h
@@ -381,10 +381,10 @@ extern void macdrv_set_cocoa_window_state(macdrv_window w,
         const struct macdrv_window_state* state) DECLSPEC_HIDDEN;
 extern void macdrv_set_cocoa_window_title(macdrv_window w, const UniChar* title,
         size_t length) DECLSPEC_HIDDEN;
-extern int macdrv_order_cocoa_window(macdrv_window w, macdrv_window prev,
+extern void macdrv_order_cocoa_window(macdrv_window w, macdrv_window prev,
         macdrv_window next, int activate) DECLSPEC_HIDDEN;
 extern void macdrv_hide_cocoa_window(macdrv_window w) DECLSPEC_HIDDEN;
-extern int macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame) DECLSPEC_HIDDEN;
+extern void macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame) DECLSPEC_HIDDEN;
 extern void macdrv_get_cocoa_window_frame(macdrv_window w, CGRect* out_frame) DECLSPEC_HIDDEN;
 extern void macdrv_set_cocoa_parent_window(macdrv_window w, macdrv_window parent) DECLSPEC_HIDDEN;
 extern void macdrv_set_window_surface(macdrv_window w, void *surface, pthread_mutex_t *mutex) DECLSPEC_HIDDEN;
diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c
index 3d92481..eac333a 100644
--- a/dlls/winemac.drv/window.c
+++ b/dlls/winemac.drv/window.c
@@ -729,6 +729,7 @@ static void show_window(struct macdrv_win_data *data)
     macdrv_window prev_window = NULL;
     macdrv_window next_window = NULL;
     BOOL activate = FALSE;
+    HWND hwndFocus;
 
     /* find window that this one must be after */
     prev = GetWindow(data->hwnd, GW_HWNDPREV);
@@ -749,15 +750,14 @@ static void show_window(struct macdrv_win_data *data)
 
     if (!prev_window)
         activate = activate_on_focus_time && (GetTickCount() - activate_on_focus_time < 2000);
-    data->on_screen = macdrv_order_cocoa_window(data->cocoa_window, prev_window, next_window, activate);
-    if (data->on_screen)
-    {
-        HWND hwndFocus = GetFocus();
-        if (hwndFocus && (data->hwnd == hwndFocus || IsChild(data->hwnd, hwndFocus)))
-            macdrv_SetFocus(hwndFocus);
-        if (activate)
-            activate_on_focus_time = 0;
-    }
+    macdrv_order_cocoa_window(data->cocoa_window, prev_window, next_window, activate);
+    data->on_screen = TRUE;
+
+    hwndFocus = GetFocus();
+    if (hwndFocus && (data->hwnd == hwndFocus || IsChild(data->hwnd, hwndFocus)))
+        macdrv_SetFocus(hwndFocus);
+    if (activate)
+        activate_on_focus_time = 0;
 }
 
 
@@ -857,7 +857,7 @@ static void sync_window_position(struct macdrv_win_data *data, UINT swp_flags, c
     if (frame.size.width < 1 || frame.size.height < 1)
         frame.size.width = frame.size.height = 1;
 
-    data->on_screen = macdrv_set_cocoa_window_frame(data->cocoa_window, &frame);
+    macdrv_set_cocoa_window_frame(data->cocoa_window, &frame);
     if (old_window_rect && old_whole_rect &&
         (IsRectEmpty(old_window_rect) != IsRectEmpty(&data->window_rect) ||
          old_window_rect->left - old_whole_rect->left != data->window_rect.left - data->whole_rect.left ||




More information about the wine-cvs mailing list