From 5028b354ccf8eceba1014192f2b81edbc7b6ae40 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sun, 10 Aug 2025 12:34:03 +0200 Subject: [PATCH] impr: Clean up window setup code --- .../include/hex/api/events/events_gui.hpp | 9 - .../hex/api/events/requests_lifecycle.hpp | 11 -- main/gui/CMakeLists.txt | 12 +- main/gui/include/init/run.hpp | 1 + main/gui/include/window.hpp | 4 +- main/gui/source/init/run/common.cpp | 21 +++ .../init/run/{native.cpp => desktop.cpp} | 2 + main/gui/source/init/run/web.cpp | 2 + .../source/messaging/{win.cpp => windows.cpp} | 0 .../{linux_window.cpp => platform/linux.cpp} | 0 .../{macos_window.cpp => platform/macos.cpp} | 0 .../{web_window.cpp => platform/web.cpp} | 0 .../{win_window.cpp => platform/windows.cpp} | 0 main/gui/source/window/window.cpp | 159 +++++++----------- plugins/builtin/source/content/events.cpp | 26 ++- plugins/windows/source/plugin_windows.cpp | 2 +- 16 files changed, 120 insertions(+), 129 deletions(-) rename main/gui/source/init/run/{native.cpp => desktop.cpp} (96%) rename main/gui/source/messaging/{win.cpp => windows.cpp} (100%) rename main/gui/source/window/{linux_window.cpp => platform/linux.cpp} (100%) rename main/gui/source/window/{macos_window.cpp => platform/macos.cpp} (100%) rename main/gui/source/window/{web_window.cpp => platform/web.cpp} (100%) rename main/gui/source/window/{win_window.cpp => platform/windows.cpp} (100%) diff --git a/lib/libimhex/include/hex/api/events/events_gui.hpp b/lib/libimhex/include/hex/api/events/events_gui.hpp index 074d35010..7402dfbb8 100644 --- a/lib/libimhex/include/hex/api/events/events_gui.hpp +++ b/lib/libimhex/include/hex/api/events/events_gui.hpp @@ -61,15 +61,6 @@ namespace hex { */ EVENT_DEF(EventWindowClosing, GLFWwindow*); - /** - * @brief Informs that the main window is initialized - * - * On Windows OS, it is used to initialize system theme, if ImHex's theme is following it. - * - * FIXME: Change event name to reflect Theme detection, if it's only used for that purpose? - */ - EVENT_DEF(EventWindowInitialized); - /** * @brief Informs that the main window is deinitializing * diff --git a/lib/libimhex/include/hex/api/events/requests_lifecycle.hpp b/lib/libimhex/include/hex/api/events/requests_lifecycle.hpp index 486e373ed..82b184aa7 100644 --- a/lib/libimhex/include/hex/api/events/requests_lifecycle.hpp +++ b/lib/libimhex/include/hex/api/events/requests_lifecycle.hpp @@ -56,17 +56,6 @@ namespace hex { */ EVENT_DEF(RequestInitThemeHandlers); - /** - * @brief Requests version and first-startup checks - * - * This request is called during ImHex's startup, and allows ImHex to check if it was updated since last launch. - * It also ensures newcomers (that open ImHex for the first time) are greeted with the tutorial. - * - * FIXME: the name is misleading, as this request does not effectively start any migration. It only executes - * checks about ImHex's version. The name should be changed to reflect this behaviour. - */ - EVENT_DEF(RequestStartMigration); - /** * @brief Send a subcommand to the main Imhex instance * diff --git a/main/gui/CMakeLists.txt b/main/gui/CMakeLists.txt index 8acb12d0f..11f139af5 100644 --- a/main/gui/CMakeLists.txt +++ b/main/gui/CMakeLists.txt @@ -5,22 +5,22 @@ add_executable(main ${APPLICATION_TYPE} source/crash_handlers.cpp source/window/window.cpp - source/window/win_window.cpp - source/window/macos_window.cpp - source/window/linux_window.cpp - source/window/web_window.cpp + source/window/platform/windows.cpp + source/window/platform/macos.cpp + source/window/platform/linux.cpp + source/window/platform/web.cpp source/messaging/common.cpp source/messaging/linux.cpp source/messaging/macos.cpp - source/messaging/win.cpp + source/messaging/windows.cpp source/messaging/web.cpp source/init/splash_window.cpp source/init/tasks.cpp source/init/run/common.cpp - source/init/run/native.cpp + source/init/run/desktop.cpp source/init/run/web.cpp source/init/run/cli.cpp diff --git a/main/gui/include/init/run.hpp b/main/gui/include/init/run.hpp index b6dcbc62c..c22e5cb8d 100644 --- a/main/gui/include/init/run.hpp +++ b/main/gui/include/init/run.hpp @@ -6,6 +6,7 @@ namespace hex::init { void handleFileOpenRequest(); + void initializationFinished(); std::unique_ptr initializeImHex(); void deinitializeImHex(); diff --git a/main/gui/include/window.hpp b/main/gui/include/window.hpp index 56eef6145..271ed3350 100644 --- a/main/gui/include/window.hpp +++ b/main/gui/include/window.hpp @@ -53,6 +53,7 @@ namespace hex { void registerEventHandlers(); void loadPostProcessingShader(); + void setupEmergencyPopups(); void drawImGui(); void drawWithShader(); @@ -66,13 +67,10 @@ namespace hex { double m_lastStartFrameTime = 0; double m_lastFrameTime = 0; - std::mutex m_popupMutex; - std::list m_popupsToOpen; std::set m_pressedKeys; ImGuiExt::ImHexCustomData m_imguiCustomData; - u32 m_searchBarPosition = 0; bool m_emergencyPopupOpen = false; bool m_shouldUnlockFrameRate = false; double m_fpsUnlockedEndTime = 0.0; diff --git a/main/gui/source/init/run/common.cpp b/main/gui/source/init/run/common.cpp index b7df1b188..d5bf89120 100644 --- a/main/gui/source/init/run/common.cpp +++ b/main/gui/source/init/run/common.cpp @@ -1,5 +1,11 @@ #include #include +#include +#include +#include + +#include + #include #include @@ -35,11 +41,26 @@ namespace hex::init { return splashWindow; } + void initializationFinished() { + ContentRegistry::Settings::impl::store(); + ContentRegistry::Settings::impl::load(); + + EventImHexStartupFinished::post(); + + TutorialManager::init(); + + #if defined(OS_MACOS) + ShortcutManager::enableMacOSMode(); + #endif + } + /** * @brief Deinitializes ImHex by running all exit tasks */ void deinitializeImHex() { + ContentRegistry::Settings::impl::store(); + // Run exit tasks init::runExitTasks(); diff --git a/main/gui/source/init/run/native.cpp b/main/gui/source/init/run/desktop.cpp similarity index 96% rename from main/gui/source/init/run/native.cpp rename to main/gui/source/init/run/desktop.cpp index 768ba581b..bb83167cc 100644 --- a/main/gui/source/init/run/native.cpp +++ b/main/gui/source/init/run/desktop.cpp @@ -48,6 +48,8 @@ // Main window { Window window; + initializationFinished(); + window.loop(); } diff --git a/main/gui/source/init/run/web.cpp b/main/gui/source/init/run/web.cpp index 1f667b207..1dae30c25 100644 --- a/main/gui/source/init/run/web.cpp +++ b/main/gui/source/init/run/web.cpp @@ -90,6 +90,8 @@ static std::optional window; window.emplace(); + initializationFinished(); + emscripten_set_main_loop([]() { window->fullFrame(); }, 60, 0); diff --git a/main/gui/source/messaging/win.cpp b/main/gui/source/messaging/windows.cpp similarity index 100% rename from main/gui/source/messaging/win.cpp rename to main/gui/source/messaging/windows.cpp diff --git a/main/gui/source/window/linux_window.cpp b/main/gui/source/window/platform/linux.cpp similarity index 100% rename from main/gui/source/window/linux_window.cpp rename to main/gui/source/window/platform/linux.cpp diff --git a/main/gui/source/window/macos_window.cpp b/main/gui/source/window/platform/macos.cpp similarity index 100% rename from main/gui/source/window/macos_window.cpp rename to main/gui/source/window/platform/macos.cpp diff --git a/main/gui/source/window/web_window.cpp b/main/gui/source/window/platform/web.cpp similarity index 100% rename from main/gui/source/window/web_window.cpp rename to main/gui/source/window/platform/web.cpp diff --git a/main/gui/source/window/win_window.cpp b/main/gui/source/window/platform/windows.cpp similarity index 100% rename from main/gui/source/window/win_window.cpp rename to main/gui/source/window/platform/windows.cpp diff --git a/main/gui/source/window/window.cpp b/main/gui/source/window/window.cpp index b9d007391..3114db15b 100644 --- a/main/gui/source/window/window.cpp +++ b/main/gui/source/window/window.cpp @@ -59,6 +59,67 @@ namespace hex { using namespace std::literals::chrono_literals; Window::Window() { + this->initGLFW(); + this->initImGui(); + this->setupNativeWindow(); + this->registerEventHandlers(); + this->setupEmergencyPopups(); + + #if !defined(OS_WEB) + this->loadPostProcessingShader(); + #endif + } + + Window::~Window() { + RequestCloseImHex::unsubscribe(this); + EventDPIChanged::unsubscribe(this); + + EventWindowDeinitializing::post(m_window); + + this->exitImGui(); + this->exitGLFW(); + } + + void Window::registerEventHandlers() { + // Initialize default theme + RequestChangeTheme::post("Dark"); + + // Handle the close window request by telling GLFW to shut down + RequestCloseImHex::subscribe(this, [this](bool noQuestions) { + glfwSetWindowShouldClose(m_window, GLFW_TRUE); + + if (!noQuestions) + EventWindowClosing::post(m_window); + }); + + EventDPIChanged::subscribe(this, [this](float oldScaling, float newScaling) { + if (oldScaling == newScaling || oldScaling == 0 || newScaling == 0) + return; + + int width, height; + glfwGetWindowSize(m_window, &width, &height); + + width = float(width) * newScaling / oldScaling; + height = float(height) * newScaling / oldScaling; + + ImHexApi::System::impl::setMainWindowSize(width, height); + glfwSetWindowSize(m_window, width, height); + }); + + + LayoutManager::registerLoadCallback([this](std::string_view line) { + int width = 0, height = 0; + sscanf(line.data(), "MainWindowSize=%d,%d", &width, &height); + + if (width > 0 && height > 0) { + TaskManager::doLater([width, height, this]{ + glfwSetWindowSize(m_window, width, height); + }); + } + }); + } + + void Window::setupEmergencyPopups() { const static auto openEmergencyPopup = [this](const std::string &title){ TaskManager::doLater([this, title] { for (const auto &provider : ImHexApi::Provider::getProviders()) @@ -79,91 +140,8 @@ namespace hex { } } } - - // Initialize the window - this->initGLFW(); - this->initImGui(); - this->setupNativeWindow(); - this->registerEventHandlers(); - - #if !defined(OS_WEB) - this->loadPostProcessingShader(); - #endif - - ContentRegistry::Settings::impl::store(); - ContentRegistry::Settings::impl::load(); - - EventWindowInitialized::post(); - EventImHexStartupFinished::post(); - RequestStartMigration::post(); - - TutorialManager::init(); - - #if defined(OS_MACOS) - ShortcutManager::enableMacOSMode(); - #endif } - Window::~Window() { - EventProviderDeleted::unsubscribe(this); - RequestCloseImHex::unsubscribe(this); - RequestUpdateWindowTitle::unsubscribe(this); - EventAbnormalTermination::unsubscribe(this); - RequestOpenPopup::unsubscribe(this); - - EventWindowDeinitializing::post(m_window); - - ContentRegistry::Settings::impl::store(); - - this->exitImGui(); - this->exitGLFW(); - } - - void Window::registerEventHandlers() { - // Initialize default theme - RequestChangeTheme::post("Dark"); - - // Handle the close window request by telling GLFW to shut down - RequestCloseImHex::subscribe(this, [this](bool noQuestions) { - glfwSetWindowShouldClose(m_window, GLFW_TRUE); - - if (!noQuestions) - EventWindowClosing::post(m_window); - }); - - // Handle opening popups - RequestOpenPopup::subscribe(this, [this](auto name) { - std::scoped_lock lock(m_popupMutex); - - m_popupsToOpen.push_back(name); - }); - - EventDPIChanged::subscribe([this](float oldScaling, float newScaling) { - if (oldScaling == newScaling || oldScaling == 0 || newScaling == 0) - return; - - int width, height; - glfwGetWindowSize(m_window, &width, &height); - - width = float(width) * newScaling / oldScaling; - height = float(height) * newScaling / oldScaling; - - ImHexApi::System::impl::setMainWindowSize(width, height); - glfwSetWindowSize(m_window, width, height); - }); - - - LayoutManager::registerLoadCallback([this](std::string_view line) { - int width = 0, height = 0; - sscanf(line.data(), "MainWindowSize=%d,%d", &width, &height); - - if (width > 0 && height > 0) { - TaskManager::doLater([width, height, this]{ - glfwSetWindowSize(m_window, width, height); - }); - } - }); - } void Window::loadPostProcessingShader() { @@ -532,21 +510,6 @@ namespace hex { } } - // Open popups when plugins requested it - // We retry every frame until the popup actually opens - // It might not open the first time because another popup is already open - { - std::scoped_lock lock(m_popupMutex); - m_popupsToOpen.remove_if([](const auto &name) { - if (ImGui::IsPopupOpen(name.c_str())) - return true; - else - ImGui::OpenPopup(name.c_str()); - - return false; - }); - } - // Draw popup stack { static bool positionSet = false; diff --git a/plugins/builtin/source/content/events.cpp b/plugins/builtin/source/content/events.cpp index 00d8d0206..baeab96ee 100644 --- a/plugins/builtin/source/content/events.cpp +++ b/plugins/builtin/source/content/events.cpp @@ -280,7 +280,7 @@ namespace hex::plugin::builtin { RequestOpenFile::post(path); }); - RequestStartMigration::subscribe([] { + EventImHexStartupFinished::subscribe([] { const auto currVersion = ImHexApi::System::getImHexVersion(); const auto prevLaunchVersion = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.prev_launch_version", ""); if (prevLaunchVersion == "") { @@ -356,6 +356,30 @@ namespace hex::plugin::builtin { ThemeManager::changeTheme(theme); }); + static std::mutex s_popupMutex; + static std::list s_popupsToOpen; + RequestOpenPopup::subscribe([](auto name) { + std::scoped_lock lock(s_popupMutex); + + s_popupsToOpen.push_back(name); + }); + + EventFrameBegin::subscribe([]() { + // Open popups when plugins requested it + // We retry every frame until the popup actually opens + // It might not open the first time because another popup is already open + + std::scoped_lock lock(s_popupMutex); + s_popupsToOpen.remove_if([](const auto &name) { + if (ImGui::IsPopupOpen(name.c_str())) + return true; + else + ImGui::OpenPopup(name.c_str()); + + return false; + }); + }); + fs::setFileBrowserErrorCallback([](const std::string& errMsg){ #if defined(NFD_PORTAL) ui::PopupError::open(fmt::format("hex.builtin.popup.error.file_dialog.portal"_lang, errMsg)); diff --git a/plugins/windows/source/plugin_windows.cpp b/plugins/windows/source/plugin_windows.cpp index c8e68fec3..258fc2134 100644 --- a/plugins/windows/source/plugin_windows.cpp +++ b/plugins/windows/source/plugin_windows.cpp @@ -41,7 +41,7 @@ static void detectSystemTheme() { } }); - EventWindowInitialized::subscribe([=] { + EventImHexStartupFinished::subscribe([=] { bool themeFollowSystem = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.color", ThemeManager::NativeTheme) == ThemeManager::NativeTheme; if (themeFollowSystem)