From a9ce71c481ac4fe860c3770dc7ee41959f87e0bc Mon Sep 17 00:00:00 2001 From: WerWolv Date: Thu, 24 Jul 2025 21:37:49 +0200 Subject: [PATCH] impr: Make close button on macOS close providers if any are open instead of closing ImHex --- .../hex/api/events/events_lifecycle.hpp | 7 +++++ lib/libimhex/source/helpers/utils.cpp | 5 +-- main/gui/source/window/macos_window.cpp | 3 +- .../content/popups/popup_tasks_waiting.hpp | 10 ++++-- plugins/builtin/source/content/events.cpp | 31 ++++++++++++++++++- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/lib/libimhex/include/hex/api/events/events_lifecycle.hpp b/lib/libimhex/include/hex/api/events/events_lifecycle.hpp index e69213793..52a1540a3 100644 --- a/lib/libimhex/include/hex/api/events/events_lifecycle.hpp +++ b/lib/libimhex/include/hex/api/events/events_lifecycle.hpp @@ -12,6 +12,13 @@ namespace hex { */ EVENT_DEF(EventImHexStartupFinished); + /** + * @brief Called when the user presses the close button on the main window + * + * This is currently only used and implemented on macOS + */ + EVENT_DEF(EventCloseButtonPressed); + /** * @brief Called when ImHex is closing, to trigger the last shutdown hooks * diff --git a/lib/libimhex/source/helpers/utils.cpp b/lib/libimhex/source/helpers/utils.cpp index d37e9d666..9450ceba9 100644 --- a/lib/libimhex/source/helpers/utils.cpp +++ b/lib/libimhex/source/helpers/utils.cpp @@ -822,10 +822,7 @@ namespace hex { } extern "C" void macOSCloseButtonPressed() { - auto windowHandle = ImHexApi::System::getMainWindowHandle(); - - glfwHideWindow(windowHandle); - glfwIconifyWindow(windowHandle); + EventCloseButtonPressed::post(); } extern "C" void macosEventDataReceived(const u8 *data, size_t length) { diff --git a/main/gui/source/window/macos_window.cpp b/main/gui/source/window/macos_window.cpp index fcb87c715..323e00f7c 100644 --- a/main/gui/source/window/macos_window.cpp +++ b/main/gui/source/window/macos_window.cpp @@ -103,7 +103,8 @@ namespace hex { } void Window::beginNativeWindowFrame() { - + if (!ImHexApi::Provider::isValid()) + macosMarkContentEdited(m_window, false); } void Window::endNativeWindowFrame() { diff --git a/plugins/builtin/include/content/popups/popup_tasks_waiting.hpp b/plugins/builtin/include/content/popups/popup_tasks_waiting.hpp index 841e6faa9..b29d526f9 100644 --- a/plugins/builtin/include/content/popups/popup_tasks_waiting.hpp +++ b/plugins/builtin/include/content/popups/popup_tasks_waiting.hpp @@ -10,8 +10,9 @@ namespace hex::plugin::builtin { class PopupTasksWaiting : public Popup { public: - PopupTasksWaiting() - : hex::Popup("hex.builtin.popup.waiting_for_tasks.title", false) { } + PopupTasksWaiting(std::function onFinish) + : hex::Popup("hex.builtin.popup.waiting_for_tasks.title", false), + m_onFinish(std::move(onFinish)){ } void drawContent() override { ImGui::TextUnformatted("hex.builtin.popup.waiting_for_tasks.desc"_lang); @@ -26,13 +27,16 @@ namespace hex::plugin::builtin { if (TaskManager::getRunningTaskCount() == 0 && TaskManager::getRunningBackgroundTaskCount() == 0) { ImGui::CloseCurrentPopup(); - ImHexApi::System::closeImHex(); + m_onFinish(); } } [[nodiscard]] ImGuiWindowFlags getFlags() const override { return ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove; } + + private: + std::function m_onFinish; }; } \ No newline at end of file diff --git a/plugins/builtin/source/content/events.cpp b/plugins/builtin/source/content/events.cpp index a7e98ea16..65ddd2cda 100644 --- a/plugins/builtin/source/content/events.cpp +++ b/plugins/builtin/source/content/events.cpp @@ -95,11 +95,40 @@ namespace hex::plugin::builtin { TaskManager::doLater([] { for (auto &task : TaskManager::getRunningTasks()) task->interrupt(); - PopupTasksWaiting::open(); + PopupTasksWaiting::open([]() { + ImHexApi::System::closeImHex(); + }); }); } }); + EventCloseButtonPressed::subscribe([]() { + if (ImHexApi::Provider::isValid()) { + if (ImHexApi::Provider::isDirty()) { + ui::PopupQuestion::open("hex.builtin.popup.exit_application.desc"_lang, + [] { + for (const auto &provider : ImHexApi::Provider::getProviders()) + ImHexApi::Provider::remove(provider); + }, + [] { } + ); + } else if (TaskManager::getRunningTaskCount() > 0 || TaskManager::getRunningBackgroundTaskCount() > 0) { + TaskManager::doLater([] { + for (auto &task : TaskManager::getRunningTasks()) + task->interrupt(); + PopupTasksWaiting::open([]() { + EventCloseButtonPressed::post(); + }); + }); + } else { + for (const auto &provider : ImHexApi::Provider::getProviders()) + ImHexApi::Provider::remove(provider); + } + } else { + ImHexApi::System::closeImHex(); + } + }); + EventProviderClosing::subscribe([](const prv::Provider *provider, bool *shouldClose) { if (provider->isDirty()) { *shouldClose = false;