diff options
author | David Robillard <d@drobilla.net> | 2023-01-12 15:30:44 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-01-14 11:53:28 -0500 |
commit | 1e48f8bbfdb0f1ce2f9132d604405fb72d160d9d (patch) | |
tree | 2fbb2e70f5bf5e7f7e021dafb51dd508944426f2 | |
parent | bd4f79646f623e929e6aa22bea028952b515aeef (diff) | |
download | pugl-1e48f8bbfdb0f1ce2f9132d604405fb72d160d9d.tar.gz pugl-1e48f8bbfdb0f1ce2f9132d604405fb72d160d9d.tar.bz2 pugl-1e48f8bbfdb0f1ce2f9132d604405fb72d160d9d.zip |
Windows: Add PUGL_DARK_FRAME hint
This allows dark applications to visually integrate more nicely in Windows 10.
A little thing, but it really goes a long way to make programs not look out of
place and half-baked.
-rw-r--r-- | bindings/cpp/include/pugl/pugl.hpp | 4 | ||||
-rw-r--r-- | examples/pugl_management_demo.c | 11 | ||||
-rw-r--r-- | examples/pugl_shader_demo.c | 1 | ||||
-rw-r--r-- | examples/pugl_vulkan_cpp_demo.cpp | 1 | ||||
-rw-r--r-- | include/pugl/pugl.h | 3 | ||||
-rw-r--r-- | meson.build | 3 | ||||
-rw-r--r-- | src/win.c | 20 | ||||
-rw-r--r-- | test/test_utils.h | 2 |
8 files changed, 38 insertions, 7 deletions
diff --git a/bindings/cpp/include/pugl/pugl.hpp b/bindings/cpp/include/pugl/pugl.hpp index 90c5de6..257ccd2 100644 --- a/bindings/cpp/include/pugl/pugl.hpp +++ b/bindings/cpp/include/pugl/pugl.hpp @@ -378,9 +378,11 @@ enum class ViewHint { ignoreKeyRepeat, ///< @copydoc PUGL_IGNORE_KEY_REPEAT refreshRate, ///< @copydoc PUGL_REFRESH_RATE viewType, ///< @copydoc PUGL_VIEW_TYPE + darkFrame, ///< @copydoc PUGL_DARK_FRAME }; -static_assert(static_cast<ViewHint>(PUGL_VIEW_TYPE) == ViewHint::viewType, ""); +static_assert(static_cast<ViewHint>(PUGL_DARK_FRAME) == ViewHint::darkFrame, + ""); using ViewHintValue = PuglViewHintValue; ///< @copydoc PuglViewHintValue diff --git a/examples/pugl_management_demo.c b/examples/pugl_management_demo.c index 30a026e..766bee1 100644 --- a/examples/pugl_management_demo.c +++ b/examples/pugl_management_demo.c @@ -50,20 +50,20 @@ onExpose(PuglView* const view, const PuglExposeEvent* const event) cairo_clip_preserve(cr); // Draw background - cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); + cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); cairo_set_line_width(cr, 4.0); cairo_fill(cr); // Set up text renering char buf[128] = {0}; cairo_text_extents_t extents = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - cairo_set_font_size(cr, 32.0); + cairo_set_font_size(cr, 30.0); // Draw time label snprintf(buf, sizeof(buf), "Draw time: %g", puglGetTime(world)); cairo_text_extents(cr, buf, &extents); cairo_move_to(cr, cx - extents.width / 2.0, cy + extents.height / 2.0 - 48.0); - cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_set_source_rgb(cr, 0.9, 0.9, 0.9); cairo_show_text(cr, buf); // Draw style label @@ -112,13 +112,15 @@ toggleDialog(DemoApp* const app) puglSetHandle(app->dialogView.view, &app->dialogView); puglSetTransientParent(app->dialogView.view, puglGetNativeView(app->mainView.view)); + + puglSetViewString(app->dialogView.view, PUGL_WINDOW_TITLE, "Dialog"); + puglSetViewHint(app->dialogView.view, PUGL_DARK_FRAME, PUGL_TRUE); puglSetSizeHint(app->dialogView.view, PUGL_DEFAULT_SIZE, 320, 240); puglSetSizeHint(app->dialogView.view, PUGL_MIN_SIZE, 160, 120); puglSetViewHint(app->dialogView.view, PUGL_IGNORE_KEY_REPEAT, true); puglSetViewHint(app->dialogView.view, PUGL_RESIZABLE, true); puglSetViewHint( app->dialogView.view, PUGL_VIEW_TYPE, PUGL_VIEW_TYPE_DIALOG); - puglSetViewString(app->dialogView.view, PUGL_WINDOW_TITLE, "Dialog"); } return puglShow(app->dialogView.view, PUGL_SHOW_RAISE); @@ -240,6 +242,7 @@ main(int argc, char** argv) puglSetHandle(app.mainView.view, &app.mainView); puglSetSizeHint(app.mainView.view, PUGL_DEFAULT_SIZE, 640, 480); puglSetSizeHint(app.mainView.view, PUGL_MIN_SIZE, 320, 240); + puglSetViewHint(app.mainView.view, PUGL_DARK_FRAME, PUGL_TRUE); puglSetViewHint(app.mainView.view, PUGL_IGNORE_KEY_REPEAT, true); puglSetViewHint(app.mainView.view, PUGL_RESIZABLE, true); puglSetViewHint(app.mainView.view, PUGL_VIEW_TYPE, PUGL_VIEW_TYPE_NORMAL); diff --git a/examples/pugl_shader_demo.c b/examples/pugl_shader_demo.c index 5773a9d..5cd9c7c 100644 --- a/examples/pugl_shader_demo.c +++ b/examples/pugl_shader_demo.c @@ -265,6 +265,7 @@ setupPugl(PuglTestApp* app) puglSetViewHint(app->view, PUGL_DOUBLE_BUFFER, app->opts.doubleBuffer); puglSetViewHint(app->view, PUGL_SWAP_INTERVAL, app->opts.sync); puglSetViewHint(app->view, PUGL_IGNORE_KEY_REPEAT, PUGL_TRUE); + puglSetViewHint(app->view, PUGL_DARK_FRAME, PUGL_TRUE); puglSetHandle(app->view, app); puglSetEventFunc(app->view, onEvent); } diff --git a/examples/pugl_vulkan_cpp_demo.cpp b/examples/pugl_vulkan_cpp_demo.cpp index 7e652a5..2cfb1e8 100644 --- a/examples/pugl_vulkan_cpp_demo.cpp +++ b/examples/pugl_vulkan_cpp_demo.cpp @@ -1719,6 +1719,7 @@ run(const char* const programPath, app.view.setSizeHint(pugl::SizeHint::minSize, width / 4U, height / 4U); app.view.setBackend(pugl::vulkanBackend()); app.view.setHint(pugl::ViewHint::resizable, opts.resizable); + app.view.setHint(pugl::ViewHint::darkFrame, true); const pugl::Status st = app.view.realize(); if (st != pugl::Status::success) { return logError("Failed to create window (%s)\n", pugl::strerror(st)); diff --git a/include/pugl/pugl.h b/include/pugl/pugl.h index 4427c5a..801ae3c 100644 --- a/include/pugl/pugl.h +++ b/include/pugl/pugl.h @@ -923,10 +923,11 @@ typedef enum { PUGL_IGNORE_KEY_REPEAT, ///< True if key repeat events are ignored PUGL_REFRESH_RATE, ///< Refresh rate in Hz PUGL_VIEW_TYPE, ///< View type (a #PuglViewType) + PUGL_DARK_FRAME, ///< True if window frame should be dark } PuglViewHint; /// The number of #PuglViewHint values -#define PUGL_NUM_VIEW_HINTS ((unsigned)PUGL_VIEW_TYPE + 1U) +#define PUGL_NUM_VIEW_HINTS ((unsigned)PUGL_DARK_FRAME + 1U) /// A special view hint value typedef enum { diff --git a/meson.build b/meson.build index 652cd77..63f14bb 100644 --- a/meson.build +++ b/meson.build @@ -99,10 +99,11 @@ elif host_machine.system() == 'windows' user32_dep = cc.find_library('user32') shlwapi_dep = cc.find_library('shlwapi') + dwmapi_dep = cc.find_library('dwmapi') platform = 'win' platform_sources = files('src/win.c') - core_deps = [user32_dep, shlwapi_dep] + core_deps = [user32_dep, shlwapi_dep, dwmapi_dep] extension = '.c' else # X11 @@ -8,6 +8,7 @@ #include "pugl/pugl.h" +#include <dwmapi.h> #include <windows.h> #include <windowsx.h> @@ -30,6 +31,11 @@ # define GWLP_USERDATA (-21) #endif +#define PRE_20H1_DWMWA_USE_IMMERSIVE_DARK_MODE 19 +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +# define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + #define PUGL_LOCAL_CLOSE_MSG (WM_USER + 50) #define PUGL_LOCAL_MARK_MSG (WM_USER + 51) #define PUGL_LOCAL_CLIENT_MSG (WM_USER + 52) @@ -280,12 +286,26 @@ puglRealize(PuglView* view) } // Set basic window hints and attributes + puglSetViewString(view, PUGL_WINDOW_TITLE, view->strings[PUGL_WINDOW_TITLE]); puglSetTransientParent(view, view->transientParent); view->impl->scaleFactor = puglWinGetViewScaleFactor(view); view->impl->cursor = LoadCursor(NULL, IDC_ARROW); + if (view->hints[PUGL_DARK_FRAME]) { + const BOOL useDarkMode = TRUE; + if ((DwmSetWindowAttribute(view->impl->hwnd, + DWMWA_USE_IMMERSIVE_DARK_MODE, + &useDarkMode, + sizeof(useDarkMode)) != S_OK)) { + DwmSetWindowAttribute(view->impl->hwnd, + PRE_20H1_DWMWA_USE_IMMERSIVE_DARK_MODE, + &useDarkMode, + sizeof(useDarkMode)); + } + } + SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view); return puglDispatchSimpleEvent(view, PUGL_REALIZE); diff --git a/test/test_utils.h b/test/test_utils.h index e26e970..785c8c7 100644 --- a/test/test_utils.h +++ b/test/test_utils.h @@ -296,6 +296,8 @@ puglViewHintString(const PuglViewHint hint) return "Refresh rate"; case PUGL_VIEW_TYPE: return "View type"; + case PUGL_DARK_FRAME: + return "Dark frame"; } return "Unknown"; |