Skip to content

Commit 43aaf3c

Browse files
authored
Introduce WindowSystem (#363)
1 parent cef449c commit 43aaf3c

File tree

6 files changed

+106
-70
lines changed

6 files changed

+106
-70
lines changed

po/POTFILES

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
src/Application.vala
21
src/App.vala
3-
src/AppWindow.vala
2+
src/Application.vala
3+
src/AppSystem.vala
44
src/DesktopIntegration.vala
5-
src/Launcher.vala
65
src/ItemManager.vala
6+
src/Launcher.vala
77
src/MainWindow.vala
88
src/PoofPopover.vala
9+
src/Window.vala
10+
src/WindowSystem.vala
911
src/DBus/ItemInterface.vala
1012
src/DBus/Unity.vala
1113
src/DBus/SwitcherooControl.vala

src/App.vala

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* SPDX-License-Identifier: GPL-3.0
3-
* SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io)
3+
* SPDX-FileCopyrightText: 2024-2025 elementary, Inc. (https://elementary.io)
44
*/
55

66
public class Dock.App : Object {
@@ -48,7 +48,7 @@ public class Dock.App : Object {
4848
public SimpleActionGroup action_group { get; construct; }
4949
public Menu menu_model { get; construct; }
5050

51-
public Gee.List<AppWindow> windows { get; private owned set; } //Ordered by stacking order with topmost at 0
51+
public Gee.List<Window> windows { get; private owned set; } // Ordered by stacking order with topmost at 0
5252

5353
private static Dock.SwitcherooControl switcheroo_control;
5454

@@ -63,7 +63,7 @@ public class Dock.App : Object {
6363
}
6464

6565
construct {
66-
windows = new Gee.LinkedList<AppWindow> ();
66+
windows = new Gee.LinkedList<Window> ();
6767

6868
action_group = new SimpleActionGroup ();
6969

@@ -138,9 +138,9 @@ public class Dock.App : Object {
138138
} else if (windows.size == 0) {
139139
app_info.launch (null, context);
140140
} else if (windows.size == 1) {
141-
AppSystem.get_default ().desktop_integration.focus_window.begin (windows.first ().uid);
142-
} else if (AppSystem.get_default ().desktop_integration != null) {
143-
AppSystem.get_default ().desktop_integration.show_windows_for.begin (app_info.get_id ());
141+
WindowSystem.get_default ().desktop_integration.focus_window.begin (windows.first ().uid);
142+
} else if (WindowSystem.get_default ().desktop_integration != null) {
143+
WindowSystem.get_default ().desktop_integration.show_windows_for.begin (app_info.get_id ());
144144
}
145145
} catch (Error e) {
146146
critical (e.message);
@@ -184,9 +184,9 @@ public class Dock.App : Object {
184184
}
185185
}
186186

187-
public void update_windows (Gee.List<AppWindow>? new_windows) {
187+
public void update_windows (Gee.List<Window>? new_windows) {
188188
if (new_windows == null) {
189-
windows = new Gee.LinkedList<AppWindow> ();
189+
windows = new Gee.LinkedList<Window> ();
190190
} else {
191191
windows = new_windows;
192192
}
@@ -201,18 +201,6 @@ public class Dock.App : Object {
201201
check_remove ();
202202
}
203203

204-
public AppWindow? find_window (uint64 window_uid) {
205-
var found_win = windows.first_match ((win) => {
206-
return win.uid == window_uid;
207-
});
208-
209-
if (found_win != null) {
210-
return found_win;
211-
} else {
212-
return null;
213-
}
214-
}
215-
216204
public void perform_unity_update (VariantIter prop_iter) {
217205
string prop_key;
218206
Variant prop_value;
@@ -241,7 +229,7 @@ public class Dock.App : Object {
241229
progress = 0;
242230
}
243231

244-
private AppWindow[] current_windows;
232+
private Window[] current_windows;
245233
private uint current_index;
246234
private uint timer_id = 0;
247235
private bool should_wait = false;
@@ -264,7 +252,7 @@ public class Dock.App : Object {
264252
return;
265253
}
266254

267-
AppSystem.get_default ().desktop_integration.focus_window.begin (current_windows[current_index].uid);
255+
WindowSystem.get_default ().desktop_integration.focus_window.begin (current_windows[current_index].uid);
268256

269257
// Throttle the scroll for performance and better visibility of the windows
270258
Timeout.add (250, () => {
@@ -282,7 +270,7 @@ public class Dock.App : Object {
282270
yield AppSystem.get_default ().sync_windows (); // Get the current stacking order
283271
current_index = windows.size > 1 && windows.first ().has_focus ? 1 : 0;
284272
current_windows = {};
285-
foreach (AppWindow window in windows) {
273+
foreach (var window in windows) {
286274
current_windows += window;
287275
}
288276
}

src/AppSystem.vala

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* SPDX-License-Identifier: GPL-3.0
3-
* SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io)
3+
* SPDX-FileCopyrightText: 2024-2025 elementary, Inc. (https://elementary.io)
44
*/
55

66
public class Dock.AppSystem : Object, UnityClient {
@@ -17,8 +17,6 @@ public class Dock.AppSystem : Object, UnityClient {
1717

1818
public signal void app_added (App app);
1919

20-
public DesktopIntegration? desktop_integration { get; private set; }
21-
2220
private GLib.HashTable<unowned string, App> id_to_app;
2321

2422
private AppSystem () { }
@@ -37,19 +35,8 @@ public class Dock.AppSystem : Object, UnityClient {
3735
add_app (app_info, true);
3836
}
3937

40-
try {
41-
desktop_integration = yield GLib.Bus.get_proxy<Dock.DesktopIntegration> (
42-
SESSION,
43-
"org.pantheon.gala",
44-
"/org/pantheon/gala/DesktopInterface"
45-
);
46-
47-
yield sync_windows ();
48-
49-
desktop_integration.windows_changed.connect (sync_windows);
50-
} catch (Error e) {
51-
critical ("Failed to get desktop integration: %s", e.message);
52-
}
38+
yield sync_windows ();
39+
WindowSystem.get_default ().notify["windows"].connect (sync_windows);
5340
}
5441

5542
private App add_app (DesktopAppInfo app_info, bool pinned) {
@@ -60,47 +47,33 @@ public class Dock.AppSystem : Object, UnityClient {
6047
return app;
6148
}
6249

63-
public async void sync_windows () requires (desktop_integration != null) {
64-
DesktopIntegration.Window[] windows;
65-
try {
66-
windows = yield desktop_integration.get_windows ();
67-
} catch (Error e) {
68-
critical (e.message);
69-
return;
70-
}
50+
public async void sync_windows () {
51+
var windows = WindowSystem.get_default ().windows;
7152

72-
var app_window_list = new Gee.HashMap<App, Gee.List<AppWindow>> ();
73-
foreach (unowned var window in windows) {
74-
unowned var app_id = window.properties["app-id"].get_string ();
75-
App? app = id_to_app[app_id];
53+
var app_window_list = new Gee.HashMap<App, Gee.List<Window>> ();
54+
foreach (var window in windows) {
55+
App? app = id_to_app[window.app_id];
7656
if (app == null) {
77-
var app_info = new GLib.DesktopAppInfo (app_id);
57+
var app_info = new GLib.DesktopAppInfo (window.app_id);
7858
if (app_info == null) {
7959
continue;
8060
}
8161

8262
app = add_app (app_info, false);
8363
}
8464

85-
AppWindow? app_window = app.find_window (window.uid);
86-
if (app_window == null) {
87-
app_window = new AppWindow (window.uid);
88-
}
89-
90-
app_window.update_properties (window.properties);
91-
9265
var window_list = app_window_list.get (app);
9366
if (window_list == null) {
94-
var new_window_list = new Gee.LinkedList<AppWindow> ();
95-
new_window_list.add (app_window);
67+
var new_window_list = new Gee.LinkedList<Window> ();
68+
new_window_list.add (window);
9669
app_window_list.set (app, new_window_list);
9770
} else {
98-
window_list.add (app_window);
71+
window_list.add (window);
9972
}
10073
}
10174

10275
foreach (var app in id_to_app.get_values ()) {
103-
Gee.List<AppWindow>? window_list = null;
76+
Gee.List<Window>? window_list = null;
10477
app_window_list.unset (app, out window_list);
10578
app.update_windows (window_list);
10679
}

src/AppWindow.vala renamed to src/Window.vala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
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
*/
66

7-
public class Dock.AppWindow : GLib.Object {
7+
public class Dock.Window : GLib.Object {
88
public uint64 uid { get; construct set; }
99

10+
public string app_id { get; private set; default = ""; }
1011
public bool has_focus { get; private set; default = false; }
1112
public bool on_active_workspace { get; private set; default = false; }
1213

13-
public AppWindow (uint64 uid) {
14+
public Window (uint64 uid) {
1415
Object (uid: uid);
1516
}
1617

1718
public void update_properties (GLib.HashTable<string, Variant> properties) {
19+
if ("app-id" in properties) {
20+
app_id = properties["app-id"].get_string ();
21+
}
22+
1823
if ("has-focus" in properties) {
1924
has_focus = (bool) properties["has-focus"];
2025
}

src/WindowSystem.vala

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* SPDX-License-Identifier: GPL-3.0
3+
* SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io)
4+
*/
5+
6+
public class Dock.WindowSystem : Object {
7+
private static GLib.Once<WindowSystem> instance;
8+
public static unowned WindowSystem get_default () {
9+
return instance.once (() => { return new WindowSystem (); });
10+
}
11+
12+
public DesktopIntegration? desktop_integration { get; private set; }
13+
public Gee.List<Window> windows { get; private owned set; }
14+
15+
private WindowSystem () {}
16+
17+
construct {
18+
windows = new Gee.LinkedList<Window> ();
19+
load.begin ();
20+
}
21+
22+
private async void load () {
23+
try {
24+
desktop_integration = yield GLib.Bus.get_proxy<Dock.DesktopIntegration> (
25+
SESSION,
26+
"org.pantheon.gala",
27+
"/org/pantheon/gala/DesktopInterface"
28+
);
29+
30+
yield sync_windows ();
31+
32+
desktop_integration.windows_changed.connect (sync_windows);
33+
} catch (Error e) {
34+
critical ("Failed to get desktop integration: %s", e.message);
35+
}
36+
}
37+
38+
private Window? find_window (uint64 uid) {
39+
return windows.first_match ((win) => {
40+
return win.uid == uid;
41+
});
42+
}
43+
44+
private async void sync_windows () requires (desktop_integration != null) {
45+
DesktopIntegration.Window[] di_windows;
46+
try {
47+
di_windows = yield desktop_integration.get_windows ();
48+
} catch (Error e) {
49+
critical (e.message);
50+
return;
51+
}
52+
53+
var new_windows = new Gee.LinkedList<Window> ();
54+
foreach (unowned var di_window in di_windows) {
55+
var window = find_window (di_window.uid);
56+
if (window == null) {
57+
window = new Window (di_window.uid);
58+
}
59+
60+
window.update_properties (di_window.properties);
61+
62+
new_windows.add (window);
63+
}
64+
65+
windows = new_windows;
66+
}
67+
}

src/meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ sources = [
22
'App.vala',
33
'AppSystem.vala',
44
'Application.vala',
5-
'AppWindow.vala',
65
'DesktopIntegration.vala',
76
'ItemManager.vala',
87
'Launcher.vala',
98
'MainWindow.vala',
109
'PoofPopover.vala',
10+
'Window.vala',
11+
'WindowSystem.vala',
1112
'DBus' / 'ItemInterface.vala',
1213
'DBus' / 'ShellKeyGrabber.vala',
1314
'DBus' / 'SwitcherooControl.vala',

0 commit comments

Comments
 (0)