Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.3:Staging:C:DVD
gnome-settings-daemon
gnome-settings-daemon-keybindings-become-unavai...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gnome-settings-daemon-keybindings-become-unavaiable.patch of Package gnome-settings-daemon
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c index 719e041..ff84f49 100644 --- a/plugins/media-keys/gsd-media-keys-manager.c +++ b/plugins/media-keys/gsd-media-keys-manager.c @@ -126,6 +126,8 @@ typedef struct { } MediaPlayer; typedef struct { + gint ref_count; + MediaKeyType key_type; ShellActionMode modes; const char *settings_key; @@ -133,6 +135,7 @@ typedef struct { char *custom_path; char *custom_command; guint accel_id; + gboolean ungrab_requested; } MediaKey; typedef struct { @@ -180,6 +183,8 @@ struct GsdMediaKeysManagerPrivate GsdShell *shell_proxy; ShellKeyGrabber *key_grabber; GCancellable *grab_cancellable; + GHashTable *keys_pending_grab; + GHashTable *keys_to_grab; /* ScreenSaver stuff */ GsdScreenSaver *screen_saver_proxy; @@ -235,15 +240,31 @@ static gpointer manager_object = NULL; static void -media_key_free (MediaKey *key) +media_key_unref (MediaKey *key) { if (key == NULL) return; + if (!g_atomic_int_dec_and_test (&key->ref_count)) + return; g_free (key->custom_path); g_free (key->custom_command); g_free (key); } +static MediaKey * +media_key_ref (MediaKey *key) +{ + g_atomic_int_inc (&key->ref_count); + return key; +} + +static MediaKey * +media_key_new (void) +{ + MediaKey *key = g_new0 (MediaKey, 1); + return media_key_ref (key); +} + static void set_launch_context_env (GsdMediaKeysManager *manager, GAppLaunchContext *launch_context) @@ -452,8 +473,10 @@ grab_accelerator_complete (GObject *object, GAsyncResult *result, gpointer user_data) { + char *binding; GrabData *data = user_data; MediaKey *key = data->key; + GsdMediaKeysManager *manager = data->manager; GError *error = NULL; if (!shell_key_grabber_call_grab_accelerator_finish (SHELL_KEY_GRABBER (object), @@ -463,7 +486,20 @@ grab_accelerator_complete (GObject *object, g_error_free (error); } + if (key->ungrab_requested) + ungrab_media_key (key, manager); + + binding = get_key_string (manager, key); + g_hash_table_remove (manager->priv->keys_pending_grab, binding); + media_key_unref (key); g_slice_free (GrabData, data); + + if ((key = g_hash_table_lookup (manager->priv->keys_to_grab, binding)) != NULL) { + grab_media_key (key, manager); + g_hash_table_remove (manager->priv->keys_to_grab, binding); + } + g_free (binding); + } static void @@ -471,23 +507,27 @@ grab_media_key (MediaKey *key, GsdMediaKeysManager *manager) { GrabData *data; - char *tmp; + char *binding; - ungrab_media_key (key, manager); - - tmp = get_key_string (manager, key); + binding = get_key_string (manager, key); + if (g_hash_table_lookup (manager->priv->keys_pending_grab, binding)) { + g_hash_table_insert (manager->priv->keys_to_grab, + g_strdup (binding), media_key_ref (key)); + goto out; + } data = g_slice_new0 (GrabData); data->manager = manager; - data->key = key; + data->key = media_key_ref (key); shell_key_grabber_call_grab_accelerator (manager->priv->key_grabber, - tmp, key->modes, + binding, key->modes, manager->priv->grab_cancellable, grab_accelerator_complete, data); - - g_free (tmp); + g_hash_table_add (manager->priv->keys_pending_grab, g_strdup (binding)); + out: + g_free (binding); } static void @@ -509,8 +549,10 @@ static void ungrab_media_key (MediaKey *key, GsdMediaKeysManager *manager) { - if (key->accel_id == 0) - return; + if (key->accel_id == 0) { + key->ungrab_requested = TRUE; + return; + } shell_key_grabber_call_ungrab_accelerator (manager->priv->key_grabber, key->accel_id, @@ -556,6 +598,7 @@ gsettings_changed_cb (GSettings *settings, if (key->settings_key == NULL) continue; if (strcmp (settings_key, key->settings_key) == 0) { + ungrab_media_key (key, manager); grab_media_key (key, manager); break; } @@ -576,7 +619,7 @@ media_key_new_for_path (GsdMediaKeysManager *manager, if (settings == NULL) { settings = g_settings_new_with_path (CUSTOM_BINDING_SCHEMA, path); - g_signal_connect (settings, "changed", + g_signal_connect (settings, "changed::binding", G_CALLBACK (custom_binding_changed), manager); g_hash_table_insert (manager->priv->custom_settings, g_strdup (path), settings); @@ -593,7 +636,7 @@ media_key_new_for_path (GsdMediaKeysManager *manager, } g_free (binding); - key = g_new0 (MediaKey, 1); + key = media_key_new (); key->key_type = CUSTOM_KEY; key->modes = GSD_ACTION_MODE_LAUNCHER; key->custom_path = g_strdup (path); @@ -640,7 +683,7 @@ custom_binding_changed (GSettings *settings, { char *path; - if (strcmp (settings_key, "name") == 0) + if (strcmp (settings_key, "binding") != 0) return; /* we don't care */ g_object_get (settings, "path", &path, NULL); @@ -694,7 +737,7 @@ add_key (GsdMediaKeysManager *manager, guint i) { MediaKey *key; - key = g_new0 (MediaKey, 1); + key = media_key_new (); key->key_type = media_keys[i].key_type; key->settings_key = media_keys[i].settings_key; key->hard_coded = media_keys[i].hard_coded; @@ -2783,7 +2826,12 @@ start_media_keys_idle_cb (GsdMediaKeysManager *manager) g_debug ("Starting media_keys manager"); gnome_settings_profile_start (NULL); - manager->priv->keys = g_ptr_array_new_with_free_func ((GDestroyNotify) media_key_free); + manager->priv->keys = g_ptr_array_new_with_free_func ((GDestroyNotify) media_key_unref); + + manager->priv->keys_pending_grab = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + manager->priv->keys_to_grab = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) media_key_unref); initialize_volume_handler (manager); @@ -2943,6 +2991,9 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager) priv->keys = NULL; } + g_clear_pointer (&priv->keys_pending_grab, g_hash_table_destroy); + g_clear_pointer (&priv->keys_to_grab, g_hash_table_destroy); + g_clear_object (&priv->key_grabber); if (priv->grab_cancellable != NULL) {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor