| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <QuartzCore/QuartzCore.h> | 5 #include <QuartzCore/QuartzCore.h> |
| 6 | 6 |
| 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" | 7 #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" |
| 8 | 8 |
| 9 #include "app/app_switches.h" | 9 #include "app/app_switches.h" |
| 10 #include "app/surface/io_surface_support_mac.h" | 10 #include "app/surface/io_surface_support_mac.h" |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 /////////////////////////////////////////////////////////////////////////////// | 443 /////////////////////////////////////////////////////////////////////////////// |
| 444 // RenderWidgetHostViewMac, public: | 444 // RenderWidgetHostViewMac, public: |
| 445 | 445 |
| 446 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 446 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
| 447 : render_widget_host_(widget), | 447 : render_widget_host_(widget), |
| 448 about_to_validate_and_paint_(false), | 448 about_to_validate_and_paint_(false), |
| 449 call_set_needs_display_in_rect_pending_(false), | 449 call_set_needs_display_in_rect_pending_(false), |
| 450 text_input_type_(WebKit::WebTextInputTypeNone), | 450 text_input_type_(WebKit::WebTextInputTypeNone), |
| 451 is_loading_(false), | 451 is_loading_(false), |
| 452 is_hidden_(false), | 452 is_hidden_(false), |
| 453 shutdown_factory_(this) { | 453 shutdown_factory_(this), |
| 454 needs_gpu_visibility_update_after_repaint_(false) { |
| 454 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| goes away. | 455 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| goes away. |
| 455 // Since we autorelease it, our caller must put |native_view()| into the view | 456 // Since we autorelease it, our caller must put |native_view()| into the view |
| 456 // hierarchy right after calling us. | 457 // hierarchy right after calling us. |
| 457 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 458 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
| 458 initWithRenderWidgetHostViewMac:this] autorelease]; | 459 initWithRenderWidgetHostViewMac:this] autorelease]; |
| 459 render_widget_host_->set_view(this); | 460 render_widget_host_->set_view(this); |
| 460 | 461 |
| 461 // Turn on accessibility only if VoiceOver is running. | 462 // Turn on accessibility only if VoiceOver is running. |
| 462 if (IsVoiceOverRunning()) { | 463 if (IsVoiceOverRunning()) { |
| 463 Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected(); | 464 Singleton<BrowserAccessibilityState>()->OnScreenReaderDetected(); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 [cocoa_view_ setCaretRect:[cocoa_view_ flipRectToNSRect:caret_rect]]; | 680 [cocoa_view_ setCaretRect:[cocoa_view_ flipRectToNSRect:caret_rect]]; |
| 680 } | 681 } |
| 681 | 682 |
| 682 void RenderWidgetHostViewMac::ImeCancelComposition() { | 683 void RenderWidgetHostViewMac::ImeCancelComposition() { |
| 683 [cocoa_view_ cancelComposition]; | 684 [cocoa_view_ cancelComposition]; |
| 684 } | 685 } |
| 685 | 686 |
| 686 void RenderWidgetHostViewMac::DidUpdateBackingStore( | 687 void RenderWidgetHostViewMac::DidUpdateBackingStore( |
| 687 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, | 688 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, |
| 688 const std::vector<gfx::Rect>& copy_rects) { | 689 const std::vector<gfx::Rect>& copy_rects) { |
| 689 if (is_hidden_) | 690 if (!is_hidden_) { |
| 690 return; | 691 std::vector<gfx::Rect> rects(copy_rects); |
| 691 | 692 |
| 692 std::vector<gfx::Rect> rects(copy_rects); | 693 // Because the findbar might be open, we cannot use scrollRect:by: here. Fo
r |
| 694 // now, simply mark all of scroll rect as dirty. |
| 695 if (!scroll_rect.IsEmpty()) |
| 696 rects.push_back(scroll_rect); |
| 693 | 697 |
| 694 // Because the findbar might be open, we cannot use scrollRect:by: here. For | 698 for (size_t i = 0; i < rects.size(); ++i) { |
| 695 // now, simply mark all of scroll rect as dirty. | 699 NSRect ns_rect = [cocoa_view_ flipRectToNSRect:rects[i]]; |
| 696 if (!scroll_rect.IsEmpty()) | |
| 697 rects.push_back(scroll_rect); | |
| 698 | 700 |
| 699 for (size_t i = 0; i < rects.size(); ++i) { | 701 if (about_to_validate_and_paint_) { |
| 700 NSRect ns_rect = [cocoa_view_ flipRectToNSRect:rects[i]]; | 702 // As much as we'd like to use -setNeedsDisplayInRect: here, we can't. |
| 703 // We're in the middle of executing a -drawRect:, and as soon as it |
| 704 // returns Cocoa will clear its record of what needs display. We |
| 705 // instead use |performSelector:| to call |setNeedsDisplayInRect:| |
| 706 // after returning to the main loop, at which point |drawRect:| is no |
| 707 // longer on the stack. |
| 708 DCHECK([NSThread isMainThread]); |
| 709 if (!call_set_needs_display_in_rect_pending_) { |
| 710 [cocoa_view_ performSelector:@selector(callSetNeedsDisplayInRect) |
| 711 withObject:nil |
| 712 afterDelay:0]; |
| 713 call_set_needs_display_in_rect_pending_ = true; |
| 714 invalid_rect_ = ns_rect; |
| 715 } else { |
| 716 // The old invalid rect is probably invalid now, since the view has |
| 717 // most likely been resized, but there's no harm in dirtying the |
| 718 // union. In the limit, this becomes equivalent to dirtying the |
| 719 // whole view. |
| 720 invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); |
| 721 } |
| 722 } else { |
| 723 [cocoa_view_ setNeedsDisplayInRect:ns_rect]; |
| 724 } |
| 725 } |
| 701 | 726 |
| 702 if (about_to_validate_and_paint_) { | 727 if (!about_to_validate_and_paint_) |
| 703 // As much as we'd like to use -setNeedsDisplayInRect: here, we can't. | 728 [cocoa_view_ displayIfNeeded]; |
| 704 // We're in the middle of executing a -drawRect:, and as soon as it | |
| 705 // returns Cocoa will clear its record of what needs display. We instead | |
| 706 // use |performSelector:| to call |setNeedsDisplayInRect:| after returning | |
| 707 // to the main loop, at which point |drawRect:| is no longer on the stack. | |
| 708 DCHECK([NSThread isMainThread]); | |
| 709 if (!call_set_needs_display_in_rect_pending_) { | |
| 710 [cocoa_view_ performSelector:@selector(callSetNeedsDisplayInRect) | |
| 711 withObject:nil | |
| 712 afterDelay:0]; | |
| 713 call_set_needs_display_in_rect_pending_ = true; | |
| 714 invalid_rect_ = ns_rect; | |
| 715 } else { | |
| 716 // The old invalid rect is probably invalid now, since the view has most | |
| 717 // likely been resized, but there's no harm in dirtying the union. In | |
| 718 // the limit, this becomes equivalent to dirtying the whole view. | |
| 719 invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); | |
| 720 } | |
| 721 } else { | |
| 722 [cocoa_view_ setNeedsDisplayInRect:ns_rect]; | |
| 723 } | |
| 724 } | 729 } |
| 725 | 730 |
| 731 // If |about_to_validate_and_paint_| is set, then -drawRect: is on the stack |
| 732 // and it's not allowed to call -setHidden on the accelerated view. In that |
| 733 // case, -callSetNeedsDisplayInRect: will hide it later. |
| 734 // If |about_to_validate_and_paint_| is not set, do it now. |
| 726 if (!about_to_validate_and_paint_) | 735 if (!about_to_validate_and_paint_) |
| 727 [cocoa_view_ displayIfNeeded]; | 736 HandleDelayedGpuViewHiding(); |
| 728 } | 737 } |
| 729 | 738 |
| 730 void RenderWidgetHostViewMac::RenderViewGone() { | 739 void RenderWidgetHostViewMac::RenderViewGone() { |
| 731 // TODO(darin): keep this around, and draw sad-tab into it. | 740 // TODO(darin): keep this around, and draw sad-tab into it. |
| 732 UpdateCursorIfOverSelf(); | 741 UpdateCursorIfOverSelf(); |
| 733 Destroy(); | 742 Destroy(); |
| 734 } | 743 } |
| 735 | 744 |
| 736 void RenderWidgetHostViewMac::Destroy() { | 745 void RenderWidgetHostViewMac::Destroy() { |
| 737 // On Windows, popups are implemented with a popup window style, so that when | 746 // On Windows, popups are implemented with a popup window style, so that when |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 | 944 |
| 936 plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); | 945 plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); |
| 937 AcceleratedPluginView* view = | 946 AcceleratedPluginView* view = |
| 938 static_cast<AcceleratedPluginView*>(it->second); | 947 static_cast<AcceleratedPluginView*>(it->second); |
| 939 // The surface is hidden until its first paint, to not show gargabe. | 948 // The surface is hidden until its first paint, to not show gargabe. |
| 940 if (plugin_container_manager_.SurfaceShouldBeVisible(window)) | 949 if (plugin_container_manager_.SurfaceShouldBeVisible(window)) |
| 941 [view setHidden:NO]; | 950 [view setHidden:NO]; |
| 942 [view setSurfaceWasSwapped:YES]; | 951 [view setSurfaceWasSwapped:YES]; |
| 943 } | 952 } |
| 944 | 953 |
| 945 void RenderWidgetHostViewMac::GpuRenderingStateDidChange() { | 954 void RenderWidgetHostViewMac::UpdateRootGpuViewVisibility( |
| 946 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 955 bool show_gpu_widget) { |
| 947 // Plugins are destroyed on page navigate. The compositor layer on the other | 956 // Plugins are destroyed on page navigate. The compositor layer on the other |
| 948 // hand is created on demand and then stays alive until its renderer process | 957 // hand is created on demand and then stays alive until its renderer process |
| 949 // dies (usually on cross-domain navigation). Instead, only a flag | 958 // dies (usually on cross-domain navigation). Instead, only a flag |
| 950 // |is_gpu_rendering_active()| is flipped when the compositor output should be | 959 // |is_gpu_rendering_active()| is flipped when the compositor output should be |
| 951 // shown/hidden. | 960 // shown/hidden. |
| 952 // Show/hide the view belonging to the compositor here. | 961 // Show/hide the view belonging to the compositor here. |
| 953 plugin_container_manager_.set_gpu_rendering_active( | 962 plugin_container_manager_.set_gpu_rendering_active(show_gpu_widget); |
| 954 GetRenderWidgetHost()->is_gpu_rendering_active()); | |
| 955 | 963 |
| 956 gfx::PluginWindowHandle root_handle = | 964 gfx::PluginWindowHandle root_handle = |
| 957 plugin_container_manager_.root_container_handle(); | 965 plugin_container_manager_.root_container_handle(); |
| 958 if (root_handle != gfx::kNullPluginWindow) { | 966 if (root_handle != gfx::kNullPluginWindow) { |
| 959 PluginViewMap::iterator it = plugin_views_.find(root_handle); | 967 PluginViewMap::iterator it = plugin_views_.find(root_handle); |
| 960 DCHECK(plugin_views_.end() != it); | 968 DCHECK(plugin_views_.end() != it); |
| 961 if (plugin_views_.end() == it) { | 969 if (plugin_views_.end() == it) { |
| 962 return; | 970 return; |
| 963 } | 971 } |
| 964 bool visible = | 972 bool visible = |
| 965 plugin_container_manager_.SurfaceShouldBeVisible(root_handle); | 973 plugin_container_manager_.SurfaceShouldBeVisible(root_handle); |
| 974 [[it->second window] disableScreenUpdatesUntilFlush]; |
| 966 [it->second setHidden:!visible]; | 975 [it->second setHidden:!visible]; |
| 967 } | 976 } |
| 968 } | 977 } |
| 969 | 978 |
| 979 void RenderWidgetHostViewMac::HandleDelayedGpuViewHiding() { |
| 980 if (needs_gpu_visibility_update_after_repaint_) { |
| 981 UpdateRootGpuViewVisibility(false); |
| 982 needs_gpu_visibility_update_after_repaint_ = false; |
| 983 } |
| 984 } |
| 985 |
| 986 void RenderWidgetHostViewMac::GpuRenderingStateDidChange() { |
| 987 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 988 if (GetRenderWidgetHost()->is_gpu_rendering_active()) { |
| 989 UpdateRootGpuViewVisibility( |
| 990 GetRenderWidgetHost()->is_gpu_rendering_active()); |
| 991 } else { |
| 992 needs_gpu_visibility_update_after_repaint_ = true; |
| 993 } |
| 994 } |
| 995 |
| 970 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( | 996 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( |
| 971 CGLContextObj context, | 997 CGLContextObj context, |
| 972 gfx::PluginWindowHandle plugin_handle, | 998 gfx::PluginWindowHandle plugin_handle, |
| 973 NSSize size) { | 999 NSSize size) { |
| 974 // Called on the display link thread. | 1000 // Called on the display link thread. |
| 975 CGLSetCurrentContext(context); | 1001 CGLSetCurrentContext(context); |
| 976 | 1002 |
| 977 glMatrixMode(GL_PROJECTION); | 1003 glMatrixMode(GL_PROJECTION); |
| 978 glLoadIdentity(); | 1004 glLoadIdentity(); |
| 979 // Note that we place the origin at the upper left corner with +y | 1005 // Note that we place the origin at the upper left corner with +y |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 if (renderWidgetHostView_->render_widget_host_) | 1516 if (renderWidgetHostView_->render_widget_host_) |
| 1491 renderWidgetHostView_->render_widget_host_->WasResized(); | 1517 renderWidgetHostView_->render_widget_host_->WasResized(); |
| 1492 } | 1518 } |
| 1493 | 1519 |
| 1494 - (void)callSetNeedsDisplayInRect { | 1520 - (void)callSetNeedsDisplayInRect { |
| 1495 DCHECK([NSThread isMainThread]); | 1521 DCHECK([NSThread isMainThread]); |
| 1496 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); | 1522 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); |
| 1497 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; | 1523 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; |
| 1498 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; | 1524 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; |
| 1499 renderWidgetHostView_->invalid_rect_ = NSZeroRect; | 1525 renderWidgetHostView_->invalid_rect_ = NSZeroRect; |
| 1526 |
| 1527 renderWidgetHostView_->HandleDelayedGpuViewHiding(); |
| 1500 } | 1528 } |
| 1501 | 1529 |
| 1502 // Fills with white the parts of the area to the right and bottom for |rect| | 1530 // Fills with white the parts of the area to the right and bottom for |rect| |
| 1503 // that intersect |damagedRect|. | 1531 // that intersect |damagedRect|. |
| 1504 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect | 1532 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect |
| 1505 dirtyRect:(gfx::Rect)damagedRect { | 1533 dirtyRect:(gfx::Rect)damagedRect { |
| 1506 if (damagedRect.right() > rect.right()) { | 1534 if (damagedRect.right() > rect.right()) { |
| 1507 int x = std::max(rect.right(), damagedRect.x()); | 1535 int x = std::max(rect.right(), damagedRect.x()); |
| 1508 int y = std::min(rect.bottom(), damagedRect.bottom()); | 1536 int y = std::min(rect.bottom(), damagedRect.bottom()); |
| 1509 int width = damagedRect.right() - x; | 1537 int width = damagedRect.right() - x; |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2534 if (!string) return NO; | 2562 if (!string) return NO; |
| 2535 | 2563 |
| 2536 // If the user is currently using an IME, confirm the IME input, | 2564 // If the user is currently using an IME, confirm the IME input, |
| 2537 // and then insert the text from the service, the same as TextEdit and Safari. | 2565 // and then insert the text from the service, the same as TextEdit and Safari. |
| 2538 [self confirmComposition]; | 2566 [self confirmComposition]; |
| 2539 [self insertText:string]; | 2567 [self insertText:string]; |
| 2540 return YES; | 2568 return YES; |
| 2541 } | 2569 } |
| 2542 | 2570 |
| 2543 @end | 2571 @end |
| OLD | NEW |