napari: Allow handling of removing layer event before triggering removed event for napari layers

🚀 Feature

I would like napari to synchronously run the removing layer event handler, followed by the removed layer event handler, unlike the current behavior where the latter does not wait for the former to finish. If a user decides to cancel the removal of the layer, then there should be a mechanism in the removing layer event handler which prevents the layer from being removed.

Motivation

I am working on a brightest path image tracing plugin and I want to be able to provide the user with:

  1. an option to save the tracings that they’ve generated thus far for the layer that they’re planning to remove
  2. an option to cancel the layer removal

The right place to handle these seems to be in handler for the removing event which provides information about the layer that is about to be removed. Immediately after this event, the removed event is triggered and the layer is removed from the napari viewer.

I added the code to save the tracings in the removing event handler but the layer is removed and the removed event is triggered even before the handler for removing has finished.

Pitch

  1. I would like the napari viewer to wait for the removing event handler to finish before removing the layer and triggering the removed event.
  2. There needs to be a mechanism to prevent the layer from being removed depending on the behavior in the removing event handler.

cc @cudmore

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Comments: 15 (10 by maintainers)

Most upvoted comments

Hm. From one side I see that it is nice to have the option to prevent removing a layer.

But from another hand, such an option may really confuse users. There are two cases:

  1. User removes the layer using the button. Then we should at least inform the user that removing the layer was blocked. In an ideal situation, this should contain information on which plugin prevents this. Otherwise, I expect the Issue “Remove button not working”
  2. Layer is deleted using API. In such a situation, silent prevention of removing layers is a bug. It is a valid assumption that after calling del viewer.layers[name] the layer is removed. So this feature should not be enabled when using API or it should raise an exception.

Maybe the better solution will be to add protected attribute to the layer? And if the layer is marked as protected then show a dialog with the question on the side of napari?

cc: @jni

Hi @akuten1298, thanks for working on a fix for this. For me the handler of the “removing” event does get triggered before that of the “removed” event. However, the “removing” event handler’s execution isn’t finished before the “removed” event handler gets invoked. So if you could try adding a wait of around 5s in your “removing” event handlers, then we can confirm if it’s the same case for you.

@Czaki maybe that comment (about deleting layers) and the resulting discussion should be moved to #5891? I feel like this particular issue is more general. For example, I might want to have a plugin where if the plugin created the layer and the layer has metadata about which filename it belongs to, then when the layer is being deleted I want to synchronise the latest changes before deleting the layer. What do you think?