Add system theme support for Emscripten

This commit is contained in:
Semphris
2024-12-04 21:45:58 -05:00
committed by Sam Lantinga
parent 3060105cfa
commit 7ddda4fe18

View File

@@ -55,6 +55,77 @@ static void Emscripten_DeleteDevice(SDL_VideoDevice *device)
SDL_free(device);
}
static SDL_SystemTheme Emscripten_GetSystemTheme(void)
{
/* Technically, light theme can mean explicit light theme or no preference.
https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme#syntax */
int theme_code = EM_ASM_INT({
if (!window.matchMedia) {
return -1;
}
if (window.matchMedia('(prefers-color-scheme: light)').matches) {
return 0;
}
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 1;
}
return -1;
});
switch (theme_code) {
case 0:
return SDL_SYSTEM_THEME_LIGHT;
case 1:
return SDL_SYSTEM_THEME_DARK;
default:
return SDL_SYSTEM_THEME_UNKNOWN;
}
}
static void Emscripten_ListenSystemTheme(void)
{
MAIN_THREAD_EM_ASM({
if (window.matchMedia) {
if (typeof(Module['SDL3']) === 'undefined') {
Module['SDL3'] = {};
}
var SDL3 = Module['SDL3'];
SDL3.eventHandlerThemeChanged = function(event) {
_Emscripten_SendSystemThemeChangedEvent();
};
SDL3.themeChangedMatchMedia = window.matchMedia('(prefers-color-scheme: dark)');
SDL3.themeChangedMatchMedia.addEventListener('change', SDL3.eventHandlerThemeChanged);
}
});
}
static void Emscripten_UnlistenSystemTheme(void)
{
MAIN_THREAD_EM_ASM({
if (typeof(Module['SDL3']) !== 'undefined') {
var SDL3 = Module['SDL3'];
SDL3.themeChangedMatchMedia.removeEventListener('change', SDL3.eventHandlerThemeChanged);
SDL3.themeChangedMatchMedia = undefined;
SDL3.eventHandlerThemeChanged = undefined;
}
});
}
EMSCRIPTEN_KEEPALIVE void Emscripten_SendSystemThemeChangedEvent(void)
{
SDL_SetSystemTheme(Emscripten_GetSystemTheme());
}
static SDL_VideoDevice *Emscripten_CreateDevice(void)
{
SDL_VideoDevice *device;
@@ -111,6 +182,9 @@ static SDL_VideoDevice *Emscripten_CreateDevice(void)
device->free = Emscripten_DeleteDevice;
Emscripten_ListenSystemTheme();
device->system_theme = Emscripten_GetSystemTheme();
return device;
}
@@ -153,6 +227,7 @@ static bool Emscripten_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *
static void Emscripten_VideoQuit(SDL_VideoDevice *_this)
{
Emscripten_QuitMouse();
Emscripten_UnlistenSystemTheme();
}
static bool Emscripten_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)