diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
index 32a43e78c..8236410bd 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
@@ -1100,6 +1100,9 @@ std::string GLGizmoSlaSupports::on_get_name() const
 
 void GLGizmoSlaSupports::on_set_state()
 {
+    if (m_state == Hover)
+        return;
+
     // m_model_object pointer can be invalid (for instance because of undo/redo action),
     // we should recover it from the object id
     m_model_object = nullptr;
@@ -1111,6 +1114,7 @@ void GLGizmoSlaSupports::on_set_state()
     }
 
     if (m_state == On && m_old_state != On) { // the gizmo was just turned on
+        Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned on")));
         if (is_mesh_update_necessary())
             update_mesh();
 
@@ -1144,8 +1148,9 @@ void GLGizmoSlaSupports::on_set_state()
         }
         else {
             // we are actually shutting down
-            m_parent.toggle_model_objects_visibility(true);
             disable_editing_mode(); // so it is not active next time the gizmo opens
+            Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("SLA gizmo turned off")));
+            m_parent.toggle_model_objects_visibility(true);
             m_normal_cache.clear();
             m_clipping_plane_distance = 0.f;
             // Release triangle mesh slicer and the AABB spatial search structure.
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
index fa3facf4b..2f6e9ccf3 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
@@ -101,6 +101,8 @@ private:
     void update_cache_entry_normal(unsigned int i) const;
     bool unsaved_changes() const;
 
+    EState m_no_hover_state = Off;
+    EState m_no_hover_old_state = Off;
     bool m_lock_unique_islands = false;
     bool m_editing_mode = false;            // Is editing mode active?
     bool m_old_editing_state = false;       // To keep track of whether the user toggled between the modes (needed for imgui refreshes).
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index bd176b231..236a0a27c 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -1096,6 +1096,10 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos)
         top_y += scaled_stride_y;
     }
 
+    // We may change m_current soon. If we did it during following loop, gizmos that take undo/redo snapshots
+    // in their on_set_state function could snapshot a state with the new gizmo already active.
+    // Therefore, just remember what needs to be done and actually change m_current afterwards.
+    EType new_current = m_current;
     top_y = 0.5f * (cnv_h - height) + scaled_border;
     for (std::pair<const GLGizmosManager::EType, GLGizmoBase*> &type_and_gizmo : m_gizmos)
     {
@@ -1110,18 +1114,19 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos)
                 gizmo->set_state(GLGizmoBase::Off);
                 if (gizmo->get_state() == GLGizmoBase::Off) {
                     gizmo->set_state(GLGizmoBase::Hover);
-                    m_current = Undefined;
+                    new_current = Undefined;
                 }
             }
             else if ((gizmo->get_state() == GLGizmoBase::Hover) && could_activate)
             {
                 gizmo->set_state(GLGizmoBase::On);
-                m_current = type_and_gizmo.first;
+                new_current = type_and_gizmo.first;
             }
         }
 
         top_y += scaled_stride_y;
     }
+    m_current = new_current;
 
     if (could_activate) {
         GizmosMap::iterator it = m_gizmos.find(m_current);
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index bb6c1e2f6..3e733aef5 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -3863,6 +3863,9 @@ void Plater::priv::undo_redo_to(size_t time_to_load)
 
 void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator it_snapshot)
 {
+    // Make sure that no updating function calls take_snapshot until we are done.
+    SuppressSnapshots snapshot_supressor(q);
+
     bool 				temp_snapshot_was_taken 	= this->undo_redo_stack().temp_snapshot_active();
     PrinterTechnology 	new_printer_technology 		= it_snapshot->snapshot_data.printer_technology;
     bool 				printer_technology_changed 	= this->printer_technology != new_printer_technology;