SHA256
1
0
forked from pool/polari
polari/polari-allow-run-in-background.patch
2017-01-09 11:33:20 +00:00

187 lines
6.8 KiB
Diff

a5244483d205d69774c7adbb4f620ae49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
Date: Fri, 24 Jun 2016 13:15:03 +0200
Subject: app: Add option to run in background
Like other messaging applications, IRC clients don't require constant
attention from the user, but can sit in the background and notify the
user when an important message was received. We currently don't have
any explicit support for this mode, so users need to ignore the window
the best they can (by moving it to another workspace or keeping it at
the bottom of the window stack). This is obviously not great, but neither
are status icons that have traditionally been used by applications to
offer this mode.
Instead, implement a pattern for background applications that was agreed
upon with the GNOME design team:
When set up to run in the background, the application:
- sets itself up to start in the background on login
- keeps running after the last window has been closed
- can be stopped via the 'quit' action in the application menu
https://bugzilla.gnome.org/show_bug.cgi?id=770750
---
data/Makefile.am | 4 +++
data/org.gnome.Polari.Autostart.desktop | 4 +++
data/org.gnome.Polari.gschema.xml | 5 ++++
data/resources/menus.ui | 6 +++++
src/application.js | 48 +++++++++++++++++++++++++++++++--
5 files changed, 65 insertions(+), 2 deletions(-)
create mode 100644 data/org.gnome.Polari.Autostart.desktop
diff --git a/data/Makefile.am b/data/Makefile.am
index 3f9866c..4756d21 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -4,6 +4,9 @@ desktopdir = $(datadir)/applications
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
desktop_in_files = $(APP_ID).desktop.in
+autostartdir = $(pkgdatadir)
+autostart_DATA = $(APP_ID).Autostart.desktop
+
%.desktop: %.desktop.in Makefile
$(AM_V_GEN) $(MSGFMT) --desktop --template $< -d $(top_srcdir)/po -o $@
@@ -25,6 +28,7 @@ clientdir=$(datadir)/telepathy/clients
dist_client_DATA = Polari.client
EXTRA_DIST = \
+ $(autostart_DATA) \
$(desktop_in_files) \
$(service_in_files) \
$(APP_ID).data.gresource.xml \
diff --git a/data/org.gnome.Polari.Autostart.desktop b/data/org.gnome.Polari.Autostart.desktop
new file mode 100644
index 0000000..d0cc77d
--- /dev/null
+++ b/data/org.gnome.Polari.Autostart.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Exec=gapplication action org.gnome.Polari start-client
+NoDisplay=True
diff --git a/data/org.gnome.Polari.gschema.xml b/data/org.gnome.Polari.gschema.xml
index 839983c..d6a16b9 100644
--- a/data/org.gnome.Polari.gschema.xml
+++ b/data/org.gnome.Polari.gschema.xml
@@ -6,6 +6,11 @@
<summary>Saved channel list</summary>
<description>List of channels to restore on startup</description>
</key>
+ <key type="b" name="run-in-background">
+ <default>false</default>
+ <summary>Run in Background</summary>
+ <description>Keep running in background when closed.</description>
+ </key>
<key type="ai" name="window-size">
<default>[800,500]</default>
<summary>Window size</summary>
diff --git a/data/resources/menus.ui b/data/resources/menus.ui
index 22f20e5..eff8d78 100644
--- a/data/resources/menus.ui
+++ b/data/resources/menus.ui
@@ -2,6 +2,12 @@
<menu id="app-menu">
<section>
<item>
+ <attribute name="action">app.run-in-background</attribute>
+ <attribute name="label" translatable="yes">Run in Background</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
<attribute name="action">win.show-help-overlay</attribute>
<attribute name="label" translatable="yes">Keyboard Shortcuts</attribute>
</item>
diff --git a/src/application.js b/src/application.js
index 6e2f40d..7818776 100644
--- a/src/application.js
+++ b/src/application.js
@@ -21,6 +21,9 @@ const MAX_RETRIES = 3;
const IRC_SCHEMA_REGEX = /^(irc?:\/\/)([\da-z\.-]+):?(\d+)?\/(?:%23)?([\w\.\+-]+)/i;
+const AUTOSTART_DIR = GLib.get_user_config_dir() + '/autostart';
+const AUTOSTART_FILE = '/org.gnome.Polari.Autostart.desktop';
+
const Application = new Lang.Class({
Name: 'Application',
Extends: Gtk.Application,
@@ -149,6 +152,14 @@ const Application = new Lang.Class({
this.add_action(action);
}));
+ this._settings = new Gio.Settings({ schema_id: 'org.gnome.Polari' });
+ let action = this._settings.create_action('run-in-background');
+ this.add_action(action);
+
+ this._settings.connect('changed::run-in-background',
+ Lang.bind(this, this._onRunInBackgroundChanged));
+ this._onRunInBackgroundChanged();
+
for (let i = 1; i < 10; i++)
this.set_accels_for_action('app.nth-room(%d)'.format(i), ['<Alt>' + i]);
@@ -184,8 +195,11 @@ const Application = new Lang.Class({
if (!this.active_window) {
let window = new MainWindow.MainWindow({ application: this });
- window.connect('destroy',
- () => { this.emit('prepare-shutdown'); });
+ window.connect('destroy', () => {
+ if (this._settings.get_boolean('run-in-background'))
+ return;
+ this.emit('prepare-shutdown');
+ });
window.connect('notify::active-room',
() => { this.emit('room-focus-changed'); });
window.connect('notify::is-active',
@@ -500,6 +514,35 @@ const Application = new Lang.Class({
dialog.show();
},
+ _createLink: function(file, target) {
+ try {
+ file.get_parent().make_directory_with_parents(null);
+ } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) {
+ // not an error, carry on
+ }
+
+ file.make_symbolic_link(target, null);
+ },
+
+ _onRunInBackgroundChanged: function() {
+ let file = Gio.File.new_for_path(AUTOSTART_DIR + AUTOSTART_FILE);
+
+ if (this._settings.get_boolean('run-in-background'))
+ try {
+ this._createLink(file, pkg.pkgdatadir + AUTOSTART_FILE);
+ } catch(e) {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS))
+ log('Failed to create autostart link: ' + e.message);
+ }
+ else
+ try {
+ file.delete(null);
+ } catch(e) {
+ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
+ log('Failed to remove autostart link: ' + e.message);
+ }
+ },
+
_onStartClient: function() {
if (this._telepathyClient)
return;
@@ -564,5 +607,6 @@ const Application = new Lang.Class({
_onQuit: function() {
this.get_windows().reverse().forEach(w => { w.destroy(); });
+ this.emit('prepare-shutdown');
}
});
--
cgit v0.12