diff --git a/src/slic3r/GUI/DesignCanvas.cpp b/src/slic3r/GUI/DesignCanvas.cpp index cc9b8a55db..d51e49814c 100644 --- a/src/slic3r/GUI/DesignCanvas.cpp +++ b/src/slic3r/GUI/DesignCanvas.cpp @@ -176,6 +176,12 @@ DesignCanvas::DesignCanvas(wxWindow* parent) top->Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& e) { show_status_hud(e.GetActive()); e.Skip(); }); + // The anchor is an ABSOLUTE SCREEN position (ClientToScreen below), so moving the window + // moves the canvas out from under a chip that stays where it was. Dragging the frame by + // its title bar left the chip stranded mid-viewport until the next size, status or tab + // change happened to re-place it. Nothing on the canvas fires for a move that does not + // also resize, so it has to come from the frame. + top->Bind(wxEVT_MOVE, [this](wxMoveEvent& e) { place_status_hud(); e.Skip(); }); } refresh_bed(); diff --git a/src/slic3r/GUI/DesignSketchTool.cpp b/src/slic3r/GUI/DesignSketchTool.cpp index 30a73ef6e9..c89650d7b0 100644 --- a/src/slic3r/GUI/DesignSketchTool.cpp +++ b/src/slic3r/GUI/DesignSketchTool.cpp @@ -3073,9 +3073,21 @@ bool DesignSketchTool::handle_solid_click(GLCanvas3D& canvas, const wxMouseEvent // Double-click is safe: wx sends Down/Up/DClick/Up, and only the first Up carries a // pending press, so a fast double-click zooms to fit and picks ONCE. Escalation needs two // separate clicks, the same "click, pause, click" distinction a file manager uses. - if (m_solid_sel == prev_kind && m_sel_body == prev_body && m_sel_face == prev_face - && m_sel_edge == prev_edge - && (m_solid_sel != SolidSel::Vertex || (m_sel_vertex_pt - prev_vtx).norm() < 1e-9)) { + // + // "The same thing" is compared AT THE LEVEL THAT WAS PICKED, and nothing else. Requiring + // every field to match looked stricter and was simply wrong: an edge pick leaves m_sel_face + // set to whichever face the ray happened to hit, and a shared edge is reached through a + // different face depending on which side of the body you are looking from. So picking an + // edge, orbiting, and clicking that same edge from the other side left m_sel_edge equal and + // m_sel_face different, and the escalation the status line had just promised did not happen. + // The edge id here is already the STABLE GLOBAL one (edge_index_of, a few lines up) — it + // identifies the edge on its own and does not need the face to disambiguate it. + const bool same_pick = m_solid_sel == prev_kind && m_sel_body == prev_body + && (m_solid_sel == SolidSel::Vertex ? (m_sel_vertex_pt - prev_vtx).norm() < 1e-9 + : m_solid_sel == SolidSel::Edge ? m_sel_edge == prev_edge + : m_solid_sel == SolidSel::Face ? m_sel_face == prev_face + : true); + if (same_pick) { select_body(m_sel_body); // clears face/edge/vertex, tints the whole body dp_pick_trace("re-pick -> escalated to whole body %d", m_sel_body); }