From e00bf678efa507af9626c30c885b9c02bb1ed33b Mon Sep 17 00:00:00 2001 From: Maximiliano Sandoval R Date: Fri, 5 Aug 2022 11:11:23 +0200 Subject: [PATCH] Make mouse svg follow dark mode --- data/svgs/svg-lookup.ini | 130 +++++++++++++++++------------------ piper/mousemap.py | 27 ++++++-- piper/svg.py | 11 ++- tests/svg-lookup-ini-test.py | 3 +- 4 files changed, 96 insertions(+), 75 deletions(-) diff --git a/data/svgs/svg-lookup.ini b/data/svgs/svg-lookup.ini index 84df1b39..541049cb 100644 --- a/data/svgs/svg-lookup.ini +++ b/data/svgs/svg-lookup.ini @@ -1,259 +1,259 @@ [ASUS ROG Gladius II Origin] DeviceMatch=usb:0b05:1877 -Svg=asus-rog-gladius2-origin.svg +Svg=asus-rog-gladius2-origin [ASUS ROG Gladius II Origin PNK LTD] DeviceMatch=usb:0b05:18cd -Svg=asus-rog-gladius2-origin-pink.svg +Svg=asus-rog-gladius2-origin-pink [ASUS ROG Keris Wireless] DeviceMatch=usb:0b05:195e;usb:0b05:1960 -Svg=asus-rog-keris-wireless.svg +Svg=asus-rog-keris-wireless [ASUS ROG Strix Carry] DeviceMatch=usb:0b05:18b4 -Svg=asus-rog-strix-carry.svg +Svg=asus-rog-strix-carry [ASUS ROG Strix Impact II Wireless] DeviceMatch=usb:0b05:1949;usb:0b05:1947 -Svg=asus-rog-strix-impact2-wireless.svg +Svg=asus-rog-strix-impact2-wireless [Etekcity Scroll Alpha] DeviceMatch=usb:1ea7:4011 -Svg=fallback.svg +Svg=fallback [Logitech G102/G103] DeviceMatch=usb:046d:c084;usb:046d:c092 -Svg=logitech-g102-g203.svg +Svg=logitech-g102-g203 [Logitech G300] DeviceMatch=usb:046d:c246 -Svg=logitech-g300.svg +Svg=logitech-g300 [Logitech G302] DeviceMatch=usb:046d:c07f -Svg=logitech-g303.svg +Svg=logitech-g303 [Logitech G303] DeviceMatch=usb:046d:c080 -Svg=logitech-g303.svg +Svg=logitech-g303 [Logitech G305] DeviceMatch=usb:046d:4074 -Svg=logitech-g-pro.svg +Svg=logitech-g-pro [Logitech G402] DeviceMatch=usb:046d:c07e -Svg=logitech-g402.svg +Svg=logitech-g402 [Logitech G403] DeviceMatch=usb:046d:c083 -Svg=logitech-g403.svg +Svg=logitech-g403 [Logitech G403 Hero] DeviceMatch=usb:046d:c08f -Svg=logitech-g403.svg +Svg=logitech-g403 [Logitech G403 Wireless] DeviceMatch=usb:046d:c082;usb:046d:405d -Svg=logitech-g403.svg +Svg=logitech-g403 [Logitech G500] DeviceMatch=usb:046d:c068 -Svg=logitech-g500.svg +Svg=logitech-g500 [Logitech G500s] DeviceMatch=usb:046d:c24e -Svg=logitech-g500s.svg +Svg=logitech-g500s [Logitech G502 X Wireless] DeviceMatch=usb:046d:c098 -Svg=logitech-g502-x.svg +Svg=logitech-g502-x [Logitech G502 X] DeviceMatch=usb:046d:c099 -Svg=logitech-g502-x.svg +Svg=logitech-g502-x [Logitech G502 Hero Wireless] DeviceMatch=usb:046d:407f;usb:046d:c08d -Svg=logitech-g502.svg +Svg=logitech-g502 [Logitech G502 Hero] DeviceMatch=usb:046d:c08b -Svg=logitech-g502.svg +Svg=logitech-g502 [Logitech G502 Proteus Core] DeviceMatch=usb:046d:c07d -Svg=logitech-g502.svg +Svg=logitech-g502 [Logitech G502 Proteus Spectrum] DeviceMatch=usb:046d:c332 -Svg=logitech-g502.svg +Svg=logitech-g502 [Logitech G513 Carbon] DeviceMatch=usb:046d:c33c -Svg=logitech-g513.svg +Svg=logitech-g513 [Logitech G600] DeviceMatch=usb:046d:c24a -Svg=logitech-g600.svg +Svg=logitech-g600 [Logitech G602] DeviceMatch=usb:046d:402c -Svg=logitech-g602.svg +Svg=logitech-g602 [Logitech G603] DeviceMatch=bluetooth:046d:b01c;usb:046d:406c -Svg=logitech-g603.svg +Svg=logitech-g603 [Logitech G604] DeviceMatch=usb:046d:4085;bluetooth:046d:b024 -Svg=logitech-g604.svg +Svg=logitech-g604 [Logitech G700] DeviceMatch=usb:046d:c06b;usb:046d:c07c -Svg=logitech-g700.svg +Svg=logitech-g700 [Logitech G700s] DeviceMatch=usb:046d:c531 -Svg=logitech-g700.svg +Svg=logitech-g700 [Logitech G703] DeviceMatch=usb:046d:c087;usb:046d:4070 -Svg=logitech-g703.svg +Svg=logitech-g703 [Logitech G703 Hero] DeviceMatch=usb:046d:c090;usb:046d:4086 -Svg=logitech-g703.svg +Svg=logitech-g703 [Logitech G815] DeviceMatch=usb:046d:c33f -Svg=logitech-g815.svg +Svg=logitech-g815 [Logitech G915] DeviceMatch=usb:046d:c33e;usb:046d:c541 -Svg=logitech-g815.svg +Svg=logitech-g815 [Logitech G900] DeviceMatch=usb:046d:c081;usb:046d:4053 -Svg=logitech-g900.svg +Svg=logitech-g900 [Logitech G903] DeviceMatch=usb:046d:c086;usb:046d:4067 -Svg=logitech-g900.svg +Svg=logitech-g900 [Logitech G903 Hero] DeviceMatch=usb:046d:c091;usb:046d:4087 -Svg=logitech-g900.svg +Svg=logitech-g900 [Logitech G9] DeviceMatch=usb:046d:c048 -Svg=logitech-g9.svg +Svg=logitech-g9 [Logitech G9x] DeviceMatch=usb:046d:c066;usb:046d:c249 -Svg=logitech-g9.svg +Svg=logitech-g9 [Logitech G Pro] DeviceMatch=usb:046d:c085;usb:046d:c08c -Svg=logitech-g-pro.svg +Svg=logitech-g-pro [Logitech G Pro Wireless] DeviceMatch=usb:046d:c088;usb:046d:4079 -Svg=logitech-g-pro-wireless.svg +Svg=logitech-g-pro-wireless [Logitech G Pro X Wireless Superlight] DeviceMatch=usb:046d:4093;usb:046d:c094 -Svg=logitech-g-pro-x-wireless-superlight.svg +Svg=logitech-g-pro-x-wireless-superlight [Logitech M500s] DeviceMatch=usb:046d:c093 -Svg=logitech-m500s.svg +Svg=logitech-m500s [Logitech M720] DeviceMatch=usb:046d:405e;bluetooth:046d:b015 -Svg=logitech-m720.svg +Svg=logitech-m720 [Logitech MX518] DeviceMatch=usb:046d:c08e -Svg=logitech-mx518.svg +Svg=logitech-mx518 [Logitech MX Anywhere 3] DeviceMatch=usb:046d:c52b;bluetooth:046d:b025 -Svg=logitech-mx-anywhere3.svg +Svg=logitech-mx-anywhere3 [Logitech MX Anywhere 2] DeviceMatch=usb:046d:404a;usb:046d:4072;usb:046d:4063;bluetooth:046d:b013;bluetooth:046d:b018;bluetooth:046d:b01f -Svg=logitech-mx-anywhere2.svg +Svg=logitech-mx-anywhere2 [Logitech MX Anywhere 2S] DeviceMatch=bluetooth:046d:b01a;usb:046d:406a -Svg=logitech-mx-anywhere2.svg +Svg=logitech-mx-anywhere2 [Logitech MX Ergo] DeviceMatch=bluetooth:046d:b01d;usb:046d:406f -Svg=logitech-mx-ergo.svg +Svg=logitech-mx-ergo [Logitech MX Master 3] DeviceMatch=bluetooth:046d:b023;usb:046d:4082 -Svg=logitech-mx-master-3.svg +Svg=logitech-mx-master-3 [Logitech MX Master 2S] DeviceMatch=bluetooth:046d:b019;usb:046d:4069 -Svg=logitech-mx-master-2s.svg +Svg=logitech-mx-master-2s [Logitech MX Master] DeviceMatch=usb:046d:4041;bluetooth:046d:b012;usb:046d:4060;bluetooth:046d:b017;usb:046d:4071 -Svg=logitech-mx-master.svg +Svg=logitech-mx-master [Logitech MX Vertical] DeviceMatch=bluetooth:046d:b020;usb:046d:407b;usb:046d:c08a -Svg=logitech-mx-vertical.svg +Svg=logitech-mx-vertical [Mars Gaming MM4] DeviceMatch=usb:04d9:fa58 -Svg=marsgaming-mm4.svg +Svg=marsgaming-mm4 [Roccat Kone Pure] DeviceMatch=usb:1e7d:2dc2;usb:1e7d:2dbe -Svg=roccat-kone-pure.svg +Svg=roccat-kone-pure [Roccat Kone XTD] DeviceMatch=usb:1e7d:2e22 -Svg=roccat-kone-xtd.svg +Svg=roccat-kone-xtd [SteelSeries Kinzu V2] DeviceMatch=usb:1038:1378 -Svg=steelseries-kinzu-v2.svg +Svg=steelseries-kinzu-v2 [SteelSeries Kinzu V3] DeviceMatch=usb:1038:1388 -Svg=steelseries-kinzu-v3.svg +Svg=steelseries-kinzu-v3 [SteelSeries Rival 310] DeviceMatch=usb:1038:1720 -Svg=steelseries-rival310.svg +Svg=steelseries-rival310 [SteelSeries Rival 600] DeviceMatch=usb:1038:1724 -Svg=steelseries-rival600.svg +Svg=steelseries-rival600 [SteelSeries Rival] DeviceMatch=usb:1038:1384 -Svg=steelseries-rival.svg +Svg=steelseries-rival [SteelSeries Sensei 310] DeviceMatch=usb:1038:1722 -Svg=steelseries-sensei310.svg +Svg=steelseries-sensei310 [SteelSeries Sensei Raw] DeviceMatch=usb:1038:1369 -Svg=steelseries-senseiraw.svg +Svg=steelseries-senseiraw [SteelSeries Sensei Ten] DeviceMatch=usb:1038:1832 -Svg=steelseries-senseiten.svg +Svg=steelseries-senseiten [SN Tech T3] DeviceMatch=usb:258a:0012 -Svg=sn-tech-t3.svg +Svg=sn-tech-t3 diff --git a/piper/mousemap.py b/piper/mousemap.py index 7095dc13..4c6e9853 100644 --- a/piper/mousemap.py +++ b/piper/mousemap.py @@ -9,8 +9,9 @@ gi.require_version("Gdk", "3.0") gi.require_version("Gtk", "3.0") +gi.require_version("Handy", "1") gi.require_version("Rsvg", "2.0") -from gi.repository import Gdk, GLib, Gtk, GObject, Rsvg # noqa +from gi.repository import Gdk, GLib, Gtk, GObject, Handy, Rsvg # noqa """This module contains the MouseMap widget (and its helper class _MouseMapChild), which is central to the button and LED configuration stack @@ -89,16 +90,13 @@ def __init__(self, layer, ratbagd_device, spacing=10, *args, **kwargs): has no image registered. @raises GLib.Error when the SVG cannot be loaded. """ + if manager := Handy.StyleManager.get_default(): + manager.connect("notify::dark", self._on_dark_changed) + if layer is None: raise ValueError("Layer cannot be None") if ratbagd_device is None: raise ValueError("Device cannot be None") - try: - svg_bytes = get_svg(ratbagd_device.model) - self._handle = Rsvg.Handle.new_from_data(svg_bytes) - self._svg_data = etree.fromstring(svg_bytes) - except FileNotFoundError: - raise ValueError("Device has no image or its path is invalid") Gtk.Container.__init__(self, *args, **kwargs) self.set_has_window(False) @@ -108,6 +106,9 @@ def __init__(self, layer, ratbagd_device, spacing=10, *args, **kwargs): self._device = ratbagd_device self._children = [] self._highlight_element = None + self._ratbagd_device = ratbagd_device + + self._load_svg() # TODO: remove this when we're out of the transition to toned down SVGs device = self._handle.has_sub("#Device") @@ -404,3 +405,15 @@ def _draw_device(self, cr): for child in self._children: self._handle.render_cairo_sub(cr, id=child.svg_path) self._handle.render_cairo_sub(cr, id=child.svg_leader) + + def _on_dark_changed(self, _manager, _pspec): + self._load_svg() + self.queue_draw() + + def _load_svg(self): + try: + svg_bytes = get_svg(self._ratbagd_device.model) + self._handle = Rsvg.Handle.new_from_data(svg_bytes) + self._svg_data = etree.fromstring(svg_bytes) + except FileNotFoundError: + raise ValueError("Device has no image or its path is invalid") diff --git a/piper/svg.py b/piper/svg.py index c9f0484f..fa965ba1 100644 --- a/piper/svg.py +++ b/piper/svg.py @@ -1,6 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-or-later -from gi.repository import Gio # noqa +import gi +gi.require_version('Handy', '1') + +from gi.repository import Gio, Handy # noqa import configparser @@ -30,7 +33,11 @@ def get_svg(model): filename = config[s]['Svg'] break - resource = Gio.resources_lookup_data('/org/freedesktop/Piper/svgs/{}'.format(filename), + if manager := Handy.StyleManager.get_default(): + if manager.get_dark(): + filename += '-dark' + + resource = Gio.resources_lookup_data('/org/freedesktop/Piper/svgs/{}.svg'.format(filename), Gio.ResourceLookupFlags.NONE) return resource.get_data() diff --git a/tests/svg-lookup-ini-test.py b/tests/svg-lookup-ini-test.py index 71b8fed6..2dc72696 100755 --- a/tests/svg-lookup-ini-test.py +++ b/tests/svg-lookup-ini-test.py @@ -23,7 +23,8 @@ def test_required(self): def test_svg_filename(self): svgs = [config[s]['Svg'] for s in config.sections()] - for svg in svgs: + for filename in svgs: + svg = f'{filename}.svg' self.assertTrue(Path(svgdir, svg).exists(), msg=svg) def test_uniq_match(self):