impr: Clean up window setup code

This commit is contained in:
WerWolv
2025-08-10 12:34:03 +02:00
parent 3e98d0a0f8
commit 5028b354cc
16 changed files with 120 additions and 129 deletions

View File

@@ -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
*

View File

@@ -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
*

View File

@@ -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

View File

@@ -6,6 +6,7 @@ namespace hex::init {
void handleFileOpenRequest();
void initializationFinished();
std::unique_ptr<WindowSplash> initializeImHex();
void deinitializeImHex();

View File

@@ -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<std::string> m_popupsToOpen;
std::set<int> m_pressedKeys;
ImGuiExt::ImHexCustomData m_imguiCustomData;
u32 m_searchBarPosition = 0;
bool m_emergencyPopupOpen = false;
bool m_shouldUnlockFrameRate = false;
double m_fpsUnlockedEndTime = 0.0;

View File

@@ -1,5 +1,11 @@
#include <hex/api/events/requests_interaction.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/api/tutorial_manager.hpp>
#include <hex/api/shortcut_manager.hpp>
#include <hex/api/events/events_lifecycle.hpp>
#include <hex/helpers/utils.hpp>
#include <init/splash_window.hpp>
@@ -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();

View File

@@ -48,6 +48,8 @@
// Main window
{
Window window;
initializationFinished();
window.loop();
}

View File

@@ -90,6 +90,8 @@
static std::optional<Window> window;
window.emplace();
initializationFinished();
emscripten_set_main_loop([]() {
window->fullFrame();
}, 60, 0);

View File

@@ -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;

View File

@@ -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<std::string>("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<std::string> 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));

View File

@@ -41,7 +41,7 @@ static void detectSystemTheme() {
}
});
EventWindowInitialized::subscribe([=] {
EventImHexStartupFinished::subscribe([=] {
bool themeFollowSystem = ContentRegistry::Settings::read<std::string>("hex.builtin.setting.interface", "hex.builtin.setting.interface.color", ThemeManager::NativeTheme) == ThemeManager::NativeTheme;
if (themeFollowSystem)