diff --git a/app/actions/actions.c b/app/actions/actions.c index 97ea4d0d17..7240d45ccb 100644 --- a/app/actions/actions.c +++ b/app/actions/actions.c @@ -104,6 +104,7 @@ /* global variables */ GimpActionFactory *global_action_factory = NULL; +GHashTable *aux_filter_hash_table = NULL; /* private variables */ @@ -270,6 +271,8 @@ actions_init (Gimp *gimp) action_groups[i].icon_name, action_groups[i].setup_func, action_groups[i].update_func); + + aux_filter_hash_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); } void @@ -280,6 +283,23 @@ actions_exit (Gimp *gimp) g_return_if_fail (global_action_factory->gimp == gimp); g_clear_object (&global_action_factory); + g_hash_table_unref (aux_filter_hash_table); +} + +/* XXX Temporary code to store the list of filter operations with an + * "aux" input. This won't be necessary anymore once these filters can + * be applied non-destructively too in the future. + */ +void +actions_filter_set_aux (const gchar *action_name) +{ + g_hash_table_add (aux_filter_hash_table, (gpointer) g_strdup (action_name)); +} + +gboolean +actions_filter_get_aux (const gchar *action_name) +{ + return g_hash_table_lookup (aux_filter_hash_table, action_name) != NULL; } Gimp * diff --git a/app/actions/actions.h b/app/actions/actions.h index 494a03e1bb..89f05f709b 100644 --- a/app/actions/actions.h +++ b/app/actions/actions.h @@ -24,6 +24,9 @@ extern GimpActionFactory *global_action_factory; void actions_init (Gimp *gimp); void actions_exit (Gimp *gimp); +void actions_filter_set_aux (const gchar *action_name); +gboolean actions_filter_get_aux (const gchar *action_name); + Gimp * action_data_get_gimp (gpointer data); GimpContext * action_data_get_context (gpointer data); GimpImage * action_data_get_image (gpointer data); diff --git a/app/actions/filters-actions.c b/app/actions/filters-actions.c index bcc617a52f..e0f3e8e6de 100644 --- a/app/actions/filters-actions.c +++ b/app/actions/filters-actions.c @@ -754,10 +754,10 @@ static const GimpEnumActionEntry filters_repeat_actions[] = void filters_actions_setup (GimpActionGroup *group) { + static gboolean first_setup = TRUE; GimpProcedureActionEntry *entries; gint n_entries; gint i; - GList *actions; GList *op_classes; GList *iter; GStrvBuilder *gegl_actions; @@ -783,6 +783,21 @@ filters_actions_setup (GimpActionGroup *group) filters_actions_set_tooltips (group, filters_interactive_actions, G_N_ELEMENTS (filters_interactive_actions)); + /* XXX Hardcoded list to prevent expensive node/graph creation of a + * well-known list of operations. + * This whole code will disappear when we'll support filters with aux + * input non-destructively anyway. + */ + if (first_setup) + { + actions_filter_set_aux ("filters-variable-blur"); + actions_filter_set_aux ("filters-oilify"); + actions_filter_set_aux ("filters-lens-blur"); + actions_filter_set_aux ("filters-gaussian-blur-selective"); + actions_filter_set_aux ("filters-displace"); + actions_filter_set_aux ("filters-bump-map"); + } + gegl_actions = g_strv_builder_new (); op_classes = gimp_gegl_get_op_classes (TRUE); @@ -868,6 +883,23 @@ filters_actions_setup (GimpActionGroup *group) g_free (short_label); } + /* Identify third-party filters based on operations with an + * auxiliary pad in first setup because of slowness on Windows. + * See #14781. + */ + if (first_setup) + { + GeglNode *node = gegl_node_new (); + + gegl_node_set (node, + "operation", op_class->name, + NULL); + + if (gegl_node_has_pad (node, "aux")) + actions_filter_set_aux (action_name); + + g_clear_object (&node); + } g_strv_builder_add (gegl_actions, action_name); g_free (label); @@ -882,40 +914,6 @@ filters_actions_setup (GimpActionGroup *group) g_strv_builder_unref (gegl_actions); g_list_free (op_classes); - /* Identify all filters based on operations with an auxiliary pad in - * setup because of slowness on Windows. See #14781. - */ - actions = gimp_action_group_list_actions (group); - for (iter = actions; iter; iter = iter->next) - { - GimpAction *action = iter->data; - const gchar *action_name; - - action_name = gimp_action_get_name (action); - - if (! filters_is_non_interactive (action_name) && GIMP_IS_STRING_ACTION (action)) - { - const gchar *opname; - - opname = GIMP_STRING_ACTION (action)->value; - - if (opname != NULL && g_strcmp0 (opname, "gegl:gegl") != 0 && gegl_has_operation (opname)) - { - GeglNode *node = gegl_node_new (); - - gegl_node_set (node, - "operation", opname, - NULL); - - if (gegl_node_has_pad (node, "aux")) - g_object_set_data (G_OBJECT (action), "filters-action-has-pad", GINT_TO_POINTER (TRUE)); - - g_clear_object (&node); - } - } - } - g_list_free (actions); - gimp_action_group_add_enum_actions (group, "filters-action", filters_repeat_actions, G_N_ELEMENTS (filters_repeat_actions), @@ -951,6 +949,8 @@ filters_actions_setup (GimpActionGroup *group) group, 0); filters_actions_history_changed (group->gimp, group); + + first_setup = FALSE; } void @@ -1054,7 +1054,7 @@ filters_actions_update (GimpActionGroup *group, * types of layers where filters can only be applied * non-destructively. */ - sensitive = ! GPOINTER_TO_INT (g_object_get_data (G_OBJECT (action), "filters-action-has-pad")); + sensitive = ! actions_filter_get_aux (action_name); SET_SENSITIVE (gimp_action_get_name (action), sensitive); }