aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2025-02-08 16:49:06 -0500
committerDavid Robillard <d@drobilla.net>2025-02-08 18:02:30 -0500
commit1395c97015ac9d5069881a038f4272a426fda9e9 (patch)
tree9049ba724b9866701f9fd0330038cb6965792663 /src
parent23b0774862b79543b93a9b50b4f085c2c396698a (diff)
downloadpugl-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.c60
-rw-r--r--src/internal.c7
-rw-r--r--src/mac.m49
-rw-r--r--src/types.h15
-rw-r--r--src/win.c54
-rw-r--r--src/x11.c70
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) {
diff --git a/src/mac.m b/src/mac.m
index b6867a4..41d358a 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -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;
};
diff --git a/src/win.c b/src/win.c
index 6c823fb..a8cd841 100644
--- a/src/win.c
+++ b/src/win.c
@@ -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
diff --git a/src/x11.c b/src/x11.c
index 3d825a6..6f05c59 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -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);
}