Repository: silx-kit/silx
Issue: After an interaction the mouse cursor is not restored

- Create a ROI
- Move an handle
- Release the mouse
- The cursor hover the handle (and could drag it) but does not have the right cursor pointer

Changed files:
src/silx/gui/plot/PlotInteraction.py

diff --git a/src/silx/gui/plot/PlotInteraction.py b/src/silx/gui/plot/PlotInteraction.py
index 5c4c98c4d..fe139b48c 100644
--- a/src/silx/gui/plot/PlotInteraction.py
+++ b/src/silx/gui/plot/PlotInteraction.py
@@ -1097,6 +1097,13 @@ class ItemsInteraction(ClickOrDrag, _PlotInteraction):
             super(ItemsInteraction.Idle, self).__init__(*args, **kw)
             self._hoverMarker = None
 
+        def enterState(self):
+            widget = self.machine.plot.getWidgetHandle()
+            if widget is None or not widget.isVisible():
+                return
+            position = widget.mapFromGlobal(qt.QCursor.pos())
+            self.onMove(position.x(), position.y())
+
         def onMove(self, x, y):
             marker = self.machine.plot._getMarkerAt(x, y)
 
@@ -1112,22 +1119,7 @@ class ItemsInteraction(ClickOrDrag, _PlotInteraction):
 
             if marker != self._hoverMarker:
                 self._hoverMarker = marker
-
-                if marker is None:
-                    self.machine.plot.setGraphCursorShape()
-
-                elif marker.isDraggable():
-                    if isinstance(marker, items.YMarker):
-                        self.machine.plot.setGraphCursorShape(CURSOR_SIZE_VER)
-                    elif isinstance(marker, items.XMarker):
-                        self.machine.plot.setGraphCursorShape(CURSOR_SIZE_HOR)
-                    else:
-                        self.machine.plot.setGraphCursorShape(CURSOR_SIZE_ALL)
-
-                elif marker.isSelectable():
-                    self.machine.plot.setGraphCursorShape(CURSOR_POINTING)
-                else:
-                    self.machine.plot.setGraphCursorShape()
+                self.machine._setCursorForMarker(marker)
 
             return True
 
@@ -1139,6 +1131,27 @@ class ItemsInteraction(ClickOrDrag, _PlotInteraction):
                              clickButtons=(LEFT_BTN, RIGHT_BTN),
                              dragButtons=(LEFT_BTN, MIDDLE_BTN))
 
+    def _setCursorForMarker(self, marker: Optional[items.MarkerBase] = None):
+        """Set mouse cursor for given marker"""
+        if marker is None:
+            cursor = None
+
+        elif marker.isDraggable():
+            if isinstance(marker, items.YMarker):
+                cursor = CURSOR_SIZE_VER
+            elif isinstance(marker, items.XMarker):
+                cursor = CURSOR_SIZE_HOR
+            else:
+                cursor = CURSOR_SIZE_ALL
+
+        elif marker.isSelectable():
+            cursor = CURSOR_POINTING
+
+        else:
+            cursor = None
+
+        self.plot.setGraphCursorShape(cursor)
+
     def click(self, x, y, btn):
         """Handle mouse click
 
@@ -1253,9 +1266,9 @@ class ItemsInteraction(ClickOrDrag, _PlotInteraction):
     def __isDraggableItem(item):
         return isinstance(item, items.DraggableMixIn) and item.isDraggable()
 
-    def __terminateDrag(self):
+    def __terminateDrag(self, x, y):
         """Finalize a drag operation by reseting to initial state"""
-        self.plot.setGraphCursorShape()
+        self._setCursorForMarker(self.plot._getMarkerAt(x, y))
         self.draggedItemRef = None
 
     def beginDrag(self, x, y, btn):
@@ -1276,7 +1289,7 @@ class ItemsInteraction(ClickOrDrag, _PlotInteraction):
             self.draggedItemRef = None if item is None else weakref.ref(item)
 
             if item is None:
-                self.__terminateDrag()
+                self.__terminateDrag(x, y)
                 return False
 
             if isinstance(item, items.MarkerBase):
@@ -1325,13 +1338,17 @@ class ItemsInteraction(ClickOrDrag, _PlotInteraction):
                 self.plot.notify(**eventDict)
                 item._endDrag()
 
-            self.__terminateDrag()
+            self.__terminateDrag(*endPos)
         elif btn == MIDDLE_BTN:
             self._pan.endDrag(startPos, endPos, btn)
 
     def cancel(self):
         self._pan.cancel()
-        self.__terminateDrag()
+        widget = self.plot.getWidgetHandle()
+        if widget is None or not widget.isVisible():
+            return
+        position = widget.mapFromGlobal(qt.QCursor.pos())
+        self.__terminateDrag(position.x(), position.y())
 
 
 class ItemsInteractionForCombo(ItemsInteraction):