Skip to content

Commit 8e47606

Browse files
authored
feat(mac): Hook EAGLView methods instead of CCTouchDispatcher for mouse events (#14)
* use keyDownExec and keyUpExec to override mouse positioning on mac * fix a skill issue * maybe dont do anything idk * fix Y value * format * final format * i cant type * ok * omg im stupid
1 parent 9804607 commit 8e47606

File tree

3 files changed

+47
-39
lines changed

3 files changed

+47
-39
lines changed

mod.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"win": "2.2074",
55
"mac": "2.2074"
66
},
7-
"version": "v4.2.0-beta.10",
7+
"version": "v4.2.0-beta.11",
88
"id": "spaghettdev.betterinputs",
99
"name": "BetterInputs",
1010
"developer": "SpaghettDev",

src/macos.mm

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,19 @@ inline bool keyDown(PlatformKey key, NSEvent* event)
3232
}
3333

3434
#define HOOK_OBJC_METHOD(klass, type, cleanFuncName, funcName) \
35-
auto cleanFuncName ## Method = class_getInstanceMethod(klass, @selector(funcName)); \
36-
cleanFuncName ## OIMP = reinterpret_cast<type>(method_getImplementation(cleanFuncName ## Method)); \
37-
method_setImplementation(cleanFuncName ## Method, reinterpret_cast<IMP>(&cleanFuncName));
35+
do { \
36+
auto cleanFuncName ## Method = class_getInstanceMethod(klass, @selector(funcName)); \
37+
cleanFuncName ## OIMP = reinterpret_cast<type>(method_getImplementation(cleanFuncName ## Method)); \
38+
method_setImplementation(cleanFuncName ## Method, reinterpret_cast<IMP>(&cleanFuncName)); \
39+
geode::log::debug("Hooked Objective C Method '{}'", #funcName); \
40+
} while(0)
3841

39-
using KeyEventType = void(*)(EAGLView*, SEL, NSEvent*);
42+
using key_event_t = void(*)(EAGLView*, SEL, NSEvent*);
4043

4144

42-
static KeyEventType keyDownExecOIMP;
43-
void keyDownExec(EAGLView* self, SEL sel, NSEvent* event) {
45+
static key_event_t keyDownExecOIMP;
46+
void keyDownExec(EAGLView* self, SEL sel, NSEvent* event)
47+
{
4448
if (!g_selectedInput)
4549
return keyDownExecOIMP(self, sel, event);
4650

@@ -149,50 +153,54 @@ void keyDownExec(EAGLView* self, SEL sel, NSEvent* event) {
149153
keyDownExecOIMP(self, sel, event);
150154
}
151155

152-
static KeyEventType keyUpExecOIMP;
153-
void keyUpExec(EAGLView* self, SEL sel, NSEvent* event) {
154-
if (!g_selectedInput)
155-
return keyUpExecOIMP(self, sel, event);
156+
static key_event_t keyUpExecOIMP;
157+
void keyUpExec(EAGLView* self, SEL sel, NSEvent* event)
158+
{
159+
if (g_selectedInput)
160+
return;
161+
162+
keyUpExecOIMP(self, sel, event);
156163
}
157164

158165

159-
// TODO: move to hooking mouseDownExec/mouseUpExec
160-
// handles mouse clicks
161-
struct BetterTouchDispatcher : geode::Modify<BetterTouchDispatcher, cocos2d::CCTouchDispatcher>
166+
static key_event_t mouseDownExecOIMP;
167+
void mouseDownExec(EAGLView* self, SEL sel, NSEvent* event)
162168
{
163-
// https://github.com/ninXout/Crystal-Client/blob/7df5a8336ccb852bc984e55dd29ca27bb1741443/src/ImGui/ImGui.cpp#L96
164-
void touches(cocos2d::CCSet* touches, cocos2d::CCEvent* event, unsigned int type)
165-
{
166-
if (!g_selectedInput)
167-
return cocos2d::CCTouchDispatcher::touches(touches, event, type);
169+
if (!g_selectedInput)
170+
return mouseDownExecOIMP(self, sel, event);
168171

169-
auto* touch = static_cast<cocos2d::CCTouch*>(touches->anyObject());
170-
const auto touchPos = touch->getLocation();
172+
cocos2d::CCSize winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
173+
cocos2d::CCPoint mousePos = BI::cocos::getMousePosition();
171174

172-
if (type == TouchMessageType::Began)
173-
{
174-
cocos2d::CCSize winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
175+
// NSWindow's mouse origin is the bottom left
176+
// CCTouch's mouse origin is top left (because of course it is)
177+
cocos2d::CCTouch touch{};
178+
touch.setTouchInfo(0, mousePos.x, winSize.height - mousePos.y);
175179

176-
// the touch event's origin is bottom left
177-
cocos2d::CCTouch touch{};
178-
touch.setTouchInfo(0, touchPos.x, winSize.height - touchPos.y);
180+
g_selectedInput->useUpdateBlinkPos(true);
179181

180-
g_selectedInput->useUpdateBlinkPos(true);
182+
// 🥰
183+
g_selectedInput->ccTouchBegan(&touch, nullptr);
184+
}
181185

182-
// 🥰
183-
g_selectedInput->ccTouchBegan(&touch, nullptr);
184-
}
185-
else
186-
g_selectedInput->useUpdateBlinkPos(false);
187-
}
188-
};
186+
static key_event_t mouseUpExecOIMP;
187+
void mouseUpExec(EAGLView* self, SEL sel, NSEvent* event)
188+
{
189+
if (!g_selectedInput)
190+
return mouseUpExecOIMP(self, sel, event);
191+
192+
g_selectedInput->useUpdateBlinkPos(false);
193+
}
189194

190195

191196
// https://github.com/qimiko/click-on-steps/blob/d8a87e93b5407e5f2113a9715363a5255724c901/src/macos.mm#L101
192197
$on_mod(Loaded)
193198
{
194199
auto eaglView = objc_getClass("EAGLView");
195200

196-
HOOK_OBJC_METHOD(eaglView, KeyEventType, keyDownExec, keyDownExec:);
197-
HOOK_OBJC_METHOD(eaglView, KeyEventType, keyUpExec, keyUpExec:);
201+
HOOK_OBJC_METHOD(eaglView, key_event_t, keyDownExec, keyDownExec:);
202+
HOOK_OBJC_METHOD(eaglView, key_event_t, keyUpExec, keyUpExec:);
203+
204+
HOOK_OBJC_METHOD(eaglView, key_event_t, mouseDownExec, mouseDownExec:);
205+
HOOK_OBJC_METHOD(eaglView, key_event_t, mouseUpExec, mouseUpExec:);
198206
}

src/windows.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@ struct BetterCCEGLView : Modify<BetterCCEGLView, CCEGLView>
155155
{
156156
CCEGLView::onGLFWMouseCallBack(window, button, action, mods);
157157

158-
if (!g_selectedInput || button != GLFW_MOUSE_BUTTON_1 || action == 2) return;
158+
if (!g_selectedInput || button != GLFW_MOUSE_BUTTON_1 || action == GLFW_REPEAT) return;
159159

160-
if (action == 1)
160+
if (action == GLFW_PRESS)
161161
{
162162
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
163163
CCPoint mousePos = BI::cocos::getMousePosition();

0 commit comments

Comments
 (0)