From bd5f8ad7895e7d2d528f91b15b1d4735aeef514f Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 27 May 2026 20:01:39 +0100 Subject: [PATCH 1/3] Show similar window labels in both Wayland and X11 sessions --- src/Widgets/DisplaysOverlay.vala | 82 ++++++++++++++++++++++---------- src/Widgets/MonitorLabel.vala | 73 ++++++++++++++++++++++++++++ src/meson.build | 3 ++ 3 files changed, 133 insertions(+), 25 deletions(-) create mode 100644 src/Widgets/MonitorLabel.vala diff --git a/src/Widgets/DisplaysOverlay.vala b/src/Widgets/DisplaysOverlay.vala index 3874994d..bc0c689b 100644 --- a/src/Widgets/DisplaysOverlay.vala +++ b/src/Widgets/DisplaysOverlay.vala @@ -201,40 +201,72 @@ public class Display.DisplaysOverlay : Gtk.Box { change_active_displays_sensitivity (); calculate_ratio (); scanning = false; + + show_windows (); } - public void show_windows () requires (gala_dbus != null) { - if (monitor_manager.is_mirrored) { + private MonitorLabel[] monitor_labels = {}; + public void show_windows () { + if (monitor_manager.is_mirrored || scanning) { return; } - MonitorLabelInfo[] label_infos = {}; - - foreach (unowned var widget in display_widgets) { - if (widget.virtual_monitor.is_active) { - label_infos += MonitorLabelInfo () { - monitor = label_infos.length, - label = widget.virtual_monitor.get_display_name (), - background_color = widget.bg_color, - text_color = widget.text_color, - x = widget.virtual_monitor.current_x, - y = widget.virtual_monitor.current_y - }; + var display = Gdk.Display.get_default (); + if (display is Gdk.X11.Display) { + if (gala_dbus == null) { + return; + } + MonitorLabelInfo[] label_infos = {}; + foreach (unowned var widget in display_widgets) { + if (widget.virtual_monitor.is_active) { + label_infos += MonitorLabelInfo () { + monitor = label_infos.length, + label = widget.virtual_monitor.get_display_name (), + background_color = widget.bg_color, + text_color = widget.text_color, + x = widget.virtual_monitor.current_x, + y = widget.virtual_monitor.current_y + }; + } + } + try { + gala_dbus.show_monitor_labels (label_infos); + } catch (Error e) { + warning ("Couldn't show monitor labels: %s", e.message); + } + } else { + hide_windows (); // Ensure existing labels destroyed + foreach (unowned var widget in display_widgets) { + if (widget.virtual_monitor.is_active) { + var monitor_label = new MonitorLabel ( + monitor_labels.length, widget.virtual_monitor.get_display_name (), + widget.bg_color, widget.text_color + ); + monitor_label.present (); + monitor_labels += monitor_label; + } } - } - - try { - gala_dbus.show_monitor_labels (label_infos); - } catch (Error e) { - warning ("Couldn't show monitor labels: %s", e.message); } } - public void hide_windows () requires (gala_dbus != null) { - try { - gala_dbus.hide_monitor_labels (); - } catch (Error e) { - warning ("Couldn't hide monitor labels: %s", e.message); + public void hide_windows () { + var display = Gdk.Display.get_default (); + if (display is Gdk.X11.Display) { + if (gala_dbus == null) { + return; + } + + try { + gala_dbus.hide_monitor_labels (); + } catch (Error e) { + warning ("Couldn't hide monitor labels: %s", e.message); + } + } else { + foreach (var monitor_label in monitor_labels) { + monitor_label.destroy (); + } + + monitor_labels = {}; } } diff --git a/src/Widgets/MonitorLabel.vala b/src/Widgets/MonitorLabel.vala new file mode 100644 index 00000000..7da6717c --- /dev/null +++ b/src/Widgets/MonitorLabel.vala @@ -0,0 +1,73 @@ +/* + * Copyright 2025 elementary, Inc. (https://elementary.io) + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +public class Display.MonitorLabel : Gtk.Window, PantheonWayland.ExtendedBehavior { + private const int SPACING = 12; + private const string COLORED_STYLE_CSS = """ + .label-%d { + background-color: alpha(%s, 0.8); + color: %s; + } + """; + + public int index { get; construct; } + public string label { get; construct; } + public string bg_color { get; construct; } + public string text_color { get; construct; } + + public MonitorLabel (int index, string label, string bg_color, string text_color) { + Object ( + index: index, + label: label, + bg_color: bg_color, + text_color: text_color + ); + } + + construct { + // Construct a label roughly matching that shown in Classic session + child = new Gtk.Label (label) { + margin_start = 12, + margin_end = 12, + margin_top = 12, + margin_bottom = 12, + halign = CENTER, + valign = CENTER + }; + child.add_css_class (Granite.STYLE_CLASS_H3_LABEL); + + decorated = false; + resizable = false; + deletable = false; + can_focus = false; + titlebar = new Gtk.Grid () { visible = false }; + + var provider = new Gtk.CssProvider (); + try { + provider.load_from_string (COLORED_STYLE_CSS.printf (index, bg_color, text_color)); + add_css_class ("label-%d".printf (index)); + add_css_class ("monitor-label"); + + Gtk.StyleContext.add_provider_for_display ( + Gdk.Display.get_default (), + provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + ); + } catch (Error e) { + warning ("Failed to load CSS: %s", e.message); + } + + child.realize.connect (on_realize); + } + + private void on_realize () requires (!(Gdk.Display.get_default () is Gdk.X11.Display )) { + if (!(this is PantheonWayland.ExtendedBehavior)) { + return; + } + + connect_to_shell (); + ((PantheonWayland.ExtendedBehavior)(this)).make_monitor_label (index); + } +} diff --git a/src/meson.build b/src/meson.build index fc6df44b..345bea81 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,6 +15,7 @@ plug_files = files( 'Views' / 'FiltersView.vala', 'Widgets/DisplayWidget.vala', 'Widgets/DisplaysOverlay.vala', + 'Widgets/MonitorLabel.vala' ) switchboard_dep = dependency('switchboard-3') @@ -31,7 +32,9 @@ shared_module( dependency('gobject-2.0'), dependency('granite-7', version: '>=7.7.0'), dependency('gtk4'), + dependency('gtk4-x11'), dependency('libadwaita-1'), + dependency('pantheon-wayland-1'), meson.get_compiler('vala').find_library('posix'), switchboard_dep ], From d6ca3df2ecc84a0ea01d3d36460b732ef6db454e Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 27 May 2026 20:08:20 +0100 Subject: [PATCH 2/3] Add missing CI dependency --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index df650d15..175be742 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,7 +23,7 @@ jobs: - name: Install Dependencies run: | apt update - apt install -y meson libadwaita-1-dev libgranite-7-dev libswitchboard-3-dev valac + apt install -y meson libadwaita-1-dev libgranite-7-dev libpantheon-wayland-1-dev libswitchboard-3-dev valac - name: Build env: DESTDIR: out From ad62674e76b203d8dc5d39f3630821d80cb53a8b Mon Sep 17 00:00:00 2001 From: Jeremy Wootten Date: Wed, 27 May 2026 20:17:21 +0100 Subject: [PATCH 3/3] Use css to style Wayland label --- data/Display.css | 10 ++++++++++ src/Widgets/MonitorLabel.vala | 12 ++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/data/Display.css b/data/Display.css index 1d76c1ef..1a8a92cf 100644 --- a/data/Display.css +++ b/data/Display.css @@ -169,3 +169,13 @@ scale.warmth:dir(rtl) trough { @ORANGE_500 ); } + +.monitor-label { + border-radius: 9px; + font-weight: 600; +} + +.monitor-label label { + margin: 1em; + text-shadow: 0 1px 1px alpha(white, 0.1); +} diff --git a/src/Widgets/MonitorLabel.vala b/src/Widgets/MonitorLabel.vala index 7da6717c..3c287b03 100644 --- a/src/Widgets/MonitorLabel.vala +++ b/src/Widgets/MonitorLabel.vala @@ -27,16 +27,7 @@ public class Display.MonitorLabel : Gtk.Window, PantheonWayland.ExtendedBehavior } construct { - // Construct a label roughly matching that shown in Classic session - child = new Gtk.Label (label) { - margin_start = 12, - margin_end = 12, - margin_top = 12, - margin_bottom = 12, - halign = CENTER, - valign = CENTER - }; - child.add_css_class (Granite.STYLE_CLASS_H3_LABEL); + child = new Gtk.Label (label); decorated = false; resizable = false; @@ -46,6 +37,7 @@ public class Display.MonitorLabel : Gtk.Window, PantheonWayland.ExtendedBehavior var provider = new Gtk.CssProvider (); try { + // Provide appearance similar to classic session provider.load_from_string (COLORED_STYLE_CSS.printf (index, bg_color, text_color)); add_css_class ("label-%d".printf (index)); add_css_class ("monitor-label");