diff --git a/external/ImGui/source/imgui.cpp b/external/ImGui/source/imgui.cpp index 5594ed4f7..0413722a8 100644 --- a/external/ImGui/source/imgui.cpp +++ b/external/ImGui/source/imgui.cpp @@ -7292,7 +7292,10 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind { // We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user. ImGuiWindow* window = g.WindowsFocusOrder[i]; - IM_ASSERT(window == window->RootWindow); + //IM_ASSERT(window == window->RootWindow); + if (window != window->RootWindow) + return; + if (window != ignore_window && window->WasActive) if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) { diff --git a/include/init/splash_window.hpp b/include/init/splash_window.hpp index ca60c5cf0..7d71c2b49 100644 --- a/include/init/splash_window.hpp +++ b/include/init/splash_window.hpp @@ -14,7 +14,7 @@ namespace hex::init { class WindowSplash { public: - WindowSplash(int &argc, char **&argv, char **&envp); + WindowSplash(); ~WindowSplash(); bool loop(); diff --git a/source/init/splash_window.cpp b/source/init/splash_window.cpp index 0eca72504..10338584a 100644 --- a/source/init/splash_window.cpp +++ b/source/init/splash_window.cpp @@ -26,11 +26,7 @@ using namespace std::literals::chrono_literals; namespace hex::init { - WindowSplash::WindowSplash(int &argc, char **&argv, char **&envp) : m_window(nullptr) { - SharedData::mainArgc = argc; - SharedData::mainArgv = argv; - SharedData::mainEnvp = envp; - + WindowSplash::WindowSplash() : m_window(nullptr) { this->initGLFW(); this->initImGui(); } @@ -179,7 +175,7 @@ namespace hex::init { } } - this->m_window = glfwCreateWindow(640 * SharedData::globalScale, 400 * SharedData::globalScale, "ImHex", nullptr, nullptr); + this->m_window = glfwCreateWindow(640 * SharedData::globalScale, 400 * SharedData::globalScale, "Starting ImHex...", nullptr, nullptr); if (this->m_window == nullptr) { log::fatal("Failed to create GLFW window!"); exit(EXIT_FAILURE); diff --git a/source/main.cpp b/source/main.cpp index b23957bff..689778455 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "window.hpp" @@ -11,13 +12,17 @@ #include int main(int argc, char **argv, char **envp) { + hex::SharedData::mainArgc = argc; + hex::SharedData::mainArgv = argv; + hex::SharedData::mainEnvp = envp; + using namespace hex; // Initialization { Window::initNative(); - init::WindowSplash splashWindow(argc, argv, envp); + init::WindowSplash splashWindow; for (const auto &[name, task] : init::getInitTasks()) splashWindow.addStartupTask(name, task); diff --git a/source/window/win_window.cpp b/source/window/win_window.cpp index 8d474205a..263424747 100644 --- a/source/window/win_window.cpp +++ b/source/window/win_window.cpp @@ -145,6 +145,19 @@ break; } + case WM_COPYDATA: + { + auto message = reinterpret_cast(lParam); + if (message == nullptr) break; + + auto path = reinterpret_cast(message->lpData); + if (path == nullptr) break; + + log::info("Opening file in existing instance: {}", path); + EventManager::post(path); + break; + } + default: break; } @@ -179,9 +192,44 @@ } } } + + // Open new files in already existing ImHex instance + constexpr static auto UniqueMutexId = "ImHex/a477ea68-e334-4d07-a439-4f159c683763"; + + HANDLE globalMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, UniqueMutexId); + if (!globalMutex) { + globalMutex = CreateMutex(nullptr, FALSE, UniqueMutexId); + } else { + if (SharedData::mainArgc > 1) { + ::EnumWindows([](HWND hWnd, LPARAM lparam) -> BOOL { + auto length = ::GetWindowTextLength(hWnd); + std::string windowName(length + 1, '\x00'); + ::GetWindowText(hWnd, windowName.data(), windowName.size()); + + if (::IsWindowVisible(hWnd) && length != 0) { + if (windowName.starts_with("ImHex")) { + COPYDATASTRUCT message = { + .dwData = 0, + .cbData = static_cast(std::strlen(SharedData::mainArgv[1])) + 1, + .lpData = SharedData::mainArgv[1] + }; + + SendMessage(hWnd, WM_COPYDATA, reinterpret_cast(hWnd), reinterpret_cast(&message)); + + return FALSE; + } + } + + return TRUE; + }, 0); + + std::exit(0); + } + } } void Window::setupNativeWindow() { + // Setup borderless window auto hwnd = glfwGetWin32Window(this->m_window); oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)windowProc); @@ -195,6 +243,7 @@ ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE); ::SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW); + // Setup system theme change detector bool themeFollowSystem = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color") == 0; EventManager::subscribe(this, [themeFollowSystem]{ if (!themeFollowSystem) return;