From ac2429ef215f4c92e2a09f258e9e051697008b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 1 Sep 2026 11:57:28 -0700 Subject: [PATCH] Use Symbol for display widget --- data/24/disabled-10.svg | 39 -------------- data/24/disabled-20.svg | 39 -------------- data/24/disabled-30.svg | 39 -------------- data/24/disabled-40.svg | 39 -------------- data/24/disabled-50.svg | 39 -------------- data/24/disabled-60.svg | 39 -------------- data/24/disabled-70.svg | 39 -------------- data/24/disabled-80.svg | 39 -------------- data/24/disabled-90.svg | 39 -------------- data/24/disabled.svg | 39 -------------- data/24/night-light.svg | 117 +++++++++++++++++++++++++++++++--------- data/gresource.xml | 26 +-------- data/indicator.css | 45 ---------------- meson.build | 3 +- src/Indicator.vala | 21 +++----- src/Widgets/Symbol.vala | 78 +++++++++++++++++++++++++++ 16 files changed, 178 insertions(+), 502 deletions(-) delete mode 100644 data/24/disabled-10.svg delete mode 100644 data/24/disabled-20.svg delete mode 100644 data/24/disabled-30.svg delete mode 100644 data/24/disabled-40.svg delete mode 100644 data/24/disabled-50.svg delete mode 100644 data/24/disabled-60.svg delete mode 100644 data/24/disabled-70.svg delete mode 100644 data/24/disabled-80.svg delete mode 100644 data/24/disabled-90.svg delete mode 100644 data/24/disabled.svg delete mode 100644 data/indicator.css create mode 100644 src/Widgets/Symbol.vala diff --git a/data/24/disabled-10.svg b/data/24/disabled-10.svg deleted file mode 100644 index 352e816..0000000 --- a/data/24/disabled-10.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled-20.svg b/data/24/disabled-20.svg deleted file mode 100644 index 94f70e0..0000000 --- a/data/24/disabled-20.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled-30.svg b/data/24/disabled-30.svg deleted file mode 100644 index 89798fe..0000000 --- a/data/24/disabled-30.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled-40.svg b/data/24/disabled-40.svg deleted file mode 100644 index fe85a2f..0000000 --- a/data/24/disabled-40.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled-50.svg b/data/24/disabled-50.svg deleted file mode 100644 index 28f0a27..0000000 --- a/data/24/disabled-50.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled-60.svg b/data/24/disabled-60.svg deleted file mode 100644 index e14a8cb..0000000 --- a/data/24/disabled-60.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled-70.svg b/data/24/disabled-70.svg deleted file mode 100644 index cd612e0..0000000 --- a/data/24/disabled-70.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled-80.svg b/data/24/disabled-80.svg deleted file mode 100644 index 6dba7b4..0000000 --- a/data/24/disabled-80.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled-90.svg b/data/24/disabled-90.svg deleted file mode 100644 index 298b1d5..0000000 --- a/data/24/disabled-90.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/disabled.svg b/data/24/disabled.svg deleted file mode 100644 index c54b20d..0000000 --- a/data/24/disabled.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - diff --git a/data/24/night-light.svg b/data/24/night-light.svg index af4e797..27b9007 100644 --- a/data/24/night-light.svg +++ b/data/24/night-light.svg @@ -1,29 +1,94 @@ - - - - - - image/svg+xml - - - - + xmlns='http://www.w3.org/2000/svg' + xmlns:svg='http://www.w3.org/2000/svg' + xmlns:gpa='https://www.gtk.org/grappa' + gpa:version='1' + gpa:state-names='active disabled' + gpa:state='0' + id='svg4031' + width='24' + height='24'> + id='path28' + mask='url(#disabled-mask)' + class='foreground foreground-fill' + fill='url(#gpa:foreground) rgb(0,0,0)' + fill-opacity='1' + fill-rule='nonzero' + d='M 11.25 3 A 0.25 0.25 0 0 0 11 3.25 L 11 4.75 C 11 4.889, 11.112 5, 11.25 5 L 11.75 5 A 0.25 0.25 0 0 0 12 4.75 L 12 3.25 A 0.25 0.25 0 0 0 11.75 3 L 11.25 3 Z M 5.13281 5.53125 A 0.25 0.25 0 0 0 5.10742 5.5332 A 0.25 0.25 0 0 0 4.95898 5.60547 L 4.60547 5.95898 C 4.50718 6.05727, 4.50789 6.21492, 4.60547 6.3125 L 5.66602 7.37305 A 0.25 0.25 0 0 0 6.01953 7.37305 L 6.37305 7.01953 A 0.25 0.25 0 0 0 6.37305 6.66602 L 5.3125 5.60547 A 0.25 0.25 0 0 0 5.13281 5.53125 Z M 17.8613 5.53125 A 0.25 0.25 0 0 0 17.8359 5.5332 A 0.25 0.25 0 0 0 17.6875 5.60547 L 16.627 6.66602 C 16.5287 6.7643, 16.5294 6.92195, 16.627 7.01953 L 16.9805 7.37305 A 0.25 0.25 0 0 0 17.334 7.37305 L 18.3945 6.3125 A 0.25 0.25 0 0 0 18.3945 5.95898 L 18.041 5.60547 A 0.25 0.25 0 0 0 17.8613 5.53125 Z M 11.5 7 C 8.46529 7, 6 9.46529, 6 12.5 C 6 15.5347, 8.46529 18, 11.5 18 C 14.5347 18, 17 15.5347, 17 12.5 C 17 9.46529, 14.5347 7, 11.5 7 Z M 11.4004 8.0625 A 4.45391 4.45391 0 0 1 11.4023 8.0625 A 4.45391 4.45391 0 0 1 11.4863 8.0625 L 11.4922 8.0625 A 3.71159 3.71159 0 0 0 10.002 11.0293 A 3.71159 3.71159 0 0 0 13.7129 14.7441 A 3.71159 3.71159 0 0 0 15.5996 14.2227 A 4.45391 4.45391 0 1 1 11.4004 8.0625 Z M 2.25 12 A 0.25 0.25 0 0 0 2 12.25 L 2 12.75 C 2 12.889, 2.112 13, 2.25 13 L 3.75 13 A 0.25 0.25 0 0 0 4 12.75 L 4 12.25 A 0.25 0.25 0 0 0 3.75 12 L 2.25 12 Z M 19.25 12 A 0.25 0.25 0 0 0 19 12.25 L 19 12.75 C 19 12.889, 19.112 13, 19.25 13 L 20.75 13 A 0.25 0.25 0 0 0 21 12.75 L 21 12.25 A 0.25 0.25 0 0 0 20.75 12 L 19.25 12 Z M 5.83984 17.5527 A 0.25 0.25 0 0 0 5.66602 17.627 L 4.60547 18.6875 C 4.50718 18.7858, 4.50789 18.9434, 4.60547 19.041 L 4.95898 19.3945 A 0.25 0.25 0 0 0 5.3125 19.3945 L 6.37305 18.334 A 0.25 0.25 0 0 0 6.37305 17.9805 L 6.01953 17.627 A 0.25 0.25 0 0 0 5.83984 17.5527 Z M 17.1523 17.5527 A 0.25 0.25 0 0 0 16.9805 17.627 L 16.627 17.9805 C 16.5287 18.0788, 16.5294 18.2364, 16.627 18.334 L 17.6875 19.3945 A 0.25 0.25 0 0 0 18.041 19.3945 L 18.3945 19.041 A 0.25 0.25 0 0 0 18.3945 18.6875 L 17.334 17.627 A 0.25 0.25 0 0 0 17.1523 17.5527 Z M 11.25 20 A 0.25 0.25 0 0 0 11 20.25 L 11 21.75 C 11 21.889, 11.112 22, 11.25 22 L 11.75 22 A 0.25 0.25 0 0 0 12 21.75 L 12 20.25 A 0.25 0.25 0 0 0 11.75 20 L 11.25 20 Z' + gpa:animation-repeat='0' + gpa:animation-segment='0'> + + + + + + + + + + + diff --git a/data/gresource.xml b/data/gresource.xml index 49f4d70..ba4de5b 100644 --- a/data/gresource.xml +++ b/data/gresource.xml @@ -1,33 +1,9 @@ - indicator.css + 24/night-light.svg - 24/disabled-10.svg - 24/disabled-20.svg - 24/disabled-30.svg - 24/disabled-40.svg - 24/disabled-50.svg - 24/disabled-60.svg - 24/disabled-70.svg - 24/disabled-80.svg - 24/disabled-90.svg - 24/disabled.svg - 24/night-light.svg - - 24/disabled-10.svg - 24/disabled-20.svg - 24/disabled-30.svg - 24/disabled-40.svg - 24/disabled-50.svg - 24/disabled-60.svg - 24/disabled-70.svg - 24/disabled-80.svg - 24/disabled-90.svg - 24/disabled.svg - 24/night-light.svg - 48/disabled.svg 48/night-light.svg diff --git a/data/indicator.css b/data/indicator.css deleted file mode 100644 index 842080a..0000000 --- a/data/indicator.css +++ /dev/null @@ -1,45 +0,0 @@ -/* -* Copyright (c) 2018 elementary LLC. (https://elementary.io) -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public -* License as published by the Free Software Foundation; either -* version 2 of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public -* License along with this program; if not, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA. -*/ - -.night-light-icon { - animation: none; - min-width: 24px; - opacity: 1; - transition: none; - -gtk-icon-source: -gtk-icontheme("indicator-night-light-symbolic"); -} - -.night-light-icon.disabled { - animation: night-light-disabled 160ms cubic-bezier(0.4, 0.0, 0.2, 1); - -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-symbolic"); -} - -@keyframes night-light-disabled { - 0% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-symbolic"); } - 10% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-10-symbolic"); } - 20% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-20-symbolic"); } - 30% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-30-symbolic"); } - 40% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-40-symbolic"); } - 50% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-50-symbolic"); } - 60% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-60-symbolic"); } - 70% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-70-symbolic"); } - 80% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-80-symbolic"); } - 90% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-90-symbolic"); } - 100% { -gtk-icon-source: -gtk-icontheme("indicator-night-light-disabled-symbolic"); } -} diff --git a/meson.build b/meson.build index 02bb74b..1e6e6d1 100644 --- a/meson.build +++ b/meson.build @@ -38,13 +38,14 @@ shared_module( 'src/Indicator.vala', 'src/Services/ColorInterface.vala', 'src/Widgets/PopoverWidget.vala', + 'src/Widgets/Symbol.vala', gresource, config_file, dependencies: [ dependency('glib-2.0'), dependency('gobject-2.0'), dependency('granite-7'), - dependency('gtk4'), + dependency('gtk4', version: '>= 4.22'), wingpanel_dep ], install: true, diff --git a/src/Indicator.vala b/src/Indicator.vala index f3751ab..bb14c57 100644 --- a/src/Indicator.vala +++ b/src/Indicator.vala @@ -18,15 +18,15 @@ */ public class Nightlight.Indicator : Wingpanel.Indicator { - private Gtk.Spinner? indicator_icon = null; + private NightlightIndicator.Symbol? indicator_icon = null; private Nightlight.Widgets.PopoverWidget? popover_widget = null; public bool nightlight_state { set { if (value) { - indicator_icon.remove_css_class ("disabled"); + indicator_icon.state = NightlightIndicator.SymbolState.ACTIVE; } else { - indicator_icon.add_css_class ("disabled"); + indicator_icon.state = NightlightIndicator.SymbolState.DISABLED; } } } @@ -40,24 +40,15 @@ public class Nightlight.Indicator : Wingpanel.Indicator { public override Gtk.Widget get_display_widget () { if (indicator_icon == null) { - indicator_icon = new Gtk.Spinner (); + indicator_icon = new NightlightIndicator.Symbol ("/io/elementary/wingpanel/nightlight/24/night-light.svg") { + pixel_size = 24 + }; // Prevent a race that skips automatic resource loading // https://github.com/elementary/wingpanel-indicator-bluetooth/issues/203 unowned var default_theme = Gtk.IconTheme.get_for_display (Gdk.Display.get_default ()); default_theme.add_resource_path ("/org/elementary/wingpanel/icons"); - var provider = new Gtk.CssProvider (); - provider.load_from_resource ("io/elementary/wingpanel/nightlight/indicator.css"); - - Gtk.StyleContext.add_provider_for_display ( - Gdk.Display.get_default (), - provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION - ); - - indicator_icon.add_css_class ("night-light-icon"); - var click_gesture = new Gtk.GestureClick () { button = Gdk.BUTTON_MIDDLE }; diff --git a/src/Widgets/Symbol.vala b/src/Widgets/Symbol.vala new file mode 100644 index 0000000..9e2ba05 --- /dev/null +++ b/src/Widgets/Symbol.vala @@ -0,0 +1,78 @@ +/* +* SPDX-License-Identifier: LGPL-2.1-or-later +* SPDX-FileCopyrightText: 2026 elementary, Inc. (https://elementary.io) +*/ + +namespace NightlightIndicator.SymbolState { + // The default state + public const string NORMAL = "normal"; + // Disabled state represented by a slash + public const string DISABLED = "disabled"; + // e.g. paired, connected, needs attention + public const string ACTIVE = "active"; +} + +public class NightlightIndicator.Symbol : Granite.Bin { + public string resource_path { get; construct; } + + public int pixel_size { + get { return image.pixel_size; } + set { image.pixel_size = value; } + } + + public uint state_index { + get { return svg.state; } + set { + uint length = -1; + svg.get_state_names (out length); + + if (value > length - 1) { + warning ("Granite.Symbol set to undefined state. Ignoring."); + return; + } + + svg.state = value; + notify_property ("state"); + } + } + + public string state { + get { + uint length = -1; + return svg.get_state_names (out length)[state_index]; + } + set { + uint length = -1; + var names = svg.get_state_names (out length); + + for (int i = 0; i < length; i++) { + if (names[i] == value) { + state_index = i; + return; + } + } + + warning ("Granite.Symbol set to undefined state. Ignoring."); + } + } + + private Gtk.Image image; + private Gtk.Svg svg; + + public Symbol (string resource_path) { + Object (resource_path: resource_path); + } + + construct { + svg = new Gtk.Svg.from_resource (resource_path); + + image = new Gtk.Image.from_paintable (svg); + + child = image; + + child.realize.connect (() => { + svg.set_frame_clock (get_frame_clock ()); + svg.play (); + }); + } +}