diff --git a/src/slic3r/GUI/FilamentGroupPopup.cpp b/src/slic3r/GUI/FilamentGroupPopup.cpp index bb081a6fc1..9675aadf63 100644 --- a/src/slic3r/GUI/FilamentGroupPopup.cpp +++ b/src/slic3r/GUI/FilamentGroupPopup.cpp @@ -379,14 +379,24 @@ void FilamentGroupPopup::OnTimer(wxTimerEvent &event) // leaving event got triggered. So the timer is stopped first, then started // again, causing the popup being dismissed immediately. // To fix this, we check if cursor is still inside the popup window before - // dismissing. + // dismissing, and keep checking while it is: a leave event is not guaranteed + // to follow, and a popup left open keeps grabbing the mouse capture. wxPoint pos = this->ScreenToClient(wxGetMousePosition()); - if (this->GetClientRect().Contains(pos)) return; + if (this->GetClientRect().Contains(pos)) { + StartTimer(); + return; + } #endif Dismiss(); } +FilamentGroupPopup::~FilamentGroupPopup() +{ + m_timer->Stop(); + delete m_timer; +} + void FilamentGroupPopup::Dismiss() { m_active = false; PopupWindow::Dismiss(); @@ -405,7 +415,10 @@ void FilamentGroupPopup::OnEnterWindow(wxMouseEvent &) // Ignore spurious ENTER synthesized by PopupWindow::OnMouseEvent2 on macOS. wxPoint pos = this->ScreenToClient(wxGetMousePosition()); if (!this->GetClientRect().Contains(pos)) return; + // On macOS the timer keeps running instead, and OnTimer closes the popup once the cursor has left it. +#ifndef __APPLE__ ResetTimer(); +#endif } void FilamentGroupPopup::UpdateButtonStatus(int hover_idx) diff --git a/src/slic3r/GUI/FilamentGroupPopup.hpp b/src/slic3r/GUI/FilamentGroupPopup.hpp index bc43876af7..4e70518091 100644 --- a/src/slic3r/GUI/FilamentGroupPopup.hpp +++ b/src/slic3r/GUI/FilamentGroupPopup.hpp @@ -27,6 +27,7 @@ class FilamentGroupPopup : public PopupWindow { public: FilamentGroupPopup(wxWindow *parent); + ~FilamentGroupPopup() override; void tryPopup(Plater* plater,PartPlate* plate, bool slice_all); void tryClose(); void Dismiss() override; diff --git a/src/slic3r/GUI/FilamentMapDialog.cpp b/src/slic3r/GUI/FilamentMapDialog.cpp index 5c3a72596b..00fdfe6d21 100644 --- a/src/slic3r/GUI/FilamentMapDialog.cpp +++ b/src/slic3r/GUI/FilamentMapDialog.cpp @@ -20,6 +20,8 @@ #include #include #include "slic3r/GUI/FilamentMapPanel.hpp" +#include "slic3r/GUI/FilamentGroupPopup.hpp" +#include "slic3r/GUI/MainFrame.hpp" namespace Slic3r { namespace GUI { @@ -377,6 +379,13 @@ FilamentMapMode FilamentMapDialog::get_mode() int FilamentMapDialog::ShowModal() { + // The Slice-plate hover popup is a transient popup that keeps grabbing the mouse + // capture while shown. Left behind this modal dialog it would starve the dialog of + // mouse events, so close it synchronously first, whichever path opened the dialog. + if (MainFrame* frame = wxGetApp().mainframe; + frame && frame->m_filament_group_popup && frame->m_filament_group_popup->IsShown()) + frame->m_filament_group_popup->Dismiss(); + update_panel_status(m_page_type); return wxDialog::ShowModal(); } diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 6ef7dedaa8..db21915477 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2309,12 +2309,6 @@ wxBoxSizer* MainFrame::create_side_tools() bool slice = true; - // The Slice-plate hover popup is a transient popup that keeps grabbing - // the mouse capture while shown. Left behind the modal grouping dialog it - // would starve that dialog of mouse events, so close it synchronously first. - if (m_filament_group_popup) - m_filament_group_popup->Dismiss(); - auto curr_plate = m_plater->get_partplate_list().get_curr_plate(); #ifdef __linux__ PresetBundle* preset = wxGetApp().preset_bundle;