Skip to content

Commit 7a96025

Browse files
committed
Daemon/WindowListener: Prevent auto-suspend/idle when going fullscreen
Adds two methods to the gala daemon that are triggered by gala itself via dbus. One is used when any window goes fullscreen, to mark it as "inhibiting" automatic sleep to the session manager. The other method to "unhibit" for the same window when it exits fullscreen. Multiple windows can inhibit sleeping, they all must exit fullscreen to restore auto-sleep. NB: If any window is fullscreen, auto sleep is disabled, even if it is not on the current virtual desktop. TODO: add gschema setting for disabling auto suspend when fullscreen
1 parent 4d1b6a7 commit 7a96025

5 files changed

Lines changed: 139 additions & 2 deletions

File tree

daemon-gtk3/DBus.vala

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,56 @@ public class Gala.Daemon.DBus : GLib.Object {
114114
}
115115
}
116116

117+
public void prevent_sleep () throws GLib.DBusError, GLib.IOError {
118+
unowned var application = (Gtk.Application) GLib.Application.get_default ();
119+
120+
// TODO add gschema setting for disabling auto suspend when fullscreen
121+
if (application != null) {
122+
// Ask the session manager to not automatically turn off the screen or put the system to sleep
123+
prevent_sleep_while_fullscreen (application);
124+
}
125+
}
126+
127+
public void unprevent_sleep () throws GLib.DBusError, GLib.IOError {
128+
unowned var application = (Gtk.Application) GLib.Application.get_default ();
129+
130+
// Inform the session manager we do not want to prevent turning off the screen or sleeping
131+
if (application != null) {
132+
if (suspend_cookie > 0) {
133+
debug ("a window exited fullscreen, so it does not prevent auto-suspend anymore");
134+
end_prevent_suspend_while_fullscreen (application);
135+
}
136+
if (idle_cookie > 0) {
137+
debug ("a window exited fullscreen, so it does not prevent auto-idle anymore");
138+
end_prevent_idle_while_fullscreen (application);
139+
}
140+
}
141+
}
142+
143+
private void prevent_sleep_while_fullscreen (Gtk.Application application) {
144+
debug ("preventing auto-suspend and auto-idle because a window went fullscreen");
145+
suspend_cookie = application.inhibit (
146+
null,
147+
Gtk.ApplicationInhibitFlags.SUSPEND,
148+
"Prevent session from suspending while fullscreen"
149+
);
150+
idle_cookie = application.inhibit (
151+
null,
152+
Gtk.ApplicationInhibitFlags.IDLE,
153+
"Prevent session from idle while fullscreen"
154+
);
155+
}
156+
157+
private void end_prevent_suspend_while_fullscreen (Gtk.Application application) {
158+
application.uninhibit (suspend_cookie);
159+
suspend_cookie = 0;
160+
}
161+
162+
private void end_prevent_idle_while_fullscreen (Gtk.Application application) {
163+
application.uninhibit (idle_cookie);
164+
idle_cookie = 0;
165+
}
166+
117167
public void show_monitor_labels (MonitorLabelInfo[] label_infos) throws GLib.DBusError, GLib.IOError {
118168
hide_monitor_labels ();
119169

daemon/DBus.vala

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public class Gala.Daemon.DBus : GLib.Object {
3636

3737
private List<MonitorLabel> monitor_labels = new List<MonitorLabel> ();
3838

39+
private uint suspend_cookie = 0;
40+
private uint idle_cookie = 0;
41+
3942
construct {
4043
Bus.watch_name (BusType.SESSION, DBUS_NAME, BusNameWatcherFlags.NONE, gala_appeared, lost_gala);
4144

@@ -155,6 +158,56 @@ public class Gala.Daemon.DBus : GLib.Object {
155158
});
156159
}
157160

161+
public void prevent_sleep () throws GLib.DBusError, GLib.IOError {
162+
unowned var application = (Gtk.Application) GLib.Application.get_default ();
163+
164+
// TODO add gschema setting for disabling auto suspend when fullscreen
165+
if (application != null) {
166+
// Ask the session manager to not automatically turn off the screen or put the system to sleep
167+
prevent_sleep_while_fullscreen (application);
168+
}
169+
}
170+
171+
public void unprevent_sleep () throws GLib.DBusError, GLib.IOError {
172+
unowned var application = (Gtk.Application) GLib.Application.get_default ();
173+
174+
// Inform the session manager we do not want to prevent turning off the screen or sleeping
175+
if (application != null) {
176+
if (suspend_cookie > 0) {
177+
debug ("a window exited fullscreen, so it does not prevent auto-suspend anymore");
178+
end_prevent_suspend_while_fullscreen (application);
179+
}
180+
if (idle_cookie > 0) {
181+
debug ("a window exited fullscreen, so it does not prevent auto-idle anymore");
182+
end_prevent_idle_while_fullscreen (application);
183+
}
184+
}
185+
}
186+
187+
private void prevent_sleep_while_fullscreen (Gtk.Application application) {
188+
debug ("preventing auto-suspend and auto-idle because a window went fullscreen");
189+
suspend_cookie = application.inhibit (
190+
null,
191+
Gtk.ApplicationInhibitFlags.SUSPEND,
192+
"Prevent session from suspending while fullscreen"
193+
);
194+
idle_cookie = application.inhibit (
195+
null,
196+
Gtk.ApplicationInhibitFlags.IDLE,
197+
"Prevent session from idle while fullscreen"
198+
);
199+
}
200+
201+
private void end_prevent_suspend_while_fullscreen (Gtk.Application application) {
202+
application.uninhibit (suspend_cookie);
203+
suspend_cookie = 0;
204+
}
205+
206+
private void end_prevent_idle_while_fullscreen (Gtk.Application application) {
207+
application.uninhibit (idle_cookie);
208+
idle_cookie = 0;
209+
}
210+
158211
public void show_monitor_labels (MonitorLabelInfo[] label_infos) throws GLib.DBusError, GLib.IOError {
159212
hide_monitor_labels ();
160213

src/DaemonManager.vala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public class Gala.DaemonManager : GLib.Object {
1414
public interface Daemon: GLib.Object {
1515
public abstract async void show_window_menu (WindowFlags flags, int width, int height, int x, int y) throws Error;
1616
public abstract async void show_desktop_menu (int display_width, int display_height, int x, int y) throws Error;
17+
public abstract async void prevent_sleep () throws Error;
18+
public abstract async void unprevent_sleep () throws Error;
1719
}
1820

1921
public Meta.Display display { get; construct; }
@@ -128,4 +130,28 @@ public class Gala.DaemonManager : GLib.Object {
128130
warning ("Error invoking MenuManager: %s", e.message);
129131
}
130132
}
133+
134+
public async void prevent_sleep () {
135+
if (daemon_proxy == null) {
136+
return;
137+
}
138+
139+
try {
140+
yield daemon_proxy.prevent_sleep ();
141+
} catch (Error e) {
142+
warning ("Error invoking MenuManager: %s", e.message);
143+
}
144+
}
145+
146+
public async void unprevent_sleep () {
147+
if (daemon_proxy == null) {
148+
return;
149+
}
150+
151+
try {
152+
yield daemon_proxy.unprevent_sleep ();
153+
} catch (Error e) {
154+
warning ("Error invoking MenuManager: %s", e.message);
155+
}
156+
}
131157
}

src/WindowListener.vala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@ public class Gala.WindowListener : Object {
2222
}
2323

2424
private static WindowListener? instance = null;
25+
private static unowned DaemonManager shared_daemon_manager;
2526

26-
public static void init (Meta.Display display) {
27+
public static void init (Meta.Display display, DaemonManager daemon_manager) {
2728
if (instance != null)
2829
return;
2930

3031
instance = new WindowListener ();
3132

33+
shared_daemon_manager = daemon_manager;
34+
3235
#if HAS_MUTTER48
3336
unowned List<Meta.WindowActor> actors = display.get_compositor ().get_window_actors ();
3437
#else
@@ -92,6 +95,11 @@ public class Gala.WindowListener : Object {
9295
break;
9396
case "fullscreen":
9497
window_fullscreen_changed (window);
98+
if (window.fullscreen) {
99+
shared_daemon_manager.prevent_sleep ();
100+
} else {
101+
shared_daemon_manager.unprevent_sleep ();
102+
}
95103
break;
96104
}
97105
}

src/WindowManager.vala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ namespace Gala {
206206
private void show_stage () {
207207
unowned Meta.Display display = get_display ();
208208

209-
WindowListener.init (display);
209+
WindowListener.init (display, daemon_manager);
210210
keyboard_manager = new KeyboardManager (display);
211211
window_tracker = new WindowTracker ();
212212
WindowStateSaver.init (window_tracker);

0 commit comments

Comments
 (0)