Added SDL_GetSystemTheme() to return whether the system is using a dark or light color theme, and SDL_EVENT_SYSTEM_THEME_CHANGED is sent when this changes
Fixes https://github.com/libsdl-org/SDL/issues/5334 Fixes https://github.com/libsdl-org/SDL/issues/6958 Closes https://github.com/libsdl-org/SDL/pull/6440main
parent
fb0c3197e0
commit
8994878767
|
@ -12,6 +12,9 @@ General:
|
|||
* The preprocessor symbol __IPHONEOS__ has been renamed __IOS__
|
||||
* SDL_stdinc.h no longer includes stdio.h, stdlib.h, etc., it only provides the SDL C runtime functionality
|
||||
* SDL_intrin.h now includes the intrinsics headers that were in SDL_cpuinfo.h
|
||||
* Added SDL_GetSystemTheme() to return whether the system is using a dark or light color theme, and SDL_EVENT_SYSTEM_THEME_CHANGED is sent when this changes
|
||||
* Added SDL_GetDisplays() to return a list of connected displays
|
||||
* Added SDL_GetPrimaryDisplay() to get the instance ID of the primary display
|
||||
* Added SDL_CreateSurface() and SDL_CreateSurfaceFrom() which replace SDL_CreateRGBSurface*(), and can also be used to create YUV surfaces
|
||||
* Added SDL_GetJoysticks(), SDL_GetJoystickInstanceName(), SDL_GetJoystickInstancePath(), SDL_GetJoystickInstancePlayerIndex(), SDL_GetJoystickInstanceGUID(), SDL_GetJoystickInstanceVendor(), SDL_GetJoystickInstanceProduct(), SDL_GetJoystickInstanceProductVersion(), and SDL_GetJoystickInstanceType() to directly query the list of available joysticks
|
||||
* Added SDL_GetGamepads(), SDL_GetGamepadInstanceName(), SDL_GetGamepadInstancePath(), SDL_GetGamepadInstancePlayerIndex(), SDL_GetGamepadInstanceGUID(), SDL_GetGamepadInstanceVendor(), SDL_GetGamepadInstanceProduct(), SDL_GetGamepadInstanceProductVersion(), and SDL_GetGamepadInstanceType() to directly query the list of available gamepads
|
||||
|
|
|
@ -412,6 +412,15 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
} catch(Exception ignored) {
|
||||
}
|
||||
|
||||
switch (getContext().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) {
|
||||
case Configuration.UI_MODE_NIGHT_NO:
|
||||
SDLActivity.onNativeDarkModeChanged(false);
|
||||
break;
|
||||
case Configuration.UI_MODE_NIGHT_YES:
|
||||
SDLActivity.onNativeDarkModeChanged(true);
|
||||
break;
|
||||
}
|
||||
|
||||
setContentView(mLayout);
|
||||
|
||||
setWindowStyle(false);
|
||||
|
@ -577,6 +586,15 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
mCurrentLocale = newConfig.locale;
|
||||
SDLActivity.onNativeLocaleChanged();
|
||||
}
|
||||
|
||||
switch (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) {
|
||||
case Configuration.UI_MODE_NIGHT_NO:
|
||||
SDLActivity.onNativeDarkModeChanged(false);
|
||||
break;
|
||||
case Configuration.UI_MODE_NIGHT_YES:
|
||||
SDLActivity.onNativeDarkModeChanged(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -931,6 +949,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
|||
public static native void nativeAddTouch(int touchId, String name);
|
||||
public static native void nativePermissionResult(int requestCode, boolean result);
|
||||
public static native void onNativeLocaleChanged();
|
||||
public static native void onNativeDarkModeChanged(boolean enabled);
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
|
|
|
@ -87,6 +87,8 @@ typedef enum
|
|||
|
||||
SDL_EVENT_LOCALE_CHANGED, /**< The user's locale preferences have changed. */
|
||||
|
||||
SDL_EVENT_SYSTEM_THEME_CHANGED, /**< The system theme changed */
|
||||
|
||||
/* Display events */
|
||||
/* 0x150 was SDL_DISPLAYEVENT, reserve the number for sdl2-compat */
|
||||
SDL_EVENT_DISPLAY_ORIENTATION = 0x151, /**< Display orientation has changed to data1 */
|
||||
|
|
|
@ -43,6 +43,16 @@ extern "C" {
|
|||
typedef Uint32 SDL_DisplayID;
|
||||
typedef Uint32 SDL_WindowID;
|
||||
|
||||
/**
|
||||
* \brief System theme
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDL_SYSTEM_THEME_UNKNOWN, /**< Unknown system theme */
|
||||
SDL_SYSTEM_THEME_LIGHT, /**< Light colored system theme */
|
||||
SDL_SYSTEM_THEME_DARK, /**< Dark colored system theme */
|
||||
} SDL_SystemTheme;
|
||||
|
||||
/**
|
||||
* \brief The structure that defines a display mode
|
||||
*
|
||||
|
@ -65,6 +75,18 @@ typedef struct
|
|||
void *driverdata; /**< driver-specific data, initialize to 0 */
|
||||
} SDL_DisplayMode;
|
||||
|
||||
/**
|
||||
* \brief Display orientation
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */
|
||||
SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */
|
||||
SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */
|
||||
SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */
|
||||
SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */
|
||||
} SDL_DisplayOrientation;
|
||||
|
||||
/**
|
||||
* \brief The type used to identify a window
|
||||
*
|
||||
|
@ -151,18 +173,6 @@ typedef enum
|
|||
#define SDL_WINDOWPOS_ISCENTERED(X) \
|
||||
(((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK)
|
||||
|
||||
/**
|
||||
* \brief Display orientation
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */
|
||||
SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */
|
||||
SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */
|
||||
SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */
|
||||
SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */
|
||||
} SDL_DisplayOrientation;
|
||||
|
||||
/**
|
||||
* \brief Window flash operation
|
||||
*/
|
||||
|
@ -297,6 +307,15 @@ extern DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index);
|
|||
*/
|
||||
extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void);
|
||||
|
||||
/**
|
||||
* Get the current system theme
|
||||
*
|
||||
* \returns the current system theme, light, dark, or unknown
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern DECLSPEC SDL_SystemTheme SDLCALL SDL_GetSystemTheme(void);
|
||||
|
||||
/**
|
||||
* Get a list of currently connected displays.
|
||||
*
|
||||
|
|
|
@ -124,6 +124,9 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)(
|
|||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)(
|
||||
JNIEnv *env, jclass cls);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDarkModeChanged)(
|
||||
JNIEnv *env, jclass cls, jboolean enabled);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(
|
||||
JNIEnv *env, jclass cls);
|
||||
|
||||
|
@ -183,6 +186,7 @@ static JNINativeMethod SDLActivity_tab[] = {
|
|||
{ "onNativeClipboardChanged", "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },
|
||||
{ "nativeLowMemory", "()V", SDL_JAVA_INTERFACE(nativeLowMemory) },
|
||||
{ "onNativeLocaleChanged", "()V", SDL_JAVA_INTERFACE(onNativeLocaleChanged) },
|
||||
{ "onNativeDarkModeChanged", "(Z)V", SDL_JAVA_INTERFACE(onNativeDarkModeChanged) },
|
||||
{ "nativeSendQuit", "()V", SDL_JAVA_INTERFACE(nativeSendQuit) },
|
||||
{ "nativeQuit", "()V", SDL_JAVA_INTERFACE(nativeQuit) },
|
||||
{ "nativePause", "()V", SDL_JAVA_INTERFACE(nativePause) },
|
||||
|
@ -1199,6 +1203,13 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)(
|
|||
SDL_SendAppEvent(SDL_EVENT_LOCALE_CHANGED);
|
||||
}
|
||||
|
||||
/* Dark mode */
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDarkModeChanged)(
|
||||
JNIEnv *env, jclass cls, jboolean enabled)
|
||||
{
|
||||
Android_SetDarkMode(enabled);
|
||||
}
|
||||
|
||||
/* Send Quit event to "SDLThread" thread */
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)(
|
||||
JNIEnv *env, jclass cls)
|
||||
|
|
|
@ -838,6 +838,7 @@ SDL3_0.0.0 {
|
|||
SDL_SetRenderScale;
|
||||
SDL_GetRenderScale;
|
||||
SDL_GetRenderWindowSize;
|
||||
SDL_GetSystemTheme;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
|
|
@ -865,3 +865,4 @@
|
|||
#define SDL_SetRenderScale SDL_SetRenderScale_REAL
|
||||
#define SDL_GetRenderScale SDL_GetRenderScale_REAL
|
||||
#define SDL_GetRenderWindowSize SDL_GetRenderWindowSize_REAL
|
||||
#define SDL_GetSystemTheme SDL_GetSystemTheme_REAL
|
||||
|
|
|
@ -910,3 +910,4 @@ SDL_DYNAPI_PROC(int,SDL_ConvertEventToRenderCoordinates,(SDL_Renderer *a, SDL_Ev
|
|||
SDL_DYNAPI_PROC(int,SDL_SetRenderScale,(SDL_Renderer *a, float b, float c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetRenderScale,(SDL_Renderer *a, float *b, float *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetRenderWindowSize,(SDL_Renderer *a, int *b, int *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(SDL_SystemTheme,SDL_GetSystemTheme,(void),(),return)
|
||||
|
|
|
@ -204,6 +204,8 @@ static void SDL_LogEvent(const SDL_Event *event)
|
|||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_LOCALE_CHANGED)
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_SYSTEM_THEME_CHANGED)
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_KEYMAP_CHANGED)
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_CLIPBOARD_UPDATE)
|
||||
|
@ -1346,6 +1348,11 @@ int SDL_SendLocaleChangedEvent(void)
|
|||
return SDL_SendAppEvent(SDL_EVENT_LOCALE_CHANGED);
|
||||
}
|
||||
|
||||
int SDL_SendSystemThemeChangedEvent(void)
|
||||
{
|
||||
return SDL_SendAppEvent(SDL_EVENT_SYSTEM_THEME_CHANGED);
|
||||
}
|
||||
|
||||
int SDL_InitEvents(void)
|
||||
{
|
||||
#if !SDL_JOYSTICK_DISABLED
|
||||
|
|
|
@ -44,6 +44,7 @@ extern int SDL_SendAppEvent(SDL_EventType eventType);
|
|||
extern int SDL_SendSysWMEvent(SDL_SysWMmsg *message);
|
||||
extern int SDL_SendKeymapChangedEvent(void);
|
||||
extern int SDL_SendLocaleChangedEvent(void);
|
||||
extern int SDL_SendSystemThemeChangedEvent(void);
|
||||
|
||||
extern int SDL_SendQuit(void);
|
||||
|
||||
|
|
|
@ -1438,6 +1438,21 @@ SDLTest_CommonInit(SDLTest_CommonState *state)
|
|||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static const char *SystemThemeName(void)
|
||||
{
|
||||
switch (SDL_GetSystemTheme()) {
|
||||
#define CASE(X) \
|
||||
case SDL_SYSTEM_THEME_##X: \
|
||||
return #X
|
||||
CASE(UNKNOWN);
|
||||
CASE(LIGHT);
|
||||
CASE(DARK);
|
||||
#undef CASE
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *DisplayOrientationName(int orientation)
|
||||
{
|
||||
switch (orientation) {
|
||||
|
@ -1505,6 +1520,9 @@ static const char *GamepadButtonName(const SDL_GamepadButton button)
|
|||
static void SDLTest_PrintEvent(SDL_Event *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_SYSTEM_THEME_CHANGED:
|
||||
SDL_Log("SDL EVENT: System theme changed to %s\n", SystemThemeName());
|
||||
break;
|
||||
case SDL_EVENT_DISPLAY_CONNECTED:
|
||||
SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " connected",
|
||||
event->display.displayID);
|
||||
|
|
|
@ -354,6 +354,7 @@ struct SDL_VideoDevice
|
|||
char *primary_selection_text;
|
||||
SDL_bool setting_display_mode;
|
||||
Uint32 quirk_flags;
|
||||
SDL_SystemTheme system_theme;
|
||||
|
||||
/* * * */
|
||||
/* Data used by the GL drivers */
|
||||
|
@ -476,6 +477,7 @@ extern VideoBootStrap NGAGE_bootstrap;
|
|||
extern SDL_bool SDL_OnVideoThread(void);
|
||||
extern SDL_VideoDevice *SDL_GetVideoDevice(void);
|
||||
extern SDL_bool SDL_IsVideoContextExternal(void);
|
||||
extern void SDL_SetSystemTheme(SDL_SystemTheme theme);
|
||||
extern SDL_DisplayID SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode);
|
||||
extern SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event);
|
||||
extern void SDL_DelVideoDisplay(SDL_DisplayID display, SDL_bool send_event);
|
||||
|
|
|
@ -576,14 +576,31 @@ SDL_VideoDevice *SDL_GetVideoDevice(void)
|
|||
return _this;
|
||||
}
|
||||
|
||||
SDL_bool SDL_OnVideoThread(void)
|
||||
{
|
||||
return (_this && SDL_ThreadID() == _this->thread) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_bool SDL_IsVideoContextExternal(void)
|
||||
{
|
||||
return SDL_GetHintBoolean(SDL_HINT_VIDEO_EXTERNAL_CONTEXT, SDL_FALSE);
|
||||
}
|
||||
|
||||
SDL_bool SDL_OnVideoThread(void)
|
||||
void SDL_SetSystemTheme(SDL_SystemTheme theme)
|
||||
{
|
||||
return (_this && SDL_ThreadID() == _this->thread) ? SDL_TRUE : SDL_FALSE;
|
||||
if (_this && theme != _this->system_theme) {
|
||||
_this->system_theme = theme;
|
||||
SDL_SendSystemThemeChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SystemTheme SDL_GetSystemTheme(void)
|
||||
{
|
||||
if (_this) {
|
||||
return _this->system_theme;
|
||||
} else {
|
||||
return SDL_SYSTEM_THEME_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void SDL_FinalizeDisplayMode(SDL_DisplayMode *mode)
|
||||
|
|
|
@ -65,6 +65,7 @@ static float Android_ScreenRate = 0.0f;
|
|||
SDL_sem *Android_PauseSem = NULL;
|
||||
SDL_sem *Android_ResumeSem = NULL;
|
||||
SDL_mutex *Android_ActivityMutex = NULL;
|
||||
static SDL_SystemTheme Android_SystemTheme;
|
||||
|
||||
static int Android_SuspendScreenSaver(_THIS)
|
||||
{
|
||||
|
@ -98,6 +99,7 @@ static SDL_VideoDevice *Android_CreateDevice(void)
|
|||
}
|
||||
|
||||
device->driverdata = data;
|
||||
device->system_theme = Android_SystemTheme;
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = Android_VideoInit;
|
||||
|
@ -284,4 +286,19 @@ void Android_SendResize(SDL_Window *window)
|
|||
}
|
||||
}
|
||||
|
||||
void Android_SetDarkMode(SDL_bool enabled)
|
||||
{
|
||||
SDL_VideoDevice *device = SDL_GetVideoDevice();
|
||||
|
||||
if (enabled) {
|
||||
Android_SystemTheme = SDL_SYSTEM_THEME_DARK;
|
||||
} else {
|
||||
Android_SystemTheme = SDL_SYSTEM_THEME_LIGHT;
|
||||
}
|
||||
|
||||
if (device) {
|
||||
SDL_SetSystemTheme(Android_SystemTheme);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_ANDROID */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate);
|
||||
extern void Android_SetFormat(int format_wanted, int format_got);
|
||||
extern void Android_SendResize(SDL_Window *window);
|
||||
extern void Android_SetDarkMode(SDL_bool enabled);
|
||||
|
||||
/* Private display data */
|
||||
|
||||
|
|
|
@ -129,6 +129,10 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||
|
||||
- (id)init;
|
||||
- (void)localeDidChange:(NSNotification *)notification;
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary<NSKeyValueChangeKey, id> *)change
|
||||
context:(void *)context;
|
||||
@end
|
||||
|
||||
@implementation SDLAppDelegate : NSObject
|
||||
|
@ -154,6 +158,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||
selector:@selector(localeDidChange:)
|
||||
name:NSCurrentLocaleDidChangeNotification
|
||||
object:nil];
|
||||
|
||||
[NSApp addObserver:self
|
||||
forKeyPath:@"effectiveAppearance"
|
||||
options:NSKeyValueObservingOptionInitial
|
||||
context:nil];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -166,6 +175,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||
[center removeObserver:self name:NSWindowWillCloseNotification object:nil];
|
||||
[center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
|
||||
[center removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil];
|
||||
[NSApp removeObserver:self forKeyPath:@"effectiveAppearance"];
|
||||
|
||||
/* Remove our URL event handler only if we set it */
|
||||
if ([NSApp delegate] == self) {
|
||||
|
@ -262,11 +272,19 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||
}
|
||||
}
|
||||
|
||||
- (void)localeDidChange:(NSNotification *)notification;
|
||||
- (void)localeDidChange:(NSNotification *)notification
|
||||
{
|
||||
SDL_SendLocaleChangedEvent();
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary<NSKeyValueChangeKey, id> *)change
|
||||
context:(void *)context
|
||||
{
|
||||
SDL_SetSystemTheme(Cocoa_GetSystemTheme());
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
||||
{
|
||||
return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL);
|
||||
|
|
|
@ -108,6 +108,7 @@ DECLARE_ALERT_STYLE(Critical);
|
|||
@end
|
||||
|
||||
/* Utility functions */
|
||||
extern SDL_SystemTheme Cocoa_GetSystemTheme(void);
|
||||
extern NSImage *Cocoa_CreateImage(SDL_Surface *surface);
|
||||
|
||||
/* Fix build with the 10.11 SDK */
|
||||
|
|
|
@ -75,6 +75,7 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void)
|
|||
}
|
||||
device->driverdata = (SDL_VideoData *)CFBridgingRetain(data);
|
||||
device->wakeup_lock = SDL_CreateMutex();
|
||||
device->system_theme = Cocoa_GetSystemTheme();
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = Cocoa_VideoInit;
|
||||
|
@ -220,6 +221,18 @@ void Cocoa_VideoQuit(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
/* This function assumes that it's called from within an autorelease pool */
|
||||
SDL_SystemTheme Cocoa_GetSystemTheme(void)
|
||||
{
|
||||
NSAppearance* appearance = [[NSApplication sharedApplication] effectiveAppearance];
|
||||
|
||||
if ([appearance.name containsString: @"Dark"]) {
|
||||
return SDL_SYSTEM_THEME_DARK;
|
||||
} else {
|
||||
return SDL_SYSTEM_THEME_LIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function assumes that it's called from within an autorelease pool */
|
||||
NSImage *Cocoa_CreateImage(SDL_Surface *surface)
|
||||
{
|
||||
|
|
|
@ -43,4 +43,6 @@ void UIKit_ForceUpdateHomeIndicator(void);
|
|||
|
||||
SDL_bool UIKit_IsSystemVersionAtLeast(double version);
|
||||
|
||||
SDL_SystemTheme UIKit_GetSystemTheme(void);
|
||||
|
||||
#endif /* SDL_uikitvideo_h_ */
|
||||
|
|
|
@ -74,6 +74,7 @@ static SDL_VideoDevice *UIKit_CreateDevice(void)
|
|||
}
|
||||
|
||||
device->driverdata = (SDL_VideoData *)CFBridgingRetain(data);
|
||||
device->system_theme = UIKit_GetSystemTheme();
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = UIKit_VideoInit;
|
||||
|
@ -175,14 +176,27 @@ int UIKit_SuspendScreenSaver(_THIS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
UIKit_IsSystemVersionAtLeast(double version)
|
||||
SDL_bool UIKit_IsSystemVersionAtLeast(double version)
|
||||
{
|
||||
return [[UIDevice currentDevice].systemVersion doubleValue] >= version;
|
||||
}
|
||||
|
||||
CGRect
|
||||
UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
|
||||
SDL_SystemTheme UIKit_GetSystemTheme(void)
|
||||
{
|
||||
if (@available(iOS 12.0, tvOS 10.0, *)) {
|
||||
switch ([UIScreen mainScreen].traitCollection.userInterfaceStyle) {
|
||||
case UIUserInterfaceStyleDark:
|
||||
return SDL_SYSTEM_THEME_DARK;
|
||||
case UIUserInterfaceStyleLight:
|
||||
return SDL_SYSTEM_THEME_LIGHT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SDL_SYSTEM_THEME_UNKNOWN;
|
||||
}
|
||||
|
||||
CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
|
||||
{
|
||||
SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->driverdata;
|
||||
CGRect frame = screen.bounds;
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
|
||||
- (instancetype)initWithSDLWindow:(SDL_Window *)_window;
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection;
|
||||
|
||||
- (void)setAnimationCallback:(int)interval
|
||||
callback:(void (*)(void *))callback
|
||||
callbackParam:(void *)callbackParam;
|
||||
|
|
|
@ -136,6 +136,11 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
|||
#endif
|
||||
}
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
SDL_SetSystemTheme(UIKit_GetSystemTheme());
|
||||
}
|
||||
|
||||
- (void)setAnimationCallback:(int)interval
|
||||
callback:(void (*)(void *))callback
|
||||
callbackParam:(void *)callbackParam
|
||||
|
|
|
@ -1723,6 +1723,10 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
|
||||
case WM_SETTINGCHANGE:
|
||||
if (wParam == 0 && lParam != 0 && SDL_wcscmp((wchar_t *)lParam, L"ImmersiveColorSet") == 0) {
|
||||
SDL_SetSystemTheme(WIN_GetSystemTheme());
|
||||
WIN_UpdateDarkModeForHWND(hwnd);
|
||||
}
|
||||
if (wParam == SPI_SETMOUSE || wParam == SPI_SETMOUSESPEED) {
|
||||
WIN_UpdateMouseSystemScale();
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
|
|||
}
|
||||
device->driverdata = data;
|
||||
device->wakeup_lock = SDL_CreateMutex();
|
||||
device->system_theme = WIN_GetSystemTheme();
|
||||
|
||||
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
data->userDLL = SDL_LoadObject("USER32.DLL");
|
||||
|
@ -675,8 +676,26 @@ SDL_bool SDL_DXGIGetOutputInfo(SDL_DisplayID displayID, int *adapterIndex, int *
|
|||
#endif
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
WIN_IsPerMonitorV2DPIAware(_THIS)
|
||||
SDL_SystemTheme WIN_GetSystemTheme(void)
|
||||
{
|
||||
DWORD type;
|
||||
DWORD value;
|
||||
DWORD count = sizeof(value);
|
||||
LSTATUS status;
|
||||
|
||||
/* Technically this isn't the system theme, but it's the preference for applications */
|
||||
status = RegGetValue(HKEY_CURRENT_USER,
|
||||
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"),
|
||||
TEXT("AppsUseLightTheme"),
|
||||
RRF_RT_REG_DWORD, &type, &value, &count);
|
||||
if (status == ERROR_SUCCESS && type == REG_DWORD && value == 0) {
|
||||
return SDL_SYSTEM_THEME_DARK;
|
||||
} else {
|
||||
return SDL_SYSTEM_THEME_LIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool WIN_IsPerMonitorV2DPIAware(_THIS)
|
||||
{
|
||||
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
|
|
|
@ -466,6 +466,7 @@ extern SDL_bool g_WindowFrameUsableWhileCursorHidden;
|
|||
typedef struct IDirect3D9 IDirect3D9;
|
||||
extern SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface);
|
||||
|
||||
extern SDL_SystemTheme WIN_GetSystemTheme(void);
|
||||
extern SDL_bool WIN_IsPerMonitorV2DPIAware(_THIS);
|
||||
|
||||
#endif /* SDL_windowsvideo_h_ */
|
||||
|
|
|
@ -40,6 +40,12 @@
|
|||
|
||||
#include <SDL3/SDL_syswm.h>
|
||||
|
||||
/* Dark mode support */
|
||||
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||
#endif
|
||||
typedef HRESULT (WINAPI *DwmSetWindowAttribute_t)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
|
||||
|
||||
/* Windows CE compatibility */
|
||||
#ifndef SWP_NOCOPYBITS
|
||||
#define SWP_NOCOPYBITS 0
|
||||
|
@ -511,6 +517,8 @@ int WIN_CreateWindow(_THIS, SDL_Window *window)
|
|||
return WIN_SetError("Couldn't create window");
|
||||
}
|
||||
|
||||
WIN_UpdateDarkModeForHWND(hwnd);
|
||||
|
||||
WIN_PumpEvents(_this);
|
||||
|
||||
if (SetupWindowData(_this, window, hwnd, parent, SDL_TRUE) < 0) {
|
||||
|
@ -1459,4 +1467,18 @@ int WIN_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
|
|||
}
|
||||
#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
|
||||
|
||||
void WIN_UpdateDarkModeForHWND(HWND hwnd)
|
||||
{
|
||||
void *handle = SDL_LoadObject("dwmapi.dll");
|
||||
if (handle) {
|
||||
DwmSetWindowAttribute_t DwmSetWindowAttributeFunc = (DwmSetWindowAttribute_t)SDL_LoadFunction(handle, "DwmSetWindowAttribute");
|
||||
if (DwmSetWindowAttributeFunc) {
|
||||
/* FIXME: Do we need to traverse children? */
|
||||
BOOL value = (SDL_GetSystemTheme() == SDL_SYSTEM_THEME_DARK) ? TRUE : FALSE;
|
||||
DwmSetWindowAttributeFunc(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
|
||||
}
|
||||
SDL_UnloadObject(handle);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
|
||||
|
|
|
@ -110,6 +110,7 @@ extern void WIN_ClientPointFromSDL(const SDL_Window *window, int *x, int *y);
|
|||
extern void WIN_ClientPointFromSDLFloat(const SDL_Window *window, float x, float y, LONG *xOut, LONG *yOut);
|
||||
extern void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept);
|
||||
extern int WIN_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation);
|
||||
extern void WIN_UpdateDarkModeForHWND(HWND hwnd);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue