From f28c124039c771484b177e077d17b7693a71884d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 22 Sep 2019 13:15:01 -0400 Subject: [PATCH] Adds a route to divert key events before they reach Cocoa. If you were to use this, it would have the effect of disabling in-app keyboard short-cuts in favour of routing keys to the emulated machine. --- .../Clock Signal.xcodeproj/project.pbxproj | 10 ++++- .../xcschemes/Clock Signal.xcscheme | 4 +- OSBindings/Mac/Clock Signal/CSApplication.h | 31 ++++++++++++++++ OSBindings/Mac/Clock Signal/CSApplication.m | 37 +++++++++++++++++++ OSBindings/Mac/Clock Signal/Info.plist | 2 +- 5 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 OSBindings/Mac/Clock Signal/CSApplication.h create mode 100644 OSBindings/Mac/Clock Signal/CSApplication.m diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index a6a87d9b0..443cd4882 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -656,6 +656,7 @@ 4BCE005D227D30CC000CA200 /* MemoryPacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCE005B227D30CC000CA200 /* MemoryPacker.cpp */; }; 4BCE0060227D39AB000CA200 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCE005E227D39AB000CA200 /* Video.cpp */; }; 4BCF1FA41DADC3DD0039D2E7 /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */; }; + 4BD0FBC3233706A200148981 /* CSApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD0FBC2233706A200148981 /* CSApplication.m */; }; 4BD191F42191180E0042E144 /* ScanTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191F22191180E0042E144 /* ScanTarget.cpp */; }; 4BD191F52191180E0042E144 /* ScanTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191F22191180E0042E144 /* ScanTarget.cpp */; }; 4BD388882239E198002D14B5 /* 68000Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BD388872239E198002D14B5 /* 68000Tests.mm */; }; @@ -1095,6 +1096,7 @@ 4B90467222C6FA31000E2074 /* TestRunner68000.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TestRunner68000.hpp; sourceTree = ""; }; 4B90467322C6FADD000E2074 /* 68000BitwiseTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000BitwiseTests.mm; sourceTree = ""; }; 4B90467522C6FD6E000E2074 /* 68000ArithmeticTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000ArithmeticTests.mm; sourceTree = ""; }; + 4B911A9B2337D8AB00A2BB1D /* CSApplication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSApplication.h; sourceTree = ""; }; 4B92294222B04A3D00A1458F /* MouseMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MouseMachine.hpp; sourceTree = ""; }; 4B92294422B04ACB00A1458F /* Mouse.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Mouse.hpp; sourceTree = ""; }; 4B92294A22B064FD00A1458F /* QuadratureMouse.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = QuadratureMouse.hpp; sourceTree = ""; }; @@ -1478,6 +1480,7 @@ 4BCF1FA31DADC3DD0039D2E7 /* Oric.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Oric.hpp; path = Oric/Oric.hpp; sourceTree = ""; }; 4BD060A51FE49D3C006E14BE /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Speaker.hpp; sourceTree = ""; }; 4BD0692B22828A2D00D2A54F /* RealTimeClock.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = RealTimeClock.hpp; sourceTree = ""; }; + 4BD0FBC2233706A200148981 /* CSApplication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSApplication.m; sourceTree = ""; }; 4BD191D9219113B80042E144 /* OpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpenGL.hpp; sourceTree = ""; }; 4BD191F22191180E0042E144 /* ScanTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScanTarget.cpp; sourceTree = ""; }; 4BD191F32191180E0042E144 /* ScanTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanTarget.hpp; sourceTree = ""; }; @@ -3005,22 +3008,24 @@ 4BB73EA01B587A5100552FC2 /* Clock Signal */ = { isa = PBXGroup; children = ( - 4BBFE83B21015D9C00BF1C40 /* Joystick Manager */, 4BB73ECF1B587A6700552FC2 /* Clock Signal.entitlements */, 4B1414501B58848C00E04248 /* ClockSignal-Bridging-Header.h */, + 4B911A9B2337D8AB00A2BB1D /* CSApplication.h */, + 4BD0FBC2233706A200148981 /* CSApplication.m */, 4BB73EAD1B587A5100552FC2 /* Info.plist */, 4BB73EA11B587A5100552FC2 /* AppDelegate.swift */, 4BB73EA81B587A5100552FC2 /* Assets.xcassets */, 4B2A538F1D117D36003C6002 /* Audio */, 4B643F3D1D77B88000D431D6 /* Document Controller */, 4B55CE551C3B7D360093A61B /* Documents */, + 4BBFE83B21015D9C00BF1C40 /* Joystick Manager */, 4B2A53921D117D36003C6002 /* Machine */, 4B55DD7F20DF06680043F2E5 /* MachinePicker */, 4BB73EAA1B587A5100552FC2 /* MainMenu.xib */, 4BE5F85A1C3E1C2500C43F01 /* Resources */, + 4BDA00DB22E60EE900AC3CD0 /* ROMRequester */, 4BD5F1961D1352A000631CD1 /* Updater */, 4B55CE5A1C3B7D6F0093A61B /* Views */, - 4BDA00DB22E60EE900AC3CD0 /* ROMRequester */, ); path = "Clock Signal"; sourceTree = ""; @@ -4273,6 +4278,7 @@ 4BB697CB1D4B6D3E00248BDF /* TimedEventLoop.cpp in Sources */, 4BDACBEC22FFA5D20045EF7E /* ncr5380.cpp in Sources */, 4B54C0C21F8D91CD0050900F /* Keyboard.cpp in Sources */, + 4BD0FBC3233706A200148981 /* CSApplication.m in Sources */, 4BBC951E1F368D83008F4C34 /* i8272.cpp in Sources */, 4B89449520194CB3007DE474 /* MachineForTarget.cpp in Sources */, 4B4A76301DB1A3FA007AAE2E /* AY38910.cpp in Sources */, diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme index bc8aa321e..47f9c7286 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme @@ -67,7 +67,7 @@ diff --git a/OSBindings/Mac/Clock Signal/CSApplication.h b/OSBindings/Mac/Clock Signal/CSApplication.h new file mode 100644 index 000000000..76a81a56a --- /dev/null +++ b/OSBindings/Mac/Clock Signal/CSApplication.h @@ -0,0 +1,31 @@ +// +// CSApplication.h +// Clock Signal +// +// Created by Thomas Harte on 22/09/2019. +// Copyright © 2019 Thomas Harte. All rights reserved. +// + +#ifndef CSApplication_h +#define CSApplication_h + +#import + +@protocol CSApplicationKeyboardEventDelegate +- (void)sendEvent:(nonnull NSEvent *)event; +@end + +/*! + CSApplication differs from NSApplication in only one regard: it supports a keyboardEventDelegate. + + If a keyboardEventDelegate is installed, all keyboard events — @c NSEventTypeKeyUp, + @c NSEventTypeKeyDown and @c NSEventTypeFlagsChanged — will be diverted to it + rather than passed through the usual processing. As a result keyboard shortcuts and assistive + dialogue navigations won't work. +*/ +@interface CSApplication: NSApplication +@property(nonatomic, weak, nullable) id keyboardEventDelegate; +@end + + +#endif /* CSApplication_h */ diff --git a/OSBindings/Mac/Clock Signal/CSApplication.m b/OSBindings/Mac/Clock Signal/CSApplication.m new file mode 100644 index 000000000..7769255c1 --- /dev/null +++ b/OSBindings/Mac/Clock Signal/CSApplication.m @@ -0,0 +1,37 @@ +// +// Application.m +// Clock Signal +// +// Created by Thomas Harte on 21/09/2019. +// Copyright © 2019 Thomas Harte. All rights reserved. +// + +#import "CSApplication.h" + +@implementation CSApplication + +- (void)sendEvent:(NSEvent *)event { + // The only reason to capture events here rather than at the window or view + // is to divert key combinations such as command+w or command+q in the few + // occasions when the user would expect those to affect a running machine + // rather than to affect application state. + // + // Most obviously: when emulating a Macintosh, you'd expect command+q to + // quit the application inside the Macintosh, not to quit the emulator. + + switch(event.type) { + case NSEventTypeKeyUp: + case NSEventTypeKeyDown: + case NSEventTypeFlagsChanged: + if(self.keyboardEventDelegate) { + [self.keyboardEventDelegate sendEvent:event]; + return; + } + + default: + [super sendEvent:event]; + } + +} + +@end diff --git a/OSBindings/Mac/Clock Signal/Info.plist b/OSBindings/Mac/Clock Signal/Info.plist index 12abc7f35..d318aa73b 100644 --- a/OSBindings/Mac/Clock Signal/Info.plist +++ b/OSBindings/Mac/Clock Signal/Info.plist @@ -554,6 +554,6 @@ NSMainNibFile MainMenu NSPrincipalClass - NSApplication + CSApplication