diff --git a/lib/libimhex/include/hex/api/shortcut_manager.hpp b/lib/libimhex/include/hex/api/shortcut_manager.hpp index da80d2c45..757471c7c 100644 --- a/lib/libimhex/include/hex/api/shortcut_manager.hpp +++ b/lib/libimhex/include/hex/api/shortcut_manager.hpp @@ -153,12 +153,7 @@ namespace hex { constexpr static auto SUPER = Key(static_cast(0x0800'0000)); constexpr static auto CurrentView = Key(static_cast(0x1000'0000)); constexpr static auto AllowWhileTyping = Key(static_cast(0x2000'0000)); - - #if defined (OS_MACOS) - constexpr static auto CTRLCMD = SUPER; - #else - constexpr static auto CTRLCMD = CTRL; - #endif + constexpr static auto CTRLCMD = Key(static_cast(0x4000'0000)); class Shortcut { public: @@ -255,6 +250,8 @@ namespace hex { static void resumeShortcuts(); static void pauseShortcuts(); + static void enableMacOSMode(); + [[nodiscard]] static std::optional getPreviousShortcut(); [[nodiscard]] static std::vector getGlobalShortcuts(); diff --git a/lib/libimhex/source/api/shortcut_manager.cpp b/lib/libimhex/source/api/shortcut_manager.cpp index c2c838301..a5dbee456 100644 --- a/lib/libimhex/source/api/shortcut_manager.cpp +++ b/lib/libimhex/source/api/shortcut_manager.cpp @@ -12,6 +12,7 @@ namespace hex { AutoReset> s_globalShortcuts; std::atomic s_paused; std::optional s_prevShortcut; + bool s_macOSMode = false; } @@ -78,22 +79,14 @@ namespace hex { std::string Shortcut::toString() const { std::string result; - #if defined(OS_MACOS) - constexpr static auto CTRL_NAME = "⌃"; - constexpr static auto ALT_NAME = "⌥"; - constexpr static auto SHIFT_NAME = "⇧"; - constexpr static auto SUPER_NAME = "⌘"; - constexpr static auto Concatination = " "; - #else - constexpr static auto CTRL_NAME = "CTRL"; - constexpr static auto ALT_NAME = "ALT"; - constexpr static auto SHIFT_NAME = "SHIFT"; - constexpr static auto SUPER_NAME = "SUPER"; - constexpr static auto Concatination = " + "; - #endif + const auto CTRL_NAME = s_macOSMode ? "⌃" : "CTRL"; + const auto ALT_NAME = s_macOSMode ? "⌥" : "ALT"; + const auto SHIFT_NAME = s_macOSMode ? "⇧" : "SHIFT"; + const auto SUPER_NAME = s_macOSMode ? "⌘" : "SUPER"; + const auto Concatination = s_macOSMode ? " " : " + "; auto keys = m_keys; - if (keys.erase(CTRL) > 0) { + if (keys.erase(CTRL) > 0 || (!s_macOSMode && keys.erase(CTRLCMD) > 0)) { result += CTRL_NAME; result += Concatination; } @@ -105,7 +98,7 @@ namespace hex { result += SHIFT_NAME; result += Concatination; } - if (keys.erase(SUPER) > 0) { + if (keys.erase(SUPER) > 0 || (s_macOSMode && keys.erase(CTRLCMD) > 0)) { result += SUPER_NAME; result += Concatination; } @@ -267,13 +260,13 @@ namespace hex { Shortcut pressedShortcut; if (ctrl) - pressedShortcut += CTRL; + pressedShortcut += s_macOSMode ? CTRL : CTRLCMD; if (alt) pressedShortcut += ALT; if (shift) pressedShortcut += SHIFT; if (super) - pressedShortcut += SUPER; + pressedShortcut += s_macOSMode ? CTRLCMD : SUPER; if (focused) pressedShortcut += CurrentView; if (ImGui::GetIO().WantTextInput) @@ -387,4 +380,9 @@ namespace hex { return result; } + void ShortcutManager::enableMacOSMode() { + s_macOSMode = true; + } + + } \ No newline at end of file diff --git a/main/gui/source/window/web_window.cpp b/main/gui/source/window/web_window.cpp index 827cf72f0..32b7ae22a 100644 --- a/main/gui/source/window/web_window.cpp +++ b/main/gui/source/window/web_window.cpp @@ -25,6 +25,10 @@ EM_JS(void, resizeCanvas, (), { js_resizeCanvas(); }); +EM_JS(bool, isMacOS, (), { + return navigator.userAgent.indexOf('Mac OS X') != -1 +}); + EM_JS(void, fixCanvasInPlace, (), { document.getElementById('canvas').classList.add('canvas-fixed'); }); @@ -126,6 +130,9 @@ namespace hex { if (themeFollowSystem) EventOSThemeChanged::post(); + + if (isMacOS()) + ShortcutManager::enableMacOSMode(); } void Window::beginNativeWindowFrame() { diff --git a/main/gui/source/window/window.cpp b/main/gui/source/window/window.cpp index 7daaf39e0..b6f786380 100644 --- a/main/gui/source/window/window.cpp +++ b/main/gui/source/window/window.cpp @@ -81,6 +81,10 @@ namespace hex { EventImHexStartupFinished::post(); TutorialManager::init(); + + #if defined(OS_MACOS) + ShortcutManager::enableMacOSMode(); + #endif } Window::~Window() { @@ -881,56 +885,53 @@ namespace hex { EventWindowFocused::post(focused == GLFW_TRUE); }); - #if !defined(OS_WEB) - // Register key press callback - glfwSetInputMode(m_window, GLFW_LOCK_KEY_MODS, GLFW_TRUE); - glfwSetKeyCallback(m_window, [](GLFWwindow *window, int key, int scanCode, int action, int mods) { - std::ignore = mods; + // Register key press callback + glfwSetInputMode(m_window, GLFW_LOCK_KEY_MODS, GLFW_TRUE); + glfwSetKeyCallback(m_window, [](GLFWwindow *window, int key, int scanCode, int action, int mods) { + std::ignore = mods; + // Handle A-Z keys using their ASCII value instead of the keycode + if (key >= GLFW_KEY_A && key <= GLFW_KEY_Z) { + std::string_view name = glfwGetKeyName(key, scanCode); - // Handle A-Z keys using their ASCII value instead of the keycode - if (key >= GLFW_KEY_A && key <= GLFW_KEY_Z) { - std::string_view name = glfwGetKeyName(key, scanCode); - - // If the key name is only one character long, use the ASCII value instead - // Otherwise the keyboard was set to a non-English layout and the key name - // is not the same as the ASCII value - if (!name.empty()) { - const std::uint8_t byte = name[0]; - if (name.length() == 1 && byte <= 0x7F) { - key = std::toupper(byte); - } + // If the key name is only one character long, use the ASCII value instead + // Otherwise the keyboard was set to a non-English layout and the key name + // is not the same as the ASCII value + if (!name.empty()) { + const std::uint8_t byte = name[0]; + if (name.length() == 1 && byte <= 0x7F) { + key = std::toupper(byte); } } + } - if (key == GLFW_KEY_UNKNOWN) return; + if (key == GLFW_KEY_UNKNOWN) return; - if (action == GLFW_PRESS || action == GLFW_REPEAT) { - if (key != GLFW_KEY_LEFT_CONTROL && key != GLFW_KEY_RIGHT_CONTROL && - key != GLFW_KEY_LEFT_ALT && key != GLFW_KEY_RIGHT_ALT && - key != GLFW_KEY_LEFT_SHIFT && key != GLFW_KEY_RIGHT_SHIFT && - key != GLFW_KEY_LEFT_SUPER && key != GLFW_KEY_RIGHT_SUPER - ) { - auto win = static_cast(glfwGetWindowUserPointer(window)); - win->m_unlockFrameRate = true; + if (action == GLFW_PRESS || action == GLFW_REPEAT) { + if (key != GLFW_KEY_LEFT_CONTROL && key != GLFW_KEY_RIGHT_CONTROL && + key != GLFW_KEY_LEFT_ALT && key != GLFW_KEY_RIGHT_ALT && + key != GLFW_KEY_LEFT_SHIFT && key != GLFW_KEY_RIGHT_SHIFT && + key != GLFW_KEY_LEFT_SUPER && key != GLFW_KEY_RIGHT_SUPER + ) { + auto win = static_cast(glfwGetWindowUserPointer(window)); + win->m_unlockFrameRate = true; - if (!(mods & GLFW_MOD_NUM_LOCK)) { - if (key == GLFW_KEY_KP_0) key = GLFW_KEY_INSERT; - else if (key == GLFW_KEY_KP_1) key = GLFW_KEY_END; - else if (key == GLFW_KEY_KP_2) key = GLFW_KEY_DOWN; - else if (key == GLFW_KEY_KP_3) key = GLFW_KEY_PAGE_DOWN; - else if (key == GLFW_KEY_KP_4) key = GLFW_KEY_LEFT; - else if (key == GLFW_KEY_KP_6) key = GLFW_KEY_RIGHT; - else if (key == GLFW_KEY_KP_7) key = GLFW_KEY_HOME; - else if (key == GLFW_KEY_KP_8) key = GLFW_KEY_UP; - else if (key == GLFW_KEY_KP_9) key = GLFW_KEY_PAGE_UP; - } - - win->m_pressedKeys.push_back(key); + if (!(mods & GLFW_MOD_NUM_LOCK)) { + if (key == GLFW_KEY_KP_0) key = GLFW_KEY_INSERT; + else if (key == GLFW_KEY_KP_1) key = GLFW_KEY_END; + else if (key == GLFW_KEY_KP_2) key = GLFW_KEY_DOWN; + else if (key == GLFW_KEY_KP_3) key = GLFW_KEY_PAGE_DOWN; + else if (key == GLFW_KEY_KP_4) key = GLFW_KEY_LEFT; + else if (key == GLFW_KEY_KP_6) key = GLFW_KEY_RIGHT; + else if (key == GLFW_KEY_KP_7) key = GLFW_KEY_HOME; + else if (key == GLFW_KEY_KP_8) key = GLFW_KEY_UP; + else if (key == GLFW_KEY_KP_9) key = GLFW_KEY_PAGE_UP; } + + win->m_pressedKeys.push_back(key); } - }); - #endif + } + }); // Register window close callback glfwSetWindowCloseCallback(m_window, [](GLFWwindow *window) {