Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Unified Diff: ui/base/cocoa/command_dispatcher.mm

Issue 2666523002: Allow permission bubbles to participate in key event dispatch as if they were a Browser. (Closed)
Patch Set: Parameterize test, Comments, nits Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/base/cocoa/command_dispatcher.mm
diff --git a/ui/base/cocoa/command_dispatcher.mm b/ui/base/cocoa/command_dispatcher.mm
index 46a351b4ce8c09b399011bf36313ac34db9fb6ec..e6660c3871ad94a7b9a0f997195fa3b4d2b4bacb 100644
--- a/ui/base/cocoa/command_dispatcher.mm
+++ b/ui/base/cocoa/command_dispatcher.mm
@@ -6,6 +6,19 @@
#include "base/logging.h"
#include "ui/base/cocoa/cocoa_base_utils.h"
+#import "ui/base/cocoa/user_interface_item_command_handler.h"
+
+// Expose -[NSWindow hasKeyAppearance], which determines whether the traffic
+// lights on the window are "lit". CommandDispatcher uses this property on a
+// parent window to decide whether keys and commands should bubble up.
+@interface NSWindow (PrivateAPI)
+- (BOOL)hasKeyAppearance;
+@end
+
+@interface CommandDispatcher ()
+// The parent to bubble events to, or nil.
+- (NSWindow<CommandDispatchingWindow>*)bubbleParent;
+@end
namespace {
@@ -73,10 +86,13 @@ NSEvent* KeyEventForWindow(NSWindow* window, NSEvent* event) {
// Give a CommandDispatcherTarget (e.g. a web site) a chance to handle the
// event. If it doesn't want to handle it, it will call us back with
- // -redispatchKeyEvent:.
- NSResponder* r = [owner_ firstResponder];
- if ([r conformsToProtocol:@protocol(CommandDispatcherTarget)])
- return [r performKeyEquivalent:event];
+ // -redispatchKeyEvent:. Only allow this behavior when dispatching key events
+ // on the key window.
+ if ([owner_ isKeyWindow]) {
+ NSResponder* r = [owner_ firstResponder];
+ if ([r conformsToProtocol:@protocol(CommandDispatcherTarget)])
+ return [r performKeyEquivalent:event];
+ }
if ([delegate_ prePerformKeyEquivalent:event window:owner_])
return YES;
@@ -84,7 +100,35 @@ NSEvent* KeyEventForWindow(NSWindow* window, NSEvent* event) {
if ([owner_ defaultPerformKeyEquivalent:event])
return YES;
- return [delegate_ postPerformKeyEquivalent:event window:owner_];
+ if ([delegate_ postPerformKeyEquivalent:event window:owner_])
+ return YES;
+
+ // Allow commands to "bubble up" to CommandDispatchers in parent windows, if
+ // they were not handled here.
+ return [[self bubbleParent] performKeyEquivalent:event];
+}
+
+- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item
+ forHandler:(id<UserInterfaceItemCommandHandler>)handler {
+ // Since this class implements these selectors, |super| will always say they
+ // are enabled. Only use [super] to validate other selectors. If there is no
+ // command handler, defer to AppController.
+ if ([item action] == @selector(commandDispatch:) ||
+ [item action] == @selector(commandDispatchUsingKeyModifiers:)) {
+ if (handler)
Robert Sesek 2017/02/01 14:27:20 Why the discrepancy in handling the result of vali
tapted 2017/02/01 23:36:01 The problem is that (unlike performKeyEquivalent)
+ return [handler validateUserInterfaceItem:item window:owner_];
+
+ id appController = [NSApp delegate];
+ DCHECK([appController
+ conformsToProtocol:@protocol(NSUserInterfaceValidations)]);
+ if ([appController validateUserInterfaceItem:item])
+ return YES;
+ }
+
+ if ([owner_ defaultValidateUserInterfaceItem:item])
+ return YES;
+
+ return [[self bubbleParent] validateUserInterfaceItem:item];
}
- (BOOL)redispatchKeyEvent:(NSEvent*)event {
@@ -128,4 +172,28 @@ NSEvent* KeyEventForWindow(NSWindow* window, NSEvent* event) {
return NO;
}
+- (void)dispatch:(id)sender
+ forHandler:(id<UserInterfaceItemCommandHandler>)handler {
tapted 2017/02/01 10:35:01 I might be able to store this in the CommandDispat
+ if (handler)
+ [handler commandDispatch:sender window:owner_];
+ else
+ [[self bubbleParent] commandDispatch:sender];
+}
+
+- (void)dispatchUsingKeyModifiers:(id)sender
+ forHandler:(id<UserInterfaceItemCommandHandler>)handler {
+ if (handler)
+ [handler commandDispatchUsingKeyModifiers:sender window:owner_];
+ else
+ [[self bubbleParent] commandDispatchUsingKeyModifiers:sender];
+}
+
+- (NSWindow<CommandDispatchingWindow>*)bubbleParent {
+ NSWindow* parent = [owner_ parentWindow];
+ if (parent && [parent hasKeyAppearance] &&
+ [parent conformsToProtocol:@protocol(CommandDispatchingWindow)])
+ return static_cast<NSWindow<CommandDispatchingWindow>*>(parent);
+ return nil;
+}
+
@end

Powered by Google App Engine
This is Rietveld 408576698