| 1 | //go:build darwin |
| 2 | |
| 3 | #import <Cocoa/Cocoa.h> |
| 4 | #import <objc/runtime.h> |
| 5 | |
| 6 | extern void ReasonixMarkSystemQuit(void); |
| 7 | |
| 8 | static NSApplicationTerminateReply (*originalApplicationShouldTerminate)(id, SEL, NSApplication *); |
| 9 | static void (*originalWailsContextQuit)(id, SEL); |
| 10 | |
| 11 | static NSApplicationTerminateReply reasonixApplicationShouldTerminate(id self, SEL _cmd, NSApplication *sender) { |
| 12 | ReasonixMarkSystemQuit(); |
| 13 | if (originalApplicationShouldTerminate != NULL) { |
| 14 | return originalApplicationShouldTerminate(self, _cmd, sender); |
| 15 | } |
| 16 | return NSTerminateNow; |
| 17 | } |
| 18 | |
| 19 | static void reasonixWailsContextQuit(id self, SEL _cmd) { |
| 20 | ReasonixMarkSystemQuit(); |
| 21 | if (originalWailsContextQuit != NULL) { |
| 22 | originalWailsContextQuit(self, _cmd); |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | void installReasonixSystemQuitHook(void) { |
| 27 | Class appDelegate = NSClassFromString(@"AppDelegate"); |
| 28 | SEL selector = @selector(applicationShouldTerminate:); |
| 29 | Method method = appDelegate == Nil ? NULL : class_getInstanceMethod(appDelegate, selector); |
| 30 | if (method != NULL) { |
| 31 | IMP replacement = (IMP)reasonixApplicationShouldTerminate; |
| 32 | IMP previous = method_setImplementation(method, replacement); |
| 33 | originalApplicationShouldTerminate = (NSApplicationTerminateReply (*)(id, SEL, NSApplication *))previous; |
| 34 | } |
| 35 | |
| 36 | Class wailsContext = NSClassFromString(@"WailsContext"); |
| 37 | SEL quitSelector = @selector(Quit); |
| 38 | Method quitMethod = wailsContext == Nil ? NULL : class_getInstanceMethod(wailsContext, quitSelector); |
| 39 | if (quitMethod != NULL) { |
| 40 | IMP replacement = (IMP)reasonixWailsContextQuit; |
| 41 | IMP previous = method_setImplementation(quitMethod, replacement); |
| 42 | originalWailsContextQuit = (void (*)(id, SEL))previous; |
| 43 | } |
| 44 | } |
| 45 |