Add progress bar support for Windows (#12530)

This commit is contained in:
Rémy Tassoux 2025-03-22 16:04:10 +01:00 committed by GitHub
parent 6b13d69105
commit 7a10fcdccc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 239 additions and 2 deletions

View file

@ -1979,6 +1979,7 @@ elseif(WINDOWS)
check_include_file(audioclient.h HAVE_AUDIOCLIENT_H) check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
check_include_file(sensorsapi.h HAVE_SENSORSAPI_H) check_include_file(sensorsapi.h HAVE_SENSORSAPI_H)
check_include_file(shellscalingapi.h HAVE_SHELLSCALINGAPI_H) check_include_file(shellscalingapi.h HAVE_SHELLSCALINGAPI_H)
check_include_file(shobjidl_core.h HAVE_SHOBJIDL_CORE_H)
check_c_source_compiles(" check_c_source_compiles("
#include <windows.h> #include <windows.h>
#include <mfapi.h> #include <mfapi.h>

View file

@ -15,6 +15,7 @@ if(MSVC)
set(HAVE_MMDEVICEAPI_H "1" CACHE INTERNAL "Have include mmdeviceapi.h") set(HAVE_MMDEVICEAPI_H "1" CACHE INTERNAL "Have include mmdeviceapi.h")
set(HAVE_SENSORSAPI_H "1" CACHE INTERNAL "Have include sensorsapi.h") set(HAVE_SENSORSAPI_H "1" CACHE INTERNAL "Have include sensorsapi.h")
set(HAVE_SHELLSCALINGAPI_H "1" CACHE INTERNAL "Have include shellscalingapi.h") set(HAVE_SHELLSCALINGAPI_H "1" CACHE INTERNAL "Have include shellscalingapi.h")
set(HAVE_SHOBJIDL_CORE_H "1" CACHE INTERNAL "Have include shobjidl_core.h")
set(HAVE_TPCSHRD_H "1" CACHE INTERNAL "Have include tpcshrd.h") set(HAVE_TPCSHRD_H "1" CACHE INTERNAL "Have include tpcshrd.h")
set(HAVE_WIN32_CC "1" CACHE INTERNAL "Test HAVE_WIN32_CC") set(HAVE_WIN32_CC "1" CACHE INTERNAL "Test HAVE_WIN32_CC")
set(HAVE_XINPUT_H "1" CACHE INTERNAL "Test HAVE_XINPUT_H") set(HAVE_XINPUT_H "1" CACHE INTERNAL "Test HAVE_XINPUT_H")

View file

@ -87,6 +87,8 @@ typedef struct
const char *window_icon; const char *window_icon;
SDL_WindowFlags window_flags; SDL_WindowFlags window_flags;
bool flash_on_focus_loss; bool flash_on_focus_loss;
SDL_ProgressState progress_state;
float progress_value;
int window_x; int window_x;
int window_y; int window_y;
int window_w; int window_w;

View file

@ -307,6 +307,20 @@ typedef enum SDL_FlashOperation
SDL_FLASH_UNTIL_FOCUSED /**< Flash the window until it gets focus */ SDL_FLASH_UNTIL_FOCUSED /**< Flash the window until it gets focus */
} SDL_FlashOperation; } SDL_FlashOperation;
/**
* Window progress state
*
* \since This enum is available since SDL 3.2.8.
*/
typedef enum SDL_ProgressState
{
SDL_PROGRESS_STATE_NONE, /**< No progress bar is shown */
SDL_PROGRESS_STATE_INDETERMINATE, /**< The progress bar is shown in a indeterminate state */
SDL_PROGRESS_STATE_NORMAL, /**< The progress bar is shown in a normal state */
SDL_PROGRESS_STATE_PAUSED, /**< The progress bar is shown in a paused state */
SDL_PROGRESS_STATE_ERROR /**< The progress bar is shown in an error state */
} SDL_ProgressState;
/** /**
* An opaque handle to an OpenGL context. * An opaque handle to an OpenGL context.
* *
@ -2806,6 +2820,34 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetWindowShape(SDL_Window *window, SDL_Surf
*/ */
extern SDL_DECLSPEC bool SDLCALL SDL_FlashWindow(SDL_Window *window, SDL_FlashOperation operation); extern SDL_DECLSPEC bool SDLCALL SDL_FlashWindow(SDL_Window *window, SDL_FlashOperation operation);
/**
* Sets the state of the progress bar for the given windows taskbar icon.
*
* \param window the window whose progress state is to be modified.
* \param state the progress state.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function should only be called on the main thread.
*
* \since This function is available since SDL 3.2.8.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetWindowProgressState(SDL_Window *window, SDL_ProgressState state);
/**
* Sets the value of the progress bar for the given windows taskbar icon.
*
* \param window the window whose progress value is to be modified.
* \param value the progress value (0.0f - start, 1.0f - end).
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function should only be called on the main thread.
*
* \since This function is available since SDL 3.2.8.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetWindowProgressValue(SDL_Window *window, float value);
/** /**
* Destroy a window. * Destroy a window.
* *

View file

@ -225,6 +225,7 @@
#cmakedefine HAVE_TPCSHRD_H 1 #cmakedefine HAVE_TPCSHRD_H 1
#cmakedefine HAVE_ROAPI_H 1 #cmakedefine HAVE_ROAPI_H 1
#cmakedefine HAVE_SHELLSCALINGAPI_H 1 #cmakedefine HAVE_SHELLSCALINGAPI_H 1
#cmakedefine HAVE_SHOBJIDL_CORE_H 1
#cmakedefine USE_POSIX_SPAWN 1 #cmakedefine USE_POSIX_SPAWN 1

View file

@ -95,6 +95,9 @@ typedef unsigned int uintptr_t;
#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0603 /* Windows 8.1 SDK */ #if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0603 /* Windows 8.1 SDK */
#define HAVE_SHELLSCALINGAPI_H 1 #define HAVE_SHELLSCALINGAPI_H 1
#endif #endif
#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0601 /* Windows 7 SDK */
#define HAVE_SHOBJIDL_CORE_H 1
#endif
#define HAVE_MMDEVICEAPI_H 1 #define HAVE_MMDEVICEAPI_H 1
#define HAVE_AUDIOCLIENT_H 1 #define HAVE_AUDIOCLIENT_H 1
#define HAVE_TPCSHRD_H 1 #define HAVE_TPCSHRD_H 1

View file

@ -43,6 +43,7 @@
#define HAVE_D3D11_H 1 #define HAVE_D3D11_H 1
#define HAVE_ROAPI_H 1 #define HAVE_ROAPI_H 1
#define HAVE_SHELLSCALINGAPI_H 1 #define HAVE_SHELLSCALINGAPI_H 1
#define HAVE_SHOBJIDL_CORE_H 1
#define HAVE_MMDEVICEAPI_H 1 #define HAVE_MMDEVICEAPI_H 1
#define HAVE_AUDIOCLIENT_H 1 #define HAVE_AUDIOCLIENT_H 1
#define HAVE_TPCSHRD_H 1 #define HAVE_TPCSHRD_H 1

View file

@ -41,6 +41,7 @@
/*#define HAVE_WINDOWS_GAMING_INPUT_H 1*/ /*#define HAVE_WINDOWS_GAMING_INPUT_H 1*/
/*#define HAVE_ROAPI_H 1*/ /*#define HAVE_ROAPI_H 1*/
/*#define HAVE_SHELLSCALINGAPI_H 1*/ /*#define HAVE_SHELLSCALINGAPI_H 1*/
/*#define HAVE_SHOBJIDL_CORE_H 1*/
#define HAVE_MMDEVICEAPI_H 1 #define HAVE_MMDEVICEAPI_H 1
#define HAVE_AUDIOCLIENT_H 1 #define HAVE_AUDIOCLIENT_H 1
/*#define HAVE_TPCSHRD_H 1*/ /*#define HAVE_TPCSHRD_H 1*/

View file

@ -1242,6 +1242,8 @@ SDL3_0.0.0 {
SDL_SetGPURenderStateFragmentUniforms; SDL_SetGPURenderStateFragmentUniforms;
SDL_SetRenderGPUState; SDL_SetRenderGPUState;
SDL_DestroyGPURenderState; SDL_DestroyGPURenderState;
SDL_SetWindowProgressState;
SDL_SetWindowProgressValue;
# extra symbols go here (don't modify this line) # extra symbols go here (don't modify this line)
local: *; local: *;
}; };

View file

@ -1267,3 +1267,5 @@
#define SDL_SetGPURenderStateFragmentUniforms SDL_SetGPURenderStateFragmentUniforms_REAL #define SDL_SetGPURenderStateFragmentUniforms SDL_SetGPURenderStateFragmentUniforms_REAL
#define SDL_SetRenderGPUState SDL_SetRenderGPUState_REAL #define SDL_SetRenderGPUState SDL_SetRenderGPUState_REAL
#define SDL_DestroyGPURenderState SDL_DestroyGPURenderState_REAL #define SDL_DestroyGPURenderState SDL_DestroyGPURenderState_REAL
#define SDL_SetWindowProgressState SDL_SetWindowProgressState_REAL
#define SDL_SetWindowProgressValue SDL_SetWindowProgressValue_REAL

View file

@ -1275,3 +1275,5 @@ SDL_DYNAPI_PROC(SDL_GPURenderState*,SDL_CreateGPURenderState,(SDL_Renderer *a,SD
SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateFragmentUniforms,(SDL_GPURenderState *a,Uint32 b,const void *c,Uint32 d),(a,b,c,d),return) SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateFragmentUniforms,(SDL_GPURenderState *a,Uint32 b,const void *c,Uint32 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(bool,SDL_SetRenderGPUState,(SDL_Renderer *a,SDL_GPURenderState *b),(a,b),return) SDL_DYNAPI_PROC(bool,SDL_SetRenderGPUState,(SDL_Renderer *a,SDL_GPURenderState *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_DestroyGPURenderState,(SDL_GPURenderState *a),(a),) SDL_DYNAPI_PROC(void,SDL_DestroyGPURenderState,(SDL_GPURenderState *a),(a),)
SDL_DYNAPI_PROC(bool,SDL_SetWindowProgressState,(SDL_Window *a,SDL_ProgressState b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_SetWindowProgressValue,(SDL_Window *a,float b),(a,b),return)

View file

@ -2455,6 +2455,31 @@ SDL_AppResult SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const
} }
} }
break; break;
case SDLK_P:
if (withAlt) {
/* Ctrl-P Cycle through progress states */
SDL_Window *window = SDL_GetWindowFromEvent(event);
if (window) {
state->progress_state += 1;
if (state->progress_state > SDL_PROGRESS_STATE_ERROR) {
state->progress_state = SDL_PROGRESS_STATE_NONE;
}
SDL_SetWindowProgressState(window, state->progress_state);
}
}
else if (withControl)
{
/* Alt-P Increase progress value */
SDL_Window *window = SDL_GetWindowFromEvent(event);
if (window) {
state->progress_value += 0.1f;
if (state->progress_value > 1.f) {
state->progress_value = 0.f;
}
SDL_SetWindowProgressValue(window, state->progress_value);
}
}
break;
case SDLK_G: case SDLK_G:
if (withControl) { if (withControl) {
/* Ctrl-G toggle mouse grab */ /* Ctrl-G toggle mouse grab */

View file

@ -303,6 +303,8 @@ struct SDL_VideoDevice
void (*OnWindowEnter)(SDL_VideoDevice *_this, SDL_Window *window); void (*OnWindowEnter)(SDL_VideoDevice *_this, SDL_Window *window);
bool (*UpdateWindowShape)(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *shape); bool (*UpdateWindowShape)(SDL_VideoDevice *_this, SDL_Window *window, SDL_Surface *shape);
bool (*FlashWindow)(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation); bool (*FlashWindow)(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
bool (*SetWindowProgressState)(SDL_VideoDevice *_this, SDL_Window *window, SDL_ProgressState state);
bool (*SetWindowProgressValue)(SDL_VideoDevice *_this, SDL_Window *window, float value);
bool (*SetWindowFocusable)(SDL_VideoDevice *_this, SDL_Window *window, bool focusable); bool (*SetWindowFocusable)(SDL_VideoDevice *_this, SDL_Window *window, bool focusable);
bool (*SyncWindow)(SDL_VideoDevice *_this, SDL_Window *window); bool (*SyncWindow)(SDL_VideoDevice *_this, SDL_Window *window);

View file

@ -3921,6 +3921,30 @@ bool SDL_FlashWindow(SDL_Window *window, SDL_FlashOperation operation)
return SDL_Unsupported(); return SDL_Unsupported();
} }
bool SDL_SetWindowProgressState(SDL_Window *window, SDL_ProgressState state)
{
CHECK_WINDOW_MAGIC(window, false);
CHECK_WINDOW_NOT_POPUP(window, false);
if (_this->SetWindowProgressState) {
return _this->SetWindowProgressState(_this, window, state);
}
return SDL_Unsupported();
}
bool SDL_SetWindowProgressValue(SDL_Window *window, float value)
{
CHECK_WINDOW_MAGIC(window, false);
CHECK_WINDOW_NOT_POPUP(window, false);
if (_this->SetWindowProgressValue) {
return _this->SetWindowProgressValue(_this, window, value);
}
return SDL_Unsupported();
}
void SDL_OnWindowShown(SDL_Window *window) void SDL_OnWindowShown(SDL_Window *window)
{ {
// Set window state if we have pending window flags cached // Set window state if we have pending window flags cached

View file

@ -51,6 +51,10 @@
#include "wmmsg.h" #include "wmmsg.h"
#endif #endif
#ifdef HAVE_SHOBJIDL_CORE_H
#include <shobjidl_core.h>
#endif
#ifdef SDL_PLATFORM_GDK #ifdef SDL_PLATFORM_GDK
#include "../../core/gdk/SDL_gdk.h" #include "../../core/gdk/SDL_gdk.h"
#endif #endif
@ -2431,6 +2435,12 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) #endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
} }
#ifdef HAVE_SHOBJIDL_CORE_H
if (msg == data->videodata->WM_TASKBAR_BUTTON_CREATED) {
data->videodata->taskbar_button_created = true;
}
#endif
// If there's a window proc, assume it's going to handle messages // If there's a window proc, assume it's going to handle messages
if (data->wndproc) { if (data->wndproc) {
return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam); return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);

View file

@ -36,6 +36,10 @@
#include "SDL_windowsrawinput.h" #include "SDL_windowsrawinput.h"
#include "SDL_windowsvulkan.h" #include "SDL_windowsvulkan.h"
#ifdef HAVE_SHOBJIDL_CORE_H
#include <shobjidl_core.h>
#endif
#ifdef SDL_GDK_TEXTINPUT #ifdef SDL_GDK_TEXTINPUT
#include "../gdk/SDL_gdktextinput.h" #include "../gdk/SDL_gdktextinput.h"
#endif #endif
@ -268,6 +272,8 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->SetWindowHitTest = WIN_SetWindowHitTest; device->SetWindowHitTest = WIN_SetWindowHitTest;
device->AcceptDragAndDrop = WIN_AcceptDragAndDrop; device->AcceptDragAndDrop = WIN_AcceptDragAndDrop;
device->FlashWindow = WIN_FlashWindow; device->FlashWindow = WIN_FlashWindow;
device->SetWindowProgressState = WIN_SetWindowProgressState;
device->SetWindowProgressValue = WIN_SetWindowProgressValue;
device->ShowWindowSystemMenu = WIN_ShowWindowSystemMenu; device->ShowWindowSystemMenu = WIN_ShowWindowSystemMenu;
device->SetWindowFocusable = WIN_SetWindowFocusable; device->SetWindowFocusable = WIN_SetWindowFocusable;
device->UpdateWindowShape = WIN_UpdateWindowShape; device->UpdateWindowShape = WIN_UpdateWindowShape;
@ -552,6 +558,9 @@ static bool WIN_VideoInit(SDL_VideoDevice *_this)
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
data->_SDL_WAKEUP = RegisterWindowMessageA("_SDL_WAKEUP"); data->_SDL_WAKEUP = RegisterWindowMessageA("_SDL_WAKEUP");
#endif #endif
#if defined(HAVE_SHOBJIDL_CORE_H)
data->WM_TASKBAR_BUTTON_CREATED = RegisterWindowMessageA("TaskbarButtonCreated");
#endif
return true; return true;
} }
@ -581,6 +590,14 @@ void WIN_VideoQuit(SDL_VideoDevice *_this)
} }
#endif // !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) #endif // !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
#if defined(HAVE_SHOBJIDL_CORE_H)
data->taskbar_button_created = false;
if (data->taskbar_list) {
IUnknown_Release(data->taskbar_list);
data->taskbar_list = NULL;
}
#endif
if (data->coinitialized) { if (data->coinitialized) {
WIN_CoUninitialize(); WIN_CoUninitialize();
data->coinitialized = false; data->coinitialized = false;

View file

@ -308,6 +308,8 @@ typedef enum PROCESS_DPI_AWARENESS
#include <shellscalingapi.h> #include <shellscalingapi.h>
#endif #endif
typedef struct ITaskbarList3 ITaskbarList3;
#ifndef _DPI_AWARENESS_CONTEXTS_ #ifndef _DPI_AWARENESS_CONTEXTS_
typedef enum DPI_AWARENESS typedef enum DPI_AWARENESS
@ -536,6 +538,12 @@ struct SDL_VideoData
BYTE pre_hook_key_state[256]; BYTE pre_hook_key_state[256];
UINT _SDL_WAKEUP; UINT _SDL_WAKEUP;
#ifdef HAVE_SHOBJIDL_CORE_H
UINT WM_TASKBAR_BUTTON_CREATED;
bool taskbar_button_created;
ITaskbarList3 *taskbar_list;
#endif
}; };
extern bool g_WindowsEnableMessageLoop; extern bool g_WindowsEnableMessageLoop;

View file

@ -38,6 +38,10 @@
// Dropfile support // Dropfile support
#include <shellapi.h> #include <shellapi.h>
#ifdef HAVE_SHOBJIDL_CORE_H
#include <shobjidl_core.h>
#endif
// Dark mode support // Dark mode support
typedef enum { typedef enum {
UXTHEME_APPMODE_DEFAULT, UXTHEME_APPMODE_DEFAULT,
@ -180,6 +184,33 @@ static DWORD GetWindowStyleEx(SDL_Window *window)
return style; return style;
} }
#ifdef HAVE_SHOBJIDL_CORE_H
static ITaskbarList3 *GetTaskbarList(SDL_Window* window)
{
const SDL_WindowData *data = window->internal;
if (!data->videodata->taskbar_button_created) {
WIN_SetError("Missing taskbar button");
return NULL;
}
if (!data->videodata->taskbar_list) {
HRESULT ret = CoCreateInstance(&CLSID_TaskbarList, NULL, CLSCTX_ALL, &IID_ITaskbarList3, (LPVOID *)&data->videodata->taskbar_list);
if (FAILED(ret)) {
WIN_SetError("Unable to create taskbar list");
return NULL;
}
ITaskbarList3 *taskbarlist = data->videodata->taskbar_list;
ret = taskbarlist->lpVtbl->HrInit(taskbarlist);
if (FAILED(ret)) {
taskbarlist->lpVtbl->Release(taskbarlist);
data->videodata->taskbar_list = NULL;
WIN_SetError("Unable to initialize taskbar list");
return NULL;
}
}
return data->videodata->taskbar_list;
}
#endif
/** /**
* Returns arguments to pass to SetWindowPos - the window rect, including frame, in Windows coordinates. * Returns arguments to pass to SetWindowPos - the window rect, including frame, in Windows coordinates.
* Can be called before we have a HWND. * Can be called before we have a HWND.
@ -2217,6 +2248,66 @@ bool WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperat
return true; return true;
} }
bool WIN_SetWindowProgressState(SDL_VideoDevice *_this, SDL_Window *window, SDL_ProgressState state)
{
#ifndef HAVE_SHOBJIDL_CORE_H
return false;
#else
ITaskbarList3 *taskbar_list = GetTaskbarList(window);
if (!taskbar_list) {
return false;
};
TBPFLAG tbpFlags;
switch (state) {
case SDL_PROGRESS_STATE_NONE:
tbpFlags = TBPF_NOPROGRESS;
break;
case SDL_PROGRESS_STATE_INDETERMINATE:
tbpFlags = TBPF_INDETERMINATE;
break;
case SDL_PROGRESS_STATE_NORMAL:
tbpFlags = TBPF_NORMAL;
break;
case SDL_PROGRESS_STATE_PAUSED:
tbpFlags = TBPF_PAUSED;
break;
case SDL_PROGRESS_STATE_ERROR:
tbpFlags = TBPF_ERROR;
break;
default:
return SDL_Unsupported();
}
HRESULT ret = taskbar_list->lpVtbl->SetProgressState(taskbar_list, window->internal->hwnd, tbpFlags);
if (FAILED(ret)) {
return WIN_SetErrorFromHRESULT("ITaskbarList3::SetProgressState()", ret);
}
return true;
#endif // HAVE_SHOBJIDL_CORE_H
}
bool WIN_SetWindowProgressValue(SDL_VideoDevice *_this, SDL_Window *window, float value)
{
#ifndef HAVE_SHOBJIDL_CORE_H
return false;
#else
ITaskbarList3 *taskbar_list = GetTaskbarList(window);
if (!taskbar_list) {
return false;
};
SDL_clamp(value, 0.0f, 1.f);
HRESULT ret = taskbar_list->lpVtbl->SetProgressValue(taskbar_list, window->internal->hwnd, (ULONGLONG)(value * 10000.f), 10000);
if (FAILED(ret)) {
return WIN_SetErrorFromHRESULT("ITaskbarList3::SetProgressValue()", ret);
}
return true;
#endif // HAVE_SHOBJIDL_CORE_H
}
void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y) void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y)
{ {
const SDL_WindowData *data = window->internal; const SDL_WindowData *data = window->internal;

View file

@ -133,6 +133,8 @@ extern void WIN_UnclipCursorForWindow(SDL_Window *window);
extern bool WIN_SetWindowHitTest(SDL_Window *window, bool enabled); extern bool WIN_SetWindowHitTest(SDL_Window *window, bool enabled);
extern void WIN_AcceptDragAndDrop(SDL_Window *window, bool accept); extern void WIN_AcceptDragAndDrop(SDL_Window *window, bool accept);
extern bool WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation); extern bool WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
extern bool WIN_SetWindowProgressState(SDL_VideoDevice *_this, SDL_Window *window, SDL_ProgressState state);
extern bool WIN_SetWindowProgressValue(SDL_VideoDevice *_this, SDL_Window *window, float value);
extern void WIN_UpdateDarkModeForHWND(HWND hwnd); extern void WIN_UpdateDarkModeForHWND(HWND hwnd);
extern bool WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRect rect_type); extern bool WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags, SDL_WindowRect rect_type);
extern void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y); extern void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y);