mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-27 15:29:34 +00:00
Rationalises protocol for application-level event theft.
This commit is contained in:
parent
298694a881
commit
7112f0336c
@ -11,20 +11,22 @@
|
|||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
@protocol CSApplicationKeyboardEventDelegate
|
@class CSApplication;
|
||||||
- (void)sendEvent:(nonnull NSEvent *)event;
|
|
||||||
|
@protocol CSApplicationEventDelegate
|
||||||
|
- (BOOL)application:(nonnull CSApplication *)application shouldSendEvent:(nonnull NSEvent *)event;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
CSApplication differs from NSApplication in only one regard: it supports a keyboardEventDelegate.
|
CSApplication differs from NSApplication in only one regard: it supports an eventDelegate.
|
||||||
|
|
||||||
If a keyboardEventDelegate is installed, all keyboard events — @c NSEventTypeKeyUp,
|
If conected, an eventDelegate will be offered all application events prior to their propagation
|
||||||
@c NSEventTypeKeyDown and @c NSEventTypeFlagsChanged — will be diverted to it
|
into the application proper. It may opt to remove those events from the queue. This primarily
|
||||||
rather than passed through the usual processing. As a result keyboard shortcuts and assistive
|
provides a way to divert things like the command key that will otherwise trigger menu
|
||||||
dialogue navigations won't work.
|
shortcuts, for periods when it is appropriate to do so.
|
||||||
*/
|
*/
|
||||||
@interface CSApplication: NSApplication
|
@interface CSApplication: NSApplication
|
||||||
@property(nonatomic, weak, nullable) id<CSApplicationKeyboardEventDelegate> keyboardEventDelegate;
|
@property(nonatomic, weak, nullable) id<CSApplicationEventDelegate> eventDelegate;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,27 +11,10 @@
|
|||||||
@implementation CSApplication
|
@implementation CSApplication
|
||||||
|
|
||||||
- (void)sendEvent:(NSEvent *)event {
|
- (void)sendEvent:(NSEvent *)event {
|
||||||
// The only reason to capture events here rather than at the window or view
|
// Send the event unless an event delegate says otherwise.
|
||||||
// is to divert key combinations such as command+w or command+q in the few
|
if(!self.eventDelegate || [self.eventDelegate application:self shouldSendEvent:event]) {
|
||||||
// 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];
|
[super sendEvent:event];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
@import CoreVideo;
|
@import CoreVideo;
|
||||||
@import GLKit;
|
@import GLKit;
|
||||||
|
|
||||||
@interface CSOpenGLView () <NSDraggingDestination, CSApplicationKeyboardEventDelegate>
|
@interface CSOpenGLView () <NSDraggingDestination, CSApplicationEventDelegate>
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation CSOpenGLView {
|
@implementation CSOpenGLView {
|
||||||
@ -140,17 +140,15 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)propagateKeyboardEvent:(NSEvent *)event {
|
- (void)keyDown:(NSEvent *)event {
|
||||||
switch(event.type) {
|
|
||||||
default: break;
|
|
||||||
|
|
||||||
case kCGEventKeyDown:
|
|
||||||
[self.responderDelegate keyDown:event];
|
[self.responderDelegate keyDown:event];
|
||||||
break;
|
}
|
||||||
case kCGEventKeyUp:
|
|
||||||
|
- (void)keyUp:(NSEvent *)event {
|
||||||
[self.responderDelegate keyUp:event];
|
[self.responderDelegate keyUp:event];
|
||||||
break;
|
}
|
||||||
case kCGEventFlagsChanged:
|
|
||||||
|
- (void)flagsChanged:(NSEvent *)event {
|
||||||
// Release the mouse upon a control + command.
|
// Release the mouse upon a control + command.
|
||||||
if(_mouseIsCaptured &&
|
if(_mouseIsCaptured &&
|
||||||
event.modifierFlags & NSEventModifierFlagControl &&
|
event.modifierFlags & NSEventModifierFlagControl &&
|
||||||
@ -159,24 +157,15 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
[self.responderDelegate flagsChanged:event];
|
[self.responderDelegate flagsChanged:event];
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyDown:(NSEvent *)theEvent {
|
- (BOOL)application:(nonnull CSApplication *)application shouldSendEvent:(nonnull NSEvent *)event {
|
||||||
[self propagateKeyboardEvent:theEvent];
|
switch(event.type) {
|
||||||
|
default: return YES;
|
||||||
|
case NSEventTypeKeyUp: [self keyUp:event]; return NO;
|
||||||
|
case NSEventTypeKeyDown: [self keyDown:event]; return NO;
|
||||||
|
case NSEventTypeFlagsChanged: [self flagsChanged:event]; return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyUp:(NSEvent *)theEvent {
|
|
||||||
[self propagateKeyboardEvent:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)flagsChanged:(NSEvent *)theEvent {
|
|
||||||
[self propagateKeyboardEvent:theEvent];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendEvent:(NSEvent *)event {
|
|
||||||
[self propagateKeyboardEvent:event];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)paste:(id)sender {
|
- (void)paste:(id)sender {
|
||||||
@ -245,7 +234,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||||||
CGAssociateMouseAndMouseCursorPosition(true);
|
CGAssociateMouseAndMouseCursorPosition(true);
|
||||||
[NSCursor unhide];
|
[NSCursor unhide];
|
||||||
[self.delegate openGLViewDidReleaseMouse:self];
|
[self.delegate openGLViewDidReleaseMouse:self];
|
||||||
((CSApplication *)[NSApplication sharedApplication]).keyboardEventDelegate = nil;
|
((CSApplication *)[NSApplication sharedApplication]).eventDelegate = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +295,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||||||
CGAssociateMouseAndMouseCursorPosition(false);
|
CGAssociateMouseAndMouseCursorPosition(false);
|
||||||
[self.delegate openGLViewDidCaptureMouse:self];
|
[self.delegate openGLViewDidCaptureMouse:self];
|
||||||
if(self.shouldUsurpCommand) {
|
if(self.shouldUsurpCommand) {
|
||||||
((CSApplication *)[NSApplication sharedApplication]).keyboardEventDelegate = self;
|
((CSApplication *)[NSApplication sharedApplication]).eventDelegate = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't report the first click to the delegate; treat that as merely
|
// Don't report the first click to the delegate; treat that as merely
|
||||||
|
Loading…
x
Reference in New Issue
Block a user