Browse Source

Make system::openDirectory() and openBrowser() nonblocking by running in detached thread. Use MenuItem helpers for File menu.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
830d2fcdd4
7 changed files with 58 additions and 133 deletions
  1. +4
    -2
      include/system.hpp
  2. +31
    -101
      src/app/MenuBar.cpp
  3. +1
    -4
      src/app/ModuleBrowser.cpp
  4. +2
    -8
      src/app/ModuleWidget.cpp
  5. +1
    -4
      src/app/Scene.cpp
  6. +1
    -4
      src/app/TipWindow.cpp
  7. +18
    -10
      src/system.cpp

+ 4
- 2
include/system.hpp View File

@@ -169,10 +169,12 @@ std::string getOperatingSystemInfo();


/** Opens a URL in a browser. /** Opens a URL in a browser.
Shell injection is possible, so make sure the URL is trusted or hard coded. Shell injection is possible, so make sure the URL is trusted or hard coded.
May block, so open in a new thread.
Does not block.
*/ */
void openBrowser(const std::string& url); void openBrowser(const std::string& url);
/** Opens Windows Explorer, Finder, etc at a directory location. */
/** Opens Windows Explorer, Finder, etc at a directory location.
Does not block.
*/
void openDirectory(const std::string& path); void openDirectory(const std::string& path);
/** Runs an executable without blocking. /** Runs an executable without blocking.
The launched process will continue running if the current process is closed. The launched process will continue running if the current process is closed.


+ 31
- 101
src/app/MenuBar.cpp View File

@@ -63,20 +63,14 @@ struct NotificationIcon : widget::Widget {
struct UrlItem : ui::MenuItem { struct UrlItem : ui::MenuItem {
std::string url; std::string url;
void onAction(const ActionEvent& e) override { void onAction(const ActionEvent& e) override {
std::thread t([=] {
system::openBrowser(url);
});
t.detach();
system::openBrowser(url);
} }
}; };


struct DirItem : ui::MenuItem { struct DirItem : ui::MenuItem {
std::string path; std::string path;
void onAction(const ActionEvent& e) override { void onAction(const ActionEvent& e) override {
std::thread t([=] {
system::openDirectory(path);
});
t.detach();
system::openDirectory(path);
} }
}; };


@@ -84,118 +78,54 @@ struct DirItem : ui::MenuItem {
// File // File
//////////////////// ////////////////////


struct NewItem : ui::MenuItem {
void onAction(const ActionEvent& e) override {
APP->patch->loadTemplateDialog();
}
};

struct OpenItem : ui::MenuItem {
void onAction(const ActionEvent& e) override {
APP->patch->loadDialog();
}
};

struct OpenPathItem : ui::MenuItem {
std::string path;
void onAction(const ActionEvent& e) override {
APP->patch->loadPathDialog(path);
}
};

struct OpenRecentItem : ui::MenuItem {
ui::Menu* createChildMenu() override {
ui::Menu* menu = new ui::Menu;

for (const std::string& path : settings::recentPatchPaths) {
OpenPathItem* item = new OpenPathItem;
item->text = system::getFilename(path);
item->path = path;
menu->addChild(item);
}

return menu;
}
};

struct SaveItem : ui::MenuItem {
void onAction(const ActionEvent& e) override {
APP->patch->saveDialog();
}
};

struct SaveAsItem : ui::MenuItem {
void onAction(const ActionEvent& e) override {
APP->patch->saveAsDialog();
}
};

struct SaveTemplateItem : ui::MenuItem {
void onAction(const ActionEvent& e) override {
APP->patch->saveTemplateDialog();
}
};

struct RevertItem : ui::MenuItem {
void onAction(const ActionEvent& e) override {
APP->patch->revertDialog();
}
};

struct QuitItem : ui::MenuItem {
void onAction(const ActionEvent& e) override {
APP->window->close();
}
};

struct FileButton : MenuButton { struct FileButton : MenuButton {
void onAction(const ActionEvent& e) override { void onAction(const ActionEvent& e) override {
ui::Menu* menu = createMenu(); ui::Menu* menu = createMenu();
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y)); menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
menu->box.size.x = box.size.x; menu->box.size.x = box.size.x;


NewItem* newItem = new NewItem;
newItem->text = "New";
newItem->rightText = RACK_MOD_CTRL_NAME "+N";
menu->addChild(newItem);
menu->addChild(createMenuItem("New", RACK_MOD_CTRL_NAME "+N", []() {
APP->patch->loadTemplateDialog();
}));


OpenItem* openItem = new OpenItem;
openItem->text = "Open";
openItem->rightText = RACK_MOD_CTRL_NAME "+O";
menu->addChild(openItem);
menu->addChild(createMenuItem("Open", RACK_MOD_CTRL_NAME "+O", []() {
APP->patch->loadDialog();
}));


OpenRecentItem* openRecentItem = new OpenRecentItem;
openRecentItem->text = "Open recent";
openRecentItem->rightText = RIGHT_ARROW;
ui::MenuItem* openRecentItem = createSubmenuItem("Open recent", [](ui::Menu* menu) {
for (const std::string& path : settings::recentPatchPaths) {
std::string name = system::getStem(path);
menu->addChild(createMenuItem(name, "", [=]() {
APP->patch->loadPathDialog(path);
}));
}
});
openRecentItem->disabled = settings::recentPatchPaths.empty(); openRecentItem->disabled = settings::recentPatchPaths.empty();
menu->addChild(openRecentItem); menu->addChild(openRecentItem);


SaveItem* saveItem = new SaveItem;
saveItem->text = "Save";
saveItem->rightText = RACK_MOD_CTRL_NAME "+S";
menu->addChild(saveItem);
menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() {
APP->patch->saveDialog();
}));


SaveAsItem* saveAsItem = new SaveAsItem;
saveAsItem->text = "Save as";
saveAsItem->rightText = RACK_MOD_CTRL_NAME "+Shift+S";
menu->addChild(saveAsItem);
menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() {
APP->patch->saveAsDialog();
}));


SaveTemplateItem* saveTemplateItem = new SaveTemplateItem;
saveTemplateItem->text = "Save template";
menu->addChild(saveTemplateItem);
menu->addChild(createMenuItem("Save template", "", []() {
APP->patch->saveTemplateDialog();
}));


RevertItem* revertItem = new RevertItem;
revertItem->text = "Revert";
revertItem->rightText = RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+O";
ui::MenuItem* revertItem = createMenuItem("Revert", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+O", []() {
APP->patch->revertDialog();
});
revertItem->disabled = (APP->patch->path == ""); revertItem->disabled = (APP->patch->path == "");
menu->addChild(revertItem); menu->addChild(revertItem);


menu->addChild(new ui::MenuSeparator); menu->addChild(new ui::MenuSeparator);


QuitItem* quitItem = new QuitItem;
quitItem->text = "Quit";
quitItem->rightText = RACK_MOD_CTRL_NAME "+Q";
menu->addChild(quitItem);
menu->addChild(createMenuItem("Quit", RACK_MOD_CTRL_NAME "+Q", []() {
APP->window->close();
}));
} }
}; };




+ 1
- 4
src/app/ModuleBrowser.cpp View File

@@ -423,10 +423,7 @@ struct ZoomButton : ui::ChoiceButton {
struct UrlButton : ui::Button { struct UrlButton : ui::Button {
std::string url; std::string url;
void onAction(const ActionEvent& e) override { void onAction(const ActionEvent& e) override {
std::thread t([=] {
system::openBrowser(url);
});
t.detach();
system::openBrowser(url);
} }
}; };




+ 2
- 8
src/app/ModuleWidget.cpp View File

@@ -29,10 +29,7 @@ static const char PRESET_FILTERS[] = "VCV Rack module preset (.vcvm):vcvm";
struct ModuleUrlItem : ui::MenuItem { struct ModuleUrlItem : ui::MenuItem {
std::string url; std::string url;
void onAction(const ActionEvent& e) override { void onAction(const ActionEvent& e) override {
std::thread t([=]() {
system::openBrowser(url);
});
t.detach();
system::openBrowser(url);
} }
}; };


@@ -40,10 +37,7 @@ struct ModuleUrlItem : ui::MenuItem {
struct ModuleDirItem : ui::MenuItem { struct ModuleDirItem : ui::MenuItem {
std::string path; std::string path;
void onAction(const ActionEvent& e) override { void onAction(const ActionEvent& e) override {
std::thread t([=]() {
system::openDirectory(path);
});
t.detach();
system::openDirectory(path);
} }
}; };




+ 1
- 4
src/app/Scene.cpp View File

@@ -191,10 +191,7 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
e.consume(this); e.consume(this);
} }
if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) { if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) {
std::thread t([] {
system::openBrowser("https://vcvrack.com/manual/");
});
t.detach();
system::openBrowser("https://vcvrack.com/manual/");
e.consume(this); e.consume(this);
} }
if (e.key == GLFW_KEY_F3 && (e.mods & RACK_MOD_MASK) == 0) { if (e.key == GLFW_KEY_F3 && (e.mods & RACK_MOD_MASK) == 0) {


+ 1
- 4
src/app/TipWindow.cpp View File

@@ -19,10 +19,7 @@ namespace app {
struct UrlButton : ui::Button { struct UrlButton : ui::Button {
std::string url; std::string url;
void onAction(const ActionEvent& e) override { void onAction(const ActionEvent& e) override {
std::thread t([=] {
system::openBrowser(url);
});
t.detach();
system::openBrowser(url);
} }
}; };




+ 18
- 10
src/system.cpp View File

@@ -711,32 +711,40 @@ std::string getOperatingSystemInfo() {




void openBrowser(const std::string& url) { void openBrowser(const std::string& url) {
std::string urlL = url;
std::thread t([=] {
#if defined ARCH_LIN #if defined ARCH_LIN
std::string command = "xdg-open \"" + url + "\"";
(void) std::system(command.c_str());
std::string command = "xdg-open \"" + urlL + "\"";
(void) std::system(command.c_str());
#endif #endif
#if defined ARCH_MAC #if defined ARCH_MAC
std::string command = "open \"" + url + "\"";
std::system(command.c_str());
std::string command = "open \"" + urlL + "\"";
std::system(command.c_str());
#endif #endif
#if defined ARCH_WIN #if defined ARCH_WIN
ShellExecuteW(NULL, L"open", string::UTF8toUTF16(url).c_str(), NULL, NULL, SW_SHOWDEFAULT);
ShellExecuteW(NULL, L"open", string::UTF8toUTF16(urlL).c_str(), NULL, NULL, SW_SHOWDEFAULT);
#endif #endif
});
t.detach();
} }




void openDirectory(const std::string& path) { void openDirectory(const std::string& path) {
std::string pathL = path;
std::thread t([=] {
#if defined ARCH_LIN #if defined ARCH_LIN
std::string command = "xdg-open \"" + path + "\"";
(void) std::system(command.c_str());
std::string command = "xdg-open \"" + pathL + "\"";
(void) std::system(command.c_str());
#endif #endif
#if defined ARCH_MAC #if defined ARCH_MAC
std::string command = "open \"" + path + "\"";
std::system(command.c_str());
std::string command = "open \"" + pathL + "\"";
std::system(command.c_str());
#endif #endif
#if defined ARCH_WIN #if defined ARCH_WIN
ShellExecuteW(NULL, L"explore", string::UTF8toUTF16(path).c_str(), NULL, NULL, SW_SHOWDEFAULT);
ShellExecuteW(NULL, L"explore", string::UTF8toUTF16(pathL).c_str(), NULL, NULL, SW_SHOWDEFAULT);
#endif #endif
});
t.detach();
} }






Loading…
Cancel
Save