Skip to content

Commit b328a49

Browse files
committed
Add API for making monitor label via wayland protocol
1 parent 6f621bc commit b328a49

File tree

6 files changed

+77
-1
lines changed

6 files changed

+77
-1
lines changed

protocol/pantheon-desktop-shell-v1.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,5 +151,14 @@
151151
by the compositor.
152152
</description>
153153
</request>
154+
155+
<request name="make_monitor_label">
156+
<description summary="makes the surface a monitor label for the given monitor">
157+
Request to make the surface a monitor label for the given monitor. The surface will be placed
158+
in the top left corner of the monitor and will be kept above other surfaces.
159+
</description>
160+
161+
<arg name="monitor_index" type="int" summary="the index of the monitor this surface should label"/>
162+
</request>
154163
</interface>
155164
</protocol>

protocol/pantheon-desktop-shell.vapi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ namespace Pantheon.Desktop {
6161
public SetKeepAbove set_keep_above;
6262
public MakeCentered make_centered;
6363
public Focus focus;
64+
public MakeMonitorLabel make_monitor_label;
6465
}
6566

6667
[CCode (has_target = false, has_typedef = false)]
@@ -88,5 +89,7 @@ namespace Pantheon.Desktop {
8889
[CCode (has_target = false, has_typedef = false)]
8990
public delegate void MakeCentered (Wl.Client client, Wl.Resource resource);
9091
[CCode (has_target = false, has_typedef = false)]
92+
public delegate void MakeMonitorLabel (Wl.Client client, Wl.Resource resource, int monitor_index);
93+
[CCode (has_target = false, has_typedef = false)]
9194
public delegate void Destroy (Wl.Client client, Wl.Resource resource);
9295
}

src/PantheonShell.vala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace Gala {
5353
set_keep_above,
5454
make_centered,
5555
focus_extended_behavior,
56+
make_monitor_label,
5657
};
5758

5859
PanelSurface.quark = GLib.Quark.from_string ("-gala-wayland-panel-surface-data");
@@ -376,6 +377,21 @@ namespace Gala {
376377
ShellClientsManager.get_instance ().make_centered (window);
377378
}
378379

380+
internal static void make_monitor_label (Wl.Client client, Wl.Resource resource, int monitor_index) {
381+
unowned ExtendedBehaviorSurface? eb_surface = resource.get_user_data<ExtendedBehaviorSurface> ();
382+
if (eb_surface.wayland_surface == null) {
383+
return;
384+
}
385+
386+
Meta.Window? window;
387+
eb_surface.wayland_surface.get ("window", out window, null);
388+
if (window == null) {
389+
return;
390+
}
391+
392+
ShellClientsManager.get_instance ().make_monitor_label (window, monitor_index);
393+
}
394+
379395
internal static void destroy_panel_surface (Wl.Client client, Wl.Resource resource) {
380396
resource.destroy ();
381397
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2025 elementary, Inc. (https://elementary.io)
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*
5+
* Authored by: Leonhard Kargl <[email protected]>
6+
*/
7+
8+
public class Gala.MonitorLabelWindow : PositionedWindow {
9+
private const int MARGIN = 24;
10+
11+
public int monitor_index { get; construct; }
12+
13+
public MonitorLabelWindow (Meta.Window window, int monitor_index) {
14+
Object (window: window, monitor_index: monitor_index);
15+
}
16+
17+
protected override void get_window_position (Mtk.Rectangle window_rect, out int x, out int y) {
18+
var monitor_rect = window.display.get_monitor_geometry (monitor_index);
19+
20+
x = monitor_rect.x + MARGIN;
21+
y = monitor_rect.y + MARGIN;
22+
}
23+
}

src/ShellClients/ShellClientsManager.vala

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class Gala.ShellClientsManager : Object, GestureTarget {
2929

3030
private GLib.HashTable<Meta.Window, PanelWindow> panel_windows = new GLib.HashTable<Meta.Window, PanelWindow> (null, null);
3131
private GLib.HashTable<Meta.Window, ShellWindow> positioned_windows = new GLib.HashTable<Meta.Window, ShellWindow> (null, null);
32+
private GLib.HashTable<Meta.Window, MonitorLabelWindow> monitor_label_windows = new GLib.HashTable<Meta.Window, MonitorLabelWindow> (null, null);
3233

3334
private ShellClientsManager (WindowManager wm) {
3435
Object (wm: wm);
@@ -240,6 +241,19 @@ public class Gala.ShellClientsManager : Object, GestureTarget {
240241
window.unmanaging.connect_after ((_window) => positioned_windows.remove (_window));
241242
}
242243

244+
public void make_monitor_label (Meta.Window window, int monitor_index) requires (!is_itself_positioned (window)) {
245+
if (monitor_index < 0 || monitor_index > wm.get_display ().get_n_monitors ()) {
246+
warning ("Invalid monitor index provided: %d", monitor_index);
247+
return;
248+
}
249+
250+
warning ("Made monitor label for monitor %d", monitor_index);
251+
monitor_label_windows[window] = new MonitorLabelWindow (window, monitor_index);
252+
253+
// connect_after so we make sure that any queued move is unqueued
254+
window.unmanaging.connect_after ((_window) => monitor_label_windows.remove (_window));
255+
}
256+
243257
public void propagate (UpdateType update_type, GestureAction action, double progress) {
244258
foreach (var window in positioned_windows.get_values ()) {
245259
window.propagate (update_type, action, progress);
@@ -251,7 +265,8 @@ public class Gala.ShellClientsManager : Object, GestureTarget {
251265
}
252266

253267
public bool is_itself_positioned (Meta.Window window) {
254-
return (window in positioned_windows) || (window in panel_windows) || NotificationStack.is_notification (window);
268+
return (window in positioned_windows) || (window in panel_windows) ||
269+
(window in monitor_label_windows) || NotificationStack.is_notification (window);
255270
}
256271

257272
public bool is_positioned_window (Meta.Window window) {
@@ -350,6 +365,15 @@ public class Gala.ShellClientsManager : Object, GestureTarget {
350365
set_restore_previous_x11_region (window);
351366
break;
352367

368+
case "monitor-label":
369+
int parsed;
370+
if (int.try_parse (val, out parsed)) {
371+
make_monitor_label (window, parsed);
372+
} else {
373+
warning ("Failed to parse %s as monitor label", val);
374+
}
375+
break;
376+
353377
default:
354378
break;
355379
}

src/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ gala_bin_sources = files(
4545
'ShellClients/ExtendedBehaviorWindow.vala',
4646
'ShellClients/HideTracker.vala',
4747
'ShellClients/ManagedClient.vala',
48+
'ShellClients/MonitorLabelWindow.vala',
4849
'ShellClients/NotificationsClient.vala',
4950
'ShellClients/PanelWindow.vala',
5051
'ShellClients/PositionedWindow.vala',

0 commit comments

Comments
 (0)