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

Side by Side Diff: chrome/browser/chrome_application_mac.mm

Issue 348047: [Mac] Do not pump nested tasks in -[NSApp sendEvent:]. (Closed)
Patch Set: More tweaking of that other person's comments. Created 11 years, 1 month 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 (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "chrome/browser/chrome_application_mac.h" 5 #import "chrome/browser/chrome_application_mac.h"
6 6
7 #import "base/histogram.h" 7 #include "base/histogram.h"
8 #import "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h"
9 #import "base/scoped_nsobject.h" 10 #import "base/scoped_nsobject.h"
10 #import "base/sys_string_conversions.h" 11 #import "base/sys_string_conversions.h"
11 #import "chrome/app/breakpad_mac.h" 12 #import "chrome/app/breakpad_mac.h"
12 #import "chrome/browser/cocoa/chrome_event_processing_window.h" 13 #import "chrome/browser/cocoa/chrome_event_processing_window.h"
13 #import "chrome/browser/cocoa/objc_method_swizzle.h" 14 #import "chrome/browser/cocoa/objc_method_swizzle.h"
14 #import "chrome/browser/renderer_host/render_widget_host_view_mac.h" 15 #import "chrome/browser/renderer_host/render_widget_host_view_mac.h"
15 16
17 // When C++ exceptions are disabled, the C++ library defines |try| and
18 // |catch| so as to allow exception-expecting C++ code to build properly when
19 // language support for exceptions is not present. These macros interfere
20 // with the use of |@try| and |@catch| in Objective-C files such as this one.
21 // Undefine these macros here, after everything has been #included, since
22 // there will be no C++ uses and only Objective-C uses from this point on.
23 #undef try
24 #undef catch
25
16 // The implementation of NSExceptions break various assumptions in the 26 // The implementation of NSExceptions break various assumptions in the
17 // Chrome code. This category defines a replacement for 27 // Chrome code. This category defines a replacement for
18 // -initWithName:reason:userInfo: for purposes of forcing a break in 28 // -initWithName:reason:userInfo: for purposes of forcing a break in
19 // the debugger when an exception is raised. -raise sounds more 29 // the debugger when an exception is raised. -raise sounds more
20 // obvious to intercept, but it doesn't catch the original throw 30 // obvious to intercept, but it doesn't catch the original throw
21 // because the objc runtime doesn't use it. 31 // because the objc runtime doesn't use it.
22 @interface NSException (NSExceptionSwizzle) 32 @interface NSException (NSExceptionSwizzle)
23 - (id)chromeInitWithName:(NSString *)aName 33 - (id)chromeInitWithName:(NSString *)aName
24 reason:(NSString *)aReason 34 reason:(NSString *)aReason
25 userInfo:(NSDictionary *)someUserInfo; 35 userInfo:(NSDictionary *)someUserInfo;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 NSString* actionString = NSStringFromSelector(anAction); 247 NSString* actionString = NSStringFromSelector(anAction);
238 NSString* value = 248 NSString* value =
239 [NSString stringWithFormat:@"%@ tag %d sending %@ to %p", 249 [NSString stringWithFormat:@"%@ tag %d sending %@ to %p",
240 [sender className], tag, actionString, aTarget]; 250 [sender className], tag, actionString, aTarget];
241 251
242 ScopedCrashKey key(kActionKey, value); 252 ScopedCrashKey key(kActionKey, value);
243 return [super sendAction:anAction to:aTarget from:sender]; 253 return [super sendAction:anAction to:aTarget from:sender];
244 } 254 }
245 255
246 - (void)sendEvent:(NSEvent*)event { 256 - (void)sendEvent:(NSEvent*)event {
247 // The superclass's |sendEvent:| sends keyboard events to the menu and the key 257 // Messages from renderers and plug-ins can cause unfortunate
248 // view loop before dispatching them to |keyDown:|. Since we want to send keys 258 // interactions with modal event loops (consider a control which
249 // to the renderer before sending them to the menu, and we never want them to 259 // talks to a tab which is closed while you're click-dragging the
250 // the kev view loop when the web is focussed, we change this behavior. 260 // mouse). This turns off handling of nested events for the
251 if ([[self keyWindow] 261 // duration of -sendEvent: handling, then restores the prior. Any
252 isKindOfClass:[ChromeEventProcessingWindow class]]) { 262 // event-handling code which needs nested events to work in a modal
253 if ([static_cast<ChromeEventProcessingWindow*>([self keyWindow]) 263 // loop should explicitly turn handling back on using similar code.
254 shortcircuitEvent:event]) 264 bool wasEnabled = MessageLoop::current()->NestableTasksAllowed();
255 return; 265 MessageLoop::current()->SetNestableTasksAllowed(false);
266
267 @try {
268 // The superclass's |sendEvent:| sends keyboard events to the menu
269 // and the key view loop before dispatching them to
270 // |keyDown:|. Since we want to send keys to the renderer before
271 // sending them to the menu, and we never want them to go to the
272 // key view loop when the web is focussed, we change this
273 // behavior.
274 ChromeEventProcessingWindow* keyWindow =
275 static_cast<ChromeEventProcessingWindow*>([self keyWindow]);
276 if (![keyWindow isKindOfClass:[ChromeEventProcessingWindow class]] ||
277 ![keyWindow shortcircuitEvent:event]) {
278 [super sendEvent:event];
279 }
280 } @finally {
281 // ALWAYS set things back the way we found them, no matter what.
282 // Leaving nested tasks turned off breaks about a million things.
283 MessageLoop::current()->SetNestableTasksAllowed(wasEnabled);
256 } 284 }
257
258 [super sendEvent:event];
259 } 285 }
260 286
261 // NSExceptions which are caught by the event loop are logged here. 287 // NSExceptions which are caught by the event loop are logged here.
262 // NSException uses setjmp/longjmp, which can be very bad for C++, so 288 // NSException uses setjmp/longjmp, which can be very bad for C++, so
263 // we attempt to track and report them. 289 // we attempt to track and report them.
264 - (void)reportException:(NSException *)anException { 290 - (void)reportException:(NSException *)anException {
265 // If we throw an exception in this code, we can create an infinite 291 // If we throw an exception in this code, we can create an infinite
266 // loop. If we throw out of the if() without resetting 292 // loop. If we throw out of the if() without resetting
267 // |reportException|, we'll stop reporting exceptions for this run. 293 // |reportException|, we'll stop reporting exceptions for this run.
268 static BOOL reportingException = NO; 294 static BOOL reportingException = NO;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 333
308 @end 334 @end
309 335
310 namespace CrApplicationCC { 336 namespace CrApplicationCC {
311 337
312 void Terminate() { 338 void Terminate() {
313 [NSApp terminate:nil]; 339 [NSApp terminate:nil];
314 } 340 }
315 341
316 } // namespace CrApplicationCC 342 } // namespace CrApplicationCC
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/cocoa/tab_controller.mm » ('j') | chrome/browser/cocoa/tab_controller.mm » ('J')

Powered by Google App Engine
This is Rietveld 408576698