diff --git a/data/icons/gpu-vram-symbolic.svg b/data/icons/gpu-vram-symbolic.svg deleted file mode 100644 index 5b97cf1a6..000000000 --- a/data/icons/gpu-vram-symbolic.svg +++ /dev/null @@ -1,151 +0,0 @@ - -image/svg+xml diff --git a/data/icons/icons.indicator.gresource.xml b/data/icons/icons.indicator.gresource.xml index ad678d28b..15601ef1b 100644 --- a/data/icons/icons.indicator.gresource.xml +++ b/data/icons/icons.indicator.gresource.xml @@ -4,12 +4,10 @@ bug-symbolic.svg cpu-symbolic.svg gpu-symbolic.svg + network-symbolic.svg ram-symbolic.svg - gpu-vram-symbolic.svg swap-symbolic.svg file-deleted-symbolic.svg - temperature-sensor-symbolic.svg - temperature-gpu-symbolic.svg process-attention-symbolic.svg process-critical-symbolic.svg process-information-symbolic.svg diff --git a/data/icons/network-symbolic.svg b/data/icons/network-symbolic.svg new file mode 100644 index 000000000..b5f05eb73 --- /dev/null +++ b/data/icons/network-symbolic.svg @@ -0,0 +1,19 @@ + + + + diff --git a/data/icons/temperature-gpu-symbolic.svg b/data/icons/temperature-gpu-symbolic.svg deleted file mode 100644 index 138823fbe..000000000 --- a/data/icons/temperature-gpu-symbolic.svg +++ /dev/null @@ -1,49 +0,0 @@ - -image/svg+xml diff --git a/data/icons/temperature-sensor-symbolic.svg b/data/icons/temperature-sensor-symbolic.svg deleted file mode 100644 index acf316a2f..000000000 --- a/data/icons/temperature-sensor-symbolic.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - diff --git a/src/Indicator/Indicator.vala b/src/Indicator/Indicator.vala index ef8f16730..8fd7509b0 100644 --- a/src/Indicator/Indicator.vala +++ b/src/Indicator/Indicator.vala @@ -76,12 +76,27 @@ public class Monitor.Indicator : Wingpanel.Indicator { public void apply_custom_styles () throws GLib.Error { var provider = new Gtk.CssProvider (); string css = """ - .composited-indicator > revealer label.monitor-indicator-label-warning { - color: @warning_color; - } - .composited-indicator > revealer label.monitor-indicator-label-critical { - color: @error_color; - } + monitor-indicator-group { + font-size: 0.9rem; + } + + monitor-indicator-group:dir(ltr) { + margin-left: 1em; + } + + monitor-indicator-group:dir(rtl) { + margin-right: 1em; + } + + monitor-indicator-group label:dir(ltr), + monitor-indicator-group image:dir(rtl) { + margin-left: 0.5em; + } + + monitor-indicator-group label:dir(rtl), + monitor-indicator-group image:dir(ltr) { + margin-right: 0.5em; + } """; provider.load_from_string (css); diff --git a/src/Indicator/Widgets/DisplayWidget.vala b/src/Indicator/Widgets/DisplayWidget.vala index 9a8becd72..621951be5 100644 --- a/src/Indicator/Widgets/DisplayWidget.vala +++ b/src/Indicator/Widgets/DisplayWidget.vala @@ -7,42 +7,126 @@ public class Monitor.Widgets.DisplayWidget : Gtk.Box { construct { valign = Gtk.Align.CENTER; - var cpu_widget = new IndicatorWidgetPercentage ("cpu-symbolic"); - var cpu_frequency_widget = new IndicatorWidgetFrequency ("cpu-symbolic"); - var cpu_temperature_widget = new IndicatorWidgetTemperature ("temperature-sensor-symbolic"); + var cpu_widget = new IndicatorWidgetPercentage () { + tooltip_text = _("Processor usage") + }; - var memory_widget = new IndicatorWidgetPercentage ("ram-symbolic"); + var cpu_frequency_widget = new IndicatorWidgetFrequency () { + tooltip_text = _("Processor frequency") + }; - var network_up_widget = new IndicatorWidgetBandwidth ("go-up-symbolic"); - var network_down_widget = new IndicatorWidgetBandwidth ("go-down-symbolic"); + var cpu_temperature_widget = new IndicatorWidgetTemperature () { + tooltip_text = _("Processor temperature") + }; - var gpu_widget = new IndicatorWidgetPercentage ("gpu-symbolic"); - var gpu_memory_widget = new IndicatorWidgetPercentage ("gpu-vram-symbolic"); - var gpu_temperature_widget = new IndicatorWidgetTemperature ("temperature-gpu-symbolic"); + var cpu_group_widget = new IndicatorGroupWidget ("cpu-symbolic"); + cpu_group_widget.append (cpu_widget); + cpu_group_widget.append (cpu_frequency_widget); + cpu_group_widget.append (cpu_temperature_widget); + + var memory_widget = new IndicatorWidgetPercentage () { + tooltip_text = _("Memory usage") + }; + + var memory_group_widget = new IndicatorGroupWidget ("ram-symbolic"); + memory_group_widget.append (memory_widget); + + var gpu_widget = new IndicatorWidgetPercentage () { + tooltip_text = _("Graphics processor usage") + }; + + var gpu_memory_widget = new IndicatorWidgetPercentage () { + tooltip_text = _("Graphics memory usage") + }; + + var gpu_temperature_widget = new IndicatorWidgetTemperature () { + tooltip_text = _("Graphics processor temperature") + }; + + var gpu_group_widget = new IndicatorGroupWidget ("gpu-symbolic"); + gpu_group_widget.append (gpu_widget); + gpu_group_widget.append (gpu_memory_widget); + gpu_group_widget.append (gpu_temperature_widget); + + var network_up_widget = new IndicatorWidgetBandwidth () { + tooltip_text = _("Network upload speed") + }; + + var network_down_widget = new IndicatorWidgetBandwidth () { + tooltip_text = _("Network download speed") + }; + + var network_group_widget = new IndicatorGroupWidget ("network-symbolic"); + network_group_widget.append (network_up_widget); + network_group_widget.append (network_down_widget); + + append (cpu_group_widget); + append (memory_group_widget); + append (gpu_group_widget); + append (network_group_widget); unowned var dbusclient = DBusClient.get_default (); dbusclient.monitor_appeared.connect (() => { - cpu_widget.visible = Indicator.settings.get_boolean ("indicator-cpu-state"); - cpu_frequency_widget.visible = Indicator.settings.get_boolean ("indicator-cpu-frequency-state"); - cpu_temperature_widget.visible = Indicator.settings.get_boolean ("indicator-cpu-temperature-state"); - memory_widget.visible = Indicator.settings.get_boolean ("indicator-memory-state"); - network_up_widget.visible = Indicator.settings.get_boolean ("indicator-network-upload-state"); - network_down_widget.visible = Indicator.settings.get_boolean ("indicator-network-download-state"); - gpu_widget.visible = Indicator.settings.get_boolean ("indicator-gpu-state"); - gpu_memory_widget.visible = Indicator.settings.get_boolean ("indicator-gpu-memory-state"); - gpu_temperature_widget.visible = Indicator.settings.get_boolean ("indicator-gpu-temperature-state"); + cpu_widget.revealed = Indicator.settings.get_boolean ("indicator-cpu-state"); + cpu_frequency_widget.revealed = Indicator.settings.get_boolean ("indicator-cpu-frequency-state"); + cpu_temperature_widget.revealed = Indicator.settings.get_boolean ("indicator-cpu-temperature-state"); + cpu_group_widget.revealed = cpu_widget.revealed || cpu_frequency_widget.revealed || cpu_temperature_widget.revealed; + + memory_widget.revealed = Indicator.settings.get_boolean ("indicator-memory-state"); + memory_group_widget.revealed = memory_widget.revealed; + + network_up_widget.revealed = Indicator.settings.get_boolean ("indicator-network-upload-state"); + network_down_widget.revealed = Indicator.settings.get_boolean ("indicator-network-download-state"); + network_group_widget.revealed = network_up_widget.revealed || network_down_widget.revealed; + + gpu_widget.revealed = Indicator.settings.get_boolean ("indicator-gpu-state"); + gpu_memory_widget.revealed = Indicator.settings.get_boolean ("indicator-gpu-memory-state"); + gpu_temperature_widget.revealed = Indicator.settings.get_boolean ("indicator-gpu-temperature-state"); + gpu_group_widget.revealed = gpu_widget.revealed || gpu_memory_widget.revealed || gpu_temperature_widget.revealed; + }); + + dbusclient.interface.indicator_cpu_state.connect ((state) => { + cpu_widget.revealed = state; + cpu_group_widget.revealed = cpu_widget.revealed || cpu_frequency_widget.revealed || cpu_temperature_widget.revealed; + + }); + dbusclient.interface.indicator_cpu_frequency_state.connect ((state) => { + cpu_frequency_widget.revealed = state; + cpu_group_widget.revealed = cpu_widget.revealed || cpu_frequency_widget.revealed || cpu_temperature_widget.revealed; }); - dbusclient.interface.indicator_cpu_state.connect ((state) => cpu_widget.visible = state); - dbusclient.interface.indicator_cpu_frequency_state.connect ((state) => cpu_frequency_widget.visible = state); - dbusclient.interface.indicator_cpu_temperature_state.connect ((state) => cpu_temperature_widget.visible = state); - dbusclient.interface.indicator_memory_state.connect ((state) => memory_widget.visible = state); - dbusclient.interface.indicator_network_up_state.connect ((state) => network_up_widget.visible = state); - dbusclient.interface.indicator_network_down_state.connect ((state) => network_down_widget.visible = state); - dbusclient.interface.indicator_gpu_state.connect ((state) => gpu_widget.visible = state); - dbusclient.interface.indicator_gpu_memory_state.connect ((state) => gpu_memory_widget.visible = state); - dbusclient.interface.indicator_gpu_temperature_state.connect ((state) => gpu_temperature_widget.visible = state); + dbusclient.interface.indicator_cpu_temperature_state.connect ((state) => { + cpu_temperature_widget.revealed = state; + cpu_group_widget.revealed = cpu_widget.revealed || cpu_frequency_widget.revealed || cpu_temperature_widget.revealed; + }); + + dbusclient.interface.indicator_memory_state.connect ((state) => { + memory_widget.revealed = state; + memory_group_widget.revealed = memory_widget.revealed; + }); + + dbusclient.interface.indicator_gpu_state.connect ((state) => { + gpu_widget.revealed = state; + gpu_group_widget.revealed = gpu_widget.revealed || gpu_memory_widget.revealed || gpu_temperature_widget.revealed; + }); + dbusclient.interface.indicator_gpu_memory_state.connect ((state) => { + gpu_memory_widget.revealed = state; + gpu_group_widget.revealed = gpu_widget.revealed || gpu_memory_widget.revealed || gpu_temperature_widget.revealed; + }); + dbusclient.interface.indicator_gpu_temperature_state.connect ((state) => { + gpu_temperature_widget.revealed = state; + gpu_group_widget.revealed = gpu_widget.revealed || gpu_memory_widget.revealed || gpu_temperature_widget.revealed; + }); + + dbusclient.interface.indicator_network_up_state.connect ((state) => { + network_up_widget.revealed = state; + network_group_widget.revealed = network_up_widget.revealed || network_down_widget.revealed; + }); + dbusclient.interface.indicator_network_down_state.connect ((state) => { + network_down_widget.revealed = state; + network_group_widget.revealed = network_up_widget.revealed || network_down_widget.revealed; + }); dbusclient.interface.update.connect ((sysres) => { var cpu_percentage = Value (typeof (uint)); @@ -61,14 +145,6 @@ public class Monitor.Widgets.DisplayWidget : Gtk.Box { memory_percentage.set_uint (sysres.memory_percentage); memory_widget.update_label (memory_percentage); - var network_up = Value (typeof (uint64)); - network_up.set_uint64 (sysres.network_up); - network_up_widget.update_label (network_up); - - var network_down = Value (typeof (uint64)); - network_down.set_uint64 (sysres.network_down); - network_down_widget.update_label (network_down); - var gpu_percentage = Value (typeof (uint)); gpu_percentage.set_uint (sysres.gpu_percentage); gpu_widget.update_label (gpu_percentage); @@ -80,16 +156,25 @@ public class Monitor.Widgets.DisplayWidget : Gtk.Box { var gpu_temperature = Value (typeof (int)); gpu_temperature.set_int ((int) Math.round (sysres.gpu_temperature)); gpu_temperature_widget.update_label (gpu_temperature); + + var network_up = Value (typeof (uint64)); + network_up.set_uint64 (sysres.network_up); + network_up_widget.update_label (network_up); + + var network_down = Value (typeof (uint64)); + network_down.set_uint64 (sysres.network_down); + network_down_widget.update_label (network_down); + }); + } - append (cpu_widget); - append (cpu_frequency_widget); - append (cpu_temperature_widget); - append (memory_widget); - append (gpu_widget); - append (gpu_memory_widget); - append (gpu_temperature_widget); - append (network_down_widget); - append (network_up_widget); + public new void append (IndicatorGroupWidget widget) { + var revealer = new Gtk.Revealer () { + child = widget, + transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT, + }; + widget.bind_property ("revealed", revealer, "reveal-child", DEFAULT); + base.append (revealer); } + } diff --git a/src/Indicator/Widgets/IndicatorGroupWidget.vala b/src/Indicator/Widgets/IndicatorGroupWidget.vala new file mode 100644 index 000000000..9fffda77f --- /dev/null +++ b/src/Indicator/Widgets/IndicatorGroupWidget.vala @@ -0,0 +1,34 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2026 elementary, Inc. (https://elementary.io) + */ + +public class Monitor.IndicatorGroupWidget : Gtk.Box { + public string icon_name { get; construct; } + public bool revealed { get; set; } + + protected Gtk.Label label; + + public IndicatorGroupWidget (string icon_name) { + Object (icon_name: icon_name); + } + + class construct { + set_css_name ("monitor-indicator-group"); + } + + construct { + var icon = new Gtk.Image.from_icon_name (icon_name); + base.append (icon); + } + + public new void append (IndicatorWidget widget) { + var revealer = new Gtk.Revealer () { + child = widget, + transition_type = SLIDE_LEFT, + }; + widget.bind_property ("revealed", revealer, "reveal-child", DEFAULT); + + base.append (revealer); + } +} diff --git a/src/Indicator/Widgets/IndicatorWidget.vala b/src/Indicator/Widgets/IndicatorWidget.vala index 80301e90c..0d9da2643 100644 --- a/src/Indicator/Widgets/IndicatorWidget.vala +++ b/src/Indicator/Widgets/IndicatorWidget.vala @@ -4,31 +4,15 @@ */ public class Monitor.IndicatorWidget : Gtk.Box { - - public string icon_name { get; construct; } - protected Gtk.Label label; - - public IndicatorWidget (string icon_name) { - Object ( - orientation: Gtk.Orientation.HORIZONTAL, - icon_name: icon_name, - visible: false - ); - } + public bool revealed { get; set; } construct { - var icon = new Gtk.Image.from_icon_name (icon_name); - label = new Gtk.Label (Utils.NOT_AVAILABLE) { - margin_start = 2, - margin_end = 2, - margin_top = 2, - margin_bottom = 2, - width_chars = 4, + valign = BASELINE_CENTER }; + label.add_css_class (Granite.CssClass.NUMERIC); - append (icon); append (label); } diff --git a/src/Indicator/Widgets/IndicatorWidgetBandwidth.vala b/src/Indicator/Widgets/IndicatorWidgetBandwidth.vala index 75bdad803..9fbe3e31c 100644 --- a/src/Indicator/Widgets/IndicatorWidgetBandwidth.vala +++ b/src/Indicator/Widgets/IndicatorWidgetBandwidth.vala @@ -4,13 +4,12 @@ */ public class Monitor.IndicatorWidgetBandwidth : Monitor.IndicatorWidget { - public IndicatorWidgetBandwidth (string icon_name) { - base (icon_name); + construct { + label.width_chars = 9; } public override void update_label (Value value) { uint64 bandwidth = value.get_uint64 (); - label.label = Utils.Strings.format_network_speed (bandwidth); } } diff --git a/src/Indicator/Widgets/IndicatorWidgetFrequency.vala b/src/Indicator/Widgets/IndicatorWidgetFrequency.vala index 5aabb5def..60face509 100644 --- a/src/Indicator/Widgets/IndicatorWidgetFrequency.vala +++ b/src/Indicator/Widgets/IndicatorWidgetFrequency.vala @@ -4,13 +4,12 @@ */ public class Monitor.IndicatorWidgetFrequency : Monitor.IndicatorWidget { - public IndicatorWidgetFrequency (string icon_name) { - base (icon_name); + construct { + label.width_chars = 7; } public override void update_label (Value value) { double frequency = value.get_double (); - label.label = Utils.Strings.format_frequency (frequency); } } diff --git a/src/Indicator/Widgets/IndicatorWidgetPercentage.vala b/src/Indicator/Widgets/IndicatorWidgetPercentage.vala index f1bb98a46..dfd672527 100644 --- a/src/Indicator/Widgets/IndicatorWidgetPercentage.vala +++ b/src/Indicator/Widgets/IndicatorWidgetPercentage.vala @@ -4,23 +4,25 @@ */ public class Monitor.IndicatorWidgetPercentage : Monitor.IndicatorWidget { - public IndicatorWidgetPercentage (string icon_name) { - base (icon_name); + construct { + label.width_chars = 4; } public override void update_label (Value value) { uint percentage = value.get_uint (); label.label = "%u%%".printf (percentage); - label.remove_css_class ("monitor-indicator-label-warning"); - label.remove_css_class ("monitor-indicator-label-critical"); - if (percentage > 80) { - label.add_css_class ("monitor-indicator-label-warning"); + if (percentage > 90) { + label.css_classes = {Granite.CssClass.ERROR}; + return; } - if (percentage > 90) { - label.add_css_class ("monitor-indicator-label-critical"); + if (percentage > 80) { + label.css_classes = {Granite.CssClass.WARNING}; + return; } + + label.css_classes = {""}; } } diff --git a/src/Indicator/Widgets/IndicatorWidgetTemperature.vala b/src/Indicator/Widgets/IndicatorWidgetTemperature.vala index 4580559fd..49f5e3dd3 100644 --- a/src/Indicator/Widgets/IndicatorWidgetTemperature.vala +++ b/src/Indicator/Widgets/IndicatorWidgetTemperature.vala @@ -4,13 +4,12 @@ */ public class Monitor.IndicatorWidgetTemperature : Monitor.IndicatorWidget { - public IndicatorWidgetTemperature (string icon_name) { - base (icon_name); + construct { + label.width_chars = 3; } public override void update_label (Value value) { int temperature = value.get_int (); - label.label = "%i℃".printf (temperature); } } diff --git a/src/Indicator/meson.build b/src/Indicator/meson.build index 99457d978..be5e7e5fb 100644 --- a/src/Indicator/meson.build +++ b/src/Indicator/meson.build @@ -3,6 +3,7 @@ source_indicator_files = [ 'Services/DBusClient.vala', 'Widgets/DisplayWidget.vala', 'Widgets/IndicatorWidget.vala', + 'Widgets/IndicatorGroupWidget.vala', 'Widgets/IndicatorWidgetPercentage.vala', 'Widgets/IndicatorWidgetTemperature.vala', 'Widgets/IndicatorWidgetFrequency.vala', @@ -14,11 +15,11 @@ source_indicator_files = [ ] wingpanel_dep = dependency('wingpanel-9') -gtk_dep = dependency('gtk4', version: '>= 4.12') indicator_dependencies = [ wingpanel_dep, - gtk_dep + dependency('gtk4', version: '>= 4.12'), + dependency('granite-7', version: '>=7.7.0'), ] shared_module(