Skip to content

Commit

Permalink
Add system theme support for Emscripten
Browse files Browse the repository at this point in the history
  • Loading branch information
Semphris authored and slouken committed Dec 6, 2024
1 parent 3060105 commit 7ddda4f
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions src/video/emscripten/SDL_emscriptenvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -111,6 +182,9 @@ static SDL_VideoDevice *Emscripten_CreateDevice(void)

device->free = Emscripten_DeleteDevice;

Emscripten_ListenSystemTheme();
device->system_theme = Emscripten_GetSystemTheme();

return device;
}

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 7ddda4f

Please sign in to comment.