[core/theme] Fix detection of "best matching theme"

Previous code accepted the "first" hit in a theme - particularly, if a
module is called "A" and a *different* module "B" uses "A" as state, a
widget of module B with state A would be themed as *module* A, wrongly.

Essentially, made sure that the last (most specific) themeing "wins".

fixes #647
This commit is contained in:
tobi-wan-kenobi 2020-06-04 20:56:31 +02:00
parent 747e67e1be
commit cb9a60668a
2 changed files with 28 additions and 2 deletions

View file

@ -35,8 +35,7 @@ def merge_replace(value, new_value, key):
if not isinstance(value, dict): if not isinstance(value, dict):
return new_value return new_value
if isinstance(new_value, dict): if isinstance(new_value, dict):
util.algorithm.merge(value, new_value) return util.algorithm.merge(new_value, value)
return value
# right now, merging needs explicit pango support :( # right now, merging needs explicit pango support :(
if "pango" in value: if "pango" in value:
value["pango"]["full_text"] = new_value value["pango"]["full_text"] = new_value

View file

@ -4,6 +4,13 @@ import types
import core.theme import core.theme
import core.event import core.event
import core.widget import core.widget
import core.module
class TestModule(core.module.Module):
def __init__(self, widgets, config=core.config.Config([]), theme=None):
super().__init__(config, theme, widgets)
self.name = "test"
class theme(unittest.TestCase): class theme(unittest.TestCase):
@ -23,6 +30,10 @@ class theme(unittest.TestCase):
self.walTheme = {"colors": ["wal"]} self.walTheme = {"colors": ["wal"]}
self.cycleValueTheme = {"defaults": {"fg": ["red", "green", "blue"]}} self.cycleValueTheme = {"defaults": {"fg": ["red", "green", "blue"]}}
self.stateTheme = {"warning": {"fg": "yellow"}, "critical": {"fg": "red"}} self.stateTheme = {"warning": {"fg": "yellow"}, "critical": {"fg": "red"}}
self.overlayTheme = {
"load": {"prefix": "a"},
"test": {"load": {"prefix": "b"}, "prefix": "x"},
}
def test_invalid_theme(self): def test_invalid_theme(self):
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
@ -114,5 +125,21 @@ class theme(unittest.TestCase):
widget.state = types.MethodType(lambda self: ["critical"], widget) widget.state = types.MethodType(lambda self: ["critical"], widget)
self.assertEqual(self.stateTheme["critical"]["fg"], theme.get("fg", widget)) self.assertEqual(self.stateTheme["critical"]["fg"], theme.get("fg", widget))
def test_overlay(self):
widget = core.widget.Widget()
module = TestModule(widget)
theme = core.theme.Theme(raw_data=self.overlayTheme)
self.assertEqual(
self.overlayTheme[module.name]["prefix"], theme.get("prefix", widget)
)
widget.state = types.MethodType(lambda self: ["load"], widget)
self.assertEqual(
self.overlayTheme[module.name]["load"]["prefix"],
theme.get("prefix", widget),
)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4