ENH: restore single instance

Change-Id: Ia9b243ae5ec27bd6b786d77239916946c7c03bc7
Jira: STUDIO-5704
This commit is contained in:
chunmao.guo 2023-12-26 19:51:18 +08:00 committed by Lane.Wei
parent 168d5dfe67
commit 809f82b520
7 changed files with 56 additions and 46 deletions

View File

@ -360,8 +360,8 @@ set(SLIC3R_GUI_SOURCES
GUI/ObjectDataViewModel.hpp
GUI/AuxiliaryDataViewModel.cpp
GUI/AuxiliaryDataViewModel.hpp
#GUI/InstanceCheck.cpp
#GUI/InstanceCheck.hpp
GUI/InstanceCheck.cpp
GUI/InstanceCheck.hpp
GUI/Search.cpp
GUI/Search.hpp
GUI/NotificationManager.cpp
@ -487,8 +487,8 @@ if (APPLE)
GUI/RemovableDriveManagerMM.mm
GUI/RemovableDriveManagerMM.h
GUI/Mouse3DHandlerMac.mm
#GUI/InstanceCheckMac.mm
#GUI/InstanceCheckMac.h
GUI/InstanceCheckMac.mm
GUI/InstanceCheckMac.h
GUI/wxMediaCtrl2.mm
GUI/wxMediaCtrl2.h
)

View File

@ -923,15 +923,15 @@ static void register_win32_device_notification_event()
return false;
});
//wxWindow::MSWRegisterMessageHandler(WM_COPYDATA, [](wxWindow* win, WXUINT /* nMsg */, WXWPARAM wParam, WXLPARAM lParam) {
// COPYDATASTRUCT* copy_data_structure = { 0 };
// copy_data_structure = (COPYDATASTRUCT*)lParam;
// if (copy_data_structure->dwData == 1) {
// LPCWSTR arguments = (LPCWSTR)copy_data_structure->lpData;
// Slic3r::GUI::wxGetApp().other_instance_message_handler()->handle_message(boost::nowide::narrow(arguments));
// }
// return true;
// });
wxWindow::MSWRegisterMessageHandler(WM_COPYDATA, [](wxWindow* win, WXUINT /* nMsg */, WXWPARAM wParam, WXLPARAM lParam) {
COPYDATASTRUCT* copy_data_structure = { 0 };
copy_data_structure = (COPYDATASTRUCT*)lParam;
if (copy_data_structure->dwData == 1) {
LPCWSTR arguments = (LPCWSTR)copy_data_structure->lpData;
Slic3r::GUI::wxGetApp().other_instance_message_handler()->handle_message(boost::nowide::narrow(arguments));
}
return true;
});
}
#endif // WIN32
@ -1316,11 +1316,10 @@ void GUI_App::post_init()
}
}
BOOST_LOG_TRIVIAL(info) << "finished post_init";
//BBS: remove the single instance currently
/*#ifdef _WIN32
#ifdef _WIN32
// Sets window property to mainframe so other instances can indentify it.
OtherInstanceMessageHandler::init_windows_properties(mainframe, m_instance_hash_int);
#endif //WIN32*/
#endif //WIN32
}
wxDEFINE_EVENT(EVT_ENTER_FORCE_UPGRADE, wxCommandEvent);
@ -1339,7 +1338,7 @@ GUI_App::GUI_App()
, m_imgui(new ImGuiWrapper())
, hms_query(new HMSQuery())
, m_removable_drive_manager(std::make_unique<RemovableDriveManager>())
//, m_other_instance_message_handler(std::make_unique<OtherInstanceMessageHandler>())
, m_other_instance_message_handler(std::make_unique<OtherInstanceMessageHandler>())
{
//app config initializes early becasuse it is used in instance checking in BambuStudio.cpp
this->init_app_config();
@ -2281,11 +2280,11 @@ std::string GUI_App::get_local_models_path()
return local_path;
}
/*void GUI_App::init_single_instance_checker(const std::string &name, const std::string &path)
void GUI_App::init_single_instance_checker(const std::string &name, const std::string &path)
{
BOOST_LOG_TRIVIAL(debug) << "init wx instance checker " << name << " "<< path;
m_single_instance_checker = std::make_unique<wxSingleInstanceChecker>(boost::nowide::widen(name), boost::nowide::widen(path));
}*/
}
bool GUI_App::OnInit()
{
@ -2739,9 +2738,9 @@ bool GUI_App::on_init_inner()
update_mode(); // update view mode after fix of the object_list size
//#ifdef __APPLE__
// other_instance_message_handler()->bring_instance_forward();
//#endif //__APPLE__
#ifdef __APPLE__
other_instance_message_handler()->bring_instance_forward();
#endif //__APPLE__
Bind(EVT_HTTP_ERROR, &GUI_App::on_http_error, this);
@ -5882,7 +5881,8 @@ void GUI_App::MacOpenURL(const wxString& url)
// wxWidgets override to get an event on open files.
void GUI_App::MacOpenFiles(const wxArrayString &fileNames)
{
if (m_post_initialized) {
bool single_instance = app_config->get("app", "single_instance") == "true";
if (m_post_initialized && !single_instance) {
bool has3mf = false;
std::vector<wxString> names;
for (auto & n : fileNames) {

View File

@ -265,10 +265,10 @@ private:
std::unique_ptr<ImGuiWrapper> m_imgui;
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
//std::unique_ptr <OtherInstanceMessageHandler> m_other_instance_message_handler;
//std::unique_ptr <wxSingleInstanceChecker> m_single_instance_checker;
//std::string m_instance_hash_string;
//size_t m_instance_hash_int;
std::unique_ptr <OtherInstanceMessageHandler> m_other_instance_message_handler;
std::unique_ptr <wxSingleInstanceChecker> m_single_instance_checker;
std::string m_instance_hash_string;
size_t m_instance_hash_int;
//BBS
bool m_is_closing {false};
@ -583,13 +583,13 @@ public:
Tab* plate_tab;
RemovableDriveManager* removable_drive_manager() { return m_removable_drive_manager.get(); }
//OtherInstanceMessageHandler* other_instance_message_handler() { return m_other_instance_message_handler.get(); }
//wxSingleInstanceChecker* single_instance_checker() {return m_single_instance_checker.get();}
OtherInstanceMessageHandler* other_instance_message_handler() { return m_other_instance_message_handler.get(); }
wxSingleInstanceChecker* single_instance_checker() {return m_single_instance_checker.get();}
//void init_single_instance_checker(const std::string &name, const std::string &path);
//void set_instance_hash (const size_t hash) { m_instance_hash_int = hash; m_instance_hash_string = std::to_string(hash); }
//std::string get_instance_hash_string () { return m_instance_hash_string; }
//size_t get_instance_hash_int () { return m_instance_hash_int; }
void init_single_instance_checker(const std::string &name, const std::string &path);
void set_instance_hash (const size_t hash) { m_instance_hash_int = hash; m_instance_hash_string = std::to_string(hash); }
std::string get_instance_hash_string () { return m_instance_hash_string; }
size_t get_instance_hash_int () { return m_instance_hash_int; }
ImGuiWrapper* imgui() { return m_imgui.get(); }

View File

@ -41,14 +41,14 @@ int GUI_Run(GUI_InitParams &params)
try {
//GUI::GUI_App* gui = new GUI::GUI_App(params.start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor);
GUI::GUI_App* gui = new GUI::GUI_App();
/*if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) {
//if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) {
// G-code viewer is currently not performing instance check, a new G-code viewer is started every time.
bool gui_single_instance_setting = gui->app_config->get("single_instance") == "1";
bool gui_single_instance_setting = gui->app_config->get("app", "single_instance") == "true";
if (Slic3r::instance_check(params.argc, params.argv, gui_single_instance_setting)) {
//TODO: do we have delete gui and other stuff?
return -1;
}
//}*/
//}
// gui->autosave = m_config.opt_string("autosave");
GUI::GUI_App::SetInstance(gui);

View File

@ -101,12 +101,12 @@ public:
BambuStudioTaskBarIcon(wxTaskBarIconType iconType = wxTBI_DEFAULT_TYPE) : wxTaskBarIcon(iconType) {}
wxMenu *CreatePopupMenu() override {
wxMenu *menu = new wxMenu;
//if (wxGetApp().app_config->get("single_instance") == "false") {
if (wxGetApp().app_config->get("single_instance") == "false") {
// Only allow opening a new PrusaSlicer instance on OSX if "single_instance" is disabled,
// as starting new instances would interfere with the locking mechanism of "single_instance" support.
append_menu_item(menu, wxID_ANY, _L("New Window"), _L("Open a new window"),
[](wxCommandEvent&) { start_new_slicer(); }, "", nullptr);
//}
}
// append_menu_item(menu, wxID_ANY, _L("G-code Viewer") + dots, _L("Open G-code Viewer"),
// [](wxCommandEvent&) { start_new_gcodeviewer_open_file(); }, "", nullptr);
return menu;
@ -917,7 +917,7 @@ void MainFrame::shutdown()
// Stop the background thread of the removable drive manager, so that no new updates will be sent to the Plater.
//wxGetApp().removable_drive_manager()->shutdown();
//stop listening for messages from other instances
//wxGetApp().other_instance_message_handler()->shutdown(this);
wxGetApp().other_instance_message_handler()->shutdown(this);
// Save the slic3r.ini.Usually the ini file is saved from "on idle" callback,
// but in rare cases it may not have been called yet.
wxGetApp().app_config->save();
@ -2257,7 +2257,7 @@ void MainFrame::init_menubar_as_editor()
// New Window
append_menu_item(fileMenu, wxID_ANY, _L("New Window"), _L("Start a new window"),
[](wxCommandEvent&) { start_new_slicer(); }, "", nullptr,
[]{ return true; }, this);
[this] { return m_plater != nullptr && wxGetApp().app_config->get("app", "single_instance") == "false"; }, this);
#endif
// New Project
append_menu_item(fileMenu, wxID_ANY, _L("New Project") + "\t" + ctrl + "N", _L("Start a new project"),

View File

@ -3062,7 +3062,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
//wxPostEvent(this->q, wxCommandEvent{EVT_RESTORE_PROJECT});
}
/*this->q->Bind(EVT_LOAD_MODEL_OTHER_INSTANCE, [this](LoadFromOtherInstanceEvent& evt) {
this->q->Bind(EVT_LOAD_MODEL_OTHER_INSTANCE, [this](LoadFromOtherInstanceEvent& evt) {
BOOST_LOG_TRIVIAL(trace) << "Received load from other instance event.";
wxArrayString input_files;
for (size_t i = 0; i < evt.data.size(); ++i) {
@ -3073,8 +3073,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
});
this->q->Bind(EVT_INSTANCE_GO_TO_FRONT, [this](InstanceGoToFrontEvent &) {
bring_instance_forward();
});*/
//wxGetApp().other_instance_message_handler()->init(this->q);
});
wxGetApp().other_instance_message_handler()->init(this->q);
// collapse sidebar according to saved value
//if (wxGetApp().is_editor()) {
@ -7284,10 +7284,11 @@ void Plater::priv::set_project_name(const wxString& project_name)
BOOST_LOG_TRIVIAL(trace) << __FUNCTION__ << __LINE__ << " project is:" << project_name;
m_project_name = project_name;
//update topbar title
wxGetApp().mainframe->SetTitle(m_project_name);
#ifdef __WINDOWS__
wxGetApp().mainframe->SetTitle(m_project_name + " - BambuStudio");
wxGetApp().mainframe->topbar()->SetTitle(m_project_name);
#else
wxGetApp().mainframe->SetTitle(m_project_name);
if (!m_project_name.IsEmpty())
wxGetApp().mainframe->update_title_colour_after_set_title();
#endif
@ -8206,10 +8207,10 @@ void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bo
void Plater::priv::bring_instance_forward() const
{
/*#ifdef __APPLE__
#ifdef __APPLE__
wxGetApp().other_instance_message_handler()->bring_instance_forward();
return;
#endif //__APPLE__*/
#endif //__APPLE__
if (main_frame == nullptr) {
BOOST_LOG_TRIVIAL(debug) << "Couldnt bring instance forward - mainframe is null";
return;

View File

@ -1005,6 +1005,14 @@ wxWindow* PreferencesDialog::create_general_page()
std::vector<wxString> Units = {_L("Metric") + " (mm, g)", _L("Imperial") + " (in, oz)"};
auto item_currency = create_item_combobox(_L("Units"), page, _L("Units"), "use_inches", Units);
auto item_single_instance = create_item_checkbox(_L("Keep only one BambuStudio instance"), page,
#if __APPLE__
_L("On OSX there is always only one instance of app running by default. However it is allowed to run multiple instances "
"of same app from the command line. In such case this settings will allow only one instance."),
#else
_L("If this is enabled, when starting BambuStudio and another instance of the same BambuStudio is already running, that instance will be reactivated instead."),
#endif
50, "single_instance");
auto item_mouse_zoom_settings = create_item_checkbox(_L("Zoom to mouse position"), page, _L("Zoom in towards the mouse pointer's position in the 3D view, rather than the 2D window center."), 50, "zoom_to_mouse");
auto item_bed_type_follow_preset = create_item_checkbox(_L("Auto Bed Type"), page,
@ -1073,6 +1081,7 @@ wxWindow* PreferencesDialog::create_general_page()
sizer_page->Add(item_language, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_region, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_currency, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_single_instance, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_mouse_zoom_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_bed_type_follow_preset, 0, wxTOP, FromDIP(3));
//sizer_page->Add(item_hints, 0, wxTOP, FromDIP(3));