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

Side by Side 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, 10 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ui/base/cocoa/command_dispatcher.h" 5 #import "ui/base/cocoa/command_dispatcher.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "ui/base/cocoa/cocoa_base_utils.h" 8 #include "ui/base/cocoa/cocoa_base_utils.h"
9 #import "ui/base/cocoa/user_interface_item_command_handler.h"
10
11 // Expose -[NSWindow hasKeyAppearance], which determines whether the traffic
12 // lights on the window are "lit". CommandDispatcher uses this property on a
13 // parent window to decide whether keys and commands should bubble up.
14 @interface NSWindow (PrivateAPI)
15 - (BOOL)hasKeyAppearance;
16 @end
17
18 @interface CommandDispatcher ()
19 // The parent to bubble events to, or nil.
20 - (NSWindow<CommandDispatchingWindow>*)bubbleParent;
21 @end
9 22
10 namespace { 23 namespace {
11 24
12 // Duplicate the given key event, but changing the associated window. 25 // Duplicate the given key event, but changing the associated window.
13 NSEvent* KeyEventForWindow(NSWindow* window, NSEvent* event) { 26 NSEvent* KeyEventForWindow(NSWindow* window, NSEvent* event) {
14 NSEventType event_type = [event type]; 27 NSEventType event_type = [event type];
15 28
16 // Convert the event's location from the original window's coordinates into 29 // Convert the event's location from the original window's coordinates into
17 // our own. 30 // our own.
18 NSPoint location = [event locationInWindow]; 31 NSPoint location = [event locationInWindow];
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 if ([delegate_ eventHandledByExtensionCommand:event 79 if ([delegate_ eventHandledByExtensionCommand:event
67 isRedispatch:redispatchingEvent_]) { 80 isRedispatch:redispatchingEvent_]) {
68 return YES; 81 return YES;
69 } 82 }
70 83
71 if (redispatchingEvent_) 84 if (redispatchingEvent_)
72 return NO; 85 return NO;
73 86
74 // Give a CommandDispatcherTarget (e.g. a web site) a chance to handle the 87 // Give a CommandDispatcherTarget (e.g. a web site) a chance to handle the
75 // event. If it doesn't want to handle it, it will call us back with 88 // event. If it doesn't want to handle it, it will call us back with
76 // -redispatchKeyEvent:. 89 // -redispatchKeyEvent:. Only allow this behavior when dispatching key events
77 NSResponder* r = [owner_ firstResponder]; 90 // on the key window.
78 if ([r conformsToProtocol:@protocol(CommandDispatcherTarget)]) 91 if ([owner_ isKeyWindow]) {
79 return [r performKeyEquivalent:event]; 92 NSResponder* r = [owner_ firstResponder];
93 if ([r conformsToProtocol:@protocol(CommandDispatcherTarget)])
94 return [r performKeyEquivalent:event];
95 }
80 96
81 if ([delegate_ prePerformKeyEquivalent:event window:owner_]) 97 if ([delegate_ prePerformKeyEquivalent:event window:owner_])
82 return YES; 98 return YES;
83 99
84 if ([owner_ defaultPerformKeyEquivalent:event]) 100 if ([owner_ defaultPerformKeyEquivalent:event])
85 return YES; 101 return YES;
86 102
87 return [delegate_ postPerformKeyEquivalent:event window:owner_]; 103 if ([delegate_ postPerformKeyEquivalent:event window:owner_])
104 return YES;
105
106 // Allow commands to "bubble up" to CommandDispatchers in parent windows, if
107 // they were not handled here.
108 return [[self bubbleParent] performKeyEquivalent:event];
109 }
110
111 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item
112 forHandler:(id<UserInterfaceItemCommandHandler>)handler {
113 // Since this class implements these selectors, |super| will always say they
114 // are enabled. Only use [super] to validate other selectors. If there is no
115 // command handler, defer to AppController.
116 if ([item action] == @selector(commandDispatch:) ||
117 [item action] == @selector(commandDispatchUsingKeyModifiers:)) {
118 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)
119 return [handler validateUserInterfaceItem:item window:owner_];
120
121 id appController = [NSApp delegate];
122 DCHECK([appController
123 conformsToProtocol:@protocol(NSUserInterfaceValidations)]);
124 if ([appController validateUserInterfaceItem:item])
125 return YES;
126 }
127
128 if ([owner_ defaultValidateUserInterfaceItem:item])
129 return YES;
130
131 return [[self bubbleParent] validateUserInterfaceItem:item];
88 } 132 }
89 133
90 - (BOOL)redispatchKeyEvent:(NSEvent*)event { 134 - (BOOL)redispatchKeyEvent:(NSEvent*)event {
91 DCHECK(event); 135 DCHECK(event);
92 NSEventType eventType = [event type]; 136 NSEventType eventType = [event type];
93 if (eventType != NSKeyDown && eventType != NSKeyUp && 137 if (eventType != NSKeyDown && eventType != NSKeyUp &&
94 eventType != NSFlagsChanged) { 138 eventType != NSFlagsChanged) {
95 NOTREACHED(); 139 NOTREACHED();
96 return YES; // Pretend it's been handled in an effort to limit damage. 140 return YES; // Pretend it's been handled in an effort to limit damage.
97 } 141 }
(...skipping 23 matching lines...) Expand all
121 if (redispatchingEvent_) { 165 if (redispatchingEvent_) {
122 // If we get here, then the event was not handled by NSApplication. 166 // If we get here, then the event was not handled by NSApplication.
123 eventHandled_ = NO; 167 eventHandled_ = NO;
124 // Return YES to stop native -sendEvent handling. 168 // Return YES to stop native -sendEvent handling.
125 return YES; 169 return YES;
126 } 170 }
127 171
128 return NO; 172 return NO;
129 } 173 }
130 174
175 - (void)dispatch:(id)sender
176 forHandler:(id<UserInterfaceItemCommandHandler>)handler {
tapted 2017/02/01 10:35:01 I might be able to store this in the CommandDispat
177 if (handler)
178 [handler commandDispatch:sender window:owner_];
179 else
180 [[self bubbleParent] commandDispatch:sender];
181 }
182
183 - (void)dispatchUsingKeyModifiers:(id)sender
184 forHandler:(id<UserInterfaceItemCommandHandler>)handler {
185 if (handler)
186 [handler commandDispatchUsingKeyModifiers:sender window:owner_];
187 else
188 [[self bubbleParent] commandDispatchUsingKeyModifiers:sender];
189 }
190
191 - (NSWindow<CommandDispatchingWindow>*)bubbleParent {
192 NSWindow* parent = [owner_ parentWindow];
193 if (parent && [parent hasKeyAppearance] &&
194 [parent conformsToProtocol:@protocol(CommandDispatchingWindow)])
195 return static_cast<NSWindow<CommandDispatchingWindow>*>(parent);
196 return nil;
197 }
198
131 @end 199 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698