Subject: bug#25818: 25.2; frame moved off display does not return (OS X)

From: "Charles A. Roelli" <[email-masked]>
Date: Fri, 28 Apr 2017 19:33:00 +0200

On 27/04/2017 22:05, Alan Third wrote:
> Looks good to me. It doesn’t actually apply here, so I did it
> manually. I suspect it just needs rebased onto a more recent commit or
> something.
You're right: attached is the rebased version.
>> and drag the parent frame down until its child is off screen. When the
>> parent is moved back up, the child should reappear with it.
> If you put the top of the child frame off the top of the screen, then
> click on it, it jumps back down so the titlebar is visible again. Is
> this intentional?
For me, this can be prevented by setting variable 
`ns-auto-hide-menu-bar' to t.  And on OS X 10.9+, the behavior may 
change if you have Spaces enabled (I haven't tested it).
>> * src/nsterm.m (constrainFrameRect:toScreen:): Constrain non-child
>> frames in OS X, if they would otherwise go offscreen.
> I can’t find this in CONTRIBUTE, but you’re allowed to specify
> #ifdef’d code with something like:
>
> * src/nsterm.m (constrainFrameRect:toScreen:) [NS_IMPL_COCOA]:
> Constrain non-child frames if they would otherwise go offscreen.
>
> Thanks for working on this. :)
My pleasure, and thank you for your work on the NS port.
>From 6a68480187916af3136e36596f50226f3544ded4 Mon Sep 17 00:00:00 2001
From: Charles A. Roelli <[email-masked]>
Date: Thu, 27 Apr 2017 20:44:09 +0200
Subject: [PATCH] Constrain non-child frames to screen area in OS X

* src/nsterm.m (constrainFrameRect:toScreen:): Constrain non-child
frames in OS X, if they would otherwise go offscreen.

Fixes: debbugs:25818
---
 src/nsterm.m |   35 ++++++++++++++++++++++++++++++++++-
 1 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index f75a9fe..c22c5a7 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -8040,7 +8040,40 @@ - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
       NSTRACE_RETURN_RECT (frameRect);
       return frameRect;
     }
-#endif
+  else
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 */
+    // Check that the proposed frameRect is visible in at least one
+    // screen.  If it is not, ask the system to reposition it (only
+    // for non-child windows).
+
+    if (!FRAME_PARENT_FRAME (((EmacsView *)[self delegate])->emacsframe))
+    {
+      NSArray *screens = [NSScreen screens];
+      NSUInteger nr_screens = [screens count];
+
+      int i;
+      BOOL frame_on_screen = NO;
+
+      for (i = 0; i < nr_screens; ++i)
+        {
+          NSScreen *s = [screens objectAtIndex: i];
+          NSRect scrRect = [s frame];
+
+          if (NSIntersectsRect(frameRect, scrRect))
+            {
+              frame_on_screen = YES;
+              break;
+            }
+        }
+
+      if (!frame_on_screen)
+        {
+          NSTRACE_MSG ("Frame outside screens; constraining");
+          frameRect = [super constrainFrameRect:frameRect toScreen:screen];
+          NSTRACE_RETURN_RECT (frameRect);
+          return frameRect;
+        }
+    }
 #endif
 
   return constrain_frame_rect(frameRect,
-- 
1.7.4.4