fix(bar): let capsule foreground style neutral scripted widget colors

This commit is contained in:
Lemmy
2026-05-10 22:34:12 -04:00
parent 017ec486d8
commit 676cef81a3
3 changed files with 66 additions and 22 deletions
+10 -2
View File
@@ -4,6 +4,7 @@
#include "lualib.h" #include "lualib.h"
#include "shell/bar/widgets/scripted_widget.h" #include "shell/bar/widgets/scripted_widget.h"
#include <string_view>
#include <variant> #include <variant>
namespace { namespace {
@@ -17,6 +18,13 @@ namespace {
return w; 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) { int luau_setText(lua_State* L) {
const char* text = luaL_checkstring(L, 1); const char* text = luaL_checkstring(L, 1);
if (auto* w = getWidget(L)) if (auto* w = getWidget(L))
@@ -34,14 +42,14 @@ namespace {
int luau_setColor(lua_State* L) { int luau_setColor(lua_State* L) {
const char* role = luaL_checkstring(L, 1); const char* role = luaL_checkstring(L, 1);
if (auto* w = getWidget(L)) if (auto* w = getWidget(L))
w->luaSetColor(role); w->luaSetColor(role, optionalStringArg(L, 2));
return 0; return 0;
} }
int luau_setGlyphColor(lua_State* L) { int luau_setGlyphColor(lua_State* L) {
const char* role = luaL_checkstring(L, 1); const char* role = luaL_checkstring(L, 1);
if (auto* w = getWidget(L)) if (auto* w = getWidget(L))
w->luaSetGlyphColor(role); w->luaSetGlyphColor(role, optionalStringArg(L, 2));
return 0; return 0;
} }
+37 -16
View File
@@ -45,6 +45,7 @@ namespace {
ss << f.rdbuf(); ss << f.rdbuf();
return ss.str(); return ss.str();
} }
} // namespace } // namespace
ScriptedWidget::ScriptedWidget(std::string scriptPath, const WidgetConfig* config, FileWatcher* fileWatcher) 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) if (!m_flex)
return; return;
auto textColor = m_textColorRole ? colorSpecFromRole(*m_textColorRole) m_label->setColor(resolveScriptColor(m_textColor));
: widgetForegroundOr(colorSpecFromRole(ColorRole::OnSurface));
m_label->setColor(textColor);
m_label->setVisible(!m_label->text().empty()); m_label->setVisible(!m_label->text().empty());
if (m_label->visible()) { if (m_label->visible()) {
m_label->measure(renderer); m_label->measure(renderer);
} }
if (m_glyphVisible) { if (m_glyphVisible) {
auto glyphColor = m_glyphColorRole ? colorSpecFromRole(*m_glyphColorRole) m_glyph->setColor(resolveScriptColor(m_glyphColor));
: widgetForegroundOr(colorSpecFromRole(ColorRole::OnSurface));
m_glyph->setColor(glyphColor);
m_glyph->measure(renderer); m_glyph->measure(renderer);
} }
@@ -189,18 +186,24 @@ void ScriptedWidget::luaSetGlyph(std::string_view name) {
m_dirty |= changed; m_dirty |= changed;
} }
void ScriptedWidget::luaSetColor(std::string_view role) { void ScriptedWidget::luaSetColor(std::string_view role, std::string_view mode) {
auto parsed = colorRoleFromToken(role); ScriptColorState next{.role = colorRoleFromToken(role), .mode = scriptColorModeFromToken(mode)};
if (parsed != m_textColorRole) { if (!next.role.has_value()) {
m_textColorRole = parsed; next.mode = ScriptColorMode::Auto;
}
if (next != m_textColor) {
m_textColor = next;
m_dirty = true; m_dirty = true;
} }
} }
void ScriptedWidget::luaSetGlyphColor(std::string_view role) { void ScriptedWidget::luaSetGlyphColor(std::string_view role, std::string_view mode) {
auto parsed = colorRoleFromToken(role); ScriptColorState next{.role = colorRoleFromToken(role), .mode = scriptColorModeFromToken(mode)};
if (parsed != m_glyphColorRole) { if (!next.role.has_value()) {
m_glyphColorRole = parsed; next.mode = ScriptColorMode::Auto;
}
if (next != m_glyphColor) {
m_glyphColor = next;
m_dirty = true; m_dirty = true;
} }
} }
@@ -232,6 +235,24 @@ ScriptedWidget::IpcDispatchResult ScriptedWidget::dispatchIpcEvent(std::string_v
return IpcDispatchResult::Handled; 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() { void ScriptedWidget::startUpdateTimer() {
m_updateTimer.startRepeating(std::chrono::milliseconds(m_updateIntervalMs), [this] { m_updateTimer.startRepeating(std::chrono::milliseconds(m_updateIntervalMs), [this] {
m_dirty = false; m_dirty = false;
@@ -258,8 +279,8 @@ void ScriptedWidget::teardownScriptWatch() {
void ScriptedWidget::reloadScript() { void ScriptedWidget::reloadScript() {
m_updateTimer.stop(); m_updateTimer.stop();
m_glyphVisible = false; m_glyphVisible = false;
m_textColorRole = std::nullopt; m_textColor = {};
m_glyphColorRole = std::nullopt; m_glyphColor = {};
m_updateIntervalMs = 250; m_updateIntervalMs = 250;
if (m_glyph) if (m_glyph)
m_glyph->setVisible(false); m_glyph->setVisible(false);
+19 -4
View File
@@ -36,8 +36,8 @@ public:
void luaSetText(std::string_view text); void luaSetText(std::string_view text);
void luaSetGlyph(std::string_view name); void luaSetGlyph(std::string_view name);
void luaSetColor(std::string_view role); void luaSetColor(std::string_view role, std::string_view mode);
void luaSetGlyphColor(std::string_view role); void luaSetGlyphColor(std::string_view role, std::string_view mode);
void luaSetVisible(bool visible); void luaSetVisible(bool visible);
void luaSetUpdateInterval(float ms); void luaSetUpdateInterval(float ms);
[[nodiscard]] IpcDispatchResult dispatchIpcEvent(std::string_view event, std::string_view payload); [[nodiscard]] IpcDispatchResult dispatchIpcEvent(std::string_view event, std::string_view payload);
@@ -46,9 +46,24 @@ public:
[[nodiscard]] const std::unordered_map<std::string, WidgetSettingValue>& settings() const { return m_settings; } [[nodiscard]] const std::unordered_map<std::string, WidgetSettingValue>& settings() const { return m_settings; }
private: private:
enum class ScriptColorMode {
Auto,
Script,
};
struct ScriptColorState {
std::optional<ColorRole> role;
ScriptColorMode mode = ScriptColorMode::Auto;
bool operator==(const ScriptColorState&) const = default;
};
void doLayout(Renderer& renderer, float containerWidth, float containerHeight) override; void doLayout(Renderer& renderer, float containerWidth, float containerHeight) override;
void doUpdate(Renderer& renderer) 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 reloadScript();
void setupScriptWatch(); void setupScriptWatch();
void teardownScriptWatch(); void teardownScriptWatch();
@@ -65,8 +80,8 @@ private:
Flex* m_flex = nullptr; Flex* m_flex = nullptr;
Glyph* m_glyph = nullptr; Glyph* m_glyph = nullptr;
Label* m_label = nullptr; Label* m_label = nullptr;
std::optional<ColorRole> m_textColorRole; ScriptColorState m_textColor;
std::optional<ColorRole> m_glyphColorRole; ScriptColorState m_glyphColor;
int m_updateIntervalMs = 250; int m_updateIntervalMs = 250;
bool m_dirty = false; bool m_dirty = false;
bool m_isVertical = false; bool m_isVertical = false;