Skip to content

Commit cff86fb

Browse files
authored
Dock workspace switcher (#2265)
1 parent 2fe02e5 commit cff86fb

File tree

1 file changed

+46
-3
lines changed

1 file changed

+46
-3
lines changed

src/DesktopIntegration.vala

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 elementary, Inc. <https://elementary.io>
2+
* Copyright 2022-2025 elementary, Inc. <https://elementary.io>
33
* Copyright 2022 Corentin Noël <[email protected]>
44
* SPDX-License-Identifier: GPL-3.0-or-later
55
*/
@@ -20,11 +20,30 @@ public class Gala.DesktopIntegration : GLib.Object {
2020
public uint version { get; default = 1; }
2121
public signal void running_applications_changed ();
2222
public signal void windows_changed ();
23+
public signal void active_workspace_changed ();
24+
public signal void workspace_removed (int index);
2325

2426
public DesktopIntegration (WindowManagerGala wm) {
2527
this.wm = wm;
2628
wm.window_tracker.windows_changed.connect (() => windows_changed ());
27-
wm.get_display ().get_workspace_manager ().active_workspace_changed.connect (() => windows_changed ());
29+
30+
unowned var display = wm.get_display ();
31+
unowned var workspace_manager = display.get_workspace_manager ();
32+
workspace_manager.active_workspace_changed.connect (() => {
33+
active_workspace_changed ();
34+
windows_changed (); // windows have 'on-active-workspace' property that we need to update
35+
});
36+
workspace_manager.workspaces_reordered.connect (() => windows_changed ());
37+
workspace_manager.workspace_added.connect (() => windows_changed ());
38+
workspace_manager.workspace_removed.connect ((index) => {
39+
workspace_removed (index);
40+
windows_changed ();
41+
});
42+
43+
// TODO: figure out if there's a better way to handle ws rearrangement
44+
display.window_created.connect ((window) => {
45+
window.workspace_changed.connect (() => windows_changed ());
46+
});
2847
}
2948

3049
public RunningApplication[] get_running_applications () throws GLib.DBusError, GLib.IOError {
@@ -63,7 +82,7 @@ public class Gala.DesktopIntegration : GLib.Object {
6382
public Window[] get_windows () throws GLib.DBusError, GLib.IOError {
6483
Window[] returned_windows = {};
6584
var apps = Gala.AppSystem.get_default ().get_running_apps ();
66-
var active_workspace = wm.get_display ().get_workspace_manager ().get_active_workspace ();
85+
unowned var active_workspace = wm.get_display ().get_workspace_manager ().get_active_workspace ();
6786
foreach (unowned var app in apps) {
6887
foreach (weak Meta.Window window in app.get_windows ()) {
6988
if (!is_eligible_window (window)) {
@@ -81,6 +100,7 @@ public class Gala.DesktopIntegration : GLib.Object {
81100
properties.insert ("is-hidden", new GLib.Variant.boolean (window.is_hidden ()));
82101
properties.insert ("has-focus", new GLib.Variant.boolean (window.has_focus ()));
83102
properties.insert ("on-active-workspace", new GLib.Variant.boolean (window.located_on_workspace (active_workspace)));
103+
properties.insert ("workspace-index", new GLib.Variant.int32 (window.get_workspace ().index ()));
84104
properties.insert ("width", new GLib.Variant.uint32 (frame_rect.width));
85105
properties.insert ("height", new GLib.Variant.uint32 (frame_rect.height));
86106

@@ -122,6 +142,29 @@ public class Gala.DesktopIntegration : GLib.Object {
122142
}
123143
}
124144

145+
public void activate_workspace (int index) throws GLib.DBusError, GLib.IOError {
146+
unowned var workspace = wm.get_display ().get_workspace_manager ().get_workspace_by_index (index);
147+
if (workspace == null) {
148+
throw new IOError.NOT_FOUND ("Workspace not found");
149+
}
150+
151+
unowned var display = wm.get_display ();
152+
unowned var active_workspace_index = display.get_workspace_manager ().get_active_workspace_index ();
153+
if (active_workspace_index == index) {
154+
InternalUtils.bell_notify (display);
155+
} else {
156+
workspace.activate (display.get_current_time ());
157+
}
158+
}
159+
160+
public int get_n_workspaces () throws GLib.DBusError, GLib.IOError {
161+
return wm.get_display ().get_workspace_manager ().n_workspaces;
162+
}
163+
164+
public int get_active_workspace () throws GLib.DBusError, GLib.IOError {
165+
return wm.get_display ().get_workspace_manager ().get_active_workspace_index ();
166+
}
167+
125168
private bool notifying = false;
126169
private void notify_already_focused (Meta.Window window) {
127170
if (notifying) {

0 commit comments

Comments
 (0)