OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |