Win32 Added support for taskbar progress

This commit is contained in:
GamesTrap 2022-07-23 21:28:35 +02:00
parent 26b85215c0
commit 8acb72b9a1
No known key found for this signature in database
GPG Key ID: 31DFD452434ECDA3
19 changed files with 132 additions and 1 deletions

View File

@ -1251,6 +1251,12 @@ extern "C" {
#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR #define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR
/*! @} */ /*! @} */
#define GLFW_TASKBAR_PROGRESS_NOPROGRESS 0x00
#define GLFW_TASKBAR_PROGRESS_INDETERMINATE 0x01
#define GLFW_TASKBAR_PROGRESS_NORMAL 0x02
#define GLFW_TASKBAR_PROGRESS_ERROR 0x04
#define GLFW_TASKBAR_PROGRESS_PAUSED 0x08
#define GLFW_CONNECTED 0x00040001 #define GLFW_CONNECTED 0x00040001
#define GLFW_DISCONNECTED 0x00040002 #define GLFW_DISCONNECTED 0x00040002
@ -3283,6 +3289,8 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
*/ */
GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
GLFWAPI void glfwSetWindowTaskbarProgress(GLFWwindow* window, const int progressState, int completed);
/*! @brief Retrieves the position of the content area of the specified window. /*! @brief Retrieves the position of the content area of the specified window.
* *
* This function retrieves the position, in screen coordinates, of the * This function retrieves the position, in screen coordinates, of the

View File

@ -525,6 +525,7 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
_glfwDestroyWindowCocoa, _glfwDestroyWindowCocoa,
_glfwSetWindowTitleCocoa, _glfwSetWindowTitleCocoa,
_glfwSetWindowIconCocoa, _glfwSetWindowIconCocoa,
_glfwSetWindowTaskbarProgressCocoa,
_glfwGetWindowPosCocoa, _glfwGetWindowPosCocoa,
_glfwSetWindowPosCocoa, _glfwSetWindowPosCocoa,
_glfwGetWindowSizeCocoa, _glfwGetWindowSizeCocoa,

View File

@ -218,6 +218,7 @@ GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, const _GLFWwndconfig* wndco
void _glfwDestroyWindowCocoa(_GLFWwindow* window); void _glfwDestroyWindowCocoa(_GLFWwindow* window);
void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title); void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconCocoa(_GLFWwindow* window, int count, const GLFWimage* images); void _glfwSetWindowIconCocoa(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowTaskbarProgressCocoa(_GLFWwindow* window, const int taskbarState, int completed);
void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos); void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosCocoa(_GLFWwindow* window, int xpos, int ypos); void _glfwSetWindowPosCocoa(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height); void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height);

View File

@ -1014,6 +1014,12 @@ void _glfwSetWindowIconCocoa(_GLFWwindow* window,
"Cocoa: Regular windows do not have icons on macOS"); "Cocoa: Regular windows do not have icons on macOS");
} }
void _glfwSetWindowTaskbarProgress(_GLFWwindow* window, const int progressState, int completed)
{
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
"Cocoa: Window taskbar progress is not implemented");
}
void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos) void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos)
{ {
@autoreleasepool { @autoreleasepool {

View File

@ -708,6 +708,7 @@ struct _GLFWplatform
void (*destroyWindow)(_GLFWwindow*); void (*destroyWindow)(_GLFWwindow*);
void (*setWindowTitle)(_GLFWwindow*,const char*); void (*setWindowTitle)(_GLFWwindow*,const char*);
void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*); void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*);
void (*setWindowTaskbarProgress)(_GLFWwindow*,const int,int);
void (*getWindowPos)(_GLFWwindow*,int*,int*); void (*getWindowPos)(_GLFWwindow*,int*,int*);
void (*setWindowPos)(_GLFWwindow*,int,int); void (*setWindowPos)(_GLFWwindow*,int,int);
void (*getWindowSize)(_GLFWwindow*,int*,int*); void (*getWindowSize)(_GLFWwindow*,int*,int*);

View File

@ -73,6 +73,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
_glfwDestroyWindowNull, _glfwDestroyWindowNull,
_glfwSetWindowTitleNull, _glfwSetWindowTitleNull,
_glfwSetWindowIconNull, _glfwSetWindowIconNull,
_glfwSetWindowTaskbarProgressNull,
_glfwGetWindowPosNull, _glfwGetWindowPosNull,
_glfwSetWindowPosNull, _glfwSetWindowPosNull,
_glfwGetWindowSizeNull, _glfwGetWindowSizeNull,

View File

@ -89,6 +89,7 @@ GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndcon
void _glfwDestroyWindowNull(_GLFWwindow* window); void _glfwDestroyWindowNull(_GLFWwindow* window);
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title); void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images); void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowTaskbarProgressNull(_GLFWwindow* window, const int taskbarState, int completed);
void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos); void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos); void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos);

View File

@ -178,6 +178,10 @@ void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* ima
{ {
} }
void _glfwSetWindowTaskbarProgressNull(_GLFWwindow* window, const int progressState, int completed)
{
}
void _glfwSetWindowMonitorNull(_GLFWwindow* window, void _glfwSetWindowMonitorNull(_GLFWwindow* window,
_GLFWmonitor* monitor, _GLFWmonitor* monitor,
int xpos, int ypos, int xpos, int ypos,

View File

@ -636,6 +636,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
_glfwDestroyWindowWin32, _glfwDestroyWindowWin32,
_glfwSetWindowTitleWin32, _glfwSetWindowTitleWin32,
_glfwSetWindowIconWin32, _glfwSetWindowIconWin32,
_glfwSetWindowTaskbarProgressWin32,
_glfwGetWindowPosWin32, _glfwGetWindowPosWin32,
_glfwSetWindowPosWin32, _glfwSetWindowPosWin32,
_glfwGetWindowSizeWin32, _glfwGetWindowSizeWin32,

View File

@ -69,6 +69,7 @@
#include <dinput.h> #include <dinput.h>
#include <xinput.h> #include <xinput.h>
#include <dbt.h> #include <dbt.h>
#include <ShObjIdl_core.h>
// HACK: Define macros that some windows.h variants don't // HACK: Define macros that some windows.h variants don't
#ifndef WM_MOUSEHWHEEL #ifndef WM_MOUSEHWHEEL
@ -432,6 +433,9 @@ typedef struct _GLFWwindowWin32
int lastCursorPosX, lastCursorPosY; int lastCursorPosX, lastCursorPosY;
// The last received high surrogate when decoding pairs of UTF-16 messages // The last received high surrogate when decoding pairs of UTF-16 messages
WCHAR highSurrogate; WCHAR highSurrogate;
ITaskbarList3* TaskbarList;
UINT TaskbarListMsgID;
} _GLFWwindowWin32; } _GLFWwindowWin32;
// Win32-specific global data // Win32-specific global data
@ -541,6 +545,7 @@ GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, const _GLFWwndconfig* wndco
void _glfwDestroyWindowWin32(_GLFWwindow* window); void _glfwDestroyWindowWin32(_GLFWwindow* window);
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title); void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images); void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowTaskbarProgressWin32(_GLFWwindow* window, const int taskbarState, int completed);
void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos); void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos); void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeWin32(_GLFWwindow* window, int* width, int* height); void _glfwGetWindowSizeWin32(_GLFWwindow* window, int* width, int* height);

View File

@ -1239,6 +1239,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
} }
} }
if(uMsg == window->win32.TaskbarListMsgID)
{
HRESULT res = CoCreateInstance(&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, (LPVOID*)&window->win32.TaskbarList);
if (res != S_OK && window->win32.TaskbarList)
window->win32.TaskbarList->lpVtbl->Release(window->win32.TaskbarList);
else
{
window->win32.TaskbarList->lpVtbl->AddRef(window->win32.TaskbarList);
window->win32.TaskbarList->lpVtbl->HrInit(window->win32.TaskbarList);
}
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
} }
@ -1348,6 +1360,10 @@ static int createNativeWindow(_GLFWwindow* window,
WM_COPYDATA, MSGFLT_ALLOW, NULL); WM_COPYDATA, MSGFLT_ALLOW, NULL);
ChangeWindowMessageFilterEx(window->win32.handle, ChangeWindowMessageFilterEx(window->win32.handle,
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL); WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
window->win32.TaskbarListMsgID = RegisterWindowMessageW(L"TaskbarButtonCreated");
if (window->win32.TaskbarListMsgID)
ChangeWindowMessageFilterEx(window->win32.handle, window->win32.TaskbarListMsgID, MSGFLT_ALLOW, NULL);
} }
window->win32.scaleToMonitor = wndconfig->scaleToMonitor; window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
@ -1497,6 +1513,9 @@ void _glfwDestroyWindowWin32(_GLFWwindow* window)
if (_glfw.win32.disabledCursorWindow == window) if (_glfw.win32.disabledCursorWindow == window)
_glfw.win32.disabledCursorWindow = NULL; _glfw.win32.disabledCursorWindow = NULL;
if (window->win32.TaskbarList)
window->win32.TaskbarList->lpVtbl->Release(window->win32.TaskbarList);
if (window->win32.handle) if (window->win32.handle)
{ {
RemovePropW(window->win32.handle, L"GLFW"); RemovePropW(window->win32.handle, L"GLFW");
@ -1559,6 +1578,23 @@ void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* im
} }
} }
void _glfwSetWindowTaskbarProgressWin32(_GLFWwindow* window, const int progressState, int completed)
{
if(!window->win32.TaskbarList)
return;
HRESULT res = window->win32.TaskbarList->lpVtbl->SetProgressValue(window->win32.TaskbarList, window->win32.handle, completed, 100);
if(res != S_OK)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "Win32: Failed to set taskbar progress value");
return;
}
res = window->win32.TaskbarList->lpVtbl->SetProgressState(window->win32.TaskbarList, window->win32.handle, progressState);
if (res != S_OK)
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "Win32: Failed to set taskbar progress state");
}
void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos) void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos)
{ {
POINT pos = { 0, 0 }; POINT pos = { 0, 0 };

View File

@ -546,6 +546,36 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
_glfw.platform.setWindowIcon(window, count, images); _glfw.platform.setWindowIcon(window, count, images);
} }
GLFWAPI void glfwSetWindowTaskbarProgress(GLFWwindow* handle, const int progressState, int completed)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(completed >= 0);
assert(completed <= 100);
if (completed < 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid progress amount for window taskbar progress");
return;
}
else if (completed > 100)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid progress amount for window taskbar progress");
return;
}
if (progressState != GLFW_TASKBAR_PROGRESS_NOPROGRESS && progressState != GLFW_TASKBAR_PROGRESS_INDETERMINATE &&
progressState != GLFW_TASKBAR_PROGRESS_NORMAL && progressState != GLFW_TASKBAR_PROGRESS_ERROR &&
progressState != GLFW_TASKBAR_PROGRESS_PAUSED)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid progress state 0x%08X", progressState);
return;
}
_glfw.platform.setWindowTaskbarProgress(window, progressState, completed);
}
GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;

View File

@ -417,6 +417,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
_glfwDestroyWindowWayland, _glfwDestroyWindowWayland,
_glfwSetWindowTitleWayland, _glfwSetWindowTitleWayland,
_glfwSetWindowIconWayland, _glfwSetWindowIconWayland,
_glfwSetWindowTaskbarProgressWayland,
_glfwGetWindowPosWayland, _glfwGetWindowPosWayland,
_glfwSetWindowPosWayland, _glfwSetWindowPosWayland,
_glfwGetWindowSizeWayland, _glfwGetWindowSizeWayland,

View File

@ -446,6 +446,7 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, const _GLFWwndconfig* wnd
void _glfwDestroyWindowWayland(_GLFWwindow* window); void _glfwDestroyWindowWayland(_GLFWwindow* window);
void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title); void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconWayland(_GLFWwindow* window, int count, const GLFWimage* images); void _glfwSetWindowIconWayland(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowTaskbarProgressWayland(_GLFWwindow* window, const int taskbarState, int completed);
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos); void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos); void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height); void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height);

View File

@ -1885,6 +1885,12 @@ void _glfwSetWindowIconWayland(_GLFWwindow* window,
"Wayland: The platform does not support setting the window icon"); "Wayland: The platform does not support setting the window icon");
} }
void _glfwSetWindowTaskbarProgress(_GLFWwindow* window, const int progressState, int completed)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Wayland: The platform does not support setting the window taskbar progress");
}
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos) void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos)
{ {
// A Wayland client is not aware of its position, so just warn and leave it // A Wayland client is not aware of its position, so just warn and leave it

View File

@ -1207,6 +1207,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
_glfwDestroyWindowX11, _glfwDestroyWindowX11,
_glfwSetWindowTitleX11, _glfwSetWindowTitleX11,
_glfwSetWindowIconX11, _glfwSetWindowIconX11,
_glfwSetWindowTaskbarProgressX11,
_glfwGetWindowPosX11, _glfwGetWindowPosX11,
_glfwSetWindowPosX11, _glfwSetWindowPosX11,
_glfwGetWindowSizeX11, _glfwGetWindowSizeX11,

View File

@ -906,6 +906,7 @@ GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, const _GLFWwndconfig* wndconf
void _glfwDestroyWindowX11(_GLFWwindow* window); void _glfwDestroyWindowX11(_GLFWwindow* window);
void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title); void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* images); void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowTaskbarProgressX11(_GLFWwindow* window, const int taskbarState, int completed);
void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos); void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosX11(_GLFWwindow* window, int xpos, int ypos); void _glfwSetWindowPosX11(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height); void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height);

View File

@ -2091,6 +2091,11 @@ void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* imag
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
} }
void _glfwSetWindowTaskbarProgressX11(_GLFWwindow* window, const int taskbarState, int completed)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, "X11: The platform does not support setting the window taskbar progress");
}
void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos) void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos)
{ {
Window dummy; Window dummy;

View File

@ -71,7 +71,7 @@ int main(int argc, char** argv)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
GLFWwindow* window = glfwCreateWindow(600, 600, "Window Features", NULL, NULL); GLFWwindow* window = glfwCreateWindow(600, 700, "Window Features", NULL, NULL);
if (!window) if (!window)
{ {
glfwTerminate(); glfwTerminate();
@ -411,6 +411,27 @@ int main(int argc, char** argv)
nk_value_bool(nk, "Visible", glfwGetWindowAttrib(window, GLFW_VISIBLE)); nk_value_bool(nk, "Visible", glfwGetWindowAttrib(window, GLFW_VISIBLE));
nk_value_bool(nk, "Iconified", glfwGetWindowAttrib(window, GLFW_ICONIFIED)); nk_value_bool(nk, "Iconified", glfwGetWindowAttrib(window, GLFW_ICONIFIED));
nk_value_bool(nk, "Maximized", glfwGetWindowAttrib(window, GLFW_MAXIMIZED)); nk_value_bool(nk, "Maximized", glfwGetWindowAttrib(window, GLFW_MAXIMIZED));
nk_layout_row_dynamic(nk, 30, 1);
nk_label(nk, "Taskbar Progress", NK_TEXT_CENTERED);
nk_layout_row_dynamic(nk, 30, 5);
static int progress = 0;
if(nk_button_label(nk, "No progress"))
glfwSetWindowTaskbarProgress(window, GLFW_TASKBAR_PROGRESS_NOPROGRESS, progress);
if (nk_button_label(nk, "Indeterminate"))
glfwSetWindowTaskbarProgress(window, GLFW_TASKBAR_PROGRESS_INDETERMINATE, progress);
if (nk_button_label(nk, "Normal"))
glfwSetWindowTaskbarProgress(window, GLFW_TASKBAR_PROGRESS_NORMAL, progress);
if (nk_button_label(nk, "Error"))
glfwSetWindowTaskbarProgress(window, GLFW_TASKBAR_PROGRESS_ERROR, progress);
if (nk_button_label(nk, "Paused"))
glfwSetWindowTaskbarProgress(window, GLFW_TASKBAR_PROGRESS_PAUSED, progress);
nk_label(nk, "Progress: ", NK_TEXT_ALIGN_LEFT);
nk_slider_int(nk, 0, &progress, 100, 1);
} }
nk_end(nk); nk_end(nk);