diff --git a/data/com.github.tkashkin.gamehub.gschema.xml.in b/data/com.github.tkashkin.gamehub.gschema.xml.in
index 6b3b1256..64e9827d 100644
--- a/data/com.github.tkashkin.gamehub.gschema.xml.in
+++ b/data/com.github.tkashkin.gamehub.gschema.xml.in
@@ -132,6 +132,10 @@
true
Import tags
+
+ true
+ Inhibit screensaver while game is running
+
diff --git a/src/data/runnables/traits/HasExecutableFile.vala b/src/data/runnables/traits/HasExecutableFile.vala
index 5f888d9d..aa9a6b56 100644
--- a/src/data/runnables/traits/HasExecutableFile.vala
+++ b/src/data/runnables/traits/HasExecutableFile.vala
@@ -119,6 +119,7 @@ namespace GameHub.Data.Runnables.Traits
if(!can_be_launched(true)) return;
Runnable.IsAnyRunnableRunning = is_running = true;
+ Inhibitor.inhibit(_("%s is running").printf(name));
update_status();
yield pre_run();
@@ -129,6 +130,7 @@ namespace GameHub.Data.Runnables.Traits
Timeout.add_seconds(1, () => {
Runnable.IsAnyRunnableRunning = is_running = false;
+ Inhibitor.uninhibit();
update_status();
return Source.REMOVE;
});
diff --git a/src/meson.build b/src/meson.build
index 52ecb790..4bb399bb 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -221,6 +221,7 @@ sources = [
'utils/Parser.vala',
'utils/BinaryVDF.vala',
'utils/SignalRateLimiter.vala',
+ 'utils/Inhibitor.vala',
'settings/Settings.vala',
'settings/UI.vala',
diff --git a/src/settings/UI.vala b/src/settings/UI.vala
index 9bdb56e1..2ffbde41 100644
--- a/src/settings/UI.vala
+++ b/src/settings/UI.vala
@@ -202,6 +202,7 @@ namespace GameHub.Settings.UI
public bool grid_doubleclick { get; set; }
public bool merge_games { get; set; }
public bool import_tags { get; set; }
+ public bool inhibit_screensaver { get; set; }
public Behavior()
{
diff --git a/src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala b/src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala
index ddc6001e..25faa0b8 100644
--- a/src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala
+++ b/src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala
@@ -47,6 +47,10 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Pages.UI
var sgrp_tags = new SettingsGroup(_("Tags"));
sgrp_tags.add_setting(new SwitchSetting.bind(_("Import tags from sources"), null, settings, "import-tags"));
add_widget(sgrp_tags);
+
+ var sgrp_system = new SettingsGroup(_("System"));
+ sgrp_system.add_setting(new SwitchSetting.bind(_("Inhibit screensaver while game is running"), _("Request session manager to prevent suspending while game is running"), settings, "inhibit-screensaver"));
+ add_widget(sgrp_system);
}
}
}
diff --git a/src/utils/Inhibitor.vala b/src/utils/Inhibitor.vala
new file mode 100644
index 00000000..71b97e00
--- /dev/null
+++ b/src/utils/Inhibitor.vala
@@ -0,0 +1,100 @@
+/*
+This file is part of GameHub.
+Copyright (C) 2018-2019 Anatoliy Kashkin
+
+GameHub is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GameHub is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GameHub. If not, see .
+*/
+
+using Gtk;
+
+namespace GameHub.Utils
+{
+ public class Inhibitor
+ {
+ private static DBusFreeDesktopScreenSaver? fd_screensaver = null;
+
+ private static uint32? fd_screensaver_inhibit_id = null;
+ private static uint? gtk_inhibit_id = null;
+
+ private static void dbus_connect()
+ {
+ if(fd_screensaver != null) return;
+ try
+ {
+ fd_screensaver = Bus.get_proxy_sync(BusType.SESSION, "org.freedesktop.ScreenSaver", "/ScreenSaver", DBusProxyFlags.NONE);
+ }
+ catch(Error e)
+ {
+ warning("[ScreenSaver.dbus_connect] Failed to connect to DBus: %s", e.message);
+ }
+ }
+
+ public static void inhibit(string? reason = null)
+ {
+ if(!GameHub.Settings.UI.Behavior.instance.inhibit_screensaver) return;
+ reason = reason ?? _("Game is running");
+ if(fd_screensaver_inhibit_id == null)
+ {
+ dbus_connect();
+ if(fd_screensaver != null)
+ {
+ try
+ {
+ fd_screensaver_inhibit_id = fd_screensaver.inhibit("GameHub", reason);
+ }
+ catch(Error e)
+ {
+ warning("[ScreenSaver.inhibit] Failed to inhibit screensaver via DBus: %s", e.message);
+ }
+ }
+ }
+ if(gtk_inhibit_id == null)
+ {
+ gtk_inhibit_id = GameHub.Application.instance.inhibit(GameHub.Application.instance.active_window, ApplicationInhibitFlags.IDLE | ApplicationInhibitFlags.SUSPEND, reason);
+ }
+ }
+
+ public static void uninhibit()
+ {
+ if(fd_screensaver_inhibit_id != null)
+ {
+ dbus_connect();
+ if(fd_screensaver != null)
+ {
+ try
+ {
+ fd_screensaver.un_inhibit(fd_screensaver_inhibit_id);
+ fd_screensaver_inhibit_id = null;
+ }
+ catch(Error e)
+ {
+ warning("[ScreenSaver.uninhibit] Failed to uninhibit screensaver via DBus: %s", e.message);
+ }
+ }
+ }
+ if(gtk_inhibit_id != null)
+ {
+ GameHub.Application.instance.uninhibit(gtk_inhibit_id);
+ gtk_inhibit_id = null;
+ }
+ }
+
+ [DBus(name = "org.freedesktop.ScreenSaver")]
+ private interface DBusFreeDesktopScreenSaver: Object
+ {
+ public abstract uint32 inhibit(string app_name, string reason) throws Error;
+ public abstract void un_inhibit(uint32 cookie) throws Error;
+ }
+ }
+}