Index: webkit/glue/webplugin_impl.cc |
=================================================================== |
--- webkit/glue/webplugin_impl.cc (revision 2783) |
+++ webkit/glue/webplugin_impl.cc (working copy) |
@@ -17,6 +17,7 @@ |
#include "FrameTree.h" |
#include "FrameView.h" |
#include "GraphicsContext.h" |
+#include "HTMLNames.h" |
#include "HTMLPluginElement.h" |
#include "IntRect.h" |
#include "KURL.h" |
@@ -46,6 +47,7 @@ |
#include "webkit/glue/webplugin_impl.h" |
#include "webkit/glue/plugins/plugin_host.h" |
#include "webkit/glue/plugins/plugin_instance.h" |
+#include "webkit/glue/stacking_order_iterator.h" |
#include "webkit/glue/webview_impl.h" |
#include "googleurl/src/gurl.h" |
#include "webkit/port/platform/cursor.h" |
@@ -179,6 +181,11 @@ |
hide(); |
} |
+void WebPluginContainer::windowCutoutRects(WTF::Vector<WebCore::IntRect>* |
+ cutouts) const { |
+ impl_->windowCutoutRects(cutouts); |
+} |
+ |
void WebPluginContainer::didReceiveResponse( |
const WebCore::ResourceResponse& response) { |
@@ -530,6 +537,36 @@ |
return clip_rect; |
} |
+void WebPluginImpl::windowCutoutRects( |
+ WTF::Vector<WebCore::IntRect>* cutouts) const { |
+ WebCore::RenderObject* plugin_node = element_->renderer(); |
+ ASSERT(plugin_node); |
+ |
+ // Find all iframes that stack higher than this plugin. |
+ bool higher = false; |
+ StackingOrderIterator iterator; |
+ WebCore::RenderLayer* root = element_->document()->renderer()-> |
+ enclosingLayer(); |
+ iterator.Reset(root); |
+ |
+ while (WebCore::RenderObject* ro = iterator.Next()) { |
+ if (ro == plugin_node) { |
+ // All nodes after this one are higher than plugin. |
+ higher = true; |
+ } else if (higher) { |
+ // Is this a visible iframe? |
+ WebCore::Node* n = ro->node(); |
+ if (n && n->hasTagName(WebCore::HTMLNames::iframeTag)) { |
+ if (!ro->style() || ro->style()->visibility() == WebCore::VISIBLE) { |
+ int x, y; |
+ ro->absolutePosition(x, y); |
+ cutouts->append(WebCore::IntRect(x, y, ro->width(), ro->height())); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
void WebPluginImpl::geometryChanged() const { |
if (!widget_) |
return; |
@@ -538,7 +575,7 @@ |
// our parent view was scrolled. |
const_cast<WebPluginImpl*>(this)->widget_->setFrameGeometry( |
widget_->frameGeometry()); |
- } |
+} |
void WebPluginImpl::setFrameGeometry(const WebCore::IntRect& rect) { |
// Compute a new position and clip rect for ourselves relative to the |
@@ -564,7 +601,8 @@ |
WebCore::IntRect window_rect; |
WebCore::IntRect clip_rect; |
- CalculateBounds(rect, &window_rect, &clip_rect); |
+ std::vector<gfx::Rect> cutout_rects; |
+ CalculateBounds(rect, &window_rect, &clip_rect, &cutout_rects); |
if (window_ && received_first_paint_notification_) { |
// Let the WebViewDelegate know that the plugin window needs to be moved, |
@@ -573,12 +611,14 @@ |
move.window = window_; |
move.window_rect = gfx::Rect(window_rect); |
move.clip_rect = gfx::Rect(clip_rect); |
+ move.cutout_rects = cutout_rects; |
move.visible = visible_; |
+ |
webview->delegate()->DidMove(webview, move); |
} |
delegate_->UpdateGeometry( |
- gfx::Rect(window_rect), gfx::Rect(clip_rect), |
+ gfx::Rect(window_rect), gfx::Rect(clip_rect), cutout_rects, |
received_first_paint_notification_? visible_ : false); |
// delegate_ can go away as a result of above call, so check it first. |
@@ -613,11 +653,13 @@ |
if (!windowless_) { |
WebCore::IntRect window_rect; |
WebCore::IntRect clip_rect; |
+ std::vector<gfx::Rect> cutout_rects; |
- CalculateBounds(widget_->frameGeometry(), &window_rect, &clip_rect); |
+ CalculateBounds(widget_->frameGeometry(), &window_rect, &clip_rect, |
+ &cutout_rects); |
delegate_->UpdateGeometry(gfx::Rect(window_rect), gfx::Rect(clip_rect), |
- visible_); |
+ cutout_rects, visible_); |
delegate_->FlushGeometryUpdates(); |
} |
} |
@@ -997,7 +1039,8 @@ |
void WebPluginImpl::CalculateBounds(const WebCore::IntRect& frame_rect, |
WebCore::IntRect* window_rect, |
- WebCore::IntRect* clip_rect) { |
+ WebCore::IntRect* clip_rect, |
+ std::vector<gfx::Rect>* cutout_rects) { |
DCHECK(parent()->isFrameView()); |
WebCore::FrameView* view = static_cast<WebCore::FrameView*>(parent()); |
@@ -1007,6 +1050,16 @@ |
// Calculate a clip-rect so that we don't overlap the scrollbars, etc. |
*clip_rect = widget_->windowClipRect(); |
clip_rect->move(-window_rect->x(), -window_rect->y()); |
+ |
+ cutout_rects->clear(); |
+ WTF::Vector<WebCore::IntRect> rects; |
+ widget_->windowCutoutRects(&rects); |
+ // Convert to gfx::Rect and subtract out the plugin position. |
+ for (size_t i = 0; i < rects.size(); i++) { |
+ gfx::Rect r(rects[i]); |
+ r.Offset(-frame_rect.x(), -frame_rect.y()); |
+ cutout_rects->push_back(r); |
+ } |
} |
void WebPluginImpl::HandleURLRequest(const char *method, |