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

Side by Side Diff: ui/base/cocoa/menu_controller.mm

Issue 2863883002: Tracing for NSMenu timelines
Patch Set: big CL with more trace points Created 3 years, 7 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
« no previous file with comments | « ui/base/cocoa/menu_controller.h ('k') | ui/base/cocoa/menu_controller_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/menu_controller.h" 5 #import "ui/base/cocoa/menu_controller.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/sys_string_conversions.h" 8 #include "base/strings/sys_string_conversions.h"
9 #include "ui/base/accelerators/accelerator.h" 9 #include "ui/base/accelerators/accelerator.h"
10 #include "ui/base/accelerators/platform_accelerator_cocoa.h" 10 #include "ui/base/accelerators/platform_accelerator_cocoa.h"
11 #include "ui/base/l10n/l10n_util_mac.h" 11 #include "ui/base/l10n/l10n_util_mac.h"
12 #include "ui/base/models/simple_menu_model.h" 12 #include "ui/base/models/simple_menu_model.h"
13 #import "ui/events/event_utils.h" 13 #import "ui/events/event_utils.h"
14 #include "ui/gfx/font_list.h" 14 #include "ui/gfx/font_list.h"
15 #include "ui/gfx/image/image.h" 15 #include "ui/gfx/image/image.h"
16 #include "ui/gfx/text_elider.h" 16 #include "ui/gfx/text_elider.h"
17 17
18 NSString* const kMenuControllerMenuWillOpenNotification = 18 NSString* const kMenuControllerMenuWillOpenNotification =
19 @"MenuControllerMenuWillOpen"; 19 @"MenuControllerMenuWillOpen";
20 NSString* const kMenuControllerMenuDidCloseNotification = 20 NSString* const kMenuControllerMenuDidCloseNotification =
21 @"MenuControllerMenuDidClose"; 21 @"MenuControllerMenuDidClose";
22 22
23 @interface MenuController (Private) 23 @interface MenuController (Private)
24 - (void)addSeparatorToMenu:(NSMenu*)menu 24 - (void)addSeparatorToMenu:(NSMenu*)menu
25 atIndex:(int)index; 25 atIndex:(int)index;
26 @end 26 @end
27 27
28 @interface ResponsiveNSMenuItem : NSMenuItem
29 @end
30
28 @implementation MenuController 31 @implementation MenuController
29 32
30 @synthesize model = model_; 33 @synthesize model = model_;
31 @synthesize useWithPopUpButtonCell = useWithPopUpButtonCell_; 34 @synthesize useWithPopUpButtonCell = useWithPopUpButtonCell_;
32 35
33 + (base::string16)elideMenuTitle:(const base::string16&)title 36 + (base::string16)elideMenuTitle:(const base::string16&)title
34 toWidth:(int)width { 37 toWidth:(int)width {
35 NSFont* nsfont = [NSFont menuBarFontOfSize:0]; // 0 means "default" 38 NSFont* nsfont = [NSFont menuBarFontOfSize:0]; // 0 means "default"
36 return gfx::ElideText(title, gfx::FontList(gfx::Font(nsfont)), width, 39 return gfx::ElideText(title, gfx::FontList(gfx::Font(nsfont)), width,
37 gfx::ELIDE_TAIL); 40 gfx::ELIDE_TAIL);
(...skipping 15 matching lines...) Expand all
53 } 56 }
54 57
55 - (void)dealloc { 58 - (void)dealloc {
56 [menu_ setDelegate:nil]; 59 [menu_ setDelegate:nil];
57 60
58 // Close the menu if it is still open. This could happen if a tab gets closed 61 // Close the menu if it is still open. This could happen if a tab gets closed
59 // while its context menu is still open. 62 // while its context menu is still open.
60 [self cancel]; 63 [self cancel];
61 64
62 model_ = NULL; 65 model_ = NULL;
66 [[NSNotificationCenter defaultCenter] removeObserver:self];
67
63 [super dealloc]; 68 [super dealloc];
64 } 69 }
65 70
66 - (void)cancel { 71 - (void)cancel {
67 if (isMenuOpen_) { 72 if (isMenuOpen_) {
68 [menu_ cancelTracking]; 73 [menu_ cancelTracking];
69 model_->MenuWillClose(); 74 model_->MenuWillClose();
70 isMenuOpen_ = NO; 75 isMenuOpen_ = NO;
71 } 76 }
72 } 77 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 // associated with the entry in the model identified by |modelIndex|. 110 // associated with the entry in the model identified by |modelIndex|.
106 - (void)addItemToMenu:(NSMenu*)menu 111 - (void)addItemToMenu:(NSMenu*)menu
107 atIndex:(NSInteger)index 112 atIndex:(NSInteger)index
108 fromModel:(ui::MenuModel*)model { 113 fromModel:(ui::MenuModel*)model {
109 base::string16 label16 = model->GetLabelAt(index); 114 base::string16 label16 = model->GetLabelAt(index);
110 int maxWidth = [self maxWidthForMenuModel:model modelIndex:index]; 115 int maxWidth = [self maxWidthForMenuModel:model modelIndex:index];
111 if (maxWidth != -1) 116 if (maxWidth != -1)
112 label16 = [MenuController elideMenuTitle:label16 toWidth:maxWidth]; 117 label16 = [MenuController elideMenuTitle:label16 toWidth:maxWidth];
113 118
114 NSString* label = l10n_util::FixUpWindowsStyleLabel(label16); 119 NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
115 base::scoped_nsobject<NSMenuItem> item( 120 base::scoped_nsobject<NSMenuItem> item([[ResponsiveNSMenuItem alloc]
116 [[NSMenuItem alloc] initWithTitle:label 121 initWithTitle:label
117 action:@selector(itemSelected:) 122 action:@selector(itemSelected:)
118 keyEquivalent:@""]); 123 keyEquivalent:@""]);
119 124
120 // If the menu item has an icon, set it. 125 // If the menu item has an icon, set it.
121 gfx::Image icon; 126 gfx::Image icon;
122 if (model->GetIconAt(index, &icon) && !icon.IsEmpty()) 127 if (model->GetIconAt(index, &icon) && !icon.IsEmpty())
123 [item setImage:icon.ToNSImage()]; 128 [item setImage:icon.ToNSImage()];
124 129
125 ui::MenuModel::ItemType type = model->GetTypeAt(index); 130 ui::MenuModel::ItemType type = model->GetTypeAt(index);
126 if (type == ui::MenuModel::TYPE_SUBMENU) { 131 if (type == ui::MenuModel::TYPE_SUBMENU) {
127 // Recursively build a submenu from the sub-model at this index. 132 // Recursively build a submenu from the sub-model at this index.
128 [item setTarget:nil]; 133 [item setTarget:nil];
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 base::scoped_nsobject<NSAttributedString> title( 198 base::scoped_nsobject<NSAttributedString> title(
194 [[NSAttributedString alloc] initWithString:[(id)item title] 199 [[NSAttributedString alloc] initWithString:[(id)item title]
195 attributes:attributes]); 200 attributes:attributes]);
196 [(id)item setAttributedTitle:title.get()]; 201 [(id)item setAttributedTitle:title.get()];
197 } 202 }
198 return model->IsEnabledAt(modelIndex); 203 return model->IsEnabledAt(modelIndex);
199 } 204 }
200 return NO; 205 return NO;
201 } 206 }
202 207
203 // Called when the user chooses a particular menu item. |sender| is the menu 208 - (void)itemWillBeSelected:(id)sender {
204 // item chosen. 209 suppressNextItemSelected_ = [self processItemSelectedEarly:sender];
210 }
211
212 - (BOOL)processItemSelectedEarly:(id)sender {
213 return NO;
214 }
215
205 - (void)itemSelected:(id)sender { 216 - (void)itemSelected:(id)sender {
217 DLOG(INFO) << "got action";
218 if (suppressNextItemSelected_)
219 return;
220
206 NSInteger modelIndex = [sender tag]; 221 NSInteger modelIndex = [sender tag];
207 ui::MenuModel* model = 222 ui::MenuModel* model =
208 static_cast<ui::MenuModel*>( 223 static_cast<ui::MenuModel*>(
209 [[sender representedObject] pointerValue]); 224 [[sender representedObject] pointerValue]);
210 DCHECK(model); 225 DCHECK(model);
211 if (model) { 226 if (model) {
212 int event_flags = ui::EventFlagsFromNative([NSApp currentEvent]); 227 int event_flags = ui::EventFlagsFromNative([NSApp currentEvent]);
213 model->ActivatedAt(modelIndex, event_flags); 228 model->ActivatedAt(modelIndex, event_flags);
214 } 229 }
215 } 230 }
(...skipping 14 matching lines...) Expand all
230 } 245 }
231 return menu_.get(); 246 return menu_.get();
232 } 247 }
233 248
234 - (BOOL)isMenuOpen { 249 - (BOOL)isMenuOpen {
235 return isMenuOpen_; 250 return isMenuOpen_;
236 } 251 }
237 252
238 - (void)menuWillOpen:(NSMenu*)menu { 253 - (void)menuWillOpen:(NSMenu*)menu {
239 isMenuOpen_ = YES; 254 isMenuOpen_ = YES;
255 suppressNextItemSelected_ = NO;
240 model_->MenuWillShow(); 256 model_->MenuWillShow();
241 [[NSNotificationCenter defaultCenter] 257 [[NSNotificationCenter defaultCenter]
242 postNotificationName:kMenuControllerMenuWillOpenNotification 258 postNotificationName:kMenuControllerMenuWillOpenNotification
243 object:self]; 259 object:self];
260 [[NSNotificationCenter defaultCenter]
261 addObserver:self
262 selector:@selector(willSendAction:)
263 name:NSMenuWillSendActionNotification
264 object:nil];
244 } 265 }
245 266
246 - (void)menuDidClose:(NSMenu*)menu { 267 - (void)menuDidClose:(NSMenu*)menu {
268 DLOG(INFO) << "did close";
247 if (isMenuOpen_) { 269 if (isMenuOpen_) {
248 model_->MenuWillClose(); 270 model_->MenuWillClose();
249 isMenuOpen_ = NO; 271 isMenuOpen_ = NO;
250 } 272 }
251 [[NSNotificationCenter defaultCenter] 273 [[NSNotificationCenter defaultCenter]
252 postNotificationName:kMenuControllerMenuDidCloseNotification 274 postNotificationName:kMenuControllerMenuDidCloseNotification
253 object:self]; 275 object:self];
254 } 276 }
255 277
278 - (void)willSendAction:(NSNotification*)note {
279 DLOG(INFO) << "will send action";
280 }
281
256 @end 282 @end
283
284 @interface NSMenuItem (Private)
285 // Private method which is invoked very soon after the event that activates a
286 // menu item is received. AppKit then spends 300ms or so flashing the menu item,
287 // and fading out the menu, blocking the UI thread the entire time.
288 - (void)_sendItemSelectedNote;
289 @end
290
291 @implementation ResponsiveNSMenuItem
292 - (void)_sendItemSelectedNote {
293 DLOG(INFO) << "early";
294 if ([[self target] respondsToSelector:@selector(itemWillBeSelected:)])
295 [[self target] itemWillBeSelected:self];
296 [super _sendItemSelectedNote];
297 }
298 @end
OLDNEW
« no previous file with comments | « ui/base/cocoa/menu_controller.h ('k') | ui/base/cocoa/menu_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698