Skip to content

Commit 7dbea98

Browse files
committed
Merge pull request #97005 from Repiteo/core/window-corner-style
Core: Add `DisplayServer` flag for sharp corners
2 parents 8b5c20e + f8c4a68 commit 7dbea98

11 files changed

+62
-2
lines changed

core/config/project_settings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,7 @@ ProjectSettings::ProjectSettings() {
14771477
GLOBAL_DEF("display/window/size/transparent", false);
14781478
GLOBAL_DEF("display/window/size/extend_to_title", false);
14791479
GLOBAL_DEF("display/window/size/no_focus", false);
1480+
GLOBAL_DEF("display/window/size/sharp_corners", false);
14801481

14811482
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution
14821483
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution

doc/classes/DisplayServer.xml

+5-1
Original file line numberDiff line numberDiff line change
@@ -2099,7 +2099,11 @@
20992099
<constant name="WINDOW_FLAG_MOUSE_PASSTHROUGH" value="7" enum="WindowFlags">
21002100
All mouse events are passed to the underlying window of the same application.
21012101
</constant>
2102-
<constant name="WINDOW_FLAG_MAX" value="8" enum="WindowFlags">
2102+
<constant name="WINDOW_FLAG_SHARP_CORNERS" value="8" enum="WindowFlags">
2103+
Window style is overridden, forcing sharp corners.
2104+
[b]Note:[/b] This flag is implemented only on Windows (11).
2105+
</constant>
2106+
<constant name="WINDOW_FLAG_MAX" value="9" enum="WindowFlags">
21032107
Max value of the [enum WindowFlags].
21042108
</constant>
21052109
<constant name="WINDOW_EVENT_MOUSE_ENTER" value="0" enum="WindowEvent">

doc/classes/ProjectSettings.xml

+4
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,10 @@
875875
[b]Note:[/b] Certain window managers can be configured to ignore the non-resizable status of a window. Do not rely on this setting as a guarantee that the window will [i]never[/i] be resizable.
876876
[b]Note:[/b] This setting is ignored on iOS.
877877
</member>
878+
<member name="display/window/size/sharp_corners" type="bool" setter="" getter="" default="false">
879+
If [code]true[/code], the main window uses sharp corners by default.
880+
[b]Note:[/b] This property is implemented only on Windows (11).
881+
</member>
878882
<member name="display/window/size/transparent" type="bool" setter="" getter="" default="false">
879883
If [code]true[/code], enables a window manager hint that the main window background [i]can[/i] be transparent. This does not make the background actually transparent. For the background to be transparent, the root viewport must also be made transparent by enabling [member rendering/viewport/transparent_background].
880884
[b]Note:[/b] To use a transparent splash screen, set [member application/boot_splash/bg_color] to [code]Color(0, 0, 0, 0)[/code].

doc/classes/Window.xml

+11-1
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,11 @@
659659
If [member ProjectSettings.display/window/subwindows/embed_subwindows] is [code]false[/code], the position is in absolute screen coordinates. This typically applies to editor plugins. If the setting is [code]true[/code], the window's position is in the coordinates of its parent [Viewport].
660660
[b]Note:[/b] This property only works if [member initial_position] is set to [constant WINDOW_INITIAL_POSITION_ABSOLUTE].
661661
</member>
662+
<member name="sharp_corners" type="bool" setter="set_flag" getter="get_flag" default="false">
663+
If [code]true[/code], the [Window] will override the OS window style to display sharp corners.
664+
[b]Note:[/b] This property is implemented only on Windows (11).
665+
[b]Note:[/b] This property only works with native windows.
666+
</member>
662667
<member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i(100, 100)">
663668
The window's size in pixels.
664669
</member>
@@ -842,7 +847,12 @@
842847
All mouse events are passed to the underlying window of the same application.
843848
[b]Note:[/b] This flag has no effect in embedded windows.
844849
</constant>
845-
<constant name="FLAG_MAX" value="8" enum="Flags">
850+
<constant name="FLAG_SHARP_CORNERS" value="8" enum="Flags">
851+
Window style is overridden, forcing sharp corners.
852+
[b]Note:[/b] This flag has no effect in embedded windows.
853+
[b]Note:[/b] This flag is implemented only on Windows (11).
854+
</constant>
855+
<constant name="FLAG_MAX" value="9" enum="Flags">
846856
Max value of the [enum Flags].
847857
</constant>
848858
<constant name="CONTENT_SCALE_MODE_DISABLED" value="0" enum="ContentScaleMode">

main/main.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -2413,6 +2413,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
24132413
if (bool(GLOBAL_GET("display/window/size/no_focus"))) {
24142414
window_flags |= DisplayServer::WINDOW_FLAG_NO_FOCUS_BIT;
24152415
}
2416+
if (bool(GLOBAL_GET("display/window/size/sharp_corners"))) {
2417+
window_flags |= DisplayServer::WINDOW_FLAG_SHARP_CORNERS_BIT;
2418+
}
24162419
window_mode = (DisplayServer::WindowMode)(GLOBAL_GET("display/window/size/mode").operator int());
24172420
int initial_position_type = GLOBAL_GET("display/window/size/initial_position_type").operator int();
24182421
if (initial_position_type == 0) { // Absolute.

platform/windows/display_server_windows.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@
6767
#define DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 19
6868
#endif
6969

70+
#ifndef DWMWA_WINDOW_CORNER_PREFERENCE
71+
#define DWMWA_WINDOW_CORNER_PREFERENCE 33
72+
#endif
73+
74+
#ifndef DWMWCP_DEFAULT
75+
#define DWMWCP_DEFAULT 0
76+
#endif
77+
78+
#ifndef DWMWCP_DONOTROUND
79+
#define DWMWCP_DONOTROUND 1
80+
#endif
81+
7082
#define WM_INDICATOR_CALLBACK_MESSAGE (WM_USER + 1)
7183

7284
#if defined(__GNUC__)
@@ -1483,6 +1495,9 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
14831495
if (p_flags & WINDOW_FLAG_ALWAYS_ON_TOP_BIT && p_mode != WINDOW_MODE_FULLSCREEN && p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
14841496
wd.always_on_top = true;
14851497
}
1498+
if (p_flags & WINDOW_FLAG_SHARP_CORNERS_BIT) {
1499+
wd.sharp_corners = true;
1500+
}
14861501
if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) {
14871502
wd.no_focus = true;
14881503
}
@@ -2297,6 +2312,12 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
22972312
wd.always_on_top = p_enabled;
22982313
_update_window_style(p_window);
22992314
} break;
2315+
case WINDOW_FLAG_SHARP_CORNERS: {
2316+
wd.sharp_corners = p_enabled;
2317+
DWORD value = wd.sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
2318+
::DwmSetWindowAttribute(wd.hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
2319+
_update_window_style(p_window);
2320+
} break;
23002321
case WINDOW_FLAG_TRANSPARENT: {
23012322
if (p_enabled) {
23022323
// Enable per-pixel alpha.
@@ -3994,6 +4015,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
39944015
native_menu->_menu_activate(HMENU(lParam), (int)wParam);
39954016
} break;
39964017
case WM_CREATE: {
4018+
{
4019+
DWORD value = windows[window_id].sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
4020+
::DwmSetWindowAttribute(windows[window_id].hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
4021+
}
39974022
if (is_dark_mode_supported() && dark_title_available) {
39984023
BOOL value = is_dark_mode();
39994024

@@ -5645,6 +5670,12 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
56455670
wd_transient_parent->transient_children.insert(id);
56465671
}
56475672

5673+
wd.sharp_corners = p_flags & WINDOW_FLAG_SHARP_CORNERS_BIT;
5674+
{
5675+
DWORD value = wd.sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
5676+
::DwmSetWindowAttribute(wd.hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
5677+
}
5678+
56485679
if (is_dark_mode_supported() && dark_title_available) {
56495680
BOOL value = is_dark_mode();
56505681
::DwmSetWindowAttribute(wd.hWnd, use_legacy_dark_mode_before_20H1 ? DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 : DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));

platform/windows/display_server_windows.h

+1
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ class DisplayServerWindows : public DisplayServer {
474474
bool exclusive = false;
475475
bool context_created = false;
476476
bool mpass = false;
477+
bool sharp_corners = false;
477478

478479
// Used to transfer data between events using timer.
479480
WPARAM saved_wparam;

scene/main/window.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -3008,6 +3008,7 @@ void Window::_bind_methods() {
30083008
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "popup_window"), "set_flag", "get_flag", FLAG_POPUP);
30093009
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "extend_to_title"), "set_flag", "get_flag", FLAG_EXTEND_TO_TITLE);
30103010
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "mouse_passthrough"), "set_flag", "get_flag", FLAG_MOUSE_PASSTHROUGH);
3011+
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "sharp_corners"), "set_flag", "get_flag", FLAG_SHARP_CORNERS);
30113012
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_native"), "set_force_native", "get_force_native");
30123013

30133014
ADD_GROUP("Limits", "");
@@ -3061,6 +3062,7 @@ void Window::_bind_methods() {
30613062
BIND_ENUM_CONSTANT(FLAG_POPUP);
30623063
BIND_ENUM_CONSTANT(FLAG_EXTEND_TO_TITLE);
30633064
BIND_ENUM_CONSTANT(FLAG_MOUSE_PASSTHROUGH);
3065+
BIND_ENUM_CONSTANT(FLAG_SHARP_CORNERS);
30643066
BIND_ENUM_CONSTANT(FLAG_MAX);
30653067

30663068
BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_DISABLED);

scene/main/window.h

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class Window : public Viewport {
6262
FLAG_POPUP = DisplayServer::WINDOW_FLAG_POPUP,
6363
FLAG_EXTEND_TO_TITLE = DisplayServer::WINDOW_FLAG_EXTEND_TO_TITLE,
6464
FLAG_MOUSE_PASSTHROUGH = DisplayServer::WINDOW_FLAG_MOUSE_PASSTHROUGH,
65+
FLAG_SHARP_CORNERS = DisplayServer::WINDOW_FLAG_SHARP_CORNERS,
6566
FLAG_MAX = DisplayServer::WINDOW_FLAG_MAX,
6667
};
6768

servers/display_server.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,7 @@ void DisplayServer::_bind_methods() {
11281128
BIND_ENUM_CONSTANT(WINDOW_FLAG_POPUP);
11291129
BIND_ENUM_CONSTANT(WINDOW_FLAG_EXTEND_TO_TITLE);
11301130
BIND_ENUM_CONSTANT(WINDOW_FLAG_MOUSE_PASSTHROUGH);
1131+
BIND_ENUM_CONSTANT(WINDOW_FLAG_SHARP_CORNERS);
11311132
BIND_ENUM_CONSTANT(WINDOW_FLAG_MAX);
11321133

11331134
BIND_ENUM_CONSTANT(WINDOW_EVENT_MOUSE_ENTER);

servers/display_server.h

+2
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ class DisplayServer : public Object {
381381
WINDOW_FLAG_POPUP,
382382
WINDOW_FLAG_EXTEND_TO_TITLE,
383383
WINDOW_FLAG_MOUSE_PASSTHROUGH,
384+
WINDOW_FLAG_SHARP_CORNERS,
384385
WINDOW_FLAG_MAX,
385386
};
386387

@@ -394,6 +395,7 @@ class DisplayServer : public Object {
394395
WINDOW_FLAG_POPUP_BIT = (1 << WINDOW_FLAG_POPUP),
395396
WINDOW_FLAG_EXTEND_TO_TITLE_BIT = (1 << WINDOW_FLAG_EXTEND_TO_TITLE),
396397
WINDOW_FLAG_MOUSE_PASSTHROUGH_BIT = (1 << WINDOW_FLAG_MOUSE_PASSTHROUGH),
398+
WINDOW_FLAG_SHARP_CORNERS_BIT = (1 << WINDOW_FLAG_SHARP_CORNERS),
397399
};
398400

399401
virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID);

0 commit comments

Comments
 (0)