[gnome-boxes/wip/run-in-bg: 7/13] app: Keep GApplication alive when running in background
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes/wip/run-in-bg: 7/13] app: Keep GApplication alive when running in background
- Date: Tue, 15 Dec 2020 10:28:56 +0000 (UTC)
commit 181d3035f4ddfe252b2030aa28f3c9e9464de19e
Author: Felipe Borges <felipeborges gnome org>
Date: Fri Dec 4 12:54:52 2020 +0100
app: Keep GApplication alive when running in background
A long standing UX issue we have in Boxes are the "run in background"
virtual machines. In a typical bare metal session, Boxes wouldn't
suspend these VMs and instead keep them running thanks to libvirtd.
But for the Flatpaked apps, the lifetime of the libvirt daemon is
tied to the lifetime of Boxes itself, therefore we need to manage
it.
This solution identifies whether the "run in bg" VMs are running, and
if so, it will just hide the Boxes window and keep the GApplication
running in the background. This allows for jumping back to Boxes
if the user wants.
We also throw a notification indicating that a virtual machine is
running in the background, so the user has an UI to access the VM.
Fixes #379
src/app.vala | 65 +++++++++++++++++++++++++++++++++++++++++++++---
src/libvirt-machine.vala | 1 +
2 files changed, 62 insertions(+), 4 deletions(-)
---
diff --git a/src/app.vala b/src/app.vala
index 557f2942..4e69ee79 100644
--- a/src/app.vala
+++ b/src/app.vala
@@ -37,6 +37,10 @@ public virtual async void add_source (CollectionSource source) throws GLib.Error
private bool is_ready;
public signal void ready ();
+ public bool run_in_bg {
+ get; private set;
+ }
+
// A callback to notify that deletion of machines was undone by user.
public delegate void UndoNotifyCallback ();
@@ -92,6 +96,10 @@ public App () {
action.activate.connect ((param) => { open_name (param.get_string ()); });
add_action (action);
+ action = new GLib.SimpleAction ("launch-run-in-bg-box", GLib.VariantType.STRING);
+ action.activate.connect ((param) => { open_run_in_bg_vm (param.get_string ()); });
+ add_action (action);
+
action = new GLib.SimpleAction ("install", GLib.VariantType.STRING);
action.activate.connect ((param) => { install (param.get_string ()); });
add_action (action);
@@ -280,6 +288,10 @@ public bool quit_app () {
var display = Gdk.Display.get_default ();
display.flush ();
+ keep_on_running_on_background ();
+ if (run_in_bg)
+ return true;
+
Idle.add (() => {
quit ();
@@ -290,17 +302,32 @@ public bool quit_app () {
}
public override void shutdown () {
- base.shutdown ();
+ if (!run_in_bg) {
+ base.shutdown ();
+
+ // Withdraw all the existing notifications
+ foreach (var notification in system_notifications)
+ withdraw_notification (notification);
+ } else {
+ this.hold ();
+ }
foreach (var window in windows) {
window.notificationbar.dismiss_all ();
}
async_launcher.await_all ();
suspend_machines ();
+ }
+
+ private void open_run_in_bg_vm (string name) {
+ activate ();
+
+ var app = this;
+ main_window.present ();
+ call_when_ready (() => {
+ open_name (name);
+ });
- // Withdraw all the existing notifications
- foreach (var notification in system_notifications)
- withdraw_notification (notification);
}
public void open_name (string name) {
@@ -500,6 +527,36 @@ yield foreach_filename_from_dir (dir, (filename) => {
}
}
+ private void keep_vm_running_in_background (LibvirtMachine machine) {
+ if (!machine.run_in_bg && !machine.is_running)
+ return;
+
+ var msg = _("ā%sā is running in the background").printf (machine.name);
+ var notification = new GLib.Notification (msg);
+ notification.set_default_action ("app.launch-run-in-bg-box::" + machine.name);
+
+ send_notification ("gnome-boxes-run-in-bg-%s" + machine.name, notification);
+ }
+
+ private void keep_on_running_on_background () {
+ if (collection == null)
+ return;
+
+ run_in_bg = false;
+ collection.foreach_item((item) => {
+ var machine = item as LibvirtMachine;
+
+ var keep_vm_running = (machine.run_in_bg && machine.is_running);
+ if (keep_vm_running) {
+ run_in_bg = true;
+
+ keep_vm_running_in_background (machine);
+ debug ("Keep running %s in the background", machine.name);
+
+ }
+ });
+ }
+
private void suspend_machines () {
// if we are not the main Boxes instance, 'collection' won't
// be set as it's created in GtkApplication::startup()
diff --git a/src/libvirt-machine.vala b/src/libvirt-machine.vala
index fad51144..474be0db 100644
--- a/src/libvirt-machine.vala
+++ b/src/libvirt-machine.vala
@@ -47,6 +47,7 @@
}
}
+ public bool is_running { get { return state == MachineState.RUNNING; } }
public bool run_in_bg { get; set; } // If true, machine will never be paused automatically by Boxes.
private bool _acceleration_3d;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]