Follow-up to 3622f06bed
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:
parent
d44525d916
commit
bfce4f6901
@ -1447,7 +1447,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
|||||||
static const unsigned int progress_threshold = 1000;
|
static const unsigned int progress_threshold = 1000;
|
||||||
wxProgressDialog* progress_dialog = wxGetApp().is_gcode_viewer() ?
|
wxProgressDialog* progress_dialog = wxGetApp().is_gcode_viewer() ?
|
||||||
new wxProgressDialog(_L("Generating toolpaths"), "...",
|
new wxProgressDialog(_L("Generating toolpaths"), "...",
|
||||||
100, wxGetApp().plater(), wxPD_AUTO_HIDE | wxPD_APP_MODAL) : nullptr;
|
100, wxGetApp().mainframe, wxPD_AUTO_HIDE | wxPD_APP_MODAL) : nullptr;
|
||||||
|
|
||||||
wxBusyCursor busy;
|
wxBusyCursor busy;
|
||||||
|
|
||||||
|
@ -1446,7 +1446,7 @@ void ObjectList::load_part(ModelObject& model_object, std::vector<ModelVolume*>&
|
|||||||
else
|
else
|
||||||
wxGetApp().import_model(parent, input_files);
|
wxGetApp().import_model(parent, input_files);
|
||||||
|
|
||||||
wxProgressDialog dlg(_L("Loading") + dots, "", 100, wxGetApp().plater(), wxPD_AUTO_HIDE);
|
wxProgressDialog dlg(_L("Loading") + dots, "", 100, wxGetApp().mainframe wxPD_AUTO_HIDE);
|
||||||
wxBusyCursor busy;
|
wxBusyCursor busy;
|
||||||
|
|
||||||
for (size_t i = 0; i < input_files.size(); ++i) {
|
for (size_t i = 0; i < input_files.size(); ++i) {
|
||||||
@ -1506,7 +1506,7 @@ void ObjectList::load_modifier(ModelObject& model_object, std::vector<ModelVolum
|
|||||||
else
|
else
|
||||||
wxGetApp().import_model(parent, input_files);
|
wxGetApp().import_model(parent, input_files);
|
||||||
|
|
||||||
wxProgressDialog dlg(_L("Loading") + dots, "", 100, wxGetApp().plater(), wxPD_AUTO_HIDE);
|
wxProgressDialog dlg(_L("Loading") + dots, "", 100, wxGetApp().mainframe, wxPD_AUTO_HIDE);
|
||||||
wxBusyCursor busy;
|
wxBusyCursor busy;
|
||||||
|
|
||||||
const int obj_idx = get_selected_obj_idx();
|
const int obj_idx = get_selected_obj_idx();
|
||||||
@ -4105,7 +4105,7 @@ void ObjectList::fix_through_netfabb()
|
|||||||
Plater::TakeSnapshot snapshot(plater, _L("Fix through NetFabb"));
|
Plater::TakeSnapshot snapshot(plater, _L("Fix through NetFabb"));
|
||||||
|
|
||||||
// Open a progress dialog.
|
// Open a progress dialog.
|
||||||
wxProgressDialog progress_dlg(_L("Fixing through NetFabb"), "", 100, plater,
|
wxProgressDialog progress_dlg(_L("Fixing through NetFabb"), "", 100, find_toplevel_parent(plater),
|
||||||
wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
|
wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
|
||||||
int model_idx{ 0 };
|
int model_idx{ 0 };
|
||||||
if (vol_idxs.empty()) {
|
if (vol_idxs.empty()) {
|
||||||
|
@ -2101,21 +2101,6 @@ 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.
|
||||||
|
@ -148,15 +148,6 @@ 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 = "");
|
||||||
@ -211,7 +202,7 @@ public:
|
|||||||
SettingsDialog m_settings_dialog;
|
SettingsDialog m_settings_dialog;
|
||||||
DiffPresetDialog diff_dialog;
|
DiffPresetDialog diff_dialog;
|
||||||
wxWindow* m_plater_page{ nullptr };
|
wxWindow* m_plater_page{ nullptr };
|
||||||
wxProgressDialog* m_progress_dialog { nullptr };
|
// wxProgressDialog* m_progress_dialog { nullptr };
|
||||||
PrintHostQueueDialog* m_printhost_queue_dlg;
|
PrintHostQueueDialog* m_printhost_queue_dlg;
|
||||||
// std::shared_ptr<ProgressStatusBar> m_statusbar;
|
// std::shared_ptr<ProgressStatusBar> m_statusbar;
|
||||||
|
|
||||||
|
@ -2351,7 +2351,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto loading = _L("Loading") + dots;
|
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;
|
wxBusyCursor busy;
|
||||||
|
|
||||||
auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model();
|
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()
|
void Plater::on_activate()
|
||||||
{
|
{
|
||||||
#if defined(__linux__) || defined(_WIN32)
|
|
||||||
this->restore_keyboard_focus();
|
|
||||||
#endif
|
|
||||||
this->p->show_delayed_error_message();
|
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.
|
// 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
|
||||||
{
|
{
|
||||||
|
@ -149,16 +149,6 @@ 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();
|
||||||
|
Loading…
Reference in New Issue
Block a user