Skip to content
Closed
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "iOS" OR IOS)
set(CMAKE_OSX_ARCHITECTURES "arm64")
else()
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
set(CMAKE_OSX_ARCHITECTURES "x86_64")
endif()

project(DevTools VERSION 1.0.0)
Expand Down
85 changes: 85 additions & 0 deletions src/backend.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cocos2d.h>
#include <Geode/modify/CCTouchDispatcher.hpp>
#include <Geode/modify/CCMouseDispatcher.hpp>
#include <Geode/modify/CCKeyboardDispatcher.hpp>
#include <Geode/modify/CCIMEDispatcher.hpp>
#include "platform/platform.hpp"
#include "DevTools.hpp"
Expand Down Expand Up @@ -356,3 +357,87 @@ class $modify(CCIMEDispatcher) {
io.AddKeyEvent(ImGuiKey_Backspace, false);
}
};

ImGuiKey cocosToImGuiKey(cocos2d::enumKeyCodes key) {
if (key >= KEY_A && key <= KEY_Z) {
return static_cast<ImGuiKey>(ImGuiKey_A + (key - KEY_A));
}
if (key >= KEY_Zero && key <= KEY_Nine) {
return static_cast<ImGuiKey>(ImGuiKey_0 + (key - KEY_Zero));
}
switch (key) {
case KEY_Up: return ImGuiKey_UpArrow;
case KEY_Down: return ImGuiKey_DownArrow;
case KEY_Left: return ImGuiKey_LeftArrow;
case KEY_Right: return ImGuiKey_RightArrow;

case KEY_Control: return ImGuiKey_ModCtrl;
case KEY_LeftWindowsKey: return ImGuiKey_ModSuper;
case KEY_Shift: return ImGuiKey_ModShift;
case KEY_Alt: return ImGuiKey_ModAlt;
case KEY_Enter: return ImGuiKey_Enter;

case KEY_Home: return ImGuiKey_Home;
case KEY_End: return ImGuiKey_End;
// macos uses delete instead of backspace for some reason
#ifndef GEODE_IS_MACOS
case KEY_Delete: return ImGuiKey_Delete;
#endif
case KEY_Escape: return ImGuiKey_Escape;

// KEY_Control and KEY_Shift aren't called on android like windows or mac
#ifdef GEODE_IS_ANDROID
case KEY_LeftControl: return ImGuiKey_ModCtrl;
case KEY_RightContol: return ImGuiKey_ModCtrl;
case KEY_LeftShift: return ImGuiKey_ModShift;
case KEY_RightShift: return ImGuiKey_ModShift;
#endif

default: return ImGuiKey_None;
}
}

#ifndef GEODE_IS_IOS
class $modify(CCKeyboardDispatcher) {
bool dispatchKeyboardMSG(enumKeyCodes key, bool down, bool repeat) {
auto& io = ImGui::GetIO();
const auto imKey = cocosToImGuiKey(key);
if (imKey != ImGuiKey_None) {
io.AddKeyEvent(imKey, down);
}

// CCIMEDispatcher stuff doesn't get called on android unless the virtual keyboard would be up.
// Similarly, CCKeyboardDispatcher doesn't get called if the virtual keyboard would be up.
#ifdef GEODE_IS_ANDROID
if (down) {
char c = 0;
if (key >= KEY_A && key <= KEY_Z) {
c = static_cast<char>(key);
if (!io.KeyShift) {
c = static_cast<char>(tolower(c));
}
} else if (key >= KEY_Zero && key <= KEY_Nine) {
c = static_cast<char>('0' + (key - KEY_Zero));
} else if (key == KEY_Space) {
c = ' ';
}

if (c != 0) {
std::string str(1, c);
io.AddInputCharactersUTF8(str.c_str());
}
}
if (key == KEY_Backspace) {
io.AddKeyEvent(ImGuiKey_Backspace, true);
io.AddKeyEvent(ImGuiKey_Backspace, false);
}
#endif

if (io.WantCaptureKeyboard) {
return false;
} else {
return CCKeyboardDispatcher::dispatchKeyboardMSG(key, down, repeat);
}
}
};
#endif
61 changes: 61 additions & 0 deletions src/platform/Mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,65 @@
else return fmt::format("{:#x}", addr - base);
}

// Below is adapted from BetterInputs - thanks Spaghett
#ifdef GEODE_IS_MACOS

#include <Carbon/Carbon.h>
#import <objc/runtime.h>

#include <Geode/cocos/platform/mac/CCEventDispatcher.h>
#import <Geode/cocos/platform/mac/EAGLView.h>
#include <Geode/loader/ModEvent.hpp>
#include <Geode/loader/Log.hpp>

#include <imgui.h>

#define OBJC_SWIZZLE(klass, type, cleanFuncName, funcName) \
do { \
auto cleanFuncName ## Method = class_getInstanceMethod(objc_getClass(#klass), @selector(funcName)); \
cleanFuncName ## OIMP = reinterpret_cast<type>(method_getImplementation(cleanFuncName ## Method)); \
method_setImplementation(cleanFuncName ## Method, reinterpret_cast<IMP>(&cleanFuncName)); \
geode::log::debug("Swizzled Objective C Method '" #klass " " #funcName "'"); \
} while(0)

using key_event_t = void(*)(EAGLView*, SEL, NSEvent*);

static key_event_t flagsChangedExecOIMP;
void flagsChangedExec(EAGLView* self, SEL sel, NSEvent* event)
{

flagsChangedExecOIMP(self, sel, event);

auto& io = ImGui::GetIO();
const NSEventModifierFlags flags = [event modifierFlags];

static NSEventModifierFlags previousFlags = 0;
NSEventModifierFlags changedFlags = flags ^ previousFlags;

if (changedFlags & NSEventModifierFlagControl) {
bool isPressed = flags & NSEventModifierFlagControl;
io.AddKeyEvent(ImGuiKey_ModCtrl, isPressed);
}
if (changedFlags & NSEventModifierFlagOption) {
bool isPressed = flags & NSEventModifierFlagOption;
io.AddKeyEvent(ImGuiKey_ModAlt, isPressed);
}
if (changedFlags & NSEventModifierFlagCommand) {
bool isPressed = flags & NSEventModifierFlagCommand;
io.AddKeyEvent(ImGuiKey_ModSuper, isPressed);
}
if (changedFlags & NSEventModifierFlagShift) {
bool isPressed = flags & NSEventModifierFlagShift;
io.AddKeyEvent(ImGuiKey_ModShift, isPressed);
}

previousFlags = flags;
}

$on_mod(Loaded)
{
OBJC_SWIZZLE(EAGLView, key_event_t, flagsChangedExec, flagsChanged:);
}

#endif
#endif
34 changes: 1 addition & 33 deletions src/platform/Win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,6 @@
using namespace cocos2d;
using namespace geode;

ImGuiKey keyFromGLFW(int key) {
if (key >= GLFW_KEY_0 && key <= GLFW_KEY_9) {
return static_cast<ImGuiKey>(ImGuiKey_0 + (key - GLFW_KEY_0));
} else if (key >= GLFW_KEY_A && key <= GLFW_KEY_Z) {
return static_cast<ImGuiKey>(ImGuiKey_A + (key - GLFW_KEY_A));
}
switch (key) {
case GLFW_KEY_SPACE: return ImGuiKey_Space;
case GLFW_KEY_BACKSPACE: return ImGuiKey_Backspace;
case GLFW_KEY_COMMA: return ImGuiKey_Comma;
case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow;
case GLFW_KEY_RIGHT: return ImGuiKey_RightArrow;
case GLFW_KEY_UP: return ImGuiKey_UpArrow;
case GLFW_KEY_DOWN: return ImGuiKey_DownArrow;
case GLFW_KEY_ESCAPE: return ImGuiKey_Escape;
case GLFW_KEY_LEFT_SHIFT: return ImGuiKey_LeftShift;
case GLFW_KEY_RIGHT_SHIFT: return ImGuiKey_RightShift;
case GLFW_KEY_LEFT_CONTROL: return ImGuiKey_LeftCtrl;
case GLFW_KEY_LEFT_ALT: return ImGuiKey_LeftAlt;
// TODO: rest :-)
}
return ImGuiKey_None;
}

class $modify(CCEGLView) {
void updateWindow(int width, int height) {
shouldUpdateGDRenderBuffer() = true;
Expand All @@ -46,15 +22,7 @@ class $modify(CCEGLView) {
DevTools::get()->destroy();
CCEGLView::toggleFullScreen(value, borderless, fix);
DevTools::get()->setup();
}

//todo: i dont care someone else can figure it out, it completely breaks keyboard support
/*void onGLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
//auto& io = ImGui::GetIO();
CCEGLView::onGLFWKeyCallback(window, key, scancode, action, mods);
// in practice this is only used for arrow keys
//io.AddKeyEvent(keyFromGLFW(key), action != GLFW_RELEASE);
}*/
}
};

#include "utils.hpp"
Expand Down