diff --git a/src/client/application/geary-application.vala b/src/client/application/geary-application.vala index b891af11..efcbfb37 100644 --- a/src/client/application/geary-application.vala +++ b/src/client/application/geary-application.vala @@ -74,6 +74,14 @@ public class GearyApplication : Gtk.Application { private const int64 FORCE_SHUTDOWN_USEC = 5 * USEC_PER_SEC; + /** Object returned by {@link get_runtime_information}. */ + public struct RuntimeDetail { + + public string name; + public string value; + + } + [Version (deprecated = true)] public static GearyApplication instance { get { return _instance; } @@ -130,6 +138,90 @@ public class GearyApplication : Gtk.Application { private bool is_destroyed = false; + /** + * Returns name/value pairs of application information. + * + * This includes Geary library version information, the current + * desktop, and so on. + */ + public Gee.Collection get_runtime_information() { + Gee.LinkedList info = + new Gee.LinkedList(); + + /// Application runtime information label + info.add({ _("Geary version"), VERSION }); + /// Application runtime information label + info.add({ _("GTK version"), + "%u.%u.%u".printf( + Gtk.get_major_version(), + Gtk.get_minor_version(), + Gtk.get_micro_version() + )}); + /// Applciation runtime information label + info.add({ _("GLib version"), + "%u.%u.%u".printf( + GLib.Version.major, + GLib.Version.minor, + GLib.Version.micro + )}); + /// Application runtime information label + info.add({ _("WebKitGTK version"), + "%u.%u.%u".printf( + WebKit.get_major_version(), + WebKit.get_minor_version(), + WebKit.get_micro_version() + )}); + /// Application runtime information label + info.add({ _("Desktop environment"), + Environment.get_variable("XDG_CURRENT_DESKTOP") ?? + _("Unknown") + }); + + // Distro name and version using LSB util + + GLib.SubprocessLauncher launcher = new GLib.SubprocessLauncher( + GLib.SubprocessFlags.STDOUT_PIPE | + GLib.SubprocessFlags.STDERR_SILENCE + ); + // Reset lang vars so we can guess the strings below + launcher.setenv("LANGUAGE", "C", true); + launcher.setenv("LANG", "C", true); + launcher.setenv("LC_ALL", "C", true); + + string lsb_output = ""; + try { + GLib.Subprocess lsb_release = launcher.spawnv( + { "lsb_release", "-ir" } + ); + lsb_release.communicate_utf8(null, null, out lsb_output, null); + } catch (GLib.Error err) { + warning("Failed to exec lsb_release: %s", err.message); + } + if (lsb_output != "") { + foreach (string line in lsb_output.split("\n")) { + string[] parts = line.split(":", 2); + if (parts.length > 1) { + if (parts[0].has_prefix("Distributor ID")) { + /// Application runtime information label + info.add( + { _("Distribution name"), parts[1].strip() } + ); + } else if (parts[0].has_prefix("Release")) { + /// Application runtime information label + info.add( + { _("Distribution release"), parts[1].strip() } + ); + } + } + } + } + + /// Application runtime information label + info.add({ _("Installation prefix"), INSTALL_PREFIX }); + + return info; + } + /** * Signal that is activated when 'exit' is called, but before the application actually exits. * diff --git a/src/client/dialogs/dialogs-problem-details-dialog.vala b/src/client/dialogs/dialogs-problem-details-dialog.vala index 28d8e2fd..32bb55d1 100644 --- a/src/client/dialogs/dialogs-problem-details-dialog.vala +++ b/src/client/dialogs/dialogs-problem-details-dialog.vala @@ -24,7 +24,10 @@ public class Dialogs.ProblemDetailsDialog : Gtk.Dialog { Geary.ErrorContext error, Geary.AccountInformation? account, Geary.ServiceInformation? service) { - Object(use_header_bar: 1); + Object( + transient_for: parent, + use_header_bar: 1 + ); set_default_size(600, -1); this.error = error; @@ -50,18 +53,18 @@ public class Dialogs.ProblemDetailsDialog : Gtk.Dialog { private string format_details() { StringBuilder details = new StringBuilder(); - details.append_printf( - "Geary version: %s\n", - GearyApplication.VERSION - ); - details.append_printf( - "GTK version: %u.%u.%u\n", - Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version() - ); - details.append_printf( - "Desktop: %s\n", - Environment.get_variable("XDG_CURRENT_DESKTOP") ?? "Unknown" - ); + + Gtk.ApplicationWindow? parent = + this.get_toplevel() as Gtk.ApplicationWindow; + GearyApplication? app = (parent != null) + ? parent.application as GearyApplication + : null; + if (app != null) { + foreach (GearyApplication.RuntimeDetail? detail + in app.get_runtime_information()) { + details.append_printf("%s: %s", detail.name, detail.value); + } + } if (this.account != null) { details.append_printf( "Account id: %s\n",