From 127d31a85cedcafba8eaee4fc9619a611a46be37 Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 16 Apr 2026 02:51:53 +0100 Subject: [PATCH] graphics: add option to disable win11 rounded corners on windows (#641) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description of change This adds a toggleable option to remove the rounded window corners when running a game, or a subscreen, in a window on Windows 11 and upwards. ## Testing On Windows 11: Resort Anthem, MÚSECA and EPOLIS were tested and the window corners were removed from both main windows and the TDJ subscreen when running in windowed mode, with no change in fullscreen mode. On Windows 7: IIDX18 was tested with no change, the call to `DwmSetWindowAttribute` is ignored as `DWMWA_WINDOW_CORNER_PREFERENCE` doesn't exist. For XP builds, the call is compiled out to avoid linking against dwmapi and windows_dll_compat_checker returns successfully when testing against the XP Embedded image. I can't test it on XP, but it ran on Vista. --- src/spice2x/cfg/screen_resize.h | 1 + src/spice2x/hooks/graphics/graphics.cpp | 3 ++ src/spice2x/hooks/graphics/graphics.h | 5 ++++ .../hooks/graphics/graphics_windowed.cpp | 30 +++++++++++++++++++ src/spice2x/launcher/launcher.cpp | 1 + src/spice2x/launcher/options.cpp | 8 +++++ src/spice2x/launcher/options.h | 1 + 7 files changed, 49 insertions(+) diff --git a/src/spice2x/cfg/screen_resize.h b/src/spice2x/cfg/screen_resize.h index f986028..aa4cdcc 100644 --- a/src/spice2x/cfg/screen_resize.h +++ b/src/spice2x/cfg/screen_resize.h @@ -60,6 +60,7 @@ namespace cfg { // window = rectangle including the frame // client = just the content area without frames. bool window_always_on_top = false; + bool window_disable_round_corners = false; bool client_keep_aspect_ratio = true; bool enable_window_resize = false; int window_decoration = 0; // enum type WindowDecorationMode diff --git a/src/spice2x/hooks/graphics/graphics.cpp b/src/spice2x/hooks/graphics/graphics.cpp index 3d54e17..00522a1 100644 --- a/src/spice2x/hooks/graphics/graphics.cpp +++ b/src/spice2x/hooks/graphics/graphics.cpp @@ -924,6 +924,9 @@ void graphics_hook_subscreen_window(HWND hWnd) { if (GRAPHICS_WSUB_ALWAYS_ON_TOP) { graphics_update_z_order(hWnd, true); } + if (GRAPHICS_WINDOW_DISABLE_ROUNDED_CORNERS) { + graphics_set_corner_preference(hWnd, true); + } } void graphics_screens_register(int screen) { diff --git a/src/spice2x/hooks/graphics/graphics.h b/src/spice2x/hooks/graphics/graphics.h index f49ce21..060fa73 100644 --- a/src/spice2x/hooks/graphics/graphics.h +++ b/src/spice2x/hooks/graphics/graphics.h @@ -7,6 +7,9 @@ #include #include +#if !SPICE_XP +#include +#endif #include "external/toojpeg/toojpeg.h" @@ -50,6 +53,7 @@ extern std::optional> GRAPHICS_WINDOW_SIZE; extern std::optional GRAPHICS_WINDOW_POS; extern bool GRAPHICS_WINDOW_ALWAYS_ON_TOP; extern bool GRAPHICS_WINDOW_BACKBUFFER_SCALE; +extern bool GRAPHICS_WINDOW_DISABLE_ROUNDED_CORNERS; extern std::optional GRAPHICS_HOOKED_WINDOW; extern bool GRAPHICS_IIDX_WSUB; @@ -103,6 +107,7 @@ void graphics_windowed_wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara void graphics_capture_initial_window(HWND hWnd); void graphics_update_window_style(HWND hWnd, bool force_update=false); void graphics_update_z_order(HWND hWnd, bool always_on_top); +void graphics_set_corner_preference(HWND hWnd, bool disable); void graphics_move_resize_window(HWND hWnd); bool graphics_window_options_breaks_game(); bool graphics_window_decoration_change_crashes_game(); diff --git a/src/spice2x/hooks/graphics/graphics_windowed.cpp b/src/spice2x/hooks/graphics/graphics_windowed.cpp index 12a4f8a..56eafcc 100644 --- a/src/spice2x/hooks/graphics/graphics_windowed.cpp +++ b/src/spice2x/hooks/graphics/graphics_windowed.cpp @@ -24,6 +24,7 @@ std::optional> GRAPHICS_WINDOW_SIZE; std::optional GRAPHICS_WINDOW_POS; bool GRAPHICS_WINDOW_ALWAYS_ON_TOP = false; bool GRAPHICS_WINDOW_BACKBUFFER_SCALE = false; +bool GRAPHICS_WINDOW_DISABLE_ROUNDED_CORNERS = false; std::optional GRAPHICS_HOOKED_WINDOW; // IIDX Windowed Subscreen - starts out as false, enabled by IIDX module on pre-attach as needed @@ -132,6 +133,10 @@ void graphics_capture_initial_window(HWND hWnd) { log_info("graphics-windowed", "[{}] change window z-order - always on top", fmt::ptr(hWnd)); graphics_update_z_order(hWnd, true); } + if (cfg::SCREENRESIZE->window_disable_round_corners) { + log_info("graphics-windowed", "[{}] disabling rounded corners", fmt::ptr(hWnd)); + graphics_set_corner_preference(hWnd, true); + } // ensure spicetouch coordinates are initialized update_spicetouch_window_dimensions(hWnd); @@ -181,6 +186,10 @@ void graphics_load_windowed_parameters() { cfg::SCREENRESIZE->window_always_on_top = true; } + if (GRAPHICS_WINDOW_DISABLE_ROUNDED_CORNERS) { + cfg::SCREENRESIZE->window_disable_round_corners = true; + } + log_debug("graphics-windowed", "graphics_load_windowed_parameters returned"); } @@ -469,6 +478,27 @@ void graphics_update_z_order(HWND hWnd, bool always_on_top) { log_debug("graphics-windowed", "graphics_update_z_order returned"); } +void graphics_set_corner_preference(HWND hWnd, bool disable) { + if (!GRAPHICS_WINDOWED) { + return; + } + +#if !SPICE_XP + log_debug("graphics-windowed", "graphics_set_corner_preference called"); + + DWM_WINDOW_CORNER_PREFERENCE corner_preference = disable ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT; + DwmSetWindowAttribute( + hWnd, + DWMWA_WINDOW_CORNER_PREFERENCE, + &corner_preference, sizeof(corner_preference)); + + log_debug("graphics-windowed", "graphics_set_corner_preference returned"); +#else + // don't link against DwmSetWindowAttribute on XP + log_debug("graphics-windowed", "graphics_set_corner_preference called; ignoring"); +#endif +} + void graphics_move_resize_window(HWND hWnd) { if (!GRAPHICS_WINDOWED) { return; diff --git a/src/spice2x/launcher/launcher.cpp b/src/spice2x/launcher/launcher.cpp index ad6789c..dea4527 100644 --- a/src/spice2x/launcher/launcher.cpp +++ b/src/spice2x/launcher/launcher.cpp @@ -1117,6 +1117,7 @@ int main_implementation(int argc, char *argv[]) { } GRAPHICS_WINDOW_ALWAYS_ON_TOP = options[launcher::Options::spice2x_WindowAlwaysOnTop].value_bool(); GRAPHICS_WINDOW_BACKBUFFER_SCALE = options[launcher::Options::WindowForceScaling].value_bool(); + GRAPHICS_WINDOW_DISABLE_ROUNDED_CORNERS = options[launcher::Options::WindowDisableRoundedCorners].value_bool(); // IIDX/SDVX Windowed Subscreen if (options[launcher::Options::spice2x_IIDXWindowedSubscreenSize].is_active()) { diff --git a/src/spice2x/launcher/options.cpp b/src/spice2x/launcher/options.cpp index 66c6e28..0862188 100644 --- a/src/spice2x/launcher/options.cpp +++ b/src/spice2x/launcher/options.cpp @@ -2218,6 +2218,14 @@ static const std::vector OPTION_DEFINITIONS = { .type = OptionType::Bool, .category = "Graphics (Windowed)", }, + { + // WindowDisableRoundedCorners + .title = "Disable Round Window Corners", + .name = "windownoroundcorners", + .desc = "Windows 11 and above only: Disables rounded corners on the game window(s).", + .type = OptionType::Bool, + .category = "Graphics (Windowed)", + }, { // spice2x_IIDXWindowedSubscreenSize .title = "IIDX Windowed Subscreen Size", diff --git a/src/spice2x/launcher/options.h b/src/spice2x/launcher/options.h index bf1d03d..6a3934d 100644 --- a/src/spice2x/launcher/options.h +++ b/src/spice2x/launcher/options.h @@ -232,6 +232,7 @@ namespace launcher { spice2x_WindowPosition, spice2x_WindowAlwaysOnTop, WindowForceScaling, + WindowDisableRoundedCorners, spice2x_IIDXWindowedSubscreenSize, spice2x_IIDXWindowedSubscreenPosition, IIDXWindowedSubscreenBorderless,