Trying to 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.
May fix #5620 #6870 #6992
This commit is contained in:
bubnikv 2021-12-03 16:19:43 +01:00
parent f14a5f40b3
commit 3622f06bed
4 changed files with 57 additions and 6 deletions

View File

@ -2101,6 +2101,21 @@ void MainFrame::technology_changed()
} }
#if defined(__linux__) || defined(_WIN32)
// wxWidgets callback to enable / disable window and all its children windows.
// called by wxWindowDisabler when entering / leaving modal dialog loop.
// Unfortunately the wxWindowDisabler 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 MainFrame::Enable(bool enable)
{
bool retval = DPIFrame::Enable(enable);
if (enable && retval)
this->plater()->restore_keyboard_focus();
return retval;
}
#endif
// //
// Called after the Preferences dialog is closed and the program settings are saved. // Called after the Preferences dialog is closed and the program settings are saved.
// Update the UI based on the current preferences. // Update the UI based on the current preferences.

View File

@ -148,6 +148,15 @@ public:
void update_title(); void update_title();
#if defined(__linux__) || defined(_WIN32)
// wxWidgets callback to enable / disable window and all its children windows.
// called by wxWindowDisabler when entering / leaving modal dialog loop.
// Unfortunately the wxWindowDisabler 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 Enable(bool enable = true) override;
#endif
void init_tabpanel(); void init_tabpanel();
void create_preset_tabs(); void create_preset_tabs();
void add_created_tab(Tab* panel, const std::string& bmp_name = ""); void add_created_tab(Tab* panel, const std::string& bmp_name = "");

View File

@ -6303,16 +6303,34 @@ void Plater::force_print_bed_update()
void Plater::on_activate() void Plater::on_activate()
{ {
#if defined(__linux__) || defined(_WIN32) #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. // Activating the main frame, and no window has keyboard focus.
// Set the keyboard focus to the visible Canvas3D. // Set the keyboard focus to the visible Canvas3D.
if (this->p->view3D->IsShown() && wxWindow::FindFocus() != this->p->view3D->get_wxglcanvas()) if (this->p->view3D->IsShown() && wxWindow::FindFocus() != this->p->view3D->get_wxglcanvas())
CallAfter([this]() { this->p->view3D->get_wxglcanvas()->SetFocus(); }); this->p->view3D->get_wxglcanvas()->SetFocus();
else if (this->p->preview->IsShown() && wxWindow::FindFocus() != this->p->view3D->get_wxglcanvas()) else if (this->p->preview->IsShown() && wxWindow::FindFocus() != this->p->view3D->get_wxglcanvas())
CallAfter([this]() { this->p->preview->get_wxglcanvas()->SetFocus(); }); this->p->preview->get_wxglcanvas()->SetFocus();
#endif
this->p->show_delayed_error_message();
} }
#endif // Linux or Windows
// Get vector of extruder colors considering filament color, if extruder color is undefined. // 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 std::vector<std::string> Plater::get_extruder_colors_from_plater_config(const GCodeProcessorResult* const result) const
@ -6875,7 +6893,6 @@ wxMenu* Plater::instance_menu() { return p->menus.instance_menu();
wxMenu* Plater::layer_menu() { return p->menus.layer_menu(); } wxMenu* Plater::layer_menu() { return p->menus.layer_menu(); }
wxMenu* Plater::multi_selection_menu() { return p->menus.multi_selection_menu(); } wxMenu* Plater::multi_selection_menu() { return p->menus.multi_selection_menu(); }
SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() : SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() :
m_was_scheduled(wxGetApp().plater()->is_background_process_update_scheduled()) m_was_scheduled(wxGetApp().plater()->is_background_process_update_scheduled())
{ {

View File

@ -149,6 +149,16 @@ public:
void render_project_state_debug_window() const; void render_project_state_debug_window() const;
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW #endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
#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 Enable(bool enable) override;
void restore_keyboard_focus();
#endif
Sidebar& sidebar(); Sidebar& sidebar();
const Model& model() const; const Model& model() const;
Model& model(); Model& model();