fix: freezing caused by dynamically hidden printer edit button (#14010)
* fix: freezing caused by dynamically hidden printer edit button * track hover state of individual widgets
This commit is contained in:
@@ -1796,39 +1796,35 @@ Sidebar::Sidebar(Plater *parent)
|
||||
});
|
||||
*/
|
||||
// ORCA use Show/Hide to gain text area instead using blank icon. also manages hover effect for border
|
||||
auto printer_preset_hovered = std::make_shared<std::unordered_set<wxWindow*>>();
|
||||
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_printer_preset, p->btn_edit_printer, p->image_printer, p->combo_printer}) {
|
||||
w->Bind(wxEVT_ENTER_WINDOW, [this, panel_color](wxMouseEvent &e) {
|
||||
w->Bind(wxEVT_ENTER_WINDOW, [this, w, panel_color, printer_preset_hovered](wxMouseEvent &e) {
|
||||
printer_preset_hovered->insert(w);
|
||||
if(!p->combo_printer->HasFocus())
|
||||
p->panel_printer_preset->SetBorderColor(panel_color.bd_hover);
|
||||
if(!p->btn_edit_printer->IsShown()){
|
||||
p->btn_edit_printer->Show();
|
||||
p->panel_printer_preset->Layout();
|
||||
}
|
||||
e.Skip();
|
||||
});
|
||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, panel_color](wxMouseEvent &e) {
|
||||
// Orca: if the edit button is already hidden the handler has no
|
||||
// state to change, so skip the expensive wxFindWindowAtPoint tree
|
||||
// walk. Without this guard, when the parent window is on an
|
||||
// inactive Hyprland/Wayland workspace, GTK keeps delivering
|
||||
// synthetic leave events and the Hide()+Layout() below re-enters
|
||||
// the same handler in a feedback loop that pegs a CPU core.
|
||||
// (IsShownOnScreen() can't be used here — see Plater.cpp:9304.)
|
||||
if (!p->btn_edit_printer->IsShown()) { e.Skip(); return; }
|
||||
// Use event-relative coords instead of wxGetMousePosition() which
|
||||
// returns (0,0) on Wayland for global screen coordinates.
|
||||
wxWindow* evtObj = dynamic_cast<wxWindow*>(e.GetEventObject());
|
||||
wxPoint screenPos = evtObj ? evtObj->ClientToScreen(e.GetPosition()) : wxGetMousePosition();
|
||||
wxWindow* next_w = wxFindWindowAtPoint(screenPos);
|
||||
if (!next_w || !p->panel_printer_preset->IsDescendant(next_w)){
|
||||
if(!p->combo_printer->HasFocus())
|
||||
p->panel_printer_preset->SetBorderColor(panel_color.bd_normal);
|
||||
p->btn_edit_printer->Hide();
|
||||
p->panel_printer_preset->Layout();
|
||||
}
|
||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, w, panel_color, printer_preset_hovered](wxMouseEvent &e) {
|
||||
printer_preset_hovered->erase(w);
|
||||
if (printer_preset_hovered->empty() && !p->combo_printer->HasFocus())
|
||||
p->panel_printer_preset->SetBorderColor(panel_color.bd_normal);
|
||||
e.Skip();
|
||||
});
|
||||
}
|
||||
// Perform show/hide in wxEVT_IDLE after enter/leave events have settled.
|
||||
// This prevents the extraneous enter/leave events generated by the
|
||||
// layout change itself from causing a feedback loop.
|
||||
Bind(wxEVT_IDLE, [this, printer_preset_hovered](wxIdleEvent &e) {
|
||||
auto hovered = !printer_preset_hovered->empty();
|
||||
if (p->btn_edit_printer->IsShown() != hovered) {
|
||||
if (hovered) {
|
||||
p->btn_edit_printer->Show();
|
||||
} else {
|
||||
p->btn_edit_printer->Hide();
|
||||
}
|
||||
p->panel_printer_preset->Layout();
|
||||
}
|
||||
});
|
||||
|
||||
// ORCA unified Nozzle diameter selection
|
||||
p->panel_nozzle_dia = new StaticBox(p->m_panel_printer_content);
|
||||
@@ -1874,19 +1870,17 @@ Sidebar::Sidebar(Plater *parent)
|
||||
p->label_nozzle_type->SetMaxSize(FromDIP(wxSize(56, -1)));
|
||||
|
||||
// highlight border on hover
|
||||
auto nozzle_dia_hovered = std::make_shared<std::unordered_set<wxWindow*>>();
|
||||
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_nozzle_dia, p->label_nozzle_title, p->label_nozzle_type, p->combo_nozzle_dia}) {
|
||||
w->Bind(wxEVT_ENTER_WINDOW, [this, panel_color](wxMouseEvent &e) {
|
||||
w->Bind(wxEVT_ENTER_WINDOW, [this, w, panel_color, nozzle_dia_hovered](wxMouseEvent &e) {
|
||||
nozzle_dia_hovered->insert(w);
|
||||
if(!p->combo_nozzle_dia->HasFocus())
|
||||
p->panel_nozzle_dia->SetBorderColor(panel_color.bd_hover);
|
||||
e.Skip();
|
||||
});
|
||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, panel_color](wxMouseEvent &e) {
|
||||
// Use event-relative coords instead of wxGetMousePosition() which
|
||||
// returns (0,0) on Wayland for global screen coordinates.
|
||||
wxWindow* evtObj = dynamic_cast<wxWindow*>(e.GetEventObject());
|
||||
wxPoint screenPos = evtObj ? evtObj->ClientToScreen(e.GetPosition()) : wxGetMousePosition();
|
||||
wxWindow* next_w = wxFindWindowAtPoint(screenPos);
|
||||
if (!p->combo_nozzle_dia->HasFocus() && (!next_w || !p->panel_nozzle_dia->IsDescendant(next_w)))
|
||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, w, panel_color, nozzle_dia_hovered](wxMouseEvent &e) {
|
||||
nozzle_dia_hovered->erase(w);
|
||||
if (nozzle_dia_hovered->empty() && !p->combo_nozzle_dia->HasFocus())
|
||||
p->panel_nozzle_dia->SetBorderColor(panel_color.bd_normal);
|
||||
e.Skip();
|
||||
});
|
||||
@@ -1946,21 +1940,19 @@ Sidebar::Sidebar(Plater *parent)
|
||||
p->combo_printer_bed->Bind(wxEVT_KILL_FOCUS, [this, bed_focus_bg](auto& e) {bed_focus_bg(false); e.Skip();});
|
||||
|
||||
// highlight border on hover
|
||||
auto printer_bed_hovered = std::make_shared<std::unordered_set<wxWindow*>>();
|
||||
for (wxWindow *w : std::initializer_list<wxWindow *>{p->panel_printer_bed, p->image_printer_bed, p->combo_printer_bed}) {
|
||||
w->Bind(wxEVT_ENTER_WINDOW, [this, w, panel_color](wxMouseEvent &e) {
|
||||
w->Bind(wxEVT_ENTER_WINDOW, [this, w, panel_color, printer_bed_hovered](wxMouseEvent &e) {
|
||||
printer_bed_hovered->insert(w);
|
||||
if(!p->combo_printer_bed->HasFocus())
|
||||
p->panel_printer_bed->SetBorderColor(panel_color.bd_hover);
|
||||
if(w == p->image_printer_bed && !p->combo_printer_bed->is_drop_down()) // dont trigger while combo open
|
||||
on_enter_image_printer_bed(e);
|
||||
e.Skip();
|
||||
});
|
||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, w, panel_color](wxMouseEvent &e) {
|
||||
// Use event-relative coords instead of wxGetMousePosition() which
|
||||
// returns (0,0) on Wayland for global screen coordinates.
|
||||
wxWindow* evtObj = dynamic_cast<wxWindow*>(e.GetEventObject());
|
||||
wxPoint screenPos = evtObj ? evtObj->ClientToScreen(e.GetPosition()) : wxGetMousePosition();
|
||||
wxWindow* next_w = wxFindWindowAtPoint(screenPos);
|
||||
if (!p->combo_printer_bed->HasFocus() && (!next_w || !p->panel_printer_bed->IsDescendant(next_w)))
|
||||
w->Bind(wxEVT_LEAVE_WINDOW, [this, w, panel_color, printer_bed_hovered](wxMouseEvent &e) {
|
||||
printer_bed_hovered->erase(w);
|
||||
if (printer_bed_hovered->empty() && !p->combo_printer_bed->HasFocus())
|
||||
p->panel_printer_bed->SetBorderColor(panel_color.bd_normal);
|
||||
if(w == p->image_printer_bed)
|
||||
on_leave_image_printer_bed(e);
|
||||
|
||||
Reference in New Issue
Block a user