From 49605c7b000c06e68cdeab3bab079d5a25d208f3 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Apr 2020 17:24:06 +0200 Subject: [PATCH 1/6] shell/global: Watch for switcheroo-control appearing Rather than staticly expecting switcheroo-control to already be running on the system, wait for it appearing and disappearing. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1226 --- src/shell-global.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/shell-global.c b/src/shell-global.c index 6ad7a6673a..0488c3c441 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -299,6 +299,35 @@ shell_global_get_property(GObject *object, } } +static void +switcheroo_appeared_cb (GDBusConnection *connection, + const char *name, + const char *name_owner, + gpointer user_data) +{ + ShellGlobal *global = user_data; + + g_debug ("switcheroo-control appeared"); + shell_net_hadess_switcheroo_control_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "net.hadess.SwitcherooControl", + "/net/hadess/SwitcherooControl", + global->switcheroo_cancellable, + switcheroo_control_ready_cb, + global); +} + +static void +switcheroo_vanished_cb (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + ShellGlobal *global = user_data; + + g_debug ("switcheroo-control vanished"); + g_clear_object (&global->switcheroo_control); +} + static void shell_global_init (ShellGlobal *global) { @@ -394,13 +423,13 @@ shell_global_init (ShellGlobal *global) g_object_unref, g_object_unref); global->switcheroo_cancellable = g_cancellable_new (); - shell_net_hadess_switcheroo_control_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "net.hadess.SwitcherooControl", - "/net/hadess/SwitcherooControl", - global->switcheroo_cancellable, - switcheroo_control_ready_cb, - global); + g_bus_watch_name (G_BUS_TYPE_SYSTEM, + "net.hadess.SwitcherooControl", + G_BUS_NAME_WATCHER_FLAGS_NONE, + switcheroo_appeared_cb, + switcheroo_vanished_cb, + global, + NULL); } static void -- GitLab From 9d7832ea44470ebbb6bb8ce499a6a504f5bb5593 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Apr 2020 17:25:18 +0200 Subject: [PATCH 2/6] shell/global: Make switcheroo-control available from JS https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1226 --- src/shell-app.c | 2 +- src/shell-global.c | 4 ++-- src/shell-global.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shell-app.c b/src/shell-app.c index f72cba15d2..e7353274c9 100644 --- a/src/shell-app.c +++ b/src/shell-app.c @@ -1289,7 +1289,7 @@ apply_discrete_gpu_env (GAppLaunchContext *context, GVariant* variant; guint num_children, i; - proxy = _shell_global_get_switcheroo_control (global); + proxy = shell_global_get_switcheroo_control (global); if (!proxy) { g_warning ("Could not apply discrete GPU environment, switcheroo-control not available"); diff --git a/src/shell-global.c b/src/shell-global.c index 0488c3c441..2390c711e4 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -1402,7 +1402,7 @@ shell_global_sync_pointer (ShellGlobal *global) } /** - * _shell_global_get_switcheroo_control: (skip) + * shell_global_get_switcheroo_control: * @global: A #ShellGlobal * * Get the global #GDBusProxy instance for the switcheroo-control @@ -1412,7 +1412,7 @@ shell_global_sync_pointer (ShellGlobal *global) * or %NULL on error. */ GDBusProxy * -_shell_global_get_switcheroo_control (ShellGlobal *global) +shell_global_get_switcheroo_control (ShellGlobal *global) { return global->switcheroo_control; } diff --git a/src/shell-global.h b/src/shell-global.h index 860e60ab6c..e1fa60aefb 100644 --- a/src/shell-global.h +++ b/src/shell-global.h @@ -67,7 +67,7 @@ void shell_global_run_at_leisure (ShellGlobal *global, void shell_global_sync_pointer (ShellGlobal *global); GDBusProxy * - _shell_global_get_switcheroo_control (ShellGlobal *global); + shell_global_get_switcheroo_control (ShellGlobal *global); GAppLaunchContext * shell_global_create_app_launch_context (ShellGlobal *global, -- GitLab From b17017679b084135e34699386212a2f02528ff10 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Apr 2020 17:36:48 +0200 Subject: [PATCH 3/6] shell/global: Notify when switcheroo-control prop changes https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1226 --- src/shell-global.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/shell-global.c b/src/shell-global.c index 2390c711e4..89f163ff46 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -148,6 +148,7 @@ got_switcheroo_control_gpus_property_cb (GObject *source_object, global = user_data; g_dbus_proxy_set_cached_property (global->switcheroo_control, "GPUs", gpus); + g_object_notify (G_OBJECT (global), "switcheroo-control"); } static void @@ -175,7 +176,11 @@ switcheroo_control_ready_cb (GObject *source_object, cached_props = g_dbus_proxy_get_cached_property_names (global->switcheroo_control); if (cached_props != NULL && g_strv_contains ((const gchar * const *) cached_props, "GPUs")) - return; + { + g_object_notify (G_OBJECT (global), "switcheroo-control"); + return; + } + /* Delay property notification until we have all the properties gathered */ g_dbus_connection_call (g_dbus_proxy_get_connection (global->switcheroo_control), g_dbus_proxy_get_name (global->switcheroo_control), @@ -326,6 +331,7 @@ switcheroo_vanished_cb (GDBusConnection *connection, g_debug ("switcheroo-control vanished"); g_clear_object (&global->switcheroo_control); + g_object_notify (G_OBJECT (global), "switcheroo-control"); } static void -- GitLab From 3bfa9916dacd1c22691cb6931924b88728020c3f Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Apr 2020 17:37:29 +0200 Subject: [PATCH 4/6] appDisplay: Use global switcheroo-control D-Bus proxy Rather than creating our own. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1226 --- .../gnome-shell-dbus-interfaces.gresource.xml | 1 - js/ui/appDisplay.js | 37 +++++-------------- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/data/gnome-shell-dbus-interfaces.gresource.xml b/data/gnome-shell-dbus-interfaces.gresource.xml index db3ef4ac22..8d335124af 100644 --- a/data/gnome-shell-dbus-interfaces.gresource.xml +++ b/data/gnome-shell-dbus-interfaces.gresource.xml @@ -2,7 +2,6 @@ net.hadess.SensorProxy.xml - net.hadess.SwitcherooControl.xml org.freedesktop.Application.xml org.freedesktop.bolt1.Device.xml org.freedesktop.bolt1.Manager.xml diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 99a023fa26..604e4cd643 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -18,8 +18,6 @@ const Params = imports.misc.params; const Util = imports.misc.util; const SystemActions = imports.misc.systemActions; -const { loadInterfaceXML } = imports.misc.fileUtils; - var MENU_POPUP_TIMEOUT = 600; var MAX_COLUMNS = 6; var MIN_COLUMNS = 4; @@ -46,11 +44,6 @@ const FOLDER_DIALOG_ANIMATION_TIME = 200; const OVERSHOOT_THRESHOLD = 20; const OVERSHOOT_TIMEOUT = 1000; -const SWITCHEROO_BUS_NAME = 'net.hadess.SwitcherooControl'; -const SWITCHEROO_OBJECT_PATH = '/net/hadess/SwitcherooControl'; - -const SwitcherooProxyInterface = loadInterfaceXML('net.hadess.SwitcherooControl'); -const SwitcherooProxy = Gio.DBusProxy.makeProxyWrapper(SwitcherooProxyInterface); let discreteGpuAvailable = false; function _getCategories(info) { @@ -1162,31 +1155,19 @@ class AppDisplay extends St.BoxLayout { this._showView(initialView); this._updateFrequentVisibility(); - Gio.DBus.system.watch_name(SWITCHEROO_BUS_NAME, - Gio.BusNameWatcherFlags.NONE, - this._switcherooProxyAppeared.bind(this), - () => { - this._switcherooProxy = null; - this._updateDiscreteGpuAvailable(); - }); + this._switcherooNotifyId = global.connect('notify::switcheroo-control', + () => this._updateDiscreteGpuAvailable()); + this._updateDiscreteGpuAvailable(); } _updateDiscreteGpuAvailable() { - if (!this._switcherooProxy) + this._switcherooProxy = global.get_switcheroo_control(); + if (this._switcherooProxy) { + let prop = this._switcherooProxy.get_cached_property('HasDualGpu'); + discreteGpuAvailable = prop ? prop.unpack() : false; + } else { discreteGpuAvailable = false; - else - discreteGpuAvailable = this._switcherooProxy.HasDualGpu; - } - - _switcherooProxyAppeared() { - this._switcherooProxy = new SwitcherooProxy(Gio.DBus.system, SWITCHEROO_BUS_NAME, SWITCHEROO_OBJECT_PATH, - (proxy, error) => { - if (error) { - log(error.message); - return; - } - this._updateDiscreteGpuAvailable(); - }); + } } animate(animationDirection, onComplete) { -- GitLab From 13dcd78be1fe326aa2f9bb9d2cbc5843a89c1c57 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 29 Apr 2020 11:19:28 +0200 Subject: [PATCH 5/6] shell-app: Downgrade not finding a discrete GPU to debug As we'll want to call this unconditionally soon. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1226 --- src/shell-app.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell-app.c b/src/shell-app.c index e7353274c9..716a91c4f8 100644 --- a/src/shell-app.c +++ b/src/shell-app.c @@ -1332,7 +1332,7 @@ apply_discrete_gpu_env (GAppLaunchContext *context, return; } - g_warning ("Could not find discrete GPU data in switcheroo-control"); + g_debug ("Could not find discrete GPU in switcheroo-control, not applying environment"); } /** -- GitLab From 34da48453e592dc22102840cbf872f9d01bd8d3f Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 29 Apr 2020 11:20:40 +0200 Subject: [PATCH 6/6] shell-app: Add PrefersNonDefaultGPU support to shell_app_launch() Read the "PrefersNonDefaultGPU" key in desktop files to figure out whether the application prefers running on the discrete GPU, or the default GPU, and apply that. Update the "Launch..." contextual menu to allow launching on the default GPU if the application "prefers [the] non default GPU". See: https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#recognized-keys https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1804 --- js/ui/appDisplay.js | 12 +++++++++--- src/shell-app.c | 22 ++++++++++++++-------- src/shell-app.h | 16 +++++++++++----- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index 604e4cd643..8848817a0d 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -2512,10 +2512,16 @@ var AppIconMenu = class AppIconMenu extends PopupMenu.PopupMenu { if (discreteGpuAvailable && this._source.app.state == Shell.AppState.STOPPED) { - this._onDiscreteGpuMenuItem = this._appendMenuItem(_("Launch using Dedicated Graphics Card")); - this._onDiscreteGpuMenuItem.connect('activate', () => { + const appPrefersNonDefaultGPU = appInfo.get_boolean('PrefersNonDefaultGPU'); + const gpuPref = appPrefersNonDefaultGPU + ? Shell.AppLaunchGpu.DEFAULT + : Shell.AppLaunchGpu.DISCRETE; + this._onGpuMenuItem = this._appendMenuItem(appPrefersNonDefaultGPU + ? _('Launch using Integrated Graphics Card') + : _('Launch using Discrete Graphics Card')); + this._onGpuMenuItem.connect('activate', () => { this._source.animateLaunch(); - this._source.app.launch(0, -1, true); + this._source.app.launch(0, -1, gpuPref); this.emit('activate-window', null); }); } diff --git a/src/shell-app.c b/src/shell-app.c index 716a91c4f8..e0f5631c6e 100644 --- a/src/shell-app.c +++ b/src/shell-app.c @@ -531,7 +531,7 @@ shell_app_activate_full (ShellApp *app, case SHELL_APP_STATE_STOPPED: { GError *error = NULL; - if (!shell_app_launch (app, timestamp, workspace, FALSE, &error)) + if (!shell_app_launch (app, timestamp, workspace, SHELL_APP_LAUNCH_GPU_APP_PREF, &error)) { char *msg; msg = g_strdup_printf (_("Failed to launch ā€œ%sā€"), shell_app_get_name (app)); @@ -606,7 +606,7 @@ shell_app_open_new_window (ShellApp *app, * instance (Firefox). There are a few less-sensical cases such * as say Pidgin. */ - shell_app_launch (app, 0, workspace, FALSE, NULL); + shell_app_launch (app, 0, workspace, SHELL_APP_LAUNCH_GPU_APP_PREF, NULL); } /** @@ -1339,20 +1339,21 @@ apply_discrete_gpu_env (GAppLaunchContext *context, * shell_app_launch: * @timestamp: Event timestamp, or 0 for current event timestamp * @workspace: Start on this workspace, or -1 for default - * @discrete_gpu: Whether to start on the discrete GPU + * @gpu_pref: the GPU to prefer launching on * @error: A #GError */ gboolean -shell_app_launch (ShellApp *app, - guint timestamp, - int workspace, - gboolean discrete_gpu, - GError **error) +shell_app_launch (ShellApp *app, + guint timestamp, + int workspace, + ShellAppLaunchGpu gpu_pref, + GError **error) { ShellGlobal *global; GAppLaunchContext *context; gboolean ret; GSpawnFlags flags; + gboolean discrete_gpu = FALSE; if (app->info == NULL) { @@ -1369,6 +1370,11 @@ shell_app_launch (ShellApp *app, global = shell_global_get (); context = shell_global_create_app_launch_context (global, timestamp, workspace); + if (gpu_pref == SHELL_APP_LAUNCH_GPU_APP_PREF) + discrete_gpu = g_desktop_app_info_get_boolean (app->info, "PrefersNonDefaultGPU"); + else + discrete_gpu = (gpu_pref == SHELL_APP_LAUNCH_GPU_DISCRETE); + if (discrete_gpu) apply_discrete_gpu_env (context, global); diff --git a/src/shell-app.h b/src/shell-app.h index 8a09b642dc..a6b55c3359 100644 --- a/src/shell-app.h +++ b/src/shell-app.h @@ -18,6 +18,12 @@ typedef enum { SHELL_APP_STATE_RUNNING } ShellAppState; +typedef enum { + SHELL_APP_LAUNCH_GPU_APP_PREF = 0, + SHELL_APP_LAUNCH_GPU_DISCRETE, + SHELL_APP_LAUNCH_GPU_DEFAULT +} ShellAppLaunchGpu; + const char *shell_app_get_id (ShellApp *app); GDesktopAppInfo *shell_app_get_app_info (ShellApp *app); @@ -51,11 +57,11 @@ GSList *shell_app_get_pids (ShellApp *app); gboolean shell_app_is_on_workspace (ShellApp *app, MetaWorkspace *workspace); -gboolean shell_app_launch (ShellApp *app, - guint timestamp, - int workspace, - gboolean discrete_gpu, - GError **error); +gboolean shell_app_launch (ShellApp *app, + guint timestamp, + int workspace, + ShellAppLaunchGpu gpu_pref, + GError **error); void shell_app_launch_action (ShellApp *app, const char *action_name, -- GitLab