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

Side by Side Diff: chrome/browser/renderer_host/render_widget_host_view_mac.mm

Issue 160353: Properly destroy popups when their parent views are told to destroy.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698