Bug 775931 - Shortcut for non-existing action shadows existing one.

Current logics of dealing with duplicate accelerators was just to delete
one randomly. This works ok in most case since we can't be in the head
of people and can't know which one they want to keep (yet we can't keep
both because that makes it very complicated to reset the shortcut
appropriately by hand/GUI, without a tedious work of researching which
other action uses the same shortcut. See commit 2a232398c4).

There is still some cases where we can be a bit more clever than random
deletion: when one of the accelerator is mapped to a non-existing
action. In this case, let's delete this accelerator in priority. Not
only the chances of this being the expected result are higher; but even
worse, there is anyway no GUI way to delete the accelerator for the
non-existing action! Thus you could try and reset your existing action's
shortcut as many times as you want in the GUI, it would always end up
deleted at next startup!

Note that if the non-existing action's shortcut has no duplicate, it
won't be deleted. This ensure that you could uninstall a plugin, then
reinstall it later and still have your custom shortcuts saved in the
meantime. A shortcut of a non-existing action will *only* be cleaned out
if it is redundant with the shortcut of an existing action.
This commit is contained in:
Jehan 2017-12-05 01:10:13 +01:00
parent 4e4c1cd57e
commit 81d9da0c17
1 changed files with 39 additions and 1 deletions

View File

@ -157,6 +157,7 @@ static void gui_check_unique_accelerator (gpointer data,
guint accel_key, guint accel_key,
GdkModifierType accel_mods, GdkModifierType accel_mods,
gboolean changed); gboolean changed);
static gboolean gui_check_action_exists (const gchar *accel_path);
/* private variables */ /* private variables */
@ -936,7 +937,8 @@ gui_check_unique_accelerator (gpointer data,
GdkModifierType accel_mods, GdkModifierType accel_mods,
gboolean changed) gboolean changed)
{ {
if (gtk_accelerator_valid (accel_key, accel_mods)) if (gtk_accelerator_valid (accel_key, accel_mods) &&
gui_check_action_exists (accel_path))
{ {
accelData accel; accelData accel;
@ -948,3 +950,39 @@ gui_check_unique_accelerator (gpointer data,
gui_compare_accelerator); gui_compare_accelerator);
} }
} }
static gboolean
gui_check_action_exists (const gchar *accel_path)
{
GimpUIManager *manager;
gboolean action_exists = FALSE;
GList *list;
manager = gimp_ui_managers_from_name ("<Image>")->data;
for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
list;
list = g_list_next (list))
{
GtkActionGroup *group = list->data;
GList *actions = NULL;
GList *list2;
actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
for (list2 = actions; list2; list2 = g_list_next (list2))
{
const gchar *path;
GtkAction *action = list2->data;
path = gtk_action_get_accel_path (action);
if (g_strcmp0 (path, accel_path) == 0)
{
action_exists = TRUE;
break;
}
}
g_list_free (actions);
if (action_exists)
break;
}
return action_exists;
}