diff options
author | David Robillard <d@drobilla.net> | 2025-02-08 16:49:06 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2025-02-08 18:02:30 -0500 |
commit | 1395c97015ac9d5069881a038f4272a426fda9e9 (patch) | |
tree | 9049ba724b9866701f9fd0330038cb6965792663 /src | |
parent | 23b0774862b79543b93a9b50b4f085c2c396698a (diff) | |
download | pugl-1395c97015ac9d5069881a038f4272a426fda9e9.tar.gz pugl-1395c97015ac9d5069881a038f4272a426fda9e9.tar.bz2 pugl-1395c97015ac9d5069881a038f4272a426fda9e9.zip |
Replace frame with size and position hints
Diffstat (limited to 'src')
-rw-r--r-- | src/common.c | 60 | ||||
-rw-r--r-- | src/internal.c | 7 | ||||
-rw-r--r-- | src/mac.m | 49 | ||||
-rw-r--r-- | src/types.h | 15 | ||||
-rw-r--r-- | src/win.c | 54 | ||||
-rw-r--r-- | src/x11.c | 70 |
6 files changed, 123 insertions, 132 deletions
diff --git a/src/common.c b/src/common.c index b28b4d6..c8ac3d4 100644 --- a/src/common.c +++ b/src/common.c @@ -4,14 +4,13 @@ // Common implementations of public API functions in the core library #include "internal.h" - #include "platform.h" #include "types.h" #include <pugl/pugl.h> -#include <limits.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> @@ -127,6 +126,11 @@ puglSetDefaultHints(PuglView* const view) view->hints[PUGL_REFRESH_RATE] = PUGL_DONT_CARE; view->hints[PUGL_VIEW_TYPE] = PUGL_DONT_CARE; + for (unsigned i = 0U; i < PUGL_NUM_POSITION_HINTS; ++i) { + view->positionHints[i].x = INT16_MIN; + view->positionHints[i].y = INT16_MIN; + } + for (unsigned i = 0U; i < PUGL_NUM_SIZE_HINTS; ++i) { view->sizeHints[i].width = 0U; view->sizeHints[i].height = 0U; @@ -142,10 +146,7 @@ puglNewView(PuglWorld* const world) return NULL; } - view->world = world; - view->defaultX = INT_MIN; - view->defaultY = INT_MIN; - + view->world = world; puglSetDefaultHints(view); // Enlarge world view list @@ -289,32 +290,37 @@ puglGetViewString(const PuglView* const view, const PuglStringHint key) return view->strings[key]; } -PuglRect -puglGetFrame(const PuglView* view) +PuglPoint +puglGetPositionHint(const PuglView* const view, const PuglPositionHint hint) { - if (view->lastConfigure.type == PUGL_CONFIGURE) { - // Return the last configured frame - const PuglRect frame = {view->lastConfigure.x, - view->lastConfigure.y, - view->lastConfigure.width, - view->lastConfigure.height}; - return frame; + if (hint == PUGL_CURRENT_POSITION) { + PuglPoint pos = {0, 0}; + if (view->lastConfigure.type == PUGL_CONFIGURE) { + pos.x = view->lastConfigure.x; + pos.y = view->lastConfigure.y; + } else { + const PuglPoint defaultPos = view->positionHints[PUGL_DEFAULT_POSITION]; + if (puglIsValidPosition(defaultPos.x, defaultPos.y)) { + pos.x = defaultPos.x; + pos.y = defaultPos.y; + } + } + return pos; } - // Get the default position if set, or fallback to (0, 0) - int x = view->defaultX; - int y = view->defaultY; - if (!puglIsValidPosition(x, y)) { - x = 0; - y = 0; + return view->positionHints[hint]; +} + +PuglArea +puglGetSizeHint(const PuglView* const view, const PuglSizeHint hint) +{ + if (hint == PUGL_CURRENT_SIZE && view->lastConfigure.type == PUGL_CONFIGURE) { + const PuglArea area = {view->lastConfigure.width, + view->lastConfigure.height}; + return area; } - // Return the default frame, sanitized if necessary - const PuglRect frame = {(PuglCoord)x, - (PuglCoord)y, - view->sizeHints[PUGL_DEFAULT_SIZE].width, - view->sizeHints[PUGL_DEFAULT_SIZE].height}; - return frame; + return view->sizeHints[hint]; } PuglStatus diff --git a/src/internal.c b/src/internal.c index d75861f..00867e8 100644 --- a/src/internal.c +++ b/src/internal.c @@ -23,7 +23,7 @@ make_point(const PuglCoord x, const PuglCoord y) bool puglIsValidPosition(const int x, const int y) { - return x >= INT16_MIN && x <= INT16_MAX && y >= INT16_MIN && y <= INT16_MAX; + return x >= INT16_MIN && x < INT16_MAX && y >= INT16_MIN && y < INT16_MAX; } bool @@ -60,9 +60,10 @@ puglGetInitialPosition(const PuglView* const view, const PuglArea size) return make_point(view->lastConfigure.x, view->lastConfigure.y); } - if (puglIsValidPosition(view->defaultX, view->defaultY)) { + const PuglPoint defaultPos = view->positionHints[PUGL_DEFAULT_POSITION]; + if (puglIsValidPosition(defaultPos.x, defaultPos.y)) { // Use the default position hint set by the application - return make_point((PuglCoord)view->defaultX, (PuglCoord)view->defaultY); + return make_point(defaultPos.x, defaultPos.y); } if (view->parent) { @@ -1707,20 +1707,10 @@ puglGetScaleFactor(const PuglView* const view) return [viewScreen(view) backingScaleFactor]; } -PuglStatus -puglSetPosition(PuglView* const view, const int x, const int y) +static PuglStatus +puglSetWindowPosition(PuglView* const view, const int x, const int y) { - if (!puglIsValidPosition(x, y)) { - return PUGL_BAD_PARAMETER; - } - PuglInternals* const impl = view->impl; - if (!impl->wrapperView) { - // Set defaults to be used when realized - view->defaultX = x; - view->defaultY = y; - return PUGL_SUCCESS; - } const NSRect framePx = NSMakeRect(x, y, view->lastConfigure.width, view->lastConfigure.height); @@ -1741,20 +1731,12 @@ puglSetPosition(PuglView* const view, const int x, const int y) return dispatchCurrentChildViewConfiguration(view); } -PuglStatus -puglSetSize(PuglView* const view, const unsigned width, const unsigned height) +static PuglStatus +puglSetWindowSize(PuglView* const view, + const unsigned width, + const unsigned height) { - if (!puglIsValidSize(width, height)) { - return PUGL_BAD_PARAMETER; - } - PuglInternals* const impl = view->impl; - if (!impl->wrapperView) { - // Set defaults to be used when realized - view->sizeHints[PUGL_DEFAULT_SIZE].width = (PuglSpan)width; - view->sizeHints[PUGL_DEFAULT_SIZE].height = (PuglSpan)height; - return PUGL_SUCCESS; - } // Set wrapper view size const double scaleFactor = [viewScreen(view) backingScaleFactor]; @@ -1783,6 +1765,23 @@ puglSetSize(PuglView* const view, const unsigned width, const unsigned height) } PuglStatus +puglSetPositionHint(PuglView* const view, + const PuglPositionHint hint, + const int x, + const int y) +{ + if (x <= INT16_MIN || x > INT16_MAX || y <= INT16_MIN || y > INT16_MAX) { + return PUGL_BAD_PARAMETER; + } + + view->positionHints[hint].x = (PuglCoord)x; + view->positionHints[hint].y = (PuglCoord)y; + + return (hint == PUGL_CURRENT_POSITION) ? puglSetWindowPosition(view, x, y) + : PUGL_SUCCESS; +} + +PuglStatus puglSetSizeHint(PuglView* const view, const PuglSizeHint hint, const unsigned width, @@ -1791,7 +1790,7 @@ puglSetSizeHint(PuglView* const view, const PuglStatus st = puglStoreSizeHint(view, hint, width, height); return st ? st - : (hint == PUGL_CURRENT_SIZE) ? puglSetSize(view, width, height) + : (hint == PUGL_CURRENT_SIZE) ? puglSetWindowSize(view, width, height) : updateSizeHint(view, hint); } diff --git a/src/types.h b/src/types.h index c3ebdb6..b453f11 100644 --- a/src/types.h +++ b/src/types.h @@ -21,18 +21,6 @@ typedef struct PuglInternalsImpl PuglInternals; /// View hints typedef int PuglHints[PUGL_NUM_VIEW_HINTS]; -/// View position (both X and Y coordinates) or general point -typedef struct { - PuglCoord x; - PuglCoord y; -} PuglPoint; - -/// View size (both X and Y coordinates) -typedef struct { - PuglSpan width; - PuglSpan height; -} PuglArea; - /// Blob of arbitrary data typedef struct { void* data; ///< Dynamically allocated data @@ -57,10 +45,9 @@ struct PuglViewImpl { uintptr_t transientParent; PuglConfigureEvent lastConfigure; PuglHints hints; + PuglPoint positionHints[PUGL_NUM_POSITION_HINTS]; PuglArea sizeHints[PUGL_NUM_SIZE_HINTS]; char* strings[PUGL_NUM_STRING_HINTS]; - int defaultX; - int defaultY; PuglViewStage stage; bool resizing; }; @@ -1244,20 +1244,9 @@ puglGetScaleFactor(const PuglView* const view) : puglWinGetViewScaleFactor(view); } -PuglStatus -puglSetPosition(PuglView* const view, const int x, const int y) +static PuglStatus +puglSetWindowPosition(PuglView* const view, const int x, const int y) { - if (!puglIsValidPosition(x, y)) { - return PUGL_BAD_PARAMETER; - } - - if (!view->impl->hwnd) { - // Set defaults to be used when realized - view->defaultX = x; - view->defaultY = y; - return PUGL_SUCCESS; - } - const RECT rect = adjustedWindowRect( view, x, y, view->lastConfigure.width, view->lastConfigure.height); @@ -1268,20 +1257,11 @@ puglSetPosition(PuglView* const view, const int x, const int y) SetWindowPos(view->impl->hwnd, HWND_TOP, rect.left, rect.top, 0, 0, flags)); } -PuglStatus -puglSetSize(PuglView* const view, const unsigned width, const unsigned height) +static PuglStatus +puglSetWindowSize(PuglView* const view, + const unsigned width, + const unsigned height) { - if (!puglIsValidSize(width, height)) { - return PUGL_BAD_PARAMETER; - } - - if (!view->impl->hwnd) { - // Set defaults to be used when realized - view->sizeHints[PUGL_DEFAULT_SIZE].width = (PuglSpan)width; - view->sizeHints[PUGL_DEFAULT_SIZE].height = (PuglSpan)height; - return PUGL_SUCCESS; - } - const RECT rect = adjustedWindowRect(view, view->lastConfigure.x, view->lastConfigure.y, @@ -1301,6 +1281,23 @@ puglSetSize(PuglView* const view, const unsigned width, const unsigned height) } PuglStatus +puglSetPositionHint(PuglView* const view, + const PuglPositionHint hint, + const int x, + const int y) +{ + if (x <= INT16_MIN || x > INT16_MAX || y <= INT16_MIN || y > INT16_MAX) { + return PUGL_BAD_PARAMETER; + } + + view->positionHints[hint].x = (PuglCoord)x; + view->positionHints[hint].y = (PuglCoord)y; + + return (hint == PUGL_CURRENT_POSITION) ? puglSetWindowPosition(view, x, y) + : PUGL_SUCCESS; +} + +PuglStatus puglSetSizeHint(PuglView* const view, const PuglSizeHint hint, const unsigned width, @@ -1308,8 +1305,9 @@ puglSetSizeHint(PuglView* const view, { const PuglStatus st = puglStoreSizeHint(view, hint, width, height); - return (!st && hint == PUGL_CURRENT_SIZE) ? puglSetSize(view, width, height) - : st; + return (!st && hint == PUGL_CURRENT_SIZE) + ? puglSetWindowSize(view, width, height) + : st; } PuglStatus @@ -405,14 +405,18 @@ updateSizeHints(const PuglView* const view) XSizeHints sizeHints = PUGL_INIT_STRUCT; if (!view->hints[PUGL_RESIZABLE]) { - const PuglRect frame = puglGetFrame(view); + PuglArea size = puglGetSizeHint(view, PUGL_CURRENT_SIZE); + if (!puglIsValidSize(size.width, size.height)) { + size = puglGetSizeHint(view, PUGL_DEFAULT_SIZE); + } + sizeHints.flags = PBaseSize | PMinSize | PMaxSize; - sizeHints.base_width = (int)frame.width; - sizeHints.base_height = (int)frame.height; - sizeHints.min_width = (int)frame.width; - sizeHints.min_height = (int)frame.height; - sizeHints.max_width = (int)frame.width; - sizeHints.max_height = (int)frame.height; + sizeHints.base_width = (int)size.width; + sizeHints.base_height = (int)size.height; + sizeHints.min_width = (int)size.width; + sizeHints.min_height = (int)size.height; + sizeHints.max_width = (int)size.width; + sizeHints.max_height = (int)size.height; } else { // Avoid setting PBaseSize for top level views to avoid window manager bugs const PuglArea defaultSize = view->sizeHints[PUGL_DEFAULT_SIZE]; @@ -1945,45 +1949,41 @@ puglGetScaleFactor(const PuglView* const view) return view->world->impl->scaleFactor; } -PuglStatus -puglSetPosition(PuglView* const view, const int x, const int y) +static PuglStatus +puglSetWindowPosition(PuglView* const view, const int x, const int y) { - Display* const display = view->world->impl->display; - - if (!puglIsValidPosition(x, y)) { - return PUGL_BAD_PARAMETER; - } - - if (!view->impl->win) { - // Set defaults to be used when realized - view->defaultX = x; - view->defaultY = y; - return PUGL_SUCCESS; - } - - return puglX11Status(XMoveWindow(display, + return puglX11Status(XMoveWindow(view->world->impl->display, view->impl->win, (int)(x - view->impl->frameExtentLeft), (int)(y - view->impl->frameExtentTop))); } -PuglStatus -puglSetSize(PuglView* const view, const unsigned width, const unsigned height) +static PuglStatus +puglSetWindowSize(PuglView* const view, + const unsigned width, + const unsigned height) { - Display* const display = view->world->impl->display; + return !view->impl->win + ? PUGL_SUCCESS + : puglX11Status(XResizeWindow( + view->world->impl->display, view->impl->win, width, height)); +} - if (!puglIsValidSize(width, height)) { +PuglStatus +puglSetPositionHint(PuglView* const view, + const PuglPositionHint hint, + const int x, + const int y) +{ + if (x <= INT16_MIN || x > INT16_MAX || y <= INT16_MIN || y > INT16_MAX) { return PUGL_BAD_PARAMETER; } - if (!view->impl->win) { - // Set defaults to be used when realized - view->sizeHints[PUGL_DEFAULT_SIZE].width = (PuglSpan)width; - view->sizeHints[PUGL_DEFAULT_SIZE].height = (PuglSpan)height; - return PUGL_SUCCESS; - } + view->positionHints[hint].x = (PuglCoord)x; + view->positionHints[hint].y = (PuglCoord)y; - return puglX11Status(XResizeWindow(display, view->impl->win, width, height)); + return (hint == PUGL_CURRENT_POSITION) ? puglSetWindowPosition(view, x, y) + : PUGL_SUCCESS; } PuglStatus @@ -1995,7 +1995,7 @@ puglSetSizeHint(PuglView* const view, const PuglStatus st = puglStoreSizeHint(view, hint, width, height); return st ? st - : (hint == PUGL_CURRENT_SIZE) ? puglSetSize(view, width, height) + : (hint == PUGL_CURRENT_SIZE) ? puglSetWindowSize(view, width, height) : updateSizeHints(view); } |