From f92264fc2acf3af3f98ebefa5ef0e1d4e9be4b80 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Wed, 3 Jan 2018 13:45:03 +0000 Subject: [PATCH] Fix child frame placement issues (bug#29953) * src/nsterm.h (NS_PARENT_WINDOW_LEFT_POS): (NS_PARENT_WINDOW_TOP_POS): Get the parent frame through the frame struct as invisible child windows are detached from their parents in NS. * src/nsterm.m (x_set_offset): Offscreen frames have `nil' screen value, so handle that gracefully. Child frames with negative left and top should be positioned relative to the bottom right of the parent frame. --- src/nsterm.h | 6 +++--- src/nsterm.m | 46 ++++++++++++++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/nsterm.h b/src/nsterm.h index c40ddf3284a..588b9fc6443 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -1073,11 +1073,11 @@ struct x_output window or, if there is no parent window, the screen. */ #define NS_PARENT_WINDOW_LEFT_POS(f) \ (FRAME_PARENT_FRAME (f) != NULL \ - ? [[FRAME_NS_VIEW (f) window] parentWindow].frame.origin.x : 0) + ? [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.origin.x : 0) #define NS_PARENT_WINDOW_TOP_POS(f) \ (FRAME_PARENT_FRAME (f) != NULL \ - ? ([[FRAME_NS_VIEW (f) window] parentWindow].frame.origin.y \ - + [[FRAME_NS_VIEW (f) window] parentWindow].frame.size.height \ + ? ([FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.origin.y \ + + [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window].frame.size.height \ - FRAME_NS_TITLEBAR_HEIGHT (FRAME_PARENT_FRAME (f))) \ : [[[NSScreen screens] objectAtIndex: 0] frame].size.height) diff --git a/src/nsterm.m b/src/nsterm.m index 5798f4fd0b4..419a37033f7 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1736,7 +1736,6 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav) { NSView *view = FRAME_NS_VIEW (f); NSArray *screens = [NSScreen screens]; - NSScreen *fscreen = [screens objectAtIndex: 0]; NSScreen *screen = [[view window] screen]; NSTRACE ("x_set_offset"); @@ -1746,26 +1745,41 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav) f->left_pos = xoff; f->top_pos = yoff; - if (view != nil && screen && fscreen) + if (view != nil) { - f->left_pos = f->size_hint_flags & XNegative - ? [screen visibleFrame].size.width + f->left_pos - FRAME_PIXEL_WIDTH (f) - : f->left_pos; - /* We use visibleFrame here to take menu bar into account. - Ideally we should also adjust left/top with visibleFrame.origin. */ - - f->top_pos = f->size_hint_flags & YNegative - ? ([screen visibleFrame].size.height + f->top_pos - - FRAME_PIXEL_HEIGHT (f) - FRAME_NS_TITLEBAR_HEIGHT (f) - - FRAME_TOOLBAR_HEIGHT (f)) - : f->top_pos; + if (FRAME_PARENT_FRAME (f) == NULL && screen) + { + f->left_pos = f->size_hint_flags & XNegative + ? [screen visibleFrame].size.width + f->left_pos - FRAME_PIXEL_WIDTH (f) + : f->left_pos; + /* We use visibleFrame here to take menu bar into account. + Ideally we should also adjust left/top with visibleFrame.origin. */ + + f->top_pos = f->size_hint_flags & YNegative + ? ([screen visibleFrame].size.height + f->top_pos + - FRAME_PIXEL_HEIGHT (f) - FRAME_NS_TITLEBAR_HEIGHT (f) + - FRAME_TOOLBAR_HEIGHT (f)) + : f->top_pos; #ifdef NS_IMPL_GNUSTEP - if (FRAME_PARENT_FRAME (f) == NULL) - { if (f->left_pos < 100) f->left_pos = 100; /* don't overlap menu */ - } #endif + } + else if (FRAME_PARENT_FRAME (f) != NULL) + { + struct frame *parent = FRAME_PARENT_FRAME (f); + + /* On X negative values for child frames always result in + positioning relative to the bottom right corner of the + parent frame. */ + if (f->left_pos < 0) + f->left_pos = FRAME_PIXEL_WIDTH (parent) - FRAME_PIXEL_WIDTH (f) + f->left_pos; + + if (f->top_pos < 0) + f->top_pos = FRAME_PIXEL_HEIGHT (parent) + FRAME_TOOLBAR_HEIGHT (parent) + - FRAME_PIXEL_HEIGHT (f) + f->top_pos; + } + /* Constrain the setFrameTopLeftPoint so we don't move behind the menu bar. */ NSPoint pt = NSMakePoint (SCREENMAXBOUND (f->left_pos -- 2.39.2