Commit f095a72a authored by Florian Müllner's avatar Florian Müllner
Browse files

app: Offer restart on update

Flatpak gives us a clearly defined way of detecting when the app has
been updated, as well as a portal for spawning the latest version.
Use that to offer a seamless restart whenever the app is updated.

!80
parent 0dccdaa8
Pipeline #44114 passed with stages
in 8 minutes and 22 seconds
......@@ -35,6 +35,33 @@
<action-widget response="accept">backgroundButton</action-widget>
</action-widgets>
</object>
<object class="GtkMessageDialog" id="updateDialog">
<property name="text" translatable="yes">Polari has been updated</property>
<property name="secondary_text" translatable="yes">You can start using the new version immediately without interrupting existing connections, or keep using the current version until Polari is closed.</property>
<property name="destroy-with-parent">true</property>
<property name="modal">true</property>
<child type="action">
<object class="GtkButton" id="ignoreButton">
<property name="label" translatable="yes">Ignore</property>
<property name="visible">True</property>
<property name="can-default">True</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="restartButton">
<property name="label" translatable="yes">Restart Now</property>
<property name="visible">True</property>
<property name="can-default">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
<action-widgets>
<action-widget response="cancel">ignoreButton</action-widget>
<action-widget response="accept">restartButton</action-widget>
</action-widgets>
</object>
<template class="Gjs_MainWindow">
<property name="title" translatable="yes">Polari</property>
<property name="icon-name">org.gnome.Polari</property>
......
......@@ -38,6 +38,7 @@ var Application = GObject.registerClass({
this._windowRemovedId = 0;
this._restarting = false;
this._updatePending = false;
this.add_main_option('start-client', 0,
GLib.OptionFlags.NONE, GLib.OptionArg.NONE,
......@@ -235,6 +236,9 @@ var Application = GObject.registerClass({
accels: ['F1'] },
{ name: 'about',
activate: this._onShowAbout.bind(this) },
{ name: 'restart',
activate: this._onRestart.bind(this),
create_hook: a => { a.enabled = Utils.isFlatpakSandbox(); } },
{ name: 'quit',
activate: this._onQuit.bind(this),
accels: ['<Primary>q'] },
......@@ -341,6 +345,18 @@ var Application = GObject.registerClass({
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
let file = Gio.File.new_for_path('/app/.updated');
this._updateMonitor = file.monitor_file(Gio.FileMonitorFlags.NONE, null);
this._updateMonitor.connect('changed', (mon, file, other, eventType) => {
if (eventType != Gio.FileMonitorEvent.CREATED)
return;
if (this.active_window)
this.active_window.showUpdateDialog();
else
this._updatePending = true;
});
}
vfunc_activate() {
......@@ -371,6 +387,10 @@ var Application = GObject.registerClass({
}
this.active_window.present();
if (this._updatePending)
this.active_window.showUpdateDialog();
this._updatePending = false;
}
vfunc_window_added(window) {
......@@ -861,6 +881,31 @@ var Application = GObject.registerClass({
});
}
_onRestart() {
let cwd = GLib.get_current_dir();
let argv = ['polari', '--gapplication-replace'];
let fds = [];
let envs = [];
let flags = 2; // respawn latest
let options = [];
this.get_dbus_connection().call(
'org.freedesktop.portal.Flatpak',
'/org/freedesktop/portal/Flatpak',
'org.freedesktop.portal.Flatpak',
'Spawn',
new GLib.Variant(
'(ayaaya{uh}a{ss}ua{sv})',
[cwd, argv, fds, envs, flags, options]),
null,
Gio.DBusCallFlags.NONE,
-1,
null,
(conn, res) => {
let [pid] = conn.call_finish(res).deep_unpack();
debug(`Restarted with PID ${pid}`);
});
}
_onQuit() {
if (this._windowRemovedId)
this.disconnect(this._windowRemovedId);
......
......@@ -88,7 +88,8 @@ var MainWindow = GObject.registerClass({
'roomListRevealer',
'overlay',
'roomStack',
'closeConfirmationDialog'],
'closeConfirmationDialog',
'updateDialog'],
Properties: {
subtitle: GObject.ParamSpec.string('subtitle',
'subtitle',
......@@ -193,6 +194,13 @@ var MainWindow = GObject.registerClass({
this.destroy();
});
this._updateDialog.transient_for = this;
this._updateDialog.connect('response', (dlg, response) => {
if (response == Gtk.ResponseType.ACCEPT)
this.application.activate_action('restart', null);
dlg.destroy();
});
this.connect('window-state-event', this._onWindowStateEvent.bind(this));
this.connect('size-allocate', this._onSizeAllocate.bind(this));
this.connect('destroy', this._onDestroy.bind(this));
......@@ -375,6 +383,10 @@ var MainWindow = GObject.registerClass({
this._lastActiveRoom = null;
}
showUpdateDialog() {
this._updateDialog.show();
}
showJoinRoomDialog() {
let dialog = new JoinDialog({ transient_for: this });
dialog.show();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment