Work around 3D scene focus after de-activation of the main
window without having to resort to CallAfter(), which breaks
on Linux with some window managers that follow mouser cursor.
Fixes #5620 #6870 #6992

3622f06bed was not a correct solution,
it broke focus for non-modal windows.
Fixes #7419

The actual issue seems to be caused by wxProgressDialog not playing
well with modal dialogs closed just before wxProgressDialog opens.
If wxProgressDialog parent was not a main frame, keyboard focus
was not restored correctly after the wxProgressDialog closed.
This commit is contained in:
Vojtech Bubnik
2021-12-05 09:09:34 +01:00
parent d44525d916
commit bfce4f6901
6 changed files with 6 additions and 67 deletions

View File

@@ -2351,7 +2351,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
}
const auto loading = _L("Loading") + dots;
wxProgressDialog dlg(loading, "", 100, q, wxPD_AUTO_HIDE);
wxProgressDialog dlg(loading, "", 100, find_toplevel_parent(q), wxPD_AUTO_HIDE);
wxBusyCursor busy;
auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model();
@@ -6306,36 +6306,9 @@ void Plater::force_print_bed_update()
void Plater::on_activate()
{
#if defined(__linux__) || defined(_WIN32)
this->restore_keyboard_focus();
#endif
this->p->show_delayed_error_message();
}
#if defined(__linux__) || defined(_WIN32)
// wxWidgets callback to enable / disable window and all its children windows.
// called by wxProgressDialog when entering / leaving modal dialog loop.
// Unfortunately the wxProgressDialog calls Enable(true) after the wxEVT_ACTIVATE event is processed
// while MainFrame is not yet enabled, thus restoring focus in OnActivate() handler fails
// and we need to do it now.
bool Plater::Enable(bool enable)
{
bool retval = wxPanel::Enable(enable);
if (enable && retval)
this->restore_keyboard_focus();
return retval;
}
void Plater::restore_keyboard_focus()
{
// Activating the main frame, and no window has keyboard focus.
// Set the keyboard focus to the visible Canvas3D.
if (this->p->view3D->IsShown() && wxWindow::FindFocus() != this->p->view3D->get_wxglcanvas())
this->p->view3D->get_wxglcanvas()->SetFocus();
else if (this->p->preview->IsShown() && wxWindow::FindFocus() != this->p->view3D->get_wxglcanvas())
this->p->preview->get_wxglcanvas()->SetFocus();
}
#endif // Linux or Windows
// Get vector of extruder colors considering filament color, if extruder color is undefined.
std::vector<std::string> Plater::get_extruder_colors_from_plater_config(const GCodeProcessorResult* const result) const
{