From 139a45bfae511b2ab05b1f5db41e69b7ffb5f80a Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Tue, 25 Nov 2025 13:30:46 +0800 Subject: [PATCH 1/3] Add love.system.getTheme() This function returns wetever the device theme is dark theme, light theme, or unknown. --- src/modules/system/System.cpp | 14 ++++++++++++++ src/modules/system/System.h | 18 ++++++++++++++++++ src/modules/system/sdl/System.cpp | 18 ++++++++++++++++++ src/modules/system/sdl/System.h | 4 ++++ src/modules/system/wrap_System.cpp | 10 ++++++++++ 5 files changed, 64 insertions(+) diff --git a/src/modules/system/System.cpp b/src/modules/system/System.cpp index 19e763176..568d57908 100644 --- a/src/modules/system/System.cpp +++ b/src/modules/system/System.cpp @@ -89,6 +89,11 @@ bool System::getConstant(System::PowerState in, const char *&out) return powerStates.find(in, out); } +bool System::getConstant(System::SystemTheme in, const char *&out) +{ + return systemThemes.find(in, out); +} + StringMap::Entry System::powerEntries[] = { {"unknown", System::POWER_UNKNOWN}, @@ -100,5 +105,14 @@ StringMap::Entry System::powerEntrie StringMap System::powerStates(System::powerEntries, sizeof(System::powerEntries)); +StringMap::Entry System::systemThemeEntries[] = +{ + {"unknown", System::THEME_UNKNOWN}, + {"light", System::THEME_LIGHT}, + {"dark", System::THEME_DARK} +}; + +StringMap System::systemThemes(System::systemThemeEntries, sizeof(System::systemThemeEntries)); + } // system } // love diff --git a/src/modules/system/System.h b/src/modules/system/System.h index 143fe8969..bb3a37b18 100644 --- a/src/modules/system/System.h +++ b/src/modules/system/System.h @@ -48,6 +48,14 @@ public: POWER_MAX_ENUM }; + enum SystemTheme + { + THEME_UNKNOWN, + THEME_LIGHT, + THEME_DARK, + THEME_MAX_ENUM + }; + System(const char *name); virtual ~System() {} @@ -91,6 +99,13 @@ public: **/ virtual PowerState getPowerInfo(int &seconds, int &percent) const = 0; + /** + * Get information about the system theme. + * + * @return System theme, which can be either light, dark, or unknown. + **/ + virtual SystemTheme getTheme() const = 0; + /** * Opens the specified URL with the user's default program to handle that * particular URL type. @@ -131,11 +146,14 @@ public: static bool getConstant(const char *in, PowerState &out); static bool getConstant(PowerState in, const char *&out); + static bool getConstant(SystemTheme in, const char *&out); private: static StringMap::Entry powerEntries[]; static StringMap powerStates; + static StringMap::Entry systemThemeEntries[]; + static StringMap systemThemes; }; // System diff --git a/src/modules/system/sdl/System.cpp b/src/modules/system/sdl/System.cpp index be5fde78c..f8f8d6f55 100644 --- a/src/modules/system/sdl/System.cpp +++ b/src/modules/system/sdl/System.cpp @@ -93,6 +93,15 @@ love::system::System::PowerState System::getPowerInfo(int &seconds, int &percent return state; } +System::SystemTheme System::getTheme() const +{ + SDL_SystemTheme sdlstate = SDL_GetSystemTheme(); + SystemTheme state = THEME_UNKNOWN; + systemThemes.find(sdlstate, state); + + return state; +} + bool System::openURL(const std::string &url) const { return SDL_OpenURL(url.c_str()); @@ -128,6 +137,15 @@ EnumMap::Entry Syste EnumMap System::powerStates(System::powerEntries, sizeof(System::powerEntries)); +EnumMap::Entry System::systemThemeEntries[] = +{ + {System::THEME_UNKNOWN, SDL_SYSTEM_THEME_UNKNOWN}, + {System::THEME_LIGHT, SDL_SYSTEM_THEME_LIGHT}, + {System::THEME_DARK, SDL_SYSTEM_THEME_DARK}, +}; + +EnumMap System::systemThemes(System::systemThemeEntries, sizeof(System::systemThemeEntries)); + } // sdl } // system } // love diff --git a/src/modules/system/sdl/System.h b/src/modules/system/sdl/System.h index a296d1111..092063876 100644 --- a/src/modules/system/sdl/System.h +++ b/src/modules/system/sdl/System.h @@ -27,6 +27,7 @@ // SDL #include +#include namespace love { @@ -49,6 +50,7 @@ public: std::string getClipboardText() const override; PowerState getPowerInfo(int &seconds, int &percent) const override; + SystemTheme getTheme() const override; bool openURL(const std::string &url) const override; std::vector getPreferredLocales() const override; @@ -58,6 +60,8 @@ private: static EnumMap::Entry powerEntries[]; static EnumMap powerStates; + static EnumMap::Entry systemThemeEntries[]; + static EnumMap systemThemes; }; // System diff --git a/src/modules/system/wrap_System.cpp b/src/modules/system/wrap_System.cpp index 4fcdf1389..2c341c9ca 100644 --- a/src/modules/system/wrap_System.cpp +++ b/src/modules/system/wrap_System.cpp @@ -87,6 +87,15 @@ int w_getPowerInfo(lua_State *L) return 3; } +int w_getTheme(lua_State *L) +{ + System::SystemTheme theme = instance()->getTheme(); + const char *str = "unknown"; + System::getConstant(theme, str); + lua_pushstring(L, str); + return 1; +} + int w_openURL(lua_State *L) { std::string url = luax_checkstring(L, 1); @@ -131,6 +140,7 @@ static const luaL_Reg functions[] = { "setClipboardText", w_setClipboardText }, { "getClipboardText", w_getClipboardText }, { "getPowerInfo", w_getPowerInfo }, + { "getTheme", w_getTheme }, { "openURL", w_openURL }, { "vibrate", w_vibrate }, { "hasBackgroundMusic", w_hasBackgroundMusic }, From c4d30081f498bb9fde9c2f55573a64563fcebd4a Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Tue, 25 Nov 2025 15:29:24 +0800 Subject: [PATCH 2/3] Move `love.system.getTheme()` to `love.window.getSystemTheme()`. Despite its name, `SDL_GetSystemTheme()` needs the video subsystem to properly function. So, put it in love.window instead. --- src/modules/system/System.cpp | 14 -------------- src/modules/system/System.h | 18 ------------------ src/modules/system/sdl/System.cpp | 18 ------------------ src/modules/system/sdl/System.h | 4 ---- src/modules/system/wrap_System.cpp | 10 ---------- src/modules/window/Window.cpp | 9 +++++++++ src/modules/window/Window.h | 16 ++++++++++++++++ src/modules/window/sdl/Window.cpp | 19 +++++++++++++++++++ src/modules/window/sdl/Window.h | 6 ++++++ src/modules/window/wrap_Window.cpp | 10 ++++++++++ 10 files changed, 60 insertions(+), 64 deletions(-) diff --git a/src/modules/system/System.cpp b/src/modules/system/System.cpp index 568d57908..19e763176 100644 --- a/src/modules/system/System.cpp +++ b/src/modules/system/System.cpp @@ -89,11 +89,6 @@ bool System::getConstant(System::PowerState in, const char *&out) return powerStates.find(in, out); } -bool System::getConstant(System::SystemTheme in, const char *&out) -{ - return systemThemes.find(in, out); -} - StringMap::Entry System::powerEntries[] = { {"unknown", System::POWER_UNKNOWN}, @@ -105,14 +100,5 @@ StringMap::Entry System::powerEntrie StringMap System::powerStates(System::powerEntries, sizeof(System::powerEntries)); -StringMap::Entry System::systemThemeEntries[] = -{ - {"unknown", System::THEME_UNKNOWN}, - {"light", System::THEME_LIGHT}, - {"dark", System::THEME_DARK} -}; - -StringMap System::systemThemes(System::systemThemeEntries, sizeof(System::systemThemeEntries)); - } // system } // love diff --git a/src/modules/system/System.h b/src/modules/system/System.h index bb3a37b18..143fe8969 100644 --- a/src/modules/system/System.h +++ b/src/modules/system/System.h @@ -48,14 +48,6 @@ public: POWER_MAX_ENUM }; - enum SystemTheme - { - THEME_UNKNOWN, - THEME_LIGHT, - THEME_DARK, - THEME_MAX_ENUM - }; - System(const char *name); virtual ~System() {} @@ -99,13 +91,6 @@ public: **/ virtual PowerState getPowerInfo(int &seconds, int &percent) const = 0; - /** - * Get information about the system theme. - * - * @return System theme, which can be either light, dark, or unknown. - **/ - virtual SystemTheme getTheme() const = 0; - /** * Opens the specified URL with the user's default program to handle that * particular URL type. @@ -146,14 +131,11 @@ public: static bool getConstant(const char *in, PowerState &out); static bool getConstant(PowerState in, const char *&out); - static bool getConstant(SystemTheme in, const char *&out); private: static StringMap::Entry powerEntries[]; static StringMap powerStates; - static StringMap::Entry systemThemeEntries[]; - static StringMap systemThemes; }; // System diff --git a/src/modules/system/sdl/System.cpp b/src/modules/system/sdl/System.cpp index f8f8d6f55..be5fde78c 100644 --- a/src/modules/system/sdl/System.cpp +++ b/src/modules/system/sdl/System.cpp @@ -93,15 +93,6 @@ love::system::System::PowerState System::getPowerInfo(int &seconds, int &percent return state; } -System::SystemTheme System::getTheme() const -{ - SDL_SystemTheme sdlstate = SDL_GetSystemTheme(); - SystemTheme state = THEME_UNKNOWN; - systemThemes.find(sdlstate, state); - - return state; -} - bool System::openURL(const std::string &url) const { return SDL_OpenURL(url.c_str()); @@ -137,15 +128,6 @@ EnumMap::Entry Syste EnumMap System::powerStates(System::powerEntries, sizeof(System::powerEntries)); -EnumMap::Entry System::systemThemeEntries[] = -{ - {System::THEME_UNKNOWN, SDL_SYSTEM_THEME_UNKNOWN}, - {System::THEME_LIGHT, SDL_SYSTEM_THEME_LIGHT}, - {System::THEME_DARK, SDL_SYSTEM_THEME_DARK}, -}; - -EnumMap System::systemThemes(System::systemThemeEntries, sizeof(System::systemThemeEntries)); - } // sdl } // system } // love diff --git a/src/modules/system/sdl/System.h b/src/modules/system/sdl/System.h index 092063876..a296d1111 100644 --- a/src/modules/system/sdl/System.h +++ b/src/modules/system/sdl/System.h @@ -27,7 +27,6 @@ // SDL #include -#include namespace love { @@ -50,7 +49,6 @@ public: std::string getClipboardText() const override; PowerState getPowerInfo(int &seconds, int &percent) const override; - SystemTheme getTheme() const override; bool openURL(const std::string &url) const override; std::vector getPreferredLocales() const override; @@ -60,8 +58,6 @@ private: static EnumMap::Entry powerEntries[]; static EnumMap powerStates; - static EnumMap::Entry systemThemeEntries[]; - static EnumMap systemThemes; }; // System diff --git a/src/modules/system/wrap_System.cpp b/src/modules/system/wrap_System.cpp index 2c341c9ca..4fcdf1389 100644 --- a/src/modules/system/wrap_System.cpp +++ b/src/modules/system/wrap_System.cpp @@ -87,15 +87,6 @@ int w_getPowerInfo(lua_State *L) return 3; } -int w_getTheme(lua_State *L) -{ - System::SystemTheme theme = instance()->getTheme(); - const char *str = "unknown"; - System::getConstant(theme, str); - lua_pushstring(L, str); - return 1; -} - int w_openURL(lua_State *L) { std::string url = luax_checkstring(L, 1); @@ -140,7 +131,6 @@ static const luaL_Reg functions[] = { "setClipboardText", w_setClipboardText }, { "getClipboardText", w_getClipboardText }, { "getPowerInfo", w_getPowerInfo }, - { "getTheme", w_getTheme }, { "openURL", w_openURL }, { "vibrate", w_vibrate }, { "hasBackgroundMusic", w_hasBackgroundMusic }, diff --git a/src/modules/window/Window.cpp b/src/modules/window/Window.cpp index 15ca0ea08..57c36504c 100644 --- a/src/modules/window/Window.cpp +++ b/src/modules/window/Window.cpp @@ -112,5 +112,14 @@ STRINGMAP_CLASS_BEGIN(Window, Window::DisplayOrientation, Window::ORIENTATION_MA } STRINGMAP_CLASS_END(Window, Window::DisplayOrientation, Window::ORIENTATION_MAX_ENUM, orientation) +STRINGMAP_CLASS_BEGIN(Window, Window::SystemTheme, Window::THEME_MAX_ENUM, systemThemes) +{ + {"unknown", Window::THEME_UNKNOWN}, + {"light", Window::THEME_LIGHT}, + {"dark", Window::THEME_DARK} +}; +STRINGMAP_CLASS_END(Window, Window::SystemTheme, Window::THEME_MAX_ENUM, systemThemes) + + } // window } // love diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index 724986350..71f5e190d 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -114,6 +114,14 @@ public: ORIENTATION_MAX_ENUM }; + enum SystemTheme + { + THEME_UNKNOWN, + THEME_LIGHT, + THEME_DARK, + THEME_MAX_ENUM + }; + struct WindowSize { int width; @@ -252,11 +260,19 @@ public: virtual void requestAttention(bool continuous) = 0; + /** + * Get information about the system theme. + * + * @return System theme, which can be either light, dark, or unknown. + **/ + virtual SystemTheme getSystemTheme() const = 0; + STRINGMAP_CLASS_DECLARE(Setting); STRINGMAP_CLASS_DECLARE(FullscreenType); STRINGMAP_CLASS_DECLARE(MessageBoxType); STRINGMAP_CLASS_DECLARE(FileDialogType); STRINGMAP_CLASS_DECLARE(DisplayOrientation); + STRINGMAP_CLASS_DECLARE(SystemTheme); protected: diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 07bbb80e3..36fb75f01 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -1655,6 +1655,25 @@ void Window::requestAttention(bool continuous) // TODO: Linux? } +Window::SystemTheme Window::getSystemTheme() const +{ + SDL_SystemTheme sdlstate = SDL_GetSystemTheme(); + SystemTheme state = THEME_UNKNOWN; + systemThemes.find(sdlstate, state); + + return state; +} + +EnumMap::Entry Window::systemThemeEntries[] = +{ + {Window::THEME_UNKNOWN, SDL_SYSTEM_THEME_UNKNOWN}, + {Window::THEME_LIGHT, SDL_SYSTEM_THEME_LIGHT}, + {Window::THEME_DARK, SDL_SYSTEM_THEME_DARK}, +}; + +EnumMap Window::systemThemes(Window::systemThemeEntries, sizeof(Window::systemThemeEntries)); + + } // sdl } // window } // love diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index 5eb9bd104..66378d92a 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -24,6 +24,7 @@ // LOVE #include "window/Window.h" #include "common/config.h" +#include "common/EnumMap.h" #include "graphics/Graphics.h" // SDL @@ -133,6 +134,8 @@ public: void requestAttention(bool continuous) override; + SystemTheme getSystemTheme() const override; + void handleSDLEvent(const SDL_Event &event); private: @@ -191,6 +194,9 @@ private: Uint32 dialogEventId; + static EnumMap::Entry systemThemeEntries[]; + static EnumMap systemThemes; + }; // Window } // sdl diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index 687cbdc73..17eefff14 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -765,6 +765,15 @@ int w_getPointer(lua_State *L) return 1; } +int w_getSystemTheme(lua_State *L) +{ + Window::SystemTheme theme = instance()->getSystemTheme(); + const char *str = "unknown"; + Window::getConstant(theme, str); + lua_pushstring(L, str); + return 1; +} + static const luaL_Reg functions[] = { { "getDisplayCount", w_getDisplayCount }, @@ -809,6 +818,7 @@ static const luaL_Reg functions[] = { "showFileDialog", w_showFileDialog }, { "requestAttention", w_requestAttention }, { "getPointer", w_getPointer }, + { "getSystemTheme", w_getSystemTheme }, { 0, 0 } }; From 6eb7329a06f39781753b2c24639bffa6ee737686 Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Tue, 25 Nov 2025 15:41:42 +0800 Subject: [PATCH 3/3] Add love.themechanged() event. Called when the system theme is changed (e.g. switching from light theme to dark and vice versa). --- src/modules/event/sdl/Event.cpp | 3 +++ src/modules/love/callbacks.lua | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index fa66d3b78..2c4bb5beb 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -573,6 +573,9 @@ Message *Event::convert(const SDL_Event &e) case SDL_EVENT_LOCALE_CHANGED: msg = new Message("localechanged"); break; + case SDL_EVENT_SYSTEM_THEME_CHANGED: + msg = new Message("themechanged"); + break; case SDL_EVENT_SENSOR_UPDATE: sensorInstance = Module::getInstance(M_SENSOR); if (sensorInstance) diff --git a/src/modules/love/callbacks.lua b/src/modules/love/callbacks.lua index cfeca41c8..4ccc5824a 100644 --- a/src/modules/love/callbacks.lua +++ b/src/modules/love/callbacks.lua @@ -150,6 +150,9 @@ function love.createhandlers() sensorupdated = function (sensorType, x, y, z) if love.sensorupdated then return love.sensorupdated(sensorType, x, y, z) end end, + themechanged = function () + if love.themechanged then return love.themechanged() end + end, }, { __index = function(self, name) error("Unknown event: " .. name)