diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 11023e8716..8a69b450c9 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -2467,6 +2467,27 @@
[b]Note:[/b] It's recommended to change this value using [member Window.size] instead.
+
+
+
+
+
+ Sets the type and state of the progress bar on the taskbar/dock icon of the window specified by [param window_id]. See [enum ProgressState] for possible values and how each mode behaves.
+ [b]Note:[/b] This method is implemented only on Windows and macOS.
+ [b]Note:[/b] On macOS, the progress bar is displayed only for the main window.
+
+
+
+
+
+
+
+ Creates a progress bar on the taskbar/dock icon of the window specified by [param window_id] if it does not exist, sets the progress of the icon.
+ [param value] acts as a relative percentage value, ranges from [code]0.0[/code] (lowest) to [code]1.0[/code] (highest).
+ [b]Note:[/b] This method is implemented only on Windows and macOS.
+ [b]Note:[/b] On macOS, the progress bar is displayed only for the main window.
+
+
@@ -3125,6 +3146,24 @@
[b]On Linux (Wayland):[/b] Equivalent to [constant WINDOW_MODE_FULLSCREEN].
[b]Note:[/b] Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
+
+ Stops displaying progress and returns the button to its normal state.
+
+
+ The progress indicator shows an indeterminate progress.
+ On Windows, the progress indicator does not grow in size, but cycles repeatedly along the length of the taskbar button by default.
+
+
+ The progress indicator shows progress normally.
+
+
+ The progress indicator shows that an error has occurred.
+ On Windows, the progress indicator turns red by default to show that an error has occurred in one of the windows that is broadcasting progress.
+
+
+ The progress indicator shows it was paused.
+ On Windows, the progress indicator turns yellow by default to show that progress is currently stopped in one of the windows but can be resumed by the user.
+
The window can't be resized by dragging its resize grip. It's still possible to resize the window using [method window_set_size]. This flag is ignored for full screen windows.
diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml
index 26943d1917..f66d841f24 100644
--- a/doc/classes/Window.xml
+++ b/doc/classes/Window.xml
@@ -542,6 +542,23 @@
Sets layout direction and text writing direction. Right-to-left layouts are necessary for certain languages (e.g. Arabic and Hebrew).
+
+
+
+
+ Sets the type and state of the progress bar on the taskbar/dock icon of the [Window]. See [enum DisplayServer.ProgressState] for possible values and how each mode behaves.
+ [b]Note:[/b] This method is implemented only on Windows and macOS.
+
+
+
+
+
+
+ Creates a progress bar on the taskbar/dock icon of the [Window] if it does not exist, sets the progress of the icon.
+ [param value] acts as a relative percentage value, ranges from [code]0.0[/code] (lowest) to [code]1.0[/code] (highest).
+ [b]Note:[/b] This method is implemented only on Windows and macOS.
+
+
diff --git a/platform/macos/SCsub b/platform/macos/SCsub
index 883bd531c8..e2c15aba06 100644
--- a/platform/macos/SCsub
+++ b/platform/macos/SCsub
@@ -28,6 +28,7 @@ files = [
"rendering_context_driver_vulkan_macos.mm",
"gl_manager_macos_angle.mm",
"gl_manager_macos_legacy.mm",
+ "godot_progress_view.mm",
]
if env.editor_build:
diff --git a/platform/macos/display_server_embedded.h b/platform/macos/display_server_embedded.h
index 748f185f4e..9dc95d35b0 100644
--- a/platform/macos/display_server_embedded.h
+++ b/platform/macos/display_server_embedded.h
@@ -197,6 +197,8 @@ public:
virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_taskbar_progress_value(float p_value, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/macos/display_server_embedded.mm b/platform/macos/display_server_embedded.mm
index d85d48ca37..bacabe77ef 100644
--- a/platform/macos/display_server_embedded.mm
+++ b/platform/macos/display_server_embedded.mm
@@ -705,6 +705,14 @@ void DisplayServerEmbedded::window_request_attention(WindowID p_window) {
// Not supported
}
+void DisplayServerEmbedded::window_set_taskbar_progress_value(float p_value, WindowID p_window) {
+ // Not supported.
+}
+
+void DisplayServerEmbedded::window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window) {
+ // Not supported.
+}
+
void DisplayServerEmbedded::window_move_to_foreground(WindowID p_window) {
// Not supported
}
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index f74c841638..318530b157 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -64,6 +64,7 @@
@class GodotContentView;
@class GodotWindowDelegate;
@class GodotButtonView;
+@class GodotProgressView;
#ifdef TOOLS_ENABLED
@class GodotEmbeddedView;
@class CALayerHost;
@@ -154,6 +155,8 @@ public:
List popup_list;
uint64_t time_since_popup = 0;
+ GodotProgressView *dock_progress = nullptr;
+
private:
#if defined(GLES3_ENABLED)
GLManagerLegacy_MacOS *gl_manager_legacy = nullptr;
@@ -386,6 +389,8 @@ public:
virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_taskbar_progress_value(float p_value, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 74b31fa14c..8df934f6c3 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -38,6 +38,7 @@
#import "godot_menu_delegate.h"
#import "godot_menu_item.h"
#import "godot_open_save_delegate.h"
+#import "godot_progress_view.h"
#import "godot_status_item.h"
#import "godot_window.h"
#import "godot_window_delegate.h"
@@ -2715,6 +2716,28 @@ void DisplayServerMacOS::window_request_attention(WindowID p_window) {
[NSApp requestUserAttention:NSCriticalRequest];
}
+void DisplayServerMacOS::window_set_taskbar_progress_value(float p_value, WindowID p_window) {
+ ERR_FAIL_COND(p_window != MAIN_WINDOW_ID);
+
+ if (!dock_progress) {
+ dock_progress = [[GodotProgressView alloc] init];
+ [NSApp.dockTile setContentView:dock_progress];
+ }
+
+ [dock_progress setValue:p_value];
+}
+
+void DisplayServerMacOS::window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window) {
+ ERR_FAIL_COND(p_window != MAIN_WINDOW_ID);
+
+ if (!dock_progress) {
+ dock_progress = [[GodotProgressView alloc] init];
+ [NSApp.dockTile setContentView:dock_progress];
+ }
+
+ [dock_progress setState:p_state];
+}
+
void DisplayServerMacOS::window_move_to_foreground(WindowID p_window) {
_THREAD_SAFE_METHOD_
@@ -3260,6 +3283,11 @@ void DisplayServerMacOS::_process_events(bool p_pump) {
}
}
+ if (dock_progress) {
+ dock_progress.needsDisplay = true;
+ [NSApp.dockTile display];
+ }
+
_THREAD_SAFE_UNLOCK_
}
diff --git a/platform/macos/godot_progress_view.h b/platform/macos/godot_progress_view.h
new file mode 100644
index 0000000000..de15afeb95
--- /dev/null
+++ b/platform/macos/godot_progress_view.h
@@ -0,0 +1,45 @@
+/**************************************************************************/
+/* godot_progress_view.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#pragma once
+
+#include "display_server_macos_base.h"
+
+#import
+#import
+
+@interface GodotProgressView : NSView {
+ DisplayServer::ProgressState pr_state;
+ float pr_value;
+ float pr_offset;
+}
+- (void)setValue:(float)value;
+- (void)setState:(DisplayServer::ProgressState)state;
+@end
diff --git a/platform/macos/godot_progress_view.mm b/platform/macos/godot_progress_view.mm
new file mode 100644
index 0000000000..8bc74b2cca
--- /dev/null
+++ b/platform/macos/godot_progress_view.mm
@@ -0,0 +1,94 @@
+/**************************************************************************/
+/* godot_progress_view.mm */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#import "godot_progress_view.h"
+
+@implementation GodotProgressView
+
+- (id)init {
+ self = [super init];
+ pr_state = DisplayServer::PROGRESS_STATE_NOPROGRESS;
+ pr_value = 0.f;
+ pr_offset = 0.f;
+ return self;
+}
+
+- (void)setValue:(float)value {
+ pr_value = value;
+}
+
+- (void)setState:(DisplayServer::ProgressState)state {
+ pr_state = state;
+}
+
+- (void)drawRect:(NSRect)dirtyRect {
+ // Icon draw.
+ [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
+ [[NSApp applicationIconImage] drawInRect:self.bounds];
+
+ if (pr_state == DisplayServer::PROGRESS_STATE_NOPROGRESS) {
+ return;
+ }
+
+ // Border draw.
+ NSRect rect = NSMakeRect(1.f, 1.f, self.bounds.size.width - 2.f, 16.f);
+ NSBezierPath *bezier_path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:8.f yRadius:8.f];
+ [bezier_path setLineWidth:2.0];
+ [[NSColor grayColor] set];
+ [bezier_path stroke];
+
+ // Fill clip path.
+ rect = NSMakeRect(2.f, 2.f, self.bounds.size.width - 4.f, 14.f);
+ bezier_path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:7.f yRadius:7.f];
+ [bezier_path setLineWidth:1.0];
+ [bezier_path addClip];
+
+ // Fill draw.
+ if (pr_state == DisplayServer::PROGRESS_STATE_INDETERMINATE) {
+ rect.size.width /= 5.0;
+ pr_offset += rect.size.width / 10.0;
+ if (pr_offset > self.bounds.size.width - rect.size.width) {
+ pr_offset = 0.f;
+ }
+ rect.origin.x += pr_offset;
+ } else {
+ rect.size.width = Math::floor(rect.size.width * pr_value);
+ }
+ if (pr_state == DisplayServer::PROGRESS_STATE_ERROR) {
+ [[NSColor colorWithSRGBRed:1.0 green:0.2 blue:0.2 alpha:1.0] set];
+ } else if (pr_state == DisplayServer::PROGRESS_STATE_PAUSED) {
+ [[NSColor colorWithSRGBRed:1.0 green:1.0 blue:0.2 alpha:1.0] set];
+ } else {
+ [[NSColor colorWithSRGBRed:0.2 green:0.6 blue:1.0 alpha:1.0] set];
+ }
+ NSRectFill(rect);
+}
+
+@end
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index df6a6ae5b0..5aa00315d0 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -2820,6 +2820,69 @@ void DisplayServerWindows::window_request_attention(WindowID p_window) {
FlashWindowEx(&info);
}
+void DisplayServerWindows::window_set_taskbar_progress_value(float p_value, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND(!windows.has(p_window));
+ WindowData &wd = windows[p_window];
+ wd.progress_value = p_value;
+ if (wd.progress_state == PROGRESS_STATE_NOPROGRESS) {
+ return;
+ }
+ if (taskbar == nullptr) {
+ if (CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (void **)&taskbar) != S_OK) {
+ taskbar = nullptr;
+ return;
+ } else {
+ taskbar->HrInit();
+ }
+ }
+
+ taskbar->SetProgressValue(wd.hWnd, Math::round(p_value * 100000), 100000);
+}
+
+void DisplayServerWindows::window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND(!windows.has(p_window));
+ WindowData &wd = windows[p_window];
+ wd.progress_state = p_state;
+ if (taskbar == nullptr) {
+ if (CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (void **)&taskbar) != S_OK) {
+ taskbar = nullptr;
+ return;
+ } else {
+ taskbar->HrInit();
+ }
+ }
+
+ TBPFLAG tbpf = TBPF_NOPROGRESS;
+ switch (p_state) {
+ case PROGRESS_STATE_NOPROGRESS:
+ tbpf = TBPF_NOPROGRESS;
+ break;
+ case PROGRESS_STATE_INDETERMINATE:
+ tbpf = TBPF_INDETERMINATE;
+ break;
+ case PROGRESS_STATE_ERROR:
+ tbpf = TBPF_ERROR;
+ break;
+ case PROGRESS_STATE_PAUSED:
+ tbpf = TBPF_PAUSED;
+ break;
+ case PROGRESS_STATE_NORMAL:
+ tbpf = TBPF_NORMAL;
+ break;
+ default:
+ break;
+ }
+
+ taskbar->SetProgressState(wd.hWnd, tbpf);
+ if (p_state != PROGRESS_STATE_INDETERMINATE) {
+ taskbar->SetProgressValue(wd.hWnd, Math::round(wd.progress_value * 100000), 100000);
+ }
+}
+
void DisplayServerWindows::window_move_to_foreground(WindowID p_window) {
_THREAD_SAFE_METHOD_
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index d05fd39eb7..bac3acdd38 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -66,6 +66,7 @@
#include
#define WIN32_LEAN_AND_MEAN
+#include
#include
#include
@@ -290,12 +291,15 @@ class DisplayServerWindows : public DisplayServer {
TTS_Windows *tts = nullptr;
NativeMenuWindows *native_menu = nullptr;
+ ITaskbarList3 *taskbar = nullptr;
struct WindowData {
HWND hWnd;
WindowID id;
Vector mpath;
+ ProgressState progress_state = PROGRESS_STATE_NOPROGRESS;
+ float progress_value = 0.0;
bool create_completed = false;
bool pre_fs_valid = false;
@@ -662,6 +666,8 @@ public:
virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_taskbar_progress_value(float p_value, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 4bb28aff58..098e47f450 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -589,6 +589,20 @@ void Window::request_attention() {
}
}
+void Window::set_taskbar_progress_value(float p_value) {
+ ERR_MAIN_THREAD_GUARD;
+ if (window_id != DisplayServer::INVALID_WINDOW_ID) {
+ DisplayServer::get_singleton()->window_set_taskbar_progress_value(p_value, window_id);
+ }
+}
+
+void Window::set_taskbar_progress_state(DisplayServer::ProgressState p_state) {
+ ERR_MAIN_THREAD_GUARD;
+ if (window_id != DisplayServer::INVALID_WINDOW_ID) {
+ DisplayServer::get_singleton()->window_set_taskbar_progress_state(p_state);
+ }
+}
+
#ifndef DISABLE_DEPRECATED
void Window::move_to_foreground() {
WARN_DEPRECATED_MSG(R"*(The "move_to_foreground()" method is deprecated, use "grab_focus()" instead.)*");
@@ -3238,6 +3252,8 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("request_attention"), &Window::request_attention);
+ ClassDB::bind_method(D_METHOD("set_taskbar_progress_value", "value"), &Window::set_taskbar_progress_value);
+ ClassDB::bind_method(D_METHOD("set_taskbar_progress_state", "state"), &Window::set_taskbar_progress_state);
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("move_to_foreground"), &Window::move_to_foreground);
#endif // DISABLE_DEPRECATED
diff --git a/scene/main/window.h b/scene/main/window.h
index 1e01d37292..ca4afffb39 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -338,6 +338,8 @@ public:
bool is_maximize_allowed() const;
void request_attention();
+ void set_taskbar_progress_value(float p_value);
+ void set_taskbar_progress_state(DisplayServer::ProgressState p_state);
#ifndef DISABLE_DEPRECATED
void move_to_foreground();
#endif // DISABLE_DEPRECATED
diff --git a/servers/display/display_server.cpp b/servers/display/display_server.cpp
index 973fd121b4..d309cfd938 100644
--- a/servers/display/display_server.cpp
+++ b/servers/display/display_server.cpp
@@ -1459,6 +1459,8 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("window_get_safe_title_margins", "window_id"), &DisplayServer::window_get_safe_title_margins, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_request_attention", "window_id"), &DisplayServer::window_request_attention, DEFVAL(MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("window_set_taskbar_progress_value", "value", "window_id"), &DisplayServer::window_set_taskbar_progress_value, DEFVAL(MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("window_set_taskbar_progress_state", "state", "window_id"), &DisplayServer::window_set_taskbar_progress_state, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_move_to_foreground", "window_id"), &DisplayServer::window_move_to_foreground, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_is_focused", "window_id"), &DisplayServer::window_is_focused, DEFVAL(MAIN_WINDOW_ID));
@@ -1831,6 +1833,12 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(WINDOW_MODE_FULLSCREEN);
BIND_ENUM_CONSTANT(WINDOW_MODE_EXCLUSIVE_FULLSCREEN);
+ BIND_ENUM_CONSTANT(PROGRESS_STATE_NOPROGRESS);
+ BIND_ENUM_CONSTANT(PROGRESS_STATE_INDETERMINATE);
+ BIND_ENUM_CONSTANT(PROGRESS_STATE_NORMAL);
+ BIND_ENUM_CONSTANT(PROGRESS_STATE_ERROR);
+ BIND_ENUM_CONSTANT(PROGRESS_STATE_PAUSED);
+
BIND_ENUM_CONSTANT(WINDOW_FLAG_RESIZE_DISABLED);
BIND_ENUM_CONSTANT(WINDOW_FLAG_BORDERLESS);
BIND_ENUM_CONSTANT(WINDOW_FLAG_ALWAYS_ON_TOP);
diff --git a/servers/display/display_server.h b/servers/display/display_server.h
index ee6853ed00..d732c5fca1 100644
--- a/servers/display/display_server.h
+++ b/servers/display/display_server.h
@@ -76,6 +76,14 @@ public:
WINDOW_MODE_EXCLUSIVE_FULLSCREEN,
};
+ enum ProgressState {
+ PROGRESS_STATE_NOPROGRESS,
+ PROGRESS_STATE_INDETERMINATE,
+ PROGRESS_STATE_NORMAL,
+ PROGRESS_STATE_ERROR,
+ PROGRESS_STATE_PAUSED,
+ };
+
// Keep the VSyncMode enum values in sync with the `display/window/vsync/vsync_mode`
// project setting hint.
enum VSyncMode {
@@ -518,6 +526,8 @@ public:
virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const = 0;
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) = 0;
+ virtual void window_set_taskbar_progress_value(float p_value, WindowID p_window = MAIN_WINDOW_ID) {}
+ virtual void window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window = MAIN_WINDOW_ID) {}
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) = 0;
virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const = 0;
@@ -1027,3 +1037,4 @@ VARIANT_ENUM_CAST(DisplayServer::CursorShape)
VARIANT_ENUM_CAST(DisplayServer::VSyncMode)
VARIANT_ENUM_CAST(DisplayServer::TTSUtteranceEvent)
VARIANT_ENUM_CAST(DisplayServer::FileDialogMode)
+VARIANT_ENUM_CAST(DisplayServer::ProgressState)
diff --git a/servers/display/display_server_headless.h b/servers/display/display_server_headless.h
index 9dd8a51f10..83d5143752 100644
--- a/servers/display/display_server_headless.h
+++ b/servers/display/display_server_headless.h
@@ -142,6 +142,8 @@ public:
bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override { return false; }
void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override {}
+ void window_set_taskbar_progress_value(float p_value, WindowID p_window = MAIN_WINDOW_ID) override {}
+ void window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window = MAIN_WINDOW_ID) override {}
void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override {}
bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override { return true; }