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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_BASE_COCOA_COMMAND_DISPATCHER_H_
#define UI_BASE_COCOA_COMMAND_DISPATCHER_H_
#import <Cocoa/Cocoa.h>
#include "base/component_export.h"
@protocol CommandDispatcherDelegate;
@protocol CommandDispatchingWindow;
@protocol UserInterfaceItemCommandHandler;
// CommandDispatcher guides the processing of key events to ensure key commands
// are executed in the appropriate order. In particular, it allows a first
// responder to handle an event asynchronously and return unhandled events
// via -redispatchKeyEvent:. An NSWindow can use CommandDispatcher by
// implementing CommandDispatchingWindow and overriding
// -[NSWindow performKeyEquivalent:] and -[NSWindow sendEvent:] to call the
// respective CommandDispatcher methods.
COMPONENT_EXPORT(UI_BASE)
@interface CommandDispatcher : NSObject
@property(weak) id<CommandDispatcherDelegate> delegate;
- (instancetype)initWithOwner:(NSWindow<CommandDispatchingWindow>*)owner;
// The main entry point for key events. The CommandDispatchingWindow should
// override -[NSResponder performKeyEquivalent:] and call this instead. Returns
// YES if the event is handled.
- (BOOL)performKeyEquivalent:(NSEvent*)event;
// Validate a user interface item (e.g. an NSMenuItem), consulting |handler| for
// -commandDispatch: item actions.
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item
forHandler:(id<UserInterfaceItemCommandHandler>)handler;
// Sends a key event to -[NSApp sendEvent:]. This is used to allow default
// AppKit handling of an event that comes back from CommandDispatcherTarget,
// e.g. key equivalents in the menu, or window manager commands like Cmd+`. Once
// the event returns to the window at -preSendEvent:, handling will stop. The
// event must be of type |NSEventTypeKeyDown|, |NSEventTypeKeyUp|, or
// |NSEventTypeFlagsChanged|. Returns YES if the event is handled.
- (BOOL)redispatchKeyEvent:(NSEvent*)event;
// The CommandDispatchingWindow should override -[NSWindow sendEvent:] and call
// this before a native -sendEvent:. Ensures that a redispatched event is not
// reposted infinitely. Returns YES if the event is handled.
- (BOOL)preSendEvent:(NSEvent*)event;
// Dispatch a -commandDispatch: action either to |handler| or a parent window's
// handler.
- (void)dispatch:(id)sender
forHandler:(id<UserInterfaceItemCommandHandler>)handler;
- (void)dispatchUsingKeyModifiers:(id)sender
forHandler:(id<UserInterfaceItemCommandHandler>)handler;
@end
// If the NSWindow's firstResponder implements CommandDispatcherTarget, then
// it is allowed to grant itself exclusive access to certain keyEquivalents,
// preempting the usual consumer order.
@protocol CommandDispatcherTarget
// The System Keyboard Lock API <https://w3c.github.io/keyboard-lock/>
// allows web contents to override keyEquivalents normally reserved by the
// browser. If the firstResponder returns |YES| from this method, then
// keyEquivalents shortcuts should be skipped.
- (BOOL)isKeyLocked:(NSEvent*)event;
@end
namespace ui {
enum class PerformKeyEquivalentResult {
// The CommandDispatcherDelegate did not handle the key equivalent.
kUnhandled,
// The CommandDispatcherDelegate handled the key equivalent.
kHandled,
// The CommandDispatcherDelegate did not handle the key equivalent, but wants
// the event to be passed to the MainMenu, which will handle the key
// equivalent.
kPassToMainMenu,
// The CommandDispatcherDelegate determined the event should not be handled.
// This can occur when an event has been sent via key repeat that we've
// determined should not be triggered via repeat.
kDrop,
};
} // namespace ui
// Provides CommandDispatcher with the means to redirect key equivalents at
// different stages of event handling.
@protocol CommandDispatcherDelegate
// Gives the delegate a chance to process the keyEquivalent before the first
// responder. See https://crbug.com/846893#c5 for more details on
// keyEquivalent consumer ordering. |window| is the CommandDispatchingWindow
// that owns CommandDispatcher, not the window of the event.
- (ui::PerformKeyEquivalentResult)prePerformKeyEquivalent:(NSEvent*)event
window:(NSWindow*)window;
// Gives the delegate a chance to process the keyEquivalent after the first
// responder has declined to process the event. See https://crbug.com/846893#c5
// for more details on keyEquivalent consumer ordering.
// |window| is the CommandDispatchingWindow that owns CommandDispatcher, not the
// window of the event.
- (ui::PerformKeyEquivalentResult)postPerformKeyEquivalent:(NSEvent*)event
window:(NSWindow*)window
isRedispatch:(BOOL)isRedispatch;
@end
// The set of methods an NSWindow subclass needs to implement to use
// CommandDispatcher.
@protocol CommandDispatchingWindow
// Parent window to defer command dispatching to.
- (NSWindow<CommandDispatchingWindow>*)commandDispatchParent;
// If set, NSUserInterfaceItemValidations for -commandDispatch: and
// -commandDispatchUsingKeyModifiers: will be redirected to the command handler.
// Retains |commandHandler|.
-(void)setCommandHandler:(id<UserInterfaceItemCommandHandler>) commandHandler;
// Returns the associated CommandDispatcher.
- (CommandDispatcher*)commandDispatcher;
// Short-circuit to the default -[NSResponder performKeyEquivalent:] which
// CommandDispatcher calls as part of its -performKeyEquivalent: flow.
- (BOOL)defaultPerformKeyEquivalent:(NSEvent*)event;
// Short-circuit to the default -validateUserInterfaceItem: implementation.
- (BOOL)defaultValidateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item;
// AppKit will call -[NSUserInterfaceValidations validateUserInterfaceItem:] to
// validate UI items. Any item whose target is FirstResponder, or nil, will
// traverse the responder chain looking for a responder that implements the
// item's selector. Thus NSWindow is usually the last to be checked and will
// handle any items that are not validated elsewhere in the chain. Implement the
// following so that menu items with these selectors are validated by
// CommandDispatchingWindow.
- (void)commandDispatch:(id)sender;
- (void)commandDispatchUsingKeyModifiers:(id)sender;
@end
#endif // UI_BASE_COCOA_COMMAND_DISPATCHER_H_
|