aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-04-06 15:50:30 +0200
committerDavid Robillard <d@drobilla.net>2020-04-06 16:52:08 +0200
commit53d8fe0c19408a54165f6422319be8139758a5b2 (patch)
tree073eedb86a7b1bdbacfce9fd4ebed335781882ab
parent20fd80c8f20d0d6bda660bd9a273e0c4a78cb9ac (diff)
downloadpugl-53d8fe0c19408a54165f6422319be8139758a5b2.tar.gz
pugl-53d8fe0c19408a54165f6422319be8139758a5b2.tar.bz2
pugl-53d8fe0c19408a54165f6422319be8139758a5b2.zip
Implement puglSetTransientFor() for Mac and Windows
-rw-r--r--examples/pugl_window_demo.c13
-rw-r--r--pugl/detail/mac.m17
-rw-r--r--pugl/detail/win.c17
-rw-r--r--pugl/detail/win.h5
-rw-r--r--pugl/pugl.h3
5 files changed, 50 insertions, 5 deletions
diff --git a/examples/pugl_window_demo.c b/examples/pugl_window_demo.c
index 183119c..3a0dc51 100644
--- a/examples/pugl_window_demo.c
+++ b/examples/pugl_window_demo.c
@@ -203,10 +203,10 @@ main(int argc, char** argv)
CubeView* cube = &app.cubes[i];
PuglView* view = cube->view;
static const double pad = 64.0;
- const PuglRect frame = {pad + (256.0 + pad) * i,
- pad + (256.0 + pad) * i,
- 256.0,
- 256.0};
+ const PuglRect frame = {pad + (128.0 + pad) * i,
+ pad + (128.0 + pad) * i,
+ 512.0,
+ 512.0};
cube->dist = 10;
@@ -224,6 +224,11 @@ main(int argc, char** argv)
puglSetHandle(view, cube);
puglSetEventFunc(view, onEvent);
+ if (i == 1) {
+ puglSetTransientFor(app.cubes[1].view,
+ puglGetNativeWindow(app.cubes[0].view));
+ }
+
if ((st = puglRealize(view))) {
return logError("Failed to create window (%s)\n", puglStrerror(st));
}
diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m
index 501be02..480253e 100644
--- a/pugl/detail/mac.m
+++ b/pugl/detail/mac.m
@@ -1154,6 +1154,23 @@ puglSetAspectRatio(PuglView* const view,
return PUGL_SUCCESS;
}
+PuglStatus
+puglSetTransientFor(PuglView* view, PuglNativeView parent)
+{
+ view->transientParent = parent;
+
+ if (view->impl->window) {
+ NSWindow* parentWindow = [(NSView*)parent window];
+ if (parentWindow) {
+ [parentWindow addChildWindow:view->impl->window
+ ordered:NSWindowAbove];
+ return PUGL_SUCCESS;
+ }
+ }
+
+ return PUGL_FAILURE;
+}
+
const void*
puglGetClipboard(PuglView* const view,
const char** const type,
diff --git a/pugl/detail/win.c b/pugl/detail/win.c
index 44ba6cd..cb9a69c 100644
--- a/pugl/detail/win.c
+++ b/pugl/detail/win.c
@@ -979,6 +979,23 @@ puglSetAspectRatio(PuglView* const view,
return PUGL_SUCCESS;
}
+PuglStatus
+puglSetTransientFor(PuglView* view, PuglNativeView parent)
+{
+ if (view->parent) {
+ return PUGL_FAILURE;
+ }
+
+ view->transientParent = parent;
+
+ if (view->impl->hwnd) {
+ SetWindowLongPtr(view->impl->hwnd, GWLP_HWNDPARENT, (LONG_PTR)parent);
+ return GetLastError() == NO_ERROR ? PUGL_SUCCESS : PUGL_FAILURE;
+ }
+
+ return PUGL_SUCCESS;
+}
+
const void*
puglGetClipboard(PuglView* const view,
const char** const type,
diff --git a/pugl/detail/win.h b/pugl/detail/win.h
index 949fa90..241ea24 100644
--- a/pugl/detail/win.h
+++ b/pugl/detail/win.h
@@ -96,6 +96,9 @@ puglWinCreateWindow(const PuglView* const view,
const unsigned winFlags = puglWinGetWindowFlags(view);
const unsigned winExFlags = puglWinGetWindowExFlags(view);
+ // The meaning of "parent" depends on the window type (WS_CHILD)
+ PuglNativeView parent = view->parent ? view->parent : view->transientParent;
+
// Calculate total window size to accommodate requested view size
RECT wr = { (long)view->frame.x, (long)view->frame.y,
(long)view->frame.width, (long)view->frame.height };
@@ -105,7 +108,7 @@ puglWinCreateWindow(const PuglView* const view,
if (!(*hwnd = CreateWindowEx(winExFlags, className, title, winFlags,
CW_USEDEFAULT, CW_USEDEFAULT,
wr.right-wr.left, wr.bottom-wr.top,
- (HWND)view->parent, NULL, NULL, NULL))) {
+ (HWND)parent, NULL, NULL, NULL))) {
return PUGL_REALIZE_FAILED;
} else if (!(*hdc = GetDC(*hwnd))) {
DestroyWindow(*hwnd);
diff --git a/pugl/pugl.h b/pugl/pugl.h
index fbdf5db..84bfa98 100644
--- a/pugl/pugl.h
+++ b/pugl/pugl.h
@@ -1001,6 +1001,9 @@ puglSetParentWindow(PuglView* view, PuglNativeView parent);
Set this for transient children like dialogs, to have them properly
associated with their parent window. This should be called before
puglRealize().
+
+ A view can either have a parent (for embedding) or a transient parent (for
+ top-level windows like dialogs), but not both.
*/
PUGL_API PuglStatus
puglSetTransientFor(PuglView* view, PuglNativeView parent);