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/controls/menu/menu_runner_impl_cocoa.h" | 5 #import "ui/views/controls/menu/menu_runner_impl_cocoa.h" |
6 | 6 |
7 #include "base/mac/sdk_forward_declarations.h" | 7 #include "base/mac/sdk_forward_declarations.h" |
| 8 #import "ui/base/cocoa/cocoa_base_utils.h" |
8 #import "ui/base/cocoa/menu_controller.h" | 9 #import "ui/base/cocoa/menu_controller.h" |
9 #include "ui/base/models/menu_model.h" | 10 #include "ui/base/models/menu_model.h" |
10 #include "ui/events/base_event_utils.h" | 11 #include "ui/events/base_event_utils.h" |
11 #include "ui/events/event_utils.h" | 12 #include "ui/events/event_utils.h" |
12 #include "ui/gfx/geometry/rect.h" | 13 #include "ui/gfx/geometry/rect.h" |
13 #include "ui/gfx/mac/coordinate_conversion.h" | 14 #include "ui/gfx/mac/coordinate_conversion.h" |
14 #include "ui/views/controls/menu/menu_runner_impl_adapter.h" | 15 #include "ui/views/controls/menu/menu_runner_impl_adapter.h" |
15 #include "ui/views/widget/widget.h" | 16 #include "ui/views/widget/widget.h" |
16 | 17 |
17 namespace views { | 18 namespace views { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 } | 73 } |
73 | 74 |
74 // A plain NSView will anchor below rather than "over", so use an NSButton. | 75 // A plain NSView will anchor below rather than "over", so use an NSButton. |
75 base::scoped_nsobject<NSView> anchor_view( | 76 base::scoped_nsobject<NSView> anchor_view( |
76 [[NSButton alloc] initWithFrame:rect]); | 77 [[NSButton alloc] initWithFrame:rect]); |
77 [anchor_view setHidden:YES]; | 78 [anchor_view setHidden:YES]; |
78 [[window contentView] addSubview:anchor_view]; | 79 [[window contentView] addSubview:anchor_view]; |
79 return anchor_view; | 80 return anchor_view; |
80 } | 81 } |
81 | 82 |
| 83 // Returns an appropriate event (with a location) suitable for showing a context |
| 84 // menu. Uses [NSApp currentEvent] if it's a non-nil mouse click event, |
| 85 // otherwise creates an autoreleased dummy event located at |anchor|. |
| 86 NSEvent* EventForPositioningContextMenu(const gfx::Rect& anchor, |
| 87 NSWindow* window) { |
| 88 NSEvent* event = [NSApp currentEvent]; |
| 89 switch ([event type]) { |
| 90 case NSLeftMouseDown: |
| 91 case NSLeftMouseUp: |
| 92 case NSRightMouseDown: |
| 93 case NSRightMouseUp: |
| 94 case NSOtherMouseDown: |
| 95 case NSOtherMouseUp: |
| 96 return event; |
| 97 default: |
| 98 break; |
| 99 } |
| 100 NSPoint location_in_window = ui::ConvertPointFromScreenToWindow( |
| 101 window, gfx::ScreenPointToNSPoint(anchor.CenterPoint())); |
| 102 return [NSEvent mouseEventWithType:NSRightMouseDown |
| 103 location:location_in_window |
| 104 modifierFlags:0 |
| 105 timestamp:0 |
| 106 windowNumber:[window windowNumber] |
| 107 context:nil |
| 108 eventNumber:0 |
| 109 clickCount:1 |
| 110 pressure:0]; |
| 111 } |
| 112 |
82 } // namespace | 113 } // namespace |
83 | 114 |
84 // static | 115 // static |
85 MenuRunnerImplInterface* MenuRunnerImplInterface::Create( | 116 MenuRunnerImplInterface* MenuRunnerImplInterface::Create( |
86 ui::MenuModel* menu_model, | 117 ui::MenuModel* menu_model, |
87 int32_t run_types, | 118 int32_t run_types, |
88 const base::Closure& on_menu_closed_callback) { | 119 const base::Closure& on_menu_closed_callback) { |
89 if ((run_types & kNativeRunTypes) != 0 && | 120 if ((run_types & kNativeRunTypes) != 0 && |
90 (run_types & MenuRunner::IS_NESTED) == 0) { | 121 (run_types & MenuRunner::IS_NESTED) == 0) { |
91 return new MenuRunnerImplCocoa(menu_model, on_menu_closed_callback); | 122 return new MenuRunnerImplCocoa(menu_model, on_menu_closed_callback); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 MenuButton* button, | 157 MenuButton* button, |
127 const gfx::Rect& bounds, | 158 const gfx::Rect& bounds, |
128 MenuAnchorPosition anchor, | 159 MenuAnchorPosition anchor, |
129 int32_t run_types) { | 160 int32_t run_types) { |
130 DCHECK(run_types & kNativeRunTypes); | 161 DCHECK(run_types & kNativeRunTypes); |
131 DCHECK(!IsRunning()); | 162 DCHECK(!IsRunning()); |
132 DCHECK(parent); | 163 DCHECK(parent); |
133 closing_event_time_ = base::TimeTicks(); | 164 closing_event_time_ = base::TimeTicks(); |
134 running_ = true; | 165 running_ = true; |
135 | 166 |
| 167 NSWindow* window = parent->GetNativeWindow(); |
136 if (run_types & MenuRunner::CONTEXT_MENU) { | 168 if (run_types & MenuRunner::CONTEXT_MENU) { |
137 [NSMenu popUpContextMenu:[menu_controller_ menu] | 169 [NSMenu popUpContextMenu:[menu_controller_ menu] |
138 withEvent:[NSApp currentEvent] | 170 withEvent:EventForPositioningContextMenu(bounds, window) |
139 forView:parent->GetNativeView()]; | 171 forView:parent->GetNativeView()]; |
140 } else if (run_types & MenuRunner::COMBOBOX) { | 172 } else if (run_types & MenuRunner::COMBOBOX) { |
141 NSMenuItem* checked_item = FirstCheckedItem(menu_controller_); | 173 NSMenuItem* checked_item = FirstCheckedItem(menu_controller_); |
142 base::scoped_nsobject<NSView> anchor_view( | 174 base::scoped_nsobject<NSView> anchor_view( |
143 CreateMenuAnchorView(parent->GetNativeWindow(), bounds, checked_item)); | 175 CreateMenuAnchorView(window, bounds, checked_item)); |
144 NSMenu* menu = [menu_controller_ menu]; | 176 NSMenu* menu = [menu_controller_ menu]; |
145 [menu setMinimumWidth:bounds.width() + kNativeCheckmarkWidth]; | 177 [menu setMinimumWidth:bounds.width() + kNativeCheckmarkWidth]; |
146 [menu popUpMenuPositioningItem:checked_item | 178 [menu popUpMenuPositioningItem:checked_item |
147 atLocation:NSZeroPoint | 179 atLocation:NSZeroPoint |
148 inView:anchor_view]; | 180 inView:anchor_view]; |
149 [anchor_view removeFromSuperview]; | 181 [anchor_view removeFromSuperview]; |
150 } else { | 182 } else { |
151 NOTREACHED(); | 183 NOTREACHED(); |
152 } | 184 } |
153 | 185 |
(...skipping 17 matching lines...) Expand all Loading... |
171 | 203 |
172 base::TimeTicks MenuRunnerImplCocoa::GetClosingEventTime() const { | 204 base::TimeTicks MenuRunnerImplCocoa::GetClosingEventTime() const { |
173 return closing_event_time_; | 205 return closing_event_time_; |
174 } | 206 } |
175 | 207 |
176 MenuRunnerImplCocoa::~MenuRunnerImplCocoa() { | 208 MenuRunnerImplCocoa::~MenuRunnerImplCocoa() { |
177 } | 209 } |
178 | 210 |
179 } // namespace internal | 211 } // namespace internal |
180 } // namespace views | 212 } // namespace views |
OLD | NEW |