| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | 5 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" |
| 6 | 6 |
| 7 #include "base/histogram.h" | 7 #include "base/histogram.h" |
| 8 #include "base/sys_string_conversions.h" | 8 #include "base/sys_string_conversions.h" |
| 9 #include "chrome/browser/browser_trial.h" | 9 #include "chrome/browser/browser_trial.h" |
| 10 #import "chrome/browser/cocoa/rwhvm_editcommand_helper.h" | 10 #import "chrome/browser/cocoa/rwhvm_editcommand_helper.h" |
| 11 #include "chrome/browser/renderer_host/backing_store.h" | 11 #include "chrome/browser/renderer_host/backing_store.h" |
| 12 #include "chrome/browser/renderer_host/render_process_host.h" | 12 #include "chrome/browser/renderer_host/render_process_host.h" |
| 13 #include "chrome/browser/renderer_host/render_widget_host.h" | 13 #include "chrome/browser/renderer_host/render_widget_host.h" |
| 14 #include "chrome/common/native_web_keyboard_event.h" | 14 #include "chrome/common/native_web_keyboard_event.h" |
| 15 #include "skia/ext/platform_canvas.h" | 15 #include "skia/ext/platform_canvas.h" |
| 16 #include "webkit/api/public/mac/WebInputEventFactory.h" | 16 #include "webkit/api/public/mac/WebInputEventFactory.h" |
| 17 #include "webkit/api/public/WebInputEvent.h" | 17 #include "webkit/api/public/WebInputEvent.h" |
| 18 #include "webkit/glue/webmenurunner_mac.h" | 18 #include "webkit/glue/webmenurunner_mac.h" |
| 19 | 19 |
| 20 using WebKit::WebInputEventFactory; | 20 using WebKit::WebInputEventFactory; |
| 21 using WebKit::WebMouseEvent; | 21 using WebKit::WebMouseEvent; |
| 22 using WebKit::WebMouseWheelEvent; | 22 using WebKit::WebMouseWheelEvent; |
| 23 | 23 |
| 24 @interface RenderWidgetHostViewCocoa (Private) | 24 @interface RenderWidgetHostViewCocoa (Private) |
| 25 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; | 25 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; |
| 26 - (void)cancelChildPopups; |
| 26 @end | 27 @end |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 // Maximum number of characters we allow in a tooltip. | 31 // Maximum number of characters we allow in a tooltip. |
| 31 const size_t kMaxTooltipLength = 1024; | 32 const size_t kMaxTooltipLength = 1024; |
| 32 | 33 |
| 33 } | 34 } |
| 34 | 35 |
| 35 // RenderWidgetHostView -------------------------------------------------------- | 36 // RenderWidgetHostView -------------------------------------------------------- |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 [cocoa_view_ setNeedsDisplay:YES]; | 244 [cocoa_view_ setNeedsDisplay:YES]; |
| 244 } | 245 } |
| 245 | 246 |
| 246 void RenderWidgetHostViewMac::RenderViewGone() { | 247 void RenderWidgetHostViewMac::RenderViewGone() { |
| 247 // TODO(darin): keep this around, and draw sad-tab into it. | 248 // TODO(darin): keep this around, and draw sad-tab into it. |
| 248 UpdateCursorIfOverSelf(); | 249 UpdateCursorIfOverSelf(); |
| 249 Destroy(); | 250 Destroy(); |
| 250 } | 251 } |
| 251 | 252 |
| 252 void RenderWidgetHostViewMac::Destroy() { | 253 void RenderWidgetHostViewMac::Destroy() { |
| 254 // On Windows, popups are implemented with a popup window style, so that when |
| 255 // an event comes in that would "cancel" it, it receives the OnCancelMode |
| 256 // message and can kill itself. Alas, on the Mac, views cannot capture events |
| 257 // outside of themselves. On Windows, if Destroy is being called on a view, |
| 258 // then the event causing the destroy had also cancelled any popups by the |
| 259 // time Destroy() was called. On the Mac we have to destroy all the popups |
| 260 // ourselves. |
| 261 |
| 262 // Depth-first destroy all popups. Use ShutdownHost() to enforce deepest-first |
| 263 // ordering. |
| 264 for (RenderWidgetHostViewCocoa* subview in [cocoa_view_ subviews]) { |
| 265 [subview renderWidgetHostViewMac]->ShutdownHost(); |
| 266 } |
| 267 |
| 253 // We've been told to destroy. | 268 // We've been told to destroy. |
| 254 [cocoa_view_ retain]; | 269 [cocoa_view_ retain]; |
| 255 [cocoa_view_ removeFromSuperview]; | 270 [cocoa_view_ removeFromSuperview]; |
| 256 [cocoa_view_ autorelease]; | 271 [cocoa_view_ autorelease]; |
| 257 | 272 |
| 258 // We get this call just before |render_widget_host_| deletes | 273 // We get this call just before |render_widget_host_| deletes |
| 259 // itself. But we are owned by |cocoa_view_|, which may be retained | 274 // itself. But we are owned by |cocoa_view_|, which may be retained |
| 260 // by some other code. Examples are TabContentsViewMac's | 275 // by some other code. Examples are TabContentsViewMac's |
| 261 // |latent_focus_view_| and TabWindowController's | 276 // |latent_focus_view_| and TabWindowController's |
| 262 // |cachedContentView_|. | 277 // |cachedContentView_|. |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 | 431 |
| 417 - (void)setCanBeKeyView:(BOOL)can { | 432 - (void)setCanBeKeyView:(BOOL)can { |
| 418 canBeKeyView_ = can; | 433 canBeKeyView_ = can; |
| 419 } | 434 } |
| 420 | 435 |
| 421 - (void)setCloseOnDeactivate:(BOOL)b { | 436 - (void)setCloseOnDeactivate:(BOOL)b { |
| 422 closeOnDeactivate_ = b; | 437 closeOnDeactivate_ = b; |
| 423 } | 438 } |
| 424 | 439 |
| 425 - (void)mouseEvent:(NSEvent *)theEvent { | 440 - (void)mouseEvent:(NSEvent *)theEvent { |
| 441 // Don't cancel child popups; killing them on a mouse click would prevent the |
| 442 // user from positioning the insertion point in the text field spawning the |
| 443 // popup. A click outside the text field would cause the text field to drop |
| 444 // the focus, and then EditorClientImpl::textFieldDidEndEditing() would cancel |
| 445 // the popup anyway, so we're OK. |
| 446 |
| 426 const WebMouseEvent& event = | 447 const WebMouseEvent& event = |
| 427 WebInputEventFactory::mouseEvent(theEvent, self); | 448 WebInputEventFactory::mouseEvent(theEvent, self); |
| 428 if (renderWidgetHostView_->render_widget_host_) | 449 if (renderWidgetHostView_->render_widget_host_) |
| 429 renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); | 450 renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); |
| 430 } | 451 } |
| 431 | 452 |
| 432 - (void)keyEvent:(NSEvent *)theEvent { | 453 - (void)keyEvent:(NSEvent *)theEvent { |
| 433 // TODO(avi): Possibly kill self? See RenderWidgetHostViewWin::OnKeyEvent and | 454 // TODO(avi): Possibly kill self? See RenderWidgetHostViewWin::OnKeyEvent and |
| 434 // http://b/issue?id=1192881 . | 455 // http://b/issue?id=1192881 . |
| 435 | 456 |
| 457 // Don't cancel child popups; the key events are probably what's triggering |
| 458 // the popup in the first place. |
| 459 |
| 436 NativeWebKeyboardEvent event(theEvent); | 460 NativeWebKeyboardEvent event(theEvent); |
| 437 if (renderWidgetHostView_->render_widget_host_) | 461 if (renderWidgetHostView_->render_widget_host_) |
| 438 renderWidgetHostView_->render_widget_host_->ForwardKeyboardEvent(event); | 462 renderWidgetHostView_->render_widget_host_->ForwardKeyboardEvent(event); |
| 439 } | 463 } |
| 440 | 464 |
| 441 - (void)scrollWheel:(NSEvent *)theEvent { | 465 - (void)scrollWheel:(NSEvent *)theEvent { |
| 442 // On Windows, popups are implemented with a popup window style, so that when | 466 [self cancelChildPopups]; |
| 443 // an event comes in that would "cancel" it, it receives the OnCancelMode | |
| 444 // message and can kill itself. Alas, on the Mac, views cannot capture events | |
| 445 // outside of themselves. While a click outside a popup kills it, that's just | |
| 446 // a defocusing of the text field in WebCore and our editor client kills the | |
| 447 // popup. But a scroll wheel event outside a popup must kill it. | |
| 448 // | |
| 449 // Thus this lovely case of filicide. If this view can be the key view, it is | |
| 450 // not a popup. Therefore, if it has any children, they are popups that need | |
| 451 // to be canceled. | |
| 452 if (canBeKeyView_) { | |
| 453 for (NSView* subview in [self subviews]) { | |
| 454 ((RenderWidgetHostViewCocoa*)subview)->renderWidgetHostView_->KillSelf(); | |
| 455 } | |
| 456 } | |
| 457 | 467 |
| 458 const WebMouseWheelEvent& event = | 468 const WebMouseWheelEvent& event = |
| 459 WebInputEventFactory::mouseWheelEvent(theEvent, self); | 469 WebInputEventFactory::mouseWheelEvent(theEvent, self); |
| 460 if (renderWidgetHostView_->render_widget_host_) | 470 if (renderWidgetHostView_->render_widget_host_) |
| 461 renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); | 471 renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(event); |
| 462 } | 472 } |
| 463 | 473 |
| 474 // See the comment in RenderWidgetHostViewMac::Destroy() about cancellation |
| 475 // events. On the Mac we must kill popups on outside events, thus this lovely |
| 476 // case of filicide caused by events on parent views. |
| 477 - (void)cancelChildPopups { |
| 478 // If this view can be the key view, it is not a popup. Therefore, if it has |
| 479 // any children, they are popups that need to be canceled. |
| 480 if (canBeKeyView_) { |
| 481 for (RenderWidgetHostViewCocoa* subview in [self subviews]) { |
| 482 subview->renderWidgetHostView_->KillSelf(); |
| 483 } |
| 484 } |
| 485 } |
| 486 |
| 464 - (void)setFrame:(NSRect)frameRect { | 487 - (void)setFrame:(NSRect)frameRect { |
| 465 [super setFrame:frameRect]; | 488 [super setFrame:frameRect]; |
| 466 if (renderWidgetHostView_->render_widget_host_) | 489 if (renderWidgetHostView_->render_widget_host_) |
| 467 renderWidgetHostView_->render_widget_host_->WasResized(); | 490 renderWidgetHostView_->render_widget_host_->WasResized(); |
| 468 } | 491 } |
| 469 | 492 |
| 470 - (void)drawRect:(NSRect)dirtyRect { | 493 - (void)drawRect:(NSRect)dirtyRect { |
| 471 if (!renderWidgetHostView_->render_widget_host_) { | 494 if (!renderWidgetHostView_->render_widget_host_) { |
| 472 // TODO(shess): Consider using something more noticable? | 495 // TODO(shess): Consider using something more noticable? |
| 473 [[NSColor whiteColor] set]; | 496 [[NSColor whiteColor] set]; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 // NSView calls this to get the text when displaying the tooltip. | 814 // NSView calls this to get the text when displaying the tooltip. |
| 792 - (NSString *)view:(NSView *)view | 815 - (NSString *)view:(NSView *)view |
| 793 stringForToolTip:(NSToolTipTag)tag | 816 stringForToolTip:(NSToolTipTag)tag |
| 794 point:(NSPoint)point | 817 point:(NSPoint)point |
| 795 userData:(void *)data { | 818 userData:(void *)data { |
| 796 return [[toolTip_ copy] autorelease]; | 819 return [[toolTip_ copy] autorelease]; |
| 797 } | 820 } |
| 798 | 821 |
| 799 @end | 822 @end |
| 800 | 823 |
| OLD | NEW |