From 16739fe3b2cf0fe8c2ffcb3e983ef09aa04517dc Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 10 Jan 2023 15:26:44 -0500 Subject: Center windows on their transient parent where possible This is only really relevant in practice on MacOS and Windows. On X11, the window manager places new windows where it pleases. --- src/mac.m | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'src/mac.m') diff --git a/src/mac.m b/src/mac.m index 841a154..77c825f 100644 --- a/src/mac.m +++ b/src/mac.m @@ -91,7 +91,7 @@ utiForMimeType(const NSString* const mimeType) } static NSRect -rectToScreen(NSScreen* screen, NSRect rect) +rectToScreen(const NSScreen* screen, NSRect rect) { const double screenHeight = [screen frame].size.height; @@ -99,6 +99,17 @@ rectToScreen(NSScreen* screen, NSRect rect) return rect; } +static NSRect +rectFromScreen(const NSScreen* screen, NSRect rect) +{ + /* The math happens to work out to the same expression because this is just + an inversion of the Y axis based on the screen height. This function is + preserved to make the code clearer and more future-proof since the use + cases are distinctly either a "from" or "to" conversion. */ + + return rectToScreen(screen, rect); +} + static NSScreen* viewScreen(const PuglView* view) { @@ -1109,6 +1120,25 @@ updateSizeHints(PuglView* const view) } } +static void +puglMacSetDefaultPosition(PuglView* const view) +{ + // Get a bounding rect from the transient parent or the screen + const NSScreen* const screen = viewScreen(view); + const NSRect boundsPt = + rectFromScreen(screen, + view->transientParent + ? [[(const NSView*)view->transientParent window] frame] + : [screen frame]); + + // Center the frame around the center of the bounding rectangle + const NSRect boundsPx = nsRectFromPoints(view, boundsPt); + const double centerX = boundsPx.origin.x + boundsPx.size.width / 2; + const double centerY = boundsPx.origin.y + boundsPx.size.height / 2; + view->frame.x = (PuglCoord)(centerX - (view->frame.width / 2U)); + view->frame.y = (PuglCoord)(centerY - (view->frame.height / 2U)); +} + PuglStatus puglRealize(PuglView* view) { @@ -1156,11 +1186,7 @@ puglRealize(PuglView* view) // Center top-level windows if a position has not been set if (!view->parent && !view->frame.x && !view->frame.y) { - const double screenWidthPx = [screen frame].size.width * scaleFactor; - const double screenHeightPx = [screen frame].size.height * scaleFactor; - - view->frame.x = (PuglCoord)((screenWidthPx - view->frame.width) / 2.0); - view->frame.y = (PuglCoord)((screenHeightPx - view->frame.height) / 2.0); + puglMacSetDefaultPosition(view); } const NSRect framePx = rectToNsRect(view->frame); -- cgit v1.2.1