[gnome-settings-daemon] media-keys: Add support for Killswitch media keys
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] media-keys: Add support for Killswitch media keys
- Date: Sat, 9 Jan 2016 16:06:00 +0000 (UTC)
commit 3fa0f7260a6864dfe67bdbd82b22b168e1e66457
Author: Bastien Nocera <hadess hadess net>
Date: Fri Jan 8 04:11:02 2016 +0100
media-keys: Add support for Killswitch media keys
Add support for the XF86Bluetooth, XF86WLAN and XF86UWB media keys.
The first one will toggle Bluetooth on/off, as the Bluetooth panel does,
the latter ones will toggle the global software killswitch.
The reasoning behind those 2 keys toggling the global software
killswitch is that:
- we don't have a killswitch for only WiFi
- there are very very few laptops with a UWB killswitch button, if
anyone actually remembers what UWB actually is
- there are no XF86 keys for the global killswitch, so they usually get
mislabeled as the WLAN killswitch
https://bugzilla.gnome.org/show_bug.cgi?id=661643
plugins/media-keys/gsd-media-keys-manager.c | 158 +++++++++++++++++++++++++++
plugins/media-keys/media-keys.h | 2 +
plugins/media-keys/shortcuts-list.h | 3 +
3 files changed, 163 insertions(+), 0 deletions(-)
---
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index 917b47c..b688fcc 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -185,6 +185,11 @@ struct GsdMediaKeysManagerPrivate
guint orientation_watch_id;
gboolean orientation_available;
+ /* RFKill stuff */
+ guint rfkill_watch_id;
+ GDBusProxy *rfkill_proxy;
+ GCancellable *rfkill_cancellable;
+
/* systemd stuff */
GDBusProxy *logind_proxy;
gint inhibit_keys_fd;
@@ -1979,6 +1984,107 @@ do_battery_action (GsdMediaKeysManager *manager)
g_free (icon_name);
}
+static gboolean
+get_rfkill_property (GsdMediaKeysManager *manager,
+ const char *property)
+{
+ GVariant *v;
+ gboolean ret;
+
+ v = g_dbus_proxy_get_cached_property (manager->priv->rfkill_proxy, property);
+ if (!v)
+ return FALSE;
+ ret = g_variant_get_boolean (v);
+ g_variant_unref (v);
+
+ return ret;
+}
+
+typedef struct {
+ GsdMediaKeysManager *manager;
+ char *property;
+ gboolean bluetooth;
+ gboolean target_state;
+} RfkillData;
+
+static void
+set_rfkill_complete (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GVariant *variant;
+ RfkillData *data = user_data;
+
+ variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), result, &error);
+
+ if (variant == NULL) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Failed to set '%s' property: %s", data->property, error->message);
+ g_error_free (error);
+ goto out;
+ }
+ g_variant_unref (variant);
+
+ g_debug ("Finished changing rfkill, property %s is now %s",
+ data->property, data->target_state ? "true" : "false");
+
+ if (data->bluetooth)
+ show_osd (data->manager, data->target_state ? "bluetooth-disabled-symbolic"
+ : "bluetooth-active-symbolic", NULL, -1, OSD_ALL_OUTPUTS);
+ else
+ show_osd (data->manager, data->target_state ? "airplane-mode-symbolic"
+ : "network-wireless-signal-excellent-symbolic", NULL, -1, OSD_ALL_OUTPUTS);
+
+out:
+ g_free (data->property);
+ g_free (data);
+}
+
+static void
+do_rfkill_action (GsdMediaKeysManager *manager,
+ gboolean bluetooth)
+{
+ const char *has_mode, *hw_mode, *mode;
+ gboolean new_state;
+ RfkillData *data;
+
+ has_mode = bluetooth ? "BluetoothHasAirplaneMode" : "HasAirplaneMode";
+ hw_mode = bluetooth ? "BluetoothHardwareAirplaneMode" : "HardwareAirplaneMode";
+ mode = bluetooth ? "BluetoothAirplaneMode" : "AirplaneMode";
+
+ if (manager->priv->rfkill_proxy == NULL)
+ return;
+
+ if (get_rfkill_property (manager, has_mode) == FALSE)
+ return;
+
+ if (get_rfkill_property (manager, hw_mode)) {
+ show_osd (manager, "airplane-mode-symbolic",
+ _("Hardware Airplane Mode"), -1, OSD_ALL_OUTPUTS);
+ return;
+ }
+
+ new_state = !get_rfkill_property (manager, mode);
+ data = g_new0 (RfkillData, 1);
+ data->manager = manager;
+ data->property = g_strdup (mode);
+ data->bluetooth = bluetooth;
+ data->target_state = new_state;
+ g_dbus_proxy_call (manager->priv->rfkill_proxy,
+ "org.freedesktop.DBus.Properties.Set",
+ g_variant_new ("(ssv)",
+ "org.gnome.SettingsDaemon.Rfkill",
+ data->property,
+ g_variant_new_boolean (new_state)),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ manager->priv->rfkill_cancellable,
+ set_rfkill_complete, data);
+
+ g_debug ("Setting rfkill property %s to %s",
+ data->property, new_state ? "true" : "false");
+}
+
static void
screencast_stop (GsdMediaKeysManager *manager)
{
@@ -2205,6 +2311,12 @@ do_action (GsdMediaKeysManager *manager,
case BATTERY_KEY:
do_battery_action (manager);
break;
+ case RFKILL_KEY:
+ do_rfkill_action (manager, FALSE);
+ break;
+ case BLUETOOTH_RFKILL_KEY:
+ do_rfkill_action (manager, TRUE);
+ break;
/* Note, no default so compiler catches missing keys */
case CUSTOM_KEY:
g_assert_not_reached ();
@@ -2366,6 +2478,34 @@ shell_presence_changed (GsdMediaKeysManager *manager)
}
}
+static void
+on_rfkill_proxy_ready (GObject *source,
+ GAsyncResult *result,
+ gpointer data)
+{
+ GsdMediaKeysManager *manager = data;
+
+ manager->priv->rfkill_proxy =
+ g_dbus_proxy_new_for_bus_finish (result, NULL);
+}
+
+static void
+rfkill_appeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ GsdMediaKeysManager *manager = user_data;
+
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ 0, NULL,
+ "org.gnome.SettingsDaemon.Rfkill",
+ "/org/gnome/SettingsDaemon/Rfkill",
+ "org.gnome.SettingsDaemon.Rfkill",
+ manager->priv->rfkill_cancellable,
+ on_rfkill_proxy_ready, manager);
+}
+
static gboolean
start_media_keys_idle_cb (GsdMediaKeysManager *manager)
{
@@ -2405,12 +2545,20 @@ start_media_keys_idle_cb (GsdMediaKeysManager *manager)
ensure_cancellable (&manager->priv->grab_cancellable);
ensure_cancellable (&manager->priv->screencast_cancellable);
+ ensure_cancellable (&manager->priv->rfkill_cancellable);
manager->priv->shell_proxy = gnome_settings_bus_get_shell_proxy ();
g_signal_connect_swapped (manager->priv->shell_proxy, "notify::g-name-owner",
G_CALLBACK (shell_presence_changed), manager);
shell_presence_changed (manager);
+ manager->priv->rfkill_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+ "org.gnome.SettingsDaemon.Rfkill",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ rfkill_appeared_cb,
+ NULL,
+ manager, NULL);
+
g_debug ("Starting mpris controller");
manager->priv->mpris_controller = mpris_controller_new ();
@@ -2476,6 +2624,11 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
manager->priv->gtksettings = NULL;
}
+ if (manager->priv->rfkill_watch_id > 0) {
+ g_bus_unwatch_name (manager->priv->rfkill_watch_id);
+ manager->priv->rfkill_watch_id = 0;
+ }
+
if (manager->priv->orientation_watch_id > 0) {
g_bus_unwatch_name (manager->priv->orientation_watch_id);
manager->priv->orientation_watch_id = 0;
@@ -2530,6 +2683,11 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
g_clear_object (&priv->screencast_cancellable);
}
+ if (priv->rfkill_cancellable != NULL) {
+ g_cancellable_cancel (priv->rfkill_cancellable);
+ g_clear_object (&priv->rfkill_cancellable);
+ }
+
g_clear_object (&priv->sink);
g_clear_object (&priv->source);
g_clear_object (&priv->volume);
diff --git a/plugins/media-keys/media-keys.h b/plugins/media-keys/media-keys.h
index 970415b..387ff05 100644
--- a/plugins/media-keys/media-keys.h
+++ b/plugins/media-keys/media-keys.h
@@ -78,6 +78,8 @@ typedef enum {
KEYBOARD_BRIGHTNESS_DOWN_KEY,
KEYBOARD_BRIGHTNESS_TOGGLE_KEY,
BATTERY_KEY,
+ RFKILL_KEY,
+ BLUETOOTH_RFKILL_KEY,
CUSTOM_KEY
} MediaKeyType;
diff --git a/plugins/media-keys/shortcuts-list.h b/plugins/media-keys/shortcuts-list.h
index e8ab8ea..3ed24c4 100644
--- a/plugins/media-keys/shortcuts-list.h
+++ b/plugins/media-keys/shortcuts-list.h
@@ -107,6 +107,9 @@ static struct {
{ KEYBOARD_BRIGHTNESS_DOWN_KEY, NULL, N_("Keyboard Brightness Down"), "XF86KbdBrightnessDown",
SHELL_ACTION_MODE_ALL },
{ KEYBOARD_BRIGHTNESS_TOGGLE_KEY, NULL, N_("Keyboard Brightness Toggle"), "XF86KbdLightOnOff",
SHELL_ACTION_MODE_ALL },
{ BATTERY_KEY, NULL, N_("Battery Status"), "XF86Battery", GSD_ACTION_MODE_LAUNCHER },
+ { RFKILL_KEY, NULL, N_("Toggle Airplane Mode"), "XF86WLAN", GSD_ACTION_MODE_LAUNCHER },
+ { RFKILL_KEY, NULL, N_("Toggle Airplane Mode"), "XF86UWB", GSD_ACTION_MODE_LAUNCHER },
+ { BLUETOOTH_RFKILL_KEY, NULL, N_("Toggle Bluetooth"), "XF86Bluetooth", GSD_ACTION_MODE_LAUNCHER }
};
#undef SCREENSAVER_MODE
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]