From 2087f9be74172805f4382a059431b31ff4aca9f7 Mon Sep 17 00:00:00 2001 From: Hei <40064911+Lielay9@users.noreply.github.com> Date: Sat, 30 Nov 2024 00:16:35 +0200 Subject: [PATCH] Add functionality to hide windows from taskbar (Windows only). --- core/config/project_settings.cpp | 1 + doc/classes/DisplayServer.xml | 6 +++- doc/classes/ProjectSettings.xml | 4 +++ doc/classes/Window.xml | 12 +++++++- main/main.cpp | 3 ++ platform/windows/display_server_windows.cpp | 32 +++++++++++++++++++++ platform/windows/display_server_windows.h | 1 + scene/main/window.cpp | 2 ++ scene/main/window.h | 1 + servers/display_server.cpp | 1 + servers/display_server.h | 2 ++ 11 files changed, 63 insertions(+), 2 deletions(-) diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 6c28b00f4870..48d51e95cfbb 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1487,6 +1487,7 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("display/window/size/extend_to_title", false); GLOBAL_DEF("display/window/size/no_focus", false); GLOBAL_DEF("display/window/size/sharp_corners", false); + GLOBAL_DEF("display/window/size/skip_taskbar", false); GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 47611e59df74..9b2213ba5928 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -2110,7 +2110,11 @@ Window style is overridden, forcing sharp corners. [b]Note:[/b] This flag is implemented only on Windows (11). - + + Window won't be visible in the taskbar or in the system's window manager's window list. + [b]Note:[/b] This flag is implemented only on Windows. + + Max value of the [enum WindowFlags]. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 91961fcf02b6..cceacc844143 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -892,6 +892,10 @@ If [code]true[/code], the main window uses sharp corners by default. [b]Note:[/b] This property is implemented only on Windows (11). + + If [code]true[/code], the main window won't be visible in the taskbar or in the system's window manager's window list. + [b]Note:[/b] This property is implemented only on Windows. + 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]. [b]Note:[/b] To use a transparent splash screen, set [member application/boot_splash/bg_color] to [code]Color(0, 0, 0, 0)[/code]. diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 6d3294cc2754..d6298181d904 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -667,6 +667,11 @@ The window's size in pixels. + + If [code]true[/code], the [Window] won't be visible in the taskbar or in the system's window manager's window list. + [b]Note:[/b] This property is implemented only on Windows. + [b]Note:[/b] This property only works with native windows. + The [Theme] resource this node and all its [Control] and [Window] children use. If a child node has its own [Theme] resource set, theme items are merged with child's definitions having higher priority. [b]Note:[/b] [Window] styles will have no effect unless the window is embedded. @@ -853,7 +858,12 @@ [b]Note:[/b] This flag has no effect in embedded windows. [b]Note:[/b] This flag is implemented only on Windows (11). - + + Window won't be visible in the taskbar or in the system's window manager's window list. + [b]Note:[/b] This flag has no effect in embedded windows. + [b]Note:[/b] This flag is implemented only on Windows. + + Max value of the [enum Flags]. diff --git a/main/main.cpp b/main/main.cpp index 123114ce8d0e..6d8a7a2c96f0 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2449,6 +2449,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph if (bool(GLOBAL_GET("display/window/size/sharp_corners"))) { window_flags |= DisplayServer::WINDOW_FLAG_SHARP_CORNERS_BIT; } + if (bool(GLOBAL_GET("display/window/size/skip_taskbar"))) { + window_flags |= DisplayServer::WINDOW_FLAG_SKIP_TASKBAR_BIT; + } window_mode = (DisplayServer::WindowMode)(GLOBAL_GET("display/window/size/mode").operator int()); int initial_position_type = GLOBAL_GET("display/window/size/initial_position_type").operator int(); if (initial_position_type == 0) { // Absolute. diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index ec3fcea6cba9..e75eedc70425 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1500,6 +1500,9 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod if (p_flags & WINDOW_FLAG_SHARP_CORNERS_BIT) { wd.sharp_corners = true; } + if (p_flags & WINDOW_FLAG_SKIP_TASKBAR_BIT) { + wd.skip_taskbar = true; + } if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) { wd.no_focus = true; } @@ -2389,6 +2392,22 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W ERR_FAIL_COND_MSG(IsWindowVisible(wd.hWnd) && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened."); wd.is_popup = p_enabled; } break; + case WINDOW_FLAG_SKIP_TASKBAR: { + if (wd.skip_taskbar != p_enabled) { + wd.skip_taskbar = p_enabled; + ITaskbarList *tbl = nullptr; + if (SUCCEEDED(CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (LPVOID *)&tbl))) { + if (SUCCEEDED(tbl->HrInit())) { + if (p_enabled) { + tbl->DeleteTab(wd.hWnd); + } else { + tbl->AddTab(wd.hWnd); + } + } + SAFE_RELEASE(tbl) + } + } + } break; default: break; } @@ -2421,6 +2440,9 @@ bool DisplayServerWindows::window_get_flag(WindowFlags p_flag, WindowID p_window case WINDOW_FLAG_POPUP: { return wd.is_popup; } break; + case WINDOW_FLAG_SKIP_TASKBAR: { + return wd.skip_taskbar; + } break; default: break; } @@ -5852,6 +5874,16 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, SetWindowPos(wd.hWnd, HWND_TOP, srect.position.x, srect.position.y, srect.size.width, srect.size.height, SWP_NOZORDER | SWP_NOACTIVATE); } + if (p_flags & WINDOW_FLAG_SKIP_TASKBAR_BIT) { + ITaskbarList *tbl = nullptr; + if (SUCCEEDED(CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (LPVOID *)&tbl))) { + if (SUCCEEDED(tbl->HrInit())) { + tbl->DeleteTab(wd.hWnd); + } + SAFE_RELEASE(tbl) + } + } + wd.create_completed = true; window_id_counter++; } diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 886026811574..1aa4d65c975a 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -482,6 +482,7 @@ class DisplayServerWindows : public DisplayServer { bool context_created = false; bool mpass = false; bool sharp_corners = false; + bool skip_taskbar = false; // Used to transfer data between events using timer. WPARAM saved_wparam; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 6341575b6340..79088d498eed 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -2990,6 +2990,7 @@ void Window::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "extend_to_title"), "set_flag", "get_flag", FLAG_EXTEND_TO_TITLE); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "mouse_passthrough"), "set_flag", "get_flag", FLAG_MOUSE_PASSTHROUGH); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "sharp_corners"), "set_flag", "get_flag", FLAG_SHARP_CORNERS); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "skip_taskbar"), "set_flag", "get_flag", FLAG_SKIP_TASKBAR); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_native"), "set_force_native", "get_force_native"); ADD_GROUP("Limits", ""); @@ -3044,6 +3045,7 @@ void Window::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_EXTEND_TO_TITLE); BIND_ENUM_CONSTANT(FLAG_MOUSE_PASSTHROUGH); BIND_ENUM_CONSTANT(FLAG_SHARP_CORNERS); + BIND_ENUM_CONSTANT(FLAG_SKIP_TASKBAR); BIND_ENUM_CONSTANT(FLAG_MAX); BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_DISABLED); diff --git a/scene/main/window.h b/scene/main/window.h index 6c82efcc3f9b..8fee8267d116 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -63,6 +63,7 @@ class Window : public Viewport { FLAG_EXTEND_TO_TITLE = DisplayServer::WINDOW_FLAG_EXTEND_TO_TITLE, FLAG_MOUSE_PASSTHROUGH = DisplayServer::WINDOW_FLAG_MOUSE_PASSTHROUGH, FLAG_SHARP_CORNERS = DisplayServer::WINDOW_FLAG_SHARP_CORNERS, + FLAG_SKIP_TASKBAR = DisplayServer::WINDOW_FLAG_SKIP_TASKBAR, FLAG_MAX = DisplayServer::WINDOW_FLAG_MAX, }; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 82ac62bc9fae..0432f9481612 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -1130,6 +1130,7 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(WINDOW_FLAG_EXTEND_TO_TITLE); BIND_ENUM_CONSTANT(WINDOW_FLAG_MOUSE_PASSTHROUGH); BIND_ENUM_CONSTANT(WINDOW_FLAG_SHARP_CORNERS); + BIND_ENUM_CONSTANT(WINDOW_FLAG_SKIP_TASKBAR); BIND_ENUM_CONSTANT(WINDOW_FLAG_MAX); BIND_ENUM_CONSTANT(WINDOW_EVENT_MOUSE_ENTER); diff --git a/servers/display_server.h b/servers/display_server.h index 916c006f0113..717d08d1e70a 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -386,6 +386,7 @@ class DisplayServer : public Object { WINDOW_FLAG_EXTEND_TO_TITLE, WINDOW_FLAG_MOUSE_PASSTHROUGH, WINDOW_FLAG_SHARP_CORNERS, + WINDOW_FLAG_SKIP_TASKBAR, WINDOW_FLAG_MAX, }; @@ -400,6 +401,7 @@ class DisplayServer : public Object { WINDOW_FLAG_EXTEND_TO_TITLE_BIT = (1 << WINDOW_FLAG_EXTEND_TO_TITLE), WINDOW_FLAG_MOUSE_PASSTHROUGH_BIT = (1 << WINDOW_FLAG_MOUSE_PASSTHROUGH), WINDOW_FLAG_SHARP_CORNERS_BIT = (1 << WINDOW_FLAG_SHARP_CORNERS), + WINDOW_FLAG_SKIP_TASKBAR_BIT = (1 << WINDOW_FLAG_SKIP_TASKBAR), }; 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);