forked from gerhardberger/electron-drag-click
-
Notifications
You must be signed in to change notification settings - Fork 0
/
electron_drag_click.mm
78 lines (59 loc) · 2.3 KB
/
electron_drag_click.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#import <Cocoa/Cocoa.h>
#include <Foundation/Foundation.h>
#import <objc/runtime.h>
#include <napi.h>
static IMP g_originalHitTest;
static IMP g_originalMouseEvent;
static char kAssociatedObjectKey;
NSView* viewUnderneathPoint(NSView* self, NSPoint point) {
NSView *contentView = self.window.contentView;
NSArray *views = [contentView subviews];
for (NSView *v in views) {
if (v != self && ![v isKindOfClass:[NSVisualEffectView class]]) {
NSPoint pointInView = [v convertPoint:point fromView:nil];
if ([v hitTest:pointInView] && [v mouse:pointInView inRect:v.bounds]) {
return v;
}
}
}
return nil;
}
NSView* swizzledHitTest(id obj, SEL sel, NSPoint point) {
NSView* originalReturn =
((NSView*(*) (id, SEL, NSPoint))g_originalHitTest)(obj, sel, point);
NSNumber* isDraggable = @(originalReturn == nil);
objc_setAssociatedObject(obj,
&kAssociatedObjectKey,
isDraggable,
OBJC_ASSOCIATION_COPY_NONATOMIC);
NSView* viewUnderPoint = viewUnderneathPoint(obj, point);
return [viewUnderPoint hitTest:point];
}
void swizzledMouseEvent(id obj, SEL sel, NSEvent* theEvent) {
((void(*) (id, SEL, NSEvent*))g_originalMouseEvent)(obj, sel, theEvent);
NSView* view = obj;
NSNumber* isDragging = objc_getAssociatedObject(view.window.contentView,
&kAssociatedObjectKey);
if ([theEvent type] == NSEventTypeLeftMouseDown && isDragging.boolValue) {
NSView* self = obj;
[self.window performWindowDragWithEvent:theEvent];
}
}
void Setup(const Napi::CallbackInfo &info) {
auto hitTestMethod = class_getInstanceMethod(
NSClassFromString(@"BridgedContentView"),
NSSelectorFromString(@"hitTest:"));
g_originalHitTest = method_setImplementation(hitTestMethod,
(IMP)&swizzledHitTest);
auto mouseEventMethod = class_getInstanceMethod(
NSClassFromString(@"RenderWidgetHostViewCocoa"),
NSSelectorFromString(@"mouseEvent:"));
g_originalMouseEvent = method_setImplementation(mouseEventMethod,
(IMP)&swizzledMouseEvent);
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "setup"),
Napi::Function::New(env, Setup));
return exports;
}
NODE_API_MODULE(electron_drag_click, Init)