app: fix menu states/callbacks for "Show Layer Masks" and "Disable

Layer Masks", Fixes #14055.

- change the logic to show the toggles in "on" state ONLY when ANY
  selected layer has the property enabled.
- adjust the action callbacks accordingly, and fix them to only push
  undo groups when multiple layers are changed.
- completely remove gimp_layer_tree_view_update_menu(), which did the
  same as the action update code, only more broken, was causing
  redundant undo steps beibng pushed, and was probably obsolete for 20
  years.
This commit is contained in:
Michael Natterer 2025-05-27 19:15:54 +02:00
parent 1f37f92667
commit c460450b4a
3 changed files with 57 additions and 89 deletions

View file

@ -780,8 +780,8 @@ layers_actions_update (GimpActionGroup *group,
gboolean all_visible = TRUE;
gboolean all_next_visible = TRUE;
gboolean all_masks_shown = TRUE;
gboolean all_masks_disabled = TRUE;
gboolean any_mask_shown = FALSE;
gboolean any_mask_disabled = FALSE;
gboolean all_writable = TRUE;
gboolean all_movable = TRUE;
@ -816,10 +816,11 @@ layers_actions_update (GimpActionGroup *group,
if (gimp_layer_get_mask (iter->data))
{
have_masks = TRUE;
if (! gimp_layer_get_show_mask (iter->data))
all_masks_shown = FALSE;
if (gimp_layer_get_apply_mask (iter->data))
all_masks_disabled = FALSE;
if (gimp_layer_get_show_mask (iter->data))
any_mask_shown = TRUE;
if (! gimp_layer_get_apply_mask (iter->data))
any_mask_disabled = TRUE;
}
else
{
@ -1082,8 +1083,8 @@ layers_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("layers-mask-disable", n_selected_layers > 0 && !fs && !ac && have_masks);
SET_ACTIVE ("layers-mask-edit", n_selected_layers == 1 && have_masks && gimp_layer_get_edit_mask (layers->data));
SET_ACTIVE ("layers-mask-show", all_masks_shown);
SET_ACTIVE ("layers-mask-disable", all_masks_disabled);
SET_ACTIVE ("layers-mask-show", any_mask_shown);
SET_ACTIVE ("layers-mask-disable", any_mask_disabled);
SET_SENSITIVE ("layers-mask-selection-replace", n_selected_layers && !fs && !ac && have_masks);
SET_SENSITIVE ("layers-mask-selection-add", n_selected_layers && !fs && !ac && have_masks);

View file

@ -1689,42 +1689,46 @@ layers_mask_show_cmd_callback (GimpAction *action,
GimpImage *image;
GList *layers;
GList *iter;
gboolean active = g_variant_get_boolean (value);
gboolean have_masks = FALSE;
gboolean active = g_variant_get_boolean (value);
gint n_masks = 0;
return_if_no_layers (image, layers, data);
for (iter = layers; iter; iter = iter->next)
{
if (gimp_layer_get_mask (iter->data))
{
have_masks = TRUE;
/* A bit of tricky to handle multiple and diverse layers with
* a toggle action (with only binary state).
* In non-active state, we will consider sets of both shown
* and hidden masks as ok and exits. This allows us to switch
* the action "active" state without actually changing
* individual masks state without explicit user request.
*/
if (! active && ! gimp_layer_get_show_mask (iter->data))
return;
if (active && gimp_layer_get_show_mask (iter->data))
{
/* if switching "show mask" on, and any selected layer's
* mask is already visible, bail out because that's
* exactly the logic we use in the ui for multile
* visible layer masks.
*/
return;
}
if (gimp_layer_get_show_mask (iter->data) != active)
n_masks++;
}
}
if (! have_masks)
if (n_masks == 0)
return;
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_LAYER_ADD,
_("Show Layer Masks"));
if (n_masks > 1)
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_LAYER_ADD,
_("Show Layer Masks"));
for (iter = layers; iter; iter = iter->next)
{
if (gimp_layer_get_mask (iter->data))
{
gimp_layer_set_show_mask (iter->data, active, TRUE);
}
gimp_layer_set_show_mask (iter->data, active, TRUE);
}
gimp_image_undo_group_end (image);
if (n_masks > 1)
gimp_image_undo_group_end (image);
gimp_image_flush (image);
}
@ -1736,42 +1740,46 @@ layers_mask_disable_cmd_callback (GimpAction *action,
GimpImage *image;
GList *layers;
GList *iter;
gboolean active = g_variant_get_boolean (value);
gboolean have_masks = FALSE;
gboolean active = g_variant_get_boolean (value);
gint n_masks = 0;
return_if_no_layers (image, layers, data);
for (iter = layers; iter; iter = iter->next)
{
if (gimp_layer_get_mask (iter->data))
{
have_masks = TRUE;
/* A bit of tricky to handle multiple and diverse layers with
* a toggle action (with only binary state).
* In non-active state, we will consider sets of both enabled
* and disabled masks as ok and exits. This allows us to
* switch the action "active" state without actually changing
* individual masks state without explicit user request.
*/
if (! active && gimp_layer_get_apply_mask (iter->data))
return;
if (active && ! gimp_layer_get_apply_mask (iter->data))
{
/* if switching "disable mask" on, and any selected
* layer's mask is already disabled, bail out because
* that's exactly the logic we use in the ui for multile
* disabled layer masks.
*/
return;
}
if ((! gimp_layer_get_apply_mask (iter->data)) != active)
n_masks++;
}
}
if (! have_masks)
if (n_masks == 0)
return;
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_LAYER_ADD,
_("Disable Layer Masks"));
if (n_masks > 1)
gimp_image_undo_group_start (image,
GIMP_UNDO_GROUP_LAYER_ADD,
_("Disable Layer Masks"));
for (iter = layers; iter; iter = iter->next)
{
if (gimp_layer_get_mask (iter->data))
{
gimp_layer_set_apply_mask (iter->data, ! active, TRUE);
}
gimp_layer_set_apply_mask (iter->data, ! active, TRUE);
}
gimp_image_undo_group_end (image);
if (n_masks > 1)
gimp_image_undo_group_end (image);
gimp_image_flush (image);
}

View file

@ -149,8 +149,6 @@ static void gimp_layer_tree_view_layer_signal_handler (GimpLayer
GimpLayerTreeView *view);
static void gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
GList *layers);
static void gimp_layer_tree_view_update_menu (GimpLayerTreeView *view,
GList *layers);
static void gimp_layer_tree_view_update_highlight (GimpLayerTreeView *view);
static void gimp_layer_tree_view_mask_update (GimpLayerTreeView *view,
GtkTreeIter *iter,
@ -637,7 +635,6 @@ gimp_layer_tree_view_select_items (GimpContainerView *view,
}
gimp_layer_tree_view_update_options (layer_view, items);
gimp_layer_tree_view_update_menu (layer_view, items);
}
}
@ -1232,44 +1229,6 @@ gimp_layer_tree_view_update_options (GimpLayerTreeView *view,
#undef BLOCK
#undef UNBLOCK
static void
gimp_layer_tree_view_update_menu (GimpLayerTreeView *layer_view,
GList *layers)
{
GimpUIManager *ui_manager = gimp_editor_get_ui_manager (GIMP_EDITOR (layer_view));
GimpActionGroup *group;
GList *iter;
gboolean have_masks = FALSE;
gboolean all_masks_shown = TRUE;
gboolean all_masks_disabled = TRUE;
group = gimp_ui_manager_get_action_group (ui_manager, "layers");
for (iter = layers; iter; iter = iter->next)
{
if (gimp_layer_get_mask (iter->data))
{
have_masks = TRUE;
if (! gimp_layer_get_show_mask (iter->data))
all_masks_shown = FALSE;
if (gimp_layer_get_apply_mask (iter->data))
all_masks_disabled = FALSE;
}
}
gimp_action_group_set_action_active (group, "layers-mask-show",
have_masks && all_masks_shown);
gimp_action_group_set_action_active (group, "layers-mask-disable",
have_masks && all_masks_disabled);
/* Only one layer mask at a time can be edited. */
gimp_action_group_set_action_active (group, "layers-mask-edit",
g_list_length (layers) == 1 &&
gimp_layer_get_mask (layers->data) &&
gimp_layer_get_edit_mask (layers->data));
}
static void
gimp_layer_tree_view_update_highlight (GimpLayerTreeView *layer_view)
{