mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-26 18:21:18 -06:00 
			
		
		
		
	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
					
				
					 6 changed files with 6 additions and 67 deletions
				
			
		|  | @ -1447,7 +1447,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) | |||
|     static const unsigned int progress_threshold = 1000; | ||||
|     wxProgressDialog* progress_dialog = wxGetApp().is_gcode_viewer() ? | ||||
|         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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1446,7 +1446,7 @@ void ObjectList::load_part(ModelObject& model_object, std::vector<ModelVolume*>& | |||
|     else | ||||
|         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; | ||||
| 
 | ||||
|     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 | ||||
|         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; | ||||
| 
 | ||||
|     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")); | ||||
| 
 | ||||
|     // 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); | ||||
|     int model_idx{ 0 }; | ||||
|     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.
 | ||||
| // Update the UI based on the current preferences.
 | ||||
|  |  | |||
|  | @ -148,15 +148,6 @@ public: | |||
| 
 | ||||
|     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        create_preset_tabs(); | ||||
|     void        add_created_tab(Tab* panel, const std::string& bmp_name = ""); | ||||
|  | @ -211,7 +202,7 @@ public: | |||
|     SettingsDialog        m_settings_dialog; | ||||
|     DiffPresetDialog      diff_dialog; | ||||
|     wxWindow*             m_plater_page{ nullptr }; | ||||
|     wxProgressDialog*     m_progress_dialog { nullptr }; | ||||
| //    wxProgressDialog*     m_progress_dialog { nullptr };
 | ||||
|     PrintHostQueueDialog* m_printhost_queue_dlg; | ||||
| //    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; | ||||
|     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 | ||||
| { | ||||
|  |  | |||
|  | @ -149,16 +149,6 @@ public: | |||
|     void render_project_state_debug_window() const; | ||||
| #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(); | ||||
|     const Model& model() const; | ||||
|     Model& model(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Bubnik
						Vojtech Bubnik