Repository: napari/napari

Issue:
Keybinding to set a new label doesn't work consistently
### 🐛 Bug Report

After creating a labels layer, I observed that the `m` keybinding does not behave consistently.



### 💡 Steps to Reproduce

Create a labels layer.

- If the layer is selected, the `m` keybinding will either do nothing or select another layer wiht a name that starts with the letter `m`;
- If the paintbrush, fill bucket or polygon tools are selected, the `m` keybinding doesn't do anything;
- If the paintbrush has been used in the canvas, the `m` keybinding correctly adds 1 to the label control and a new label is selected and can be used to paint.

### 💡 Expected Behavior

The `m` keybinding should increase the label number in all those situations.

### 🌎 Environment

napari: 0.5.0a2.dev486+g4d60a7ce
Platform: Linux-6.1.64-1-MANJARO-x86_64-with-glibc2.38
System: Manjaro Linux
Python: 3.11.6 | packaged by conda-forge | (main, Oct  3 2023, 10:40:35) [GCC 12.3.0]
Qt: 5.15.2
PyQt5: 5.15.10
NumPy: 1.26.2
SciPy: 1.11.4
Dask: 2023.11.0
VisPy: 0.14.1
magicgui: 0.8.0
superqt: 0.6.1
in-n-out: 0.1.9
app-model: 0.2.2
npe2: 0.7.3

OpenGL:
  - GL version:  4.6 (Compatibility Profile) Mesa 23.1.9-manjaro1.1
  - MAX_TEXTURE_SIZE: 16384

Screens:
  - screen 1: resolution 1920x1080, scale 1.0
  - screen 2: resolution 1920x1080, scale 1.0

Settings path:
  - /home/melissa/.config/napari/napari-dev_f5bfbd9c5d96bcb503f816d91f8db95d3b6d554f/settings.yaml
Plugins:
  - napari: 0.5.0a2.dev486+g4d60a7ce (77 contributions)
  - napari-console: 0.0.9 (0 contributions)
  - napari-svg: 0.1.10 (2 contributions)

### 💡 Additional Context

_No response_


Discussion:
Hi there, just in case, gave this a check and seems like the related logic for that shortcut is at https://github.com/napari/napari/blob/e6a454eaa3ed8628b1f0c6a3237d9e33e1f96d72/napari/layers/labels/_labels_key_bindings.py#L70-L78

Seems like it depends on the layer data to work (which I guess is the reason why it only works when you painted something). Also, maybe that is the reason why there are a couple of other shortcuts which change the current selected label regardless of layer data (`-` to decrease and `=` to increase)?

Sorry I missed this!!
Daniel is right `m` doesn't increase the label number, it sets it to the next unused number. So if there are no labels painted then max+1 will return 1 which is the first label (0 is background/erase). 
Likewise, if you paint with 1, hit `m` to get `2` then hitting `m` again won't do anything, because it's already at max+1.
So I would say this is not a bug, but it might be worth considering a Notification in these cases just not sure how to phrase it, maybe like:
`Largest label already selected` or something?

Oh that makes sense, yes! A warning sounds very reasonable. Thanks! 
So something like this could work?:

```python
@register_label_action(
    trans._(
        "Set the currently selected label to the largest used label plus one."
    ),
)
def new_label(layer: Labels):
    """Set the currently selected label to the largest used label plus one."""
    new_selected_label = np.max(layer.data) + 1
    if layer.selected_label == new_selected_label:
        warnings.warn(
            trans._(
                "Largest label already selected",
            )
        )
    else:
        layer.selected_label = new_selected_label
```

A preview:

![label](https://github.com/napari/napari/assets/16781833/78cbb30d-9b17-4a5b-8543-2c53b7fb60ac)

Let me know if such an approach could be worthy to submit a PR :)

Yeah that's exactly what I was thinking, only using `show_info`
https://github.com/napari/napari/blob/d507dd64ed6d96e984fa7fa57f2f232be388b5f7/napari/utils/notifications.py#L359
see also:
https://github.com/napari/napari/blob/d507dd64ed6d96e984fa7fa57f2f232be388b5f7/napari/layers/points/_points_key_bindings.py#L66-L78
It has a different icon in the notification, versus warning.

Resolving patch:
diff --git a/napari/layers/labels/_labels_key_bindings.py b/napari/layers/labels/_labels_key_bindings.py
--- a/napari/layers/labels/_labels_key_bindings.py
+++ b/napari/layers/labels/_labels_key_bindings.py
@@ -76,10 +76,21 @@ def activate_labels_erase_mode(layer: Labels):
 def new_label(layer: Labels):
     """Set the currently selected label to the largest used label plus one."""
     if isinstance(layer.data, np.ndarray):
-        layer.selected_label = np.max(layer.data) + 1
+        new_selected_label = np.max(layer.data) + 1
+        if layer.selected_label == new_selected_label:
+            show_info(
+                trans._(
+                    "Current selected label is not being used. You will need to use it first "
+                    "to be able to set the current select label to the next one available",
+                )
+            )
+        else:
+            layer.selected_label = new_selected_label
     else:
         show_info(
-            "Calculating empty label on non-numpy array is not supported"
+            trans._(
+                "Calculating empty label on non-numpy array is not supported"
+            )
         )
 
 


Test patch: