Skip to content

Commit 750cb32

Browse files
authored
WindowStateSaver: save windows position on sleep and shutdown (#2318)
1 parent af44207 commit 750cb32

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/Main.vala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ namespace Gala {
9191
return Posix.EXIT_FAILURE;
9292
}
9393

94+
WindowStateSaver.on_shutdown ();
95+
9496
return Posix.EXIT_SUCCESS;
9597
}
9698
}

src/WindowStateSaver.vala

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
/*
2-
* Copyright 2023 elementary, Inc. <https://elementary.io>
2+
* Copyright 2023-2025 elementary, Inc. <https://elementary.io>
33
* SPDX-License-Identifier: GPL-3.0-or-later
44
*/
55

66
public class Gala.WindowStateSaver : GLib.Object {
7+
[DBus (name = "org.freedesktop.login1.Manager")]
8+
private interface LoginManager : Object {
9+
public signal void prepare_for_sleep (bool about_to_suspend);
10+
}
11+
712
private static unowned WindowTracker window_tracker;
813
private static GLib.HashTable<string, GLib.Array<Meta.Window?>> app_windows;
14+
private static LoginManager? login_manager;
915
private static Sqlite.Database db;
1016

1117
public static void init (WindowTracker window_tracker) {
1218
WindowStateSaver.window_tracker = window_tracker;
1319
app_windows = new GLib.HashTable<string, GLib.Array<Meta.Window?>> (GLib.str_hash, GLib.str_equal);
1420

21+
connect_to_logind.begin ();
22+
1523
var dir = Path.build_filename (GLib.Environment.get_user_data_dir (), "io.elementary.gala");
1624
Posix.mkdir (dir, 0775);
1725
var path = Path.build_filename (dir, "windowstate.db");
@@ -54,6 +62,19 @@ public class Gala.WindowStateSaver : GLib.Object {
5462
critical ("Cannot create table 'apps': %d, %s", rc, db.errmsg ());
5563
}
5664

65+
private async static void connect_to_logind () {
66+
try {
67+
login_manager = yield Bus.get_proxy (SYSTEM, "org.freedesktop.login1", "/org/freedesktop/login1");
68+
login_manager.prepare_for_sleep.connect ((about_to_suspend) => {
69+
if (about_to_suspend) {
70+
save_all_windows_state ();
71+
}
72+
});
73+
} catch (Error e) {
74+
warning ("Unable to connect to logind bus: %s", e.message);
75+
}
76+
}
77+
5778
public static void on_map (Meta.Window window) {
5879
var app_id = GLib.Markup.escape_text (window_tracker.get_app_for_window (window).id);
5980

@@ -114,11 +135,15 @@ public class Gala.WindowStateSaver : GLib.Object {
114135
critical ("Cannot insert app information into database: %d, %s", rc, db.errmsg ());
115136
}
116137

138+
public static void on_shutdown () {
139+
save_all_windows_state ();
140+
}
141+
117142
private static void track_window (Meta.Window window, string app_id) {
118-
window.unmanaging.connect (on_window_unmanaging);
143+
window.unmanaging.connect (save_window_state);
119144
}
120145

121-
private static void on_window_unmanaging (Meta.Window window) {
146+
private static void save_window_state (Meta.Window window) {
122147
var app_id = GLib.Markup.escape_text (window_tracker.get_app_for_window (window).id);
123148

124149
var window_index = find_window_index (window, app_id);
@@ -145,6 +170,14 @@ public class Gala.WindowStateSaver : GLib.Object {
145170
critical ("Cannot update app position in database: %d, %s", rc, db.errmsg ());
146171
}
147172

173+
private static void save_all_windows_state () {
174+
foreach (unowned var windows in app_windows.get_values ()) {
175+
foreach (var window in windows) {
176+
save_window_state (window);
177+
}
178+
}
179+
}
180+
148181
private static int find_window_index (Meta.Window window, string app_id) requires (app_id in app_windows) {
149182
unowned var windows_list = app_windows[app_id];
150183
var first_null = -1;

0 commit comments

Comments
 (0)