diff --git a/data/gnome-shell-dbus-interfaces.gresource.xml b/data/gnome-shell-dbus-interfaces.gresource.xml index db3ef4ac22a2daad8e0f63b15f4430065755be5b..8d335124af7df16ba62ac4139cd7eeb1460f1895 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 99a023fa2633124845f172cf85cc2ce68e68c14e..8848817a0d4aedc7dbc503866030202c20cd578f 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) { @@ -2531,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 f72cba15d29594bc9cf0f309efa3a46231f07c11..e0f5631c6e2d5461201fd19dc36f9348d8d90ff9 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); } /** @@ -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"); @@ -1332,27 +1332,28 @@ 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"); } /** * 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 8a09b642dc4b8cc5871f732940b6d5edd2bdde14..a6b55c3359d5c949706f768ec4c35dae007b31f4 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, diff --git a/src/shell-global.c b/src/shell-global.c index 6ad7a6673aab038c10fe32af00d628cb9afaa4bd..89f163ff46129bdc7b5e0c8f7b58ca0423d7372a 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), @@ -299,6 +304,36 @@ 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); + g_object_notify (G_OBJECT (global), "switcheroo-control"); +} + static void shell_global_init (ShellGlobal *global) { @@ -394,13 +429,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 @@ -1373,7 +1408,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 @@ -1383,7 +1418,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 860e60ab6c9ee5ba50cfcf5ba197a70ba0063a7a..e1fa60aefbb415e7dcd7b9dd6bc6467b54c9cce1 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,