OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/views/cocoa/native_widget_mac_nswindow.h" | 5 #import "ui/views/cocoa/native_widget_mac_nswindow.h" |
6 | 6 |
7 #include "base/mac/foundation_util.h" | 7 #include "base/mac/foundation_util.h" |
8 #import "ui/views/cocoa/views_nswindow_delegate.h" | 8 #import "ui/views/cocoa/views_nswindow_delegate.h" |
| 9 #include "ui/views/controls/menu/menu_controller.h" |
9 #include "ui/views/widget/native_widget_mac.h" | 10 #include "ui/views/widget/native_widget_mac.h" |
10 | 11 |
11 @interface NativeWidgetMacNSWindow () | 12 @interface NativeWidgetMacNSWindow () |
12 - (ViewsNSWindowDelegate*)viewsNSWindowDelegate; | 13 - (ViewsNSWindowDelegate*)viewsNSWindowDelegate; |
13 - (views::Widget*)viewsWidget; | 14 - (views::Widget*)viewsWidget; |
| 15 - (BOOL)hasViewsMenuActive; |
14 @end | 16 @end |
15 | 17 |
16 @implementation NativeWidgetMacNSWindow | 18 @implementation NativeWidgetMacNSWindow |
17 | 19 |
18 - (ViewsNSWindowDelegate*)viewsNSWindowDelegate { | 20 - (ViewsNSWindowDelegate*)viewsNSWindowDelegate { |
19 return base::mac::ObjCCastStrict<ViewsNSWindowDelegate>([self delegate]); | 21 return base::mac::ObjCCastStrict<ViewsNSWindowDelegate>([self delegate]); |
20 } | 22 } |
21 | 23 |
22 - (views::Widget*)viewsWidget { | 24 - (views::Widget*)viewsWidget { |
23 return [[self viewsNSWindowDelegate] nativeWidgetMac]->GetWidget(); | 25 return [[self viewsNSWindowDelegate] nativeWidgetMac]->GetWidget(); |
24 } | 26 } |
25 | 27 |
| 28 - (BOOL)hasViewsMenuActive { |
| 29 views::MenuController* menuController = |
| 30 views::MenuController::GetActiveInstance(); |
| 31 return menuController && menuController->owner() == [self viewsWidget]; |
| 32 } |
| 33 |
26 // Ignore [super canBecome{Key,Main}Window]. The default is NO for windows with | 34 // Ignore [super canBecome{Key,Main}Window]. The default is NO for windows with |
27 // NSBorderlessWindowMask, which is not the desired behavior. | 35 // NSBorderlessWindowMask, which is not the desired behavior. |
28 // Note these can be called via -[NSWindow close] while the widget is being torn | 36 // Note these can be called via -[NSWindow close] while the widget is being torn |
29 // down, so check for a delegate. | 37 // down, so check for a delegate. |
30 - (BOOL)canBecomeKeyWindow { | 38 - (BOOL)canBecomeKeyWindow { |
31 return [self delegate] && [self viewsWidget]->CanActivate(); | 39 return [self delegate] && [self viewsWidget]->CanActivate(); |
32 } | 40 } |
33 | 41 |
34 - (BOOL)canBecomeMainWindow { | 42 - (BOOL)canBecomeMainWindow { |
35 return [self delegate] && [self viewsWidget]->CanActivate(); | 43 return [self delegate] && [self viewsWidget]->CanActivate(); |
36 } | 44 } |
37 | 45 |
| 46 // Override sendEvent to allow key events to be forwarded to a toolkit-views |
| 47 // menu while it is active, and while still allowing the native subview to |
| 48 // retain firstResponder status. |
| 49 - (void)sendEvent:(NSEvent*)event { |
| 50 NSEventType type = [event type]; |
| 51 if ((type != NSKeyDown && type != NSKeyUp) || ![self hasViewsMenuActive]) { |
| 52 [super sendEvent:event]; |
| 53 return; |
| 54 } |
| 55 |
| 56 // Send to the menu, after converting the event into an action message using |
| 57 // the content view. |
| 58 if (type == NSKeyDown) |
| 59 [[self contentView] keyDown:event]; |
| 60 else |
| 61 [[self contentView] keyUp:event]; |
| 62 } |
| 63 |
38 // Override display, since this is the first opportunity Cocoa gives to detect | 64 // Override display, since this is the first opportunity Cocoa gives to detect |
39 // a visibility change in some cases. For example, restoring from the dock first | 65 // a visibility change in some cases. For example, restoring from the dock first |
40 // calls -[NSWindow display] before any NSWindowDelegate functions and before | 66 // calls -[NSWindow display] before any NSWindowDelegate functions and before |
41 // ordering the window (and without actually calling -[NSWindow deminiaturize]). | 67 // ordering the window (and without actually calling -[NSWindow deminiaturize]). |
42 // By notifying the delegate that a display is about to occur, it can apply a | 68 // By notifying the delegate that a display is about to occur, it can apply a |
43 // correct visibility state, before [super display] requests a draw of the | 69 // correct visibility state, before [super display] requests a draw of the |
44 // contentView. -[NSWindow isVisible] can still report NO at this point, so this | 70 // contentView. -[NSWindow isVisible] can still report NO at this point, so this |
45 // gives the delegate time to apply correct visibility before the draw occurs. | 71 // gives the delegate time to apply correct visibility before the draw occurs. |
46 - (void)display { | 72 - (void)display { |
47 [[self viewsNSWindowDelegate] onWindowWillDisplay]; | 73 [[self viewsNSWindowDelegate] onWindowWillDisplay]; |
48 [super display]; | 74 [super display]; |
49 } | 75 } |
50 | 76 |
51 // Override window order functions to intercept other visibility changes. This | 77 // Override window order functions to intercept other visibility changes. This |
52 // is needed in addition to the -[NSWindow display] override because Cocoa | 78 // is needed in addition to the -[NSWindow display] override because Cocoa |
53 // hardly ever calls display, and reports -[NSWindow isVisible] incorrectly | 79 // hardly ever calls display, and reports -[NSWindow isVisible] incorrectly |
54 // when ordering in a window for the first time. | 80 // when ordering in a window for the first time. |
55 - (void)orderWindow:(NSWindowOrderingMode)orderingMode | 81 - (void)orderWindow:(NSWindowOrderingMode)orderingMode |
56 relativeTo:(NSInteger)otherWindowNumber { | 82 relativeTo:(NSInteger)otherWindowNumber { |
57 [[self viewsNSWindowDelegate] onWindowOrderWillChange:orderingMode]; | 83 [[self viewsNSWindowDelegate] onWindowOrderWillChange:orderingMode]; |
58 [super orderWindow:orderingMode relativeTo:otherWindowNumber]; | 84 [super orderWindow:orderingMode relativeTo:otherWindowNumber]; |
59 [[self viewsNSWindowDelegate] onWindowOrderChanged:nil]; | 85 [[self viewsNSWindowDelegate] onWindowOrderChanged:nil]; |
60 } | 86 } |
61 | 87 |
62 @end | 88 @end |
OLD | NEW |