diff --git a/src/scripting/scripted_widget_bindings.cpp b/src/scripting/scripted_widget_bindings.cpp index 91c88d0f4..f08d514fd 100644 --- a/src/scripting/scripted_widget_bindings.cpp +++ b/src/scripting/scripted_widget_bindings.cpp @@ -4,6 +4,7 @@ #include "lualib.h" #include "shell/bar/widgets/scripted_widget.h" +#include #include namespace { @@ -17,6 +18,13 @@ namespace { return w; } + std::string_view optionalStringArg(lua_State* L, int index) { + if (lua_gettop(L) < index || lua_isnil(L, index)) { + return {}; + } + return luaL_checkstring(L, index); + } + int luau_setText(lua_State* L) { const char* text = luaL_checkstring(L, 1); if (auto* w = getWidget(L)) @@ -34,14 +42,14 @@ namespace { int luau_setColor(lua_State* L) { const char* role = luaL_checkstring(L, 1); if (auto* w = getWidget(L)) - w->luaSetColor(role); + w->luaSetColor(role, optionalStringArg(L, 2)); return 0; } int luau_setGlyphColor(lua_State* L) { const char* role = luaL_checkstring(L, 1); if (auto* w = getWidget(L)) - w->luaSetGlyphColor(role); + w->luaSetGlyphColor(role, optionalStringArg(L, 2)); return 0; } diff --git a/src/shell/bar/widgets/scripted_widget.cpp b/src/shell/bar/widgets/scripted_widget.cpp index 1d917d433..e4f9b65c4 100644 --- a/src/shell/bar/widgets/scripted_widget.cpp +++ b/src/shell/bar/widgets/scripted_widget.cpp @@ -45,6 +45,7 @@ namespace { ss << f.rdbuf(); return ss.str(); } + } // namespace ScriptedWidget::ScriptedWidget(std::string scriptPath, const WidgetConfig* config, FileWatcher* fileWatcher) @@ -142,18 +143,14 @@ void ScriptedWidget::doLayout(Renderer& renderer, float containerWidth, float co if (!m_flex) return; - auto textColor = m_textColorRole ? colorSpecFromRole(*m_textColorRole) - : widgetForegroundOr(colorSpecFromRole(ColorRole::OnSurface)); - m_label->setColor(textColor); + m_label->setColor(resolveScriptColor(m_textColor)); m_label->setVisible(!m_label->text().empty()); if (m_label->visible()) { m_label->measure(renderer); } if (m_glyphVisible) { - auto glyphColor = m_glyphColorRole ? colorSpecFromRole(*m_glyphColorRole) - : widgetForegroundOr(colorSpecFromRole(ColorRole::OnSurface)); - m_glyph->setColor(glyphColor); + m_glyph->setColor(resolveScriptColor(m_glyphColor)); m_glyph->measure(renderer); } @@ -189,18 +186,24 @@ void ScriptedWidget::luaSetGlyph(std::string_view name) { m_dirty |= changed; } -void ScriptedWidget::luaSetColor(std::string_view role) { - auto parsed = colorRoleFromToken(role); - if (parsed != m_textColorRole) { - m_textColorRole = parsed; +void ScriptedWidget::luaSetColor(std::string_view role, std::string_view mode) { + ScriptColorState next{.role = colorRoleFromToken(role), .mode = scriptColorModeFromToken(mode)}; + if (!next.role.has_value()) { + next.mode = ScriptColorMode::Auto; + } + if (next != m_textColor) { + m_textColor = next; m_dirty = true; } } -void ScriptedWidget::luaSetGlyphColor(std::string_view role) { - auto parsed = colorRoleFromToken(role); - if (parsed != m_glyphColorRole) { - m_glyphColorRole = parsed; +void ScriptedWidget::luaSetGlyphColor(std::string_view role, std::string_view mode) { + ScriptColorState next{.role = colorRoleFromToken(role), .mode = scriptColorModeFromToken(mode)}; + if (!next.role.has_value()) { + next.mode = ScriptColorMode::Auto; + } + if (next != m_glyphColor) { + m_glyphColor = next; m_dirty = true; } } @@ -232,6 +235,24 @@ ScriptedWidget::IpcDispatchResult ScriptedWidget::dispatchIpcEvent(std::string_v return IpcDispatchResult::Handled; } +ColorSpec ScriptedWidget::resolveScriptColor(const ScriptColorState& state) const noexcept { + if (m_widgetForeground.has_value()) { + return *m_widgetForeground; + } + const ColorSpec fallback = colorSpecFromRole(ColorRole::OnSurface); + if (!state.role.has_value()) { + return widgetForegroundOr(fallback); + } + if (state.mode == ScriptColorMode::Script || *state.role != ColorRole::OnSurface) { + return colorSpecFromRole(*state.role); + } + return widgetForegroundOr(fallback); +} + +ScriptedWidget::ScriptColorMode ScriptedWidget::scriptColorModeFromToken(std::string_view token) noexcept { + return token == "script" ? ScriptColorMode::Script : ScriptColorMode::Auto; +} + void ScriptedWidget::startUpdateTimer() { m_updateTimer.startRepeating(std::chrono::milliseconds(m_updateIntervalMs), [this] { m_dirty = false; @@ -258,8 +279,8 @@ void ScriptedWidget::teardownScriptWatch() { void ScriptedWidget::reloadScript() { m_updateTimer.stop(); m_glyphVisible = false; - m_textColorRole = std::nullopt; - m_glyphColorRole = std::nullopt; + m_textColor = {}; + m_glyphColor = {}; m_updateIntervalMs = 250; if (m_glyph) m_glyph->setVisible(false); diff --git a/src/shell/bar/widgets/scripted_widget.h b/src/shell/bar/widgets/scripted_widget.h index 4d1924336..cd4318a45 100644 --- a/src/shell/bar/widgets/scripted_widget.h +++ b/src/shell/bar/widgets/scripted_widget.h @@ -36,8 +36,8 @@ public: void luaSetText(std::string_view text); void luaSetGlyph(std::string_view name); - void luaSetColor(std::string_view role); - void luaSetGlyphColor(std::string_view role); + void luaSetColor(std::string_view role, std::string_view mode); + void luaSetGlyphColor(std::string_view role, std::string_view mode); void luaSetVisible(bool visible); void luaSetUpdateInterval(float ms); [[nodiscard]] IpcDispatchResult dispatchIpcEvent(std::string_view event, std::string_view payload); @@ -46,9 +46,24 @@ public: [[nodiscard]] const std::unordered_map& settings() const { return m_settings; } private: + enum class ScriptColorMode { + Auto, + Script, + }; + + struct ScriptColorState { + std::optional role; + ScriptColorMode mode = ScriptColorMode::Auto; + + bool operator==(const ScriptColorState&) const = default; + }; + void doLayout(Renderer& renderer, float containerWidth, float containerHeight) override; void doUpdate(Renderer& renderer) override; + [[nodiscard]] ColorSpec resolveScriptColor(const ScriptColorState& state) const noexcept; + [[nodiscard]] static ScriptColorMode scriptColorModeFromToken(std::string_view token) noexcept; + void reloadScript(); void setupScriptWatch(); void teardownScriptWatch(); @@ -65,8 +80,8 @@ private: Flex* m_flex = nullptr; Glyph* m_glyph = nullptr; Label* m_label = nullptr; - std::optional m_textColorRole; - std::optional m_glyphColorRole; + ScriptColorState m_textColor; + ScriptColorState m_glyphColor; int m_updateIntervalMs = 250; bool m_dirty = false; bool m_isVertical = false;