From 5f51811a3c1c8940e401a761082805c40ed117ac Mon Sep 17 00:00:00 2001
From: Filip Sykala <filip.sykala@prusa3d.cz>
Date: Wed, 9 Feb 2022 15:16:17 +0100
Subject: [PATCH] Fix dragging out of window

---
 src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
index 7c62b1160..eb6bf3ca8 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
@@ -150,13 +150,14 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
 // help function to process grabbers
 // call start_dragging, stop_dragging, on_dragging
 bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
+    bool is_dragging_finished = false;
     if (mouse_event.Moving()) { 
+        // it should not happen but for sure
         assert(!m_dragging);
-        // only for sure
-        if (m_dragging) m_dragging = false;
+        if (m_dragging) is_dragging_finished = true;
+        else return false; 
+    } 
 
-        return false; 
-    }
     if (mouse_event.LeftDown()) {
         Selection &selection = m_parent.get_selection();
         if (!selection.is_empty() && m_hover_id != -1) {
@@ -178,6 +179,8 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
             return true;
         }
     } else if (m_dragging) {
+        // when mouse cursor leave window than finish actual dragging operation
+        bool is_leaving = mouse_event.Leaving();
         if (mouse_event.Dragging()) {
             m_parent.set_mouse_as_dragging();
             Point      mouse_coord(mouse_event.GetX(), mouse_event.GetY());
@@ -189,10 +192,14 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
             wxGetApp().obj_manipul()->set_dirty();
             m_parent.set_as_dirty();
             return true;
-        } else if (mouse_event.LeftUp()) {
+        } else if (mouse_event.LeftUp() || is_leaving || is_dragging_finished) {
             for (auto &grabber : m_grabbers) grabber.dragging = false;
             m_dragging = false;
 
+            // NOTE: This should be part of GLCanvas3D
+            // Reset hover_id when leave window
+            if (is_leaving) m_parent.mouse_up_cleanup();
+
             on_stop_dragging();
 
             // There is prediction that after draggign, data are changed
@@ -209,8 +216,6 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
             // updates camera target constraints
             m_parent.refresh_camera_scene_box();
             return true;
-        } else if (mouse_event.Leaving()) {
-            m_dragging = false;
         }
     }
     return false;