diff options
author | David Robillard <d@drobilla.net> | 2025-01-22 18:42:15 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2025-01-22 21:22:11 -0500 |
commit | d7b69ead8e7e959b01cf615c5f363fd2a0a6590f (patch) | |
tree | b9e6f015ebd5b8ef357cf85a99f41c28330ad222 /src/x11.c | |
parent | 77f88bd146b1ce10d405c7812bdd2c4d78857bd4 (diff) | |
download | pugl-d7b69ead8e7e959b01cf615c5f363fd2a0a6590f.tar.gz pugl-d7b69ead8e7e959b01cf615c5f363fd2a0a6590f.tar.bz2 pugl-d7b69ead8e7e959b01cf615c5f363fd2a0a6590f.zip |
Simplify initial position code and place children at the origin
The code to find the initial size and position for a view had a lot of
duplication, and was inconsistent between platforms. Flaky positioning and
attempting to center embedded children has historically caused a bunch of
problems in general, particularly since windows can be resized.
So, factor out all the initial size and position code so that the logic is in
one centralized place used by all platforms, and always position embedded
children within their parent at the top/left origin. For top-level windows,
the view is centered on its transient parent or the screen (as before). A new
platform function puglGetAncestorCenter() is used to do this in general code.
Also towards a total separation of position and size, towards support for
Wayland, where applications don't dictate their own positions.
Diffstat (limited to 'src/x11.c')
-rw-r--r-- | src/x11.c | 84 |
1 files changed, 30 insertions, 54 deletions
@@ -510,48 +510,21 @@ clearX11Clipboard(PuglX11Clipboard* const board) board->data.len = 0; } -static PuglRect -getInitialFrame(PuglView* const view) -{ - if (view->lastConfigure.type == PUGL_CONFIGURE) { - // Use the last configured frame - const PuglRect frame = {view->lastConfigure.x, - view->lastConfigure.y, - view->lastConfigure.width, - view->lastConfigure.height}; - return frame; - } - - const PuglSpan defaultWidth = view->sizeHints[PUGL_DEFAULT_SIZE].width; - const PuglSpan defaultHeight = view->sizeHints[PUGL_DEFAULT_SIZE].height; - const int x = view->defaultX; - const int y = view->defaultY; - if (puglIsValidPosition(x, y)) { - // Use the default position set with puglSetPosition while unrealized - const PuglRect frame = { - (PuglCoord)x, (PuglCoord)y, defaultWidth, defaultHeight}; - return frame; - } - - // Get the best "parentish" window to position the window in - Display* const display = view->world->impl->display; - const Window parent = - (view->parent ? (Window)view->parent - : view->transientParent ? (Window)view->transientParent - : RootWindow(display, view->impl->screen)); - - // Get the position/size of the parent as bounds for the new window - XWindowAttributes parentAttrs = PUGL_INIT_STRUCT; - XGetWindowAttributes(display, parent, &parentAttrs); +PuglPoint +puglGetAncestorCenter(const PuglView* const view) +{ + Display* const display = view->world->impl->display; + const int screen = view->impl->screen; + XWindowAttributes ancestorAttrs = PUGL_INIT_STRUCT; + XGetWindowAttributes(display, + view->transientParent ? (Window)view->transientParent + : RootWindow(display, screen), + &ancestorAttrs); - // Center the frame within the parent bounds - const int centerX = parentAttrs.x + parentAttrs.width / 2; - const int centerY = parentAttrs.y + parentAttrs.height / 2; - const PuglRect frame = {(PuglCoord)(centerX - (defaultWidth / 2)), - (PuglCoord)(centerY - (defaultHeight / 2)), - defaultWidth, - defaultHeight}; - return frame; + const PuglPoint center = { + (PuglCoord)(ancestorAttrs.x + ancestorAttrs.width / 2), + (PuglCoord)(ancestorAttrs.y + ancestorAttrs.height / 2)}; + return center; } PuglStatus @@ -606,16 +579,17 @@ puglRealize(PuglView* const view) attr.event_mask |= StructureNotifyMask; attr.event_mask |= VisibilityChangeMask; - // Calculate the initial window rectangle - const PuglRect initialFrame = getInitialFrame(view); + // Calculate the initial window frame + const PuglArea initialSize = puglGetInitialSize(view); + const PuglPoint initialPos = puglGetInitialPosition(view, initialSize); // Create the window impl->win = XCreateWindow(display, parent, - initialFrame.x, - initialFrame.y, - initialFrame.width, - initialFrame.height, + initialPos.x, + initialPos.y, + initialSize.width, + initialSize.height, 0, impl->vi->depth, InputOutput, @@ -1099,17 +1073,19 @@ getCurrentConfiguration(PuglView* const view) XWindowAttributes attrs; XGetWindowAttributes(display, view->impl->win, &attrs); - // Get window position relative to the root window + // Get window position (relative to the root window if not a child) Window ignoredChild = 0; - int rootX = 0; - int rootY = 0; - XTranslateCoordinates( - display, view->impl->win, attrs.root, 0, 0, &rootX, &rootY, &ignoredChild); + int x = attrs.x; + int y = attrs.y; + if (!view->parent) { + XTranslateCoordinates( + display, view->impl->win, attrs.root, 0, 0, &x, &y, &ignoredChild); + } // Build a configure event based on the current window configuration PuglEvent configureEvent = {{PUGL_CONFIGURE, 0}}; - configureEvent.configure.x = (PuglCoord)rootX; - configureEvent.configure.y = (PuglCoord)rootY; + configureEvent.configure.x = (PuglCoord)x; + configureEvent.configure.y = (PuglCoord)y; configureEvent.configure.width = (PuglSpan)attrs.width; configureEvent.configure.height = (PuglSpan)attrs.height; configureEvent.configure.style = getCurrentViewStyleFlags(view); |