diff options
-rw-r--r-- | bindings/cpp/include/pugl/pugl.hpp | 17 | ||||
-rw-r--r-- | examples/pugl_cairo_demo.c | 2 | ||||
-rw-r--r-- | examples/pugl_clipboard_demo.c | 2 | ||||
-rw-r--r-- | examples/pugl_cpp_demo.cpp | 2 | ||||
-rw-r--r-- | examples/pugl_cursor_demo.c | 2 | ||||
-rw-r--r-- | examples/pugl_embed_demo.c | 4 | ||||
-rw-r--r-- | examples/pugl_management_demo.c | 4 | ||||
-rw-r--r-- | examples/pugl_print_events.c | 2 | ||||
-rw-r--r-- | examples/pugl_shader_demo.c | 2 | ||||
-rw-r--r-- | examples/pugl_vulkan_cpp_demo.cpp | 2 | ||||
-rw-r--r-- | examples/pugl_vulkan_demo.c | 2 | ||||
-rw-r--r-- | examples/pugl_window_demo.c | 2 | ||||
-rw-r--r-- | include/pugl/pugl.h | 34 | ||||
-rw-r--r-- | meson.build | 2 | ||||
-rw-r--r-- | src/mac.m | 18 | ||||
-rw-r--r-- | src/win.c | 18 | ||||
-rw-r--r-- | src/x11.c | 15 | ||||
-rw-r--r-- | test/test_cairo.c | 2 | ||||
-rw-r--r-- | test/test_gl.c | 2 | ||||
-rw-r--r-- | test/test_local_copy_paste.c | 2 | ||||
-rw-r--r-- | test/test_redisplay.c | 2 | ||||
-rw-r--r-- | test/test_remote_copy_paste.c | 4 | ||||
-rw-r--r-- | test/test_show_hide.c | 2 | ||||
-rw-r--r-- | test/test_size.c | 2 | ||||
-rw-r--r-- | test/test_stub.c | 2 | ||||
-rw-r--r-- | test/test_timer.c | 2 | ||||
-rw-r--r-- | test/test_update.c | 2 | ||||
-rw-r--r-- | test/test_view.c | 2 | ||||
-rw-r--r-- | test/test_vulkan.c | 2 |
29 files changed, 119 insertions, 37 deletions
diff --git a/bindings/cpp/include/pugl/pugl.hpp b/bindings/cpp/include/pugl/pugl.hpp index 0ce7df7..5f939d5 100644 --- a/bindings/cpp/include/pugl/pugl.hpp +++ b/bindings/cpp/include/pugl/pugl.hpp @@ -378,6 +378,17 @@ enum class Cursor { static_assert(static_cast<Cursor>(PUGL_CURSOR_UP_DOWN) == Cursor::upDown, ""); +/// @copydoc PuglShowCommand +enum class ShowCommand { + passive, ///< @copydoc PUGL_SHOW_PASSIVE, + raise, ///< @copydoc PUGL_SHOW_RAISE, + forceRaise, ///< @copydoc PUGL_SHOW_FORCE_RAISE, +}; + +static_assert(static_cast<ShowCommand>(PUGL_SHOW_FORCE_RAISE) == + ShowCommand::forceRaise, + ""); + /// @copydoc PuglView class View : protected detail::Wrapper<PuglView, puglFreeView> { @@ -508,7 +519,11 @@ public: Status realize() noexcept { return static_cast<Status>(puglRealize(cobj())); } /// @copydoc puglShow - Status show() noexcept { return static_cast<Status>(puglShow(cobj())); } + Status show(const ShowCommand command) noexcept + { + return static_cast<Status>( + puglShow(cobj(), static_cast<PuglShowCommand>(command))); + } /// @copydoc puglHide Status hide() noexcept { return static_cast<Status>(puglHide(cobj())); } diff --git a/examples/pugl_cairo_demo.c b/examples/pugl_cairo_demo.c index c0e89c7..3192183 100644 --- a/examples/pugl_cairo_demo.c +++ b/examples/pugl_cairo_demo.c @@ -230,7 +230,7 @@ main(int argc, char** argv) return logError("Failed to create window (%s)\n", puglStrerror(st)); } - puglShow(view); + puglShow(view, PUGL_SHOW_PASSIVE); PuglFpsPrinter fpsPrinter = {puglGetTime(app.world)}; const double timeout = app.opts.continuous ? (1 / 60.0) : -1.0; diff --git a/examples/pugl_clipboard_demo.c b/examples/pugl_clipboard_demo.c index 9b5fb28..ddb29e0 100644 --- a/examples/pugl_clipboard_demo.c +++ b/examples/pugl_clipboard_demo.c @@ -237,7 +237,7 @@ main(int argc, char** argv) return logError("Failed to realize view (%s)\n", puglStrerror(st)); } - if ((st = puglShow(view))) { + if ((st = puglShow(view, PUGL_SHOW_PASSIVE))) { return logError("Failed to show view (%s)\n", puglStrerror(st)); } diff --git a/examples/pugl_cpp_demo.cpp b/examples/pugl_cpp_demo.cpp index 6abe45b..49d547f 100644 --- a/examples/pugl_cpp_demo.cpp +++ b/examples/pugl_cpp_demo.cpp @@ -127,7 +127,7 @@ main(int argc, char** argv) view.setHint(pugl::ViewHint::swapInterval, opts.sync); view.setHint(pugl::ViewHint::ignoreKeyRepeat, opts.ignoreKeyRepeat); view.realize(); - view.show(); + view.show(pugl::ShowCommand::passive); unsigned framesDrawn = 0; while (!view.quit()) { diff --git a/examples/pugl_cursor_demo.c b/examples/pugl_cursor_demo.c index ccece41..50bf0da 100644 --- a/examples/pugl_cursor_demo.c +++ b/examples/pugl_cursor_demo.c @@ -143,7 +143,7 @@ main(int argc, char** argv) return logError("Failed to create window (%s)\n", puglStrerror(st)); } - puglShow(view); + puglShow(view, PUGL_SHOW_PASSIVE); while (!app.quit) { puglUpdate(app.world, -1.0); diff --git a/examples/pugl_embed_demo.c b/examples/pugl_embed_demo.c index 59d8e2b..5c75ffc 100644 --- a/examples/pugl_embed_demo.c +++ b/examples/pugl_embed_demo.c @@ -304,8 +304,8 @@ main(int argc, char** argv) return logError("Failed to create child window (%s)\n", puglStrerror(st)); } - puglShow(app.parent); - puglShow(app.child); + puglShow(app.parent, PUGL_SHOW_PASSIVE); + puglShow(app.child, PUGL_SHOW_PASSIVE); puglStartTimer(app.child, reverseTimerId, 3.6); diff --git a/examples/pugl_management_demo.c b/examples/pugl_management_demo.c index 6a62668..87b4e09 100644 --- a/examples/pugl_management_demo.c +++ b/examples/pugl_management_demo.c @@ -121,7 +121,7 @@ toggleDialog(DemoApp* const app) puglSetWindowTitle(app->dialogView.view, "Dialog"); } - return puglShow(app->dialogView.view); + return puglShow(app->dialogView.view, PUGL_SHOW_PASSIVE); } static PuglStatus @@ -250,7 +250,7 @@ main(int argc, char** argv) return logError("Failed to realize view (%s)\n", puglStrerror(st)); } - puglShow(app.mainView.view); + puglShow(app.mainView.view, PUGL_SHOW_PASSIVE); while (!app.quit) { puglUpdate(app.world, -1.0); diff --git a/examples/pugl_print_events.c b/examples/pugl_print_events.c index 3c07873..a9fa945 100644 --- a/examples/pugl_print_events.c +++ b/examples/pugl_print_events.c @@ -53,7 +53,7 @@ main(void) return logError("Failed to create window (%s)\n", puglStrerror(st)); } - puglShow(app.view); + puglShow(app.view, PUGL_SHOW_PASSIVE); while (!app.quit) { puglUpdate(app.world, -1.0); diff --git a/examples/pugl_shader_demo.c b/examples/pugl_shader_demo.c index cea6d0a..d8b9252 100644 --- a/examples/pugl_shader_demo.c +++ b/examples/pugl_shader_demo.c @@ -453,7 +453,7 @@ main(int argc, char** argv) // Show window printViewHints(app.view); - puglShow(app.view); + puglShow(app.view, PUGL_SHOW_PASSIVE); // Grind away, drawing continuously const double startTime = puglGetTime(app.world); diff --git a/examples/pugl_vulkan_cpp_demo.cpp b/examples/pugl_vulkan_cpp_demo.cpp index 487fab2..1537920 100644 --- a/examples/pugl_vulkan_cpp_demo.cpp +++ b/examples/pugl_vulkan_cpp_demo.cpp @@ -1778,7 +1778,7 @@ run(const char* const programPath, const double timeout = app.opts.sync ? frameDuration : 0.0; PuglFpsPrinter fpsPrinter = {app.world.time()}; - app.view.show(); + app.view.show(pugl::ShowCommand::passive); while (!app.quit) { app.world.update(timeout); puglPrintFps(app.world.cobj(), &fpsPrinter, &app.framesDrawn); diff --git a/examples/pugl_vulkan_demo.c b/examples/pugl_vulkan_demo.c index ec465bb..5fe7100 100644 --- a/examples/pugl_vulkan_demo.c +++ b/examples/pugl_vulkan_demo.c @@ -1101,7 +1101,7 @@ main(int argc, char** argv) printf("Swapchain images: %u\n", app.vk.swapchain->nImages); PuglFpsPrinter fpsPrinter = {puglGetTime(app.world)}; - puglShow(app.view); + puglShow(app.view, PUGL_SHOW_PASSIVE); while (!app.quit) { puglUpdate(app.world, -1.0); diff --git a/examples/pugl_window_demo.c b/examples/pugl_window_demo.c index 1827991..4596b61 100644 --- a/examples/pugl_window_demo.c +++ b/examples/pugl_window_demo.c @@ -213,7 +213,7 @@ main(int argc, char** argv) return logError("Failed to create window (%s)\n", puglStrerror(st)); } - puglShow(view); + puglShow(view, PUGL_SHOW_PASSIVE); } PuglFpsPrinter fpsPrinter = {puglGetTime(app.world)}; diff --git a/include/pugl/pugl.h b/include/pugl/pugl.h index 22cdfca..338aa4d 100644 --- a/include/pugl/pugl.h +++ b/include/pugl/pugl.h @@ -1213,6 +1213,38 @@ PUGL_API PuglStatus puglUnrealize(PuglView* view); +/// A command to control the behaviour of puglShow() +typedef enum { + /** + Realize and show the window without intentionally raising it. + + This will weakly "show" the window but without making any effort to raise + it. Depending on the platform or system configuration, the window may be + raised above some others regardless. + */ + PUGL_SHOW_PASSIVE, + + /** + Raise the window to the top of the application's stack. + + This is the normal "well-behaved" way to show and raise the window, which + should be used in most cases. + */ + PUGL_SHOW_RAISE, + + /** + Aggressively force the window to be raised to the top. + + This will attempt to raise the window to the top, even if this isn't the + active application, or if doing so would otherwise go against the + platform's guidelines. This generally shouldn't be used, and isn't + guaranteed to work. On modern Windows systems, the active application + must explicitly grant permission for others to steal the foreground from + it. + */ + PUGL_SHOW_FORCE_RAISE, +} PuglShowCommand; + /** Show the view. @@ -1224,7 +1256,7 @@ puglUnrealize(PuglView* view); */ PUGL_API PuglStatus -puglShow(PuglView* view); +puglShow(PuglView* view, PuglShowCommand command); /// Hide the current window PUGL_API diff --git a/meson.build b/meson.build index 63e9e13..652cd77 100644 --- a/meson.build +++ b/meson.build @@ -2,7 +2,7 @@ # SPDX-License-Identifier: 0BSD OR ISC project('pugl', ['c'], - version: '0.5.0', + version: '0.5.1', license: 'ISC', meson_version: '>= 0.54.0', default_options: [ @@ -1311,7 +1311,7 @@ puglUnrealize(PuglView* const view) } PuglStatus -puglShow(PuglView* view) +puglShow(PuglView* view, const PuglShowCommand command) { if (!view->impl->wrapperView) { const PuglStatus st = puglRealize(view); @@ -1320,12 +1320,24 @@ puglShow(PuglView* view) } } - if (![view->impl->window isVisible]) { - [view->impl->window setIsVisible:YES]; + NSWindow* const window = [view->impl->wrapperView window]; + if (![window isVisible]) { + [window setIsVisible:YES]; [view->impl->drawView setNeedsDisplay:YES]; updateViewRect(view); } + switch (command) { + case PUGL_SHOW_PASSIVE: + break; + case PUGL_SHOW_RAISE: + [window orderFront:view->impl->wrapperView]; + break; + case PUGL_SHOW_FORCE_RAISE: + [window orderFrontRegardless]; + break; + } + return PUGL_SUCCESS; } @@ -309,7 +309,7 @@ puglUnrealize(PuglView* const view) } PuglStatus -puglShow(PuglView* view) +puglShow(PuglView* view, const PuglShowCommand command) { PuglInternals* impl = view->impl; @@ -320,8 +320,20 @@ puglShow(PuglView* view) } } - ShowWindow(impl->hwnd, SW_SHOWNORMAL); - SetFocus(impl->hwnd); + switch (command) { + case PUGL_SHOW_PASSIVE: + ShowWindow(impl->hwnd, SW_SHOWNOACTIVATE); + break; + case PUGL_SHOW_RAISE: + ShowWindow(impl->hwnd, SW_SHOWNORMAL); + SetActiveWindow(impl->hwnd); + break; + case PUGL_SHOW_FORCE_RAISE: + ShowWindow(impl->hwnd, SW_SHOWNORMAL); + SetForegroundWindow(impl->hwnd); + break; + } + return PUGL_SUCCESS; } @@ -655,12 +655,23 @@ puglUnrealize(PuglView* const view) } PuglStatus -puglShow(PuglView* const view) +puglShow(PuglView* const view, const PuglShowCommand command) { PuglStatus st = view->impl->win ? PUGL_SUCCESS : puglRealize(view); if (!st) { - XMapRaised(view->world->impl->display, view->impl->win); + switch (command) { + case PUGL_SHOW_PASSIVE: + XMapWindow(view->world->impl->display, view->impl->win); + break; + case PUGL_SHOW_RAISE: + XMapRaised(view->world->impl->display, view->impl->win); + break; + case PUGL_SHOW_FORCE_RAISE: + XMapRaised(view->world->impl->display, view->impl->win); + break; + } + st = puglPostRedisplay(view); } diff --git a/test/test_cairo.c b/test/test_cairo.c index a9a36db..e2d0089 100644 --- a/test/test_cairo.c +++ b/test/test_cairo.c @@ -66,7 +66,7 @@ main(int argc, char** argv) puglSetBackend(test.view, puglCairoBackend()); puglSetEventFunc(test.view, onEvent); puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 512, 512); - puglShow(test.view); + puglShow(test.view, PUGL_SHOW_PASSIVE); // Drive event loop until the view gets exposed while (!test.exposed) { diff --git a/test/test_gl.c b/test/test_gl.c index da84c1a..bf9b02a 100644 --- a/test/test_gl.c +++ b/test/test_gl.c @@ -85,7 +85,7 @@ main(int argc, char** argv) puglSetBackend(test.view, puglGlBackend()); puglSetEventFunc(test.view, onEvent); puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 512, 512); - puglShow(test.view); + puglShow(test.view, PUGL_SHOW_PASSIVE); // Enter OpenGL context as if setting things up puglEnterContext(test.view); diff --git a/test/test_local_copy_paste.c b/test/test_local_copy_paste.c index 9f99a09..14614ab 100644 --- a/test/test_local_copy_paste.c +++ b/test/test_local_copy_paste.c @@ -136,7 +136,7 @@ main(int argc, char** argv) // Create and show window assert(!puglRealize(app.view)); - assert(!puglShow(app.view)); + assert(!puglShow(app.view, PUGL_SHOW_PASSIVE)); // Run until the test is finished while (app.state != FINISHED) { diff --git a/test/test_redisplay.c b/test/test_redisplay.c index afe89dc..7a98720 100644 --- a/test/test_redisplay.c +++ b/test/test_redisplay.c @@ -117,7 +117,7 @@ main(int argc, char** argv) // Create and show window assert(!puglRealize(test.view)); - assert(!puglShow(test.view)); + assert(!puglShow(test.view, PUGL_SHOW_PASSIVE)); while (test.state != EXPOSED) { assert(!puglUpdate(test.world, timeout)); } diff --git a/test/test_remote_copy_paste.c b/test/test_remote_copy_paste.c index 828992d..0abcb73 100644 --- a/test/test_remote_copy_paste.c +++ b/test/test_remote_copy_paste.c @@ -161,8 +161,8 @@ main(int argc, char** argv) puglSetPosition(app.pasterView, 512, 512); // Create and show both views - assert(!puglShow(app.copierView)); - assert(!puglShow(app.pasterView)); + assert(!puglShow(app.copierView, PUGL_SHOW_PASSIVE)); + assert(!puglShow(app.pasterView, PUGL_SHOW_PASSIVE)); // Run until the test is finished while (app.state != FINISHED) { diff --git a/test/test_show_hide.c b/test/test_show_hide.c index 6664a1e..4418da3 100644 --- a/test/test_show_hide.c +++ b/test/test_show_hide.c @@ -86,7 +86,7 @@ showHide(PuglTest* const test) { // Show and hide window a couple of times for (unsigned i = 0U; i < 2U; ++i) { - assert(!puglShow(test->view)); + assert(!puglShow(test->view, PUGL_SHOW_PASSIVE)); while (test->state != EXPOSED) { tick(test->world); } diff --git a/test/test_size.c b/test/test_size.c index f19deb9..9eaf3ca 100644 --- a/test/test_size.c +++ b/test/test_size.c @@ -91,7 +91,7 @@ main(int argc, char** argv) // Create and show window assert(!puglRealize(test.view)); - assert(!puglShow(test.view)); + assert(!puglShow(test.view, PUGL_SHOW_PASSIVE)); while (test.state < CONFIGURED) { assert(!puglUpdate(test.world, -1.0)); } diff --git a/test/test_stub.c b/test/test_stub.c index 8ab2c15..06abeb4 100644 --- a/test/test_stub.c +++ b/test/test_stub.c @@ -52,7 +52,7 @@ main(int argc, char** argv) puglSetBackend(test.view, puglStubBackend()); puglSetEventFunc(test.view, onEvent); puglSetSizeHint(test.view, PUGL_DEFAULT_SIZE, 512, 512); - puglShow(test.view); + puglShow(test.view, PUGL_SHOW_PASSIVE); // Drive event loop until the view gets exposed while (!test.exposed) { diff --git a/test/test_timer.c b/test/test_timer.c index 34223c9..cda5be9 100644 --- a/test/test_timer.c +++ b/test/test_timer.c @@ -115,7 +115,7 @@ main(int argc, char** argv) // Create and show window assert(!puglRealize(test.view)); - assert(!puglShow(test.view)); + assert(!puglShow(test.view, PUGL_SHOW_RAISE)); while (test.state != EXPOSED) { assert(!puglUpdate(test.world, timeout)); } diff --git a/test/test_update.c b/test/test_update.c index 381e34b..ff58ed2 100644 --- a/test/test_update.c +++ b/test/test_update.c @@ -93,7 +93,7 @@ main(int argc, char** argv) // Create and show window assert(!puglRealize(test.view)); - assert(!puglShow(test.view)); + assert(!puglShow(test.view, PUGL_SHOW_PASSIVE)); // Tick until an expose happens while (test.state < EXPOSED1) { diff --git a/test/test_view.c b/test/test_view.c index eeedc96..6b3624c 100644 --- a/test/test_view.c +++ b/test/test_view.c @@ -75,7 +75,7 @@ main(int argc, char** argv) // Create and show window assert(!puglRealize(test.view)); - assert(!puglShow(test.view)); + assert(!puglShow(test.view, PUGL_SHOW_PASSIVE)); while (test.state < CONFIGURED) { assert(!puglUpdate(test.world, -1.0)); } diff --git a/test/test_vulkan.c b/test/test_vulkan.c index 77921b4..ae940a2 100644 --- a/test/test_vulkan.c +++ b/test/test_vulkan.c @@ -186,7 +186,7 @@ main(int argc, char** argv) assert(puglGetDeviceProcAddrFunc(loader)); // Show view and drive event loop until the view gets exposed - puglShow(test.view); + puglShow(test.view, PUGL_SHOW_PASSIVE); while (!test.exposed) { puglUpdate(test.world, -1.0); } |