summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm23
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h3
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.h2
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm44
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.h1
-rw-r--r--chrome/common/plugin_messages.h27
-rw-r--r--chrome/common/plugin_messages_internal.h12
-rw-r--r--chrome/common/render_messages_internal.h5
-rw-r--r--chrome/plugin/webplugin_delegate_stub.cc25
-rw-r--r--chrome/plugin/webplugin_delegate_stub.h5
-rw-r--r--chrome/renderer/render_view.cc25
-rw-r--r--chrome/renderer/render_view.h5
-rw-r--r--chrome/renderer/render_widget.h2
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc38
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h2
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h40
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm122
17 files changed, 288 insertions, 93 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index ae59e2f..d7058e9 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -1701,6 +1701,12 @@ willPositionSheet:(NSWindow*)sheet
if (statusBubble_) {
statusBubble_->UpdateSizeAndPosition();
}
+
+ // Let the selected RenderWidgetHostView know, so that it can tell plugins.
+ if (TabContents* contents = browser_->GetSelectedTabContents()) {
+ if (RenderWidgetHostView* rwhv = contents->render_widget_host_view())
+ rwhv->WindowFrameChanged();
+ }
}
// Handle the openLearnMoreAboutCrashLink: action from SadTabController when
@@ -1738,6 +1744,12 @@ willPositionSheet:(NSWindow*)sheet
(windowTopGrowth_ > 0 && NSMinY(windowFrame) != NSMinY(workarea)) ||
(windowBottomGrowth_ > 0 && NSMaxY(windowFrame) != NSMaxY(workarea)))
[self resetWindowGrowthState];
+
+ // Let the selected RenderWidgetHostView know, so that it can tell plugins.
+ if (TabContents* contents = browser_->GetSelectedTabContents()) {
+ if (RenderWidgetHostView* rwhv = contents->render_widget_host_view())
+ rwhv->WindowFrameChanged();
+ }
}
// Delegate method called when window will be resized; not called for
@@ -2114,10 +2126,21 @@ willPositionSheet:(NSWindow*)sheet
width:(CGFloat)width {
NSView* tabContentView = [self tabContentArea];
NSRect tabContentFrame = [tabContentView frame];
+
+ bool contentShifted = NSMaxY(tabContentFrame) != maxY;
+
tabContentFrame.origin.y = minY;
tabContentFrame.size.height = maxY - minY;
tabContentFrame.size.width = width;
[tabContentView setFrame:tabContentFrame];
+
+ // If the relayout shifts the content area up or down, let the renderer know.
+ if (contentShifted) {
+ if (TabContents* contents = browser_->GetSelectedTabContents()) {
+ if (RenderWidgetHostView* rwhv = contents->render_widget_host_view())
+ rwhv->WindowFrameChanged();
+ }
+ }
}
- (BOOL)shouldShowBookmarkBar {
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h
index ccb1b31..f761053 100644
--- a/chrome/browser/renderer_host/render_widget_host_view.h
+++ b/chrome/browser/renderer_host/render_widget_host_view.h
@@ -171,6 +171,9 @@ class RenderWidgetHostView {
// WasHidden/DidBecomeSelected.
virtual void SetWindowVisibility(bool visible) = 0;
+ // Informs the view that its containing window's frame changed.
+ virtual void WindowFrameChanged() = 0;
+
// Methods associated with GPU plugin instances
virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle() = 0;
virtual void DestroyFakePluginWindowHandle(
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h
index c9834bf..c707205 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h
@@ -46,6 +46,7 @@ class RWHVMEditCommandHelper;
scoped_nsobject<NSString> toolTip_;
scoped_nsobject<NSEvent> lastKeyPressedEvent_;
+ NSWindow* lastWindow_; // weak
}
- (void)setCanBeKeyView:(BOOL)can;
@@ -112,6 +113,7 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
virtual gfx::Rect GetRootWindowRect();
virtual void SetActive(bool active);
virtual void SetWindowVisibility(bool visible);
+ virtual void WindowFrameChanged();
virtual void SetBackground(const SkBitmap& background);
// Methods associated with GPU plugin instances
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index db78a46..c804892 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -582,13 +582,20 @@ gfx::Rect RenderWidgetHostViewMac::GetWindowRect() {
// TODO(shess): In case of !window, the view has been removed from
// the view hierarchy because the tab isn't main. Could retrieve
// the information from the main tab for our window.
- if (!cocoa_view_ || ![cocoa_view_ window]) {
+ NSWindow* enclosing_window = [cocoa_view_ window];
+ if (!cocoa_view_ || !enclosing_window) {
return gfx::Rect();
}
+ // During dragging of a torn-off tab, [cocoa_view_ window] is a floating panel
+ // attached to the actual browser window that the tab is visually part of; we
+ // want the bounds of the browser window rather than the panel.
+ if ([enclosing_window parentWindow])
+ enclosing_window = [enclosing_window parentWindow];
+
NSRect bounds = [cocoa_view_ bounds];
bounds = [cocoa_view_ convertRect:bounds toView:nil];
- bounds.origin = [[cocoa_view_ window] convertBaseToScreen:bounds.origin];
+ bounds.origin = [enclosing_window convertBaseToScreen:bounds.origin];
return NSRectToRect(bounds, [[cocoa_view_ window] screen]);
}
@@ -596,12 +603,19 @@ gfx::Rect RenderWidgetHostViewMac::GetRootWindowRect() {
// TODO(shess): In case of !window, the view has been removed from
// the view hierarchy because the tab isn't main. Could retrieve
// the information from the main tab for our window.
- if (!cocoa_view_ || ![cocoa_view_ window]) {
+ NSWindow* enclosing_window = [cocoa_view_ window];
+ if (!enclosing_window) {
return gfx::Rect();
}
- NSRect bounds = [[cocoa_view_ window] frame];
- return NSRectToRect(bounds, [[cocoa_view_ window] screen]);
+ // During dragging of a torn-off tab, [cocoa_view_ window] is a floating panel
+ // attached to the actual browser window that the tab is visually part of; we
+ // want the bounds of the browser window rather than the panel.
+ if ([enclosing_window parentWindow])
+ enclosing_window = [enclosing_window parentWindow];
+
+ NSRect bounds = [enclosing_window frame];
+ return NSRectToRect(bounds, [enclosing_window screen]);
}
void RenderWidgetHostViewMac::SetActive(bool active) {
@@ -616,6 +630,14 @@ void RenderWidgetHostViewMac::SetWindowVisibility(bool visible) {
}
}
+void RenderWidgetHostViewMac::WindowFrameChanged() {
+ if (render_widget_host_) {
+ render_widget_host_->Send(new ViewMsg_WindowFrameChanged(
+ render_widget_host_->routing_id(), GetRootWindowRect(),
+ GetWindowRect()));
+ }
+}
+
void RenderWidgetHostViewMac::SetBackground(const SkBitmap& background) {
RenderWidgetHostView::SetBackground(background);
if (render_widget_host_)
@@ -1518,4 +1540,16 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
renderWidgetHostView_->im_composing_ = false;
}
+- (void)viewDidMoveToWindow {
+ // If we move into a new window, refresh the frame information. We don't need
+ // to do it if it was the same window as it used to be in, since that case
+ // is covered by DidBecomeSelected.
+ NSWindow* newWindow = [self window];
+ // Pointer comparison only, since we don't know if lastWindow_ is still valid.
+ if (newWindow && (newWindow != lastWindow_)) {
+ lastWindow_ = newWindow;
+ renderWidgetHostView_->WindowFrameChanged();
+ }
+}
+
@end
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h
index fde21b5..0521de9 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.h
+++ b/chrome/browser/renderer_host/test/test_render_view_host.h
@@ -78,6 +78,7 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual gfx::Rect GetRootWindowRect();
virtual void SetActive(bool active);
virtual void SetWindowVisibility(bool visible) {}
+ virtual void WindowFrameChanged() {}
virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle();
virtual void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
virtual void GPUPluginSetIOSurface(gfx::PluginWindowHandle window,
diff --git a/chrome/common/plugin_messages.h b/chrome/common/plugin_messages.h
index 74de33f..b195f5c 100644
--- a/chrome/common/plugin_messages.h
+++ b/chrome/common/plugin_messages.h
@@ -39,6 +39,11 @@ struct PluginMsg_Init_Params {
std::vector<std::string> arg_values;
bool load_manually;
int host_render_view_routing_id;
+#if defined(OS_MACOSX)
+ gfx::Rect containing_window_frame;
+ gfx::Rect containing_content_frame;
+ bool containing_window_has_focus;
+#endif
};
struct PluginHostMsg_URLRequest_Params {
@@ -119,6 +124,11 @@ struct ParamTraits<PluginMsg_Init_Params> {
WriteParam(m, p.arg_values);
WriteParam(m, p.load_manually);
WriteParam(m, p.host_render_view_routing_id);
+#if defined(OS_MACOSX)
+ WriteParam(m, p.containing_window_frame);
+ WriteParam(m, p.containing_content_frame);
+ WriteParam(m, p.containing_window_has_focus);
+#endif
}
static bool Read(const Message* m, void** iter, param_type* p) {
return ReadParam(m, iter, &p->containing_window) &&
@@ -127,7 +137,14 @@ struct ParamTraits<PluginMsg_Init_Params> {
ReadParam(m, iter, &p->arg_names) &&
ReadParam(m, iter, &p->arg_values) &&
ReadParam(m, iter, &p->load_manually) &&
- ReadParam(m, iter, &p->host_render_view_routing_id);
+ ReadParam(m, iter, &p->host_render_view_routing_id)
+#if defined(OS_MACOSX)
+ &&
+ ReadParam(m, iter, &p->containing_window_frame) &&
+ ReadParam(m, iter, &p->containing_content_frame) &&
+ ReadParam(m, iter, &p->containing_window_has_focus)
+#endif
+ ;
}
static void Log(const param_type& p, std::wstring* l) {
l->append(L"(");
@@ -144,6 +161,14 @@ struct ParamTraits<PluginMsg_Init_Params> {
LogParam(p.load_manually, l);
l->append(L", ");
LogParam(p.host_render_view_routing_id, l);
+#if defined(OS_MACOSX)
+ l->append(L", ");
+ LogParam(p.containing_window_frame, l);
+ l->append(L", ");
+ LogParam(p.containing_content_frame, l);
+ l->append(L", ");
+ LogParam(p.containing_window_has_focus, l);
+#endif
l->append(L")");
}
};
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index 05e532b..b5908a8 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -233,8 +233,16 @@ IPC_BEGIN_MESSAGES(Plugin)
IPC_MESSAGE_ROUTED1(PluginMsg_SetWindowFocus,
bool /* has_focus */)
- IPC_MESSAGE_ROUTED1(PluginMsg_SetContainerVisibility,
- bool /* is_visible */)
+ IPC_MESSAGE_ROUTED0(PluginMsg_ContainerHidden)
+
+ IPC_MESSAGE_ROUTED3(PluginMsg_ContainerShown,
+ gfx::Rect /* window_frame */,
+ gfx::Rect /* view_frame */,
+ bool /* has_focus */)
+
+ IPC_MESSAGE_ROUTED2(PluginMsg_WindowFrameChanged,
+ gfx::Rect /* window_frame */,
+ gfx::Rect /* view_frame */)
#endif
IPC_SYNC_MESSAGE_ROUTED2_0(PluginMsg_WillSendRequest,
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index bd23f31..69d7bb2 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -745,6 +745,11 @@ IPC_BEGIN_MESSAGES(View)
// Let the RenderView know its window has changed visibility.
IPC_MESSAGE_ROUTED1(ViewMsg_SetWindowVisibility,
bool /* visibile */)
+
+ // Let the RenderView know its window's frame has changed.
+ IPC_MESSAGE_ROUTED2(ViewMsg_WindowFrameChanged,
+ gfx::Rect /* window frame */,
+ gfx::Rect /* content view frame */)
#endif
// Response message to ViewHostMsg_CreateShared/DedicatedWorker.
diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc
index 80d6e62..a24f7fa 100644
--- a/chrome/plugin/webplugin_delegate_stub.cc
+++ b/chrome/plugin/webplugin_delegate_stub.cc
@@ -123,8 +123,9 @@ void WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) {
OnSendJavaScriptStream)
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(PluginMsg_SetWindowFocus, OnSetWindowFocus)
- IPC_MESSAGE_HANDLER(PluginMsg_SetContainerVisibility,
- OnSetContainerVisibility)
+ IPC_MESSAGE_HANDLER(PluginMsg_ContainerHidden, OnContainerHidden)
+ IPC_MESSAGE_HANDLER(PluginMsg_ContainerShown, OnContainerShown)
+ IPC_MESSAGE_HANDLER(PluginMsg_WindowFrameChanged, OnWindowFrameChanged)
#endif
IPC_MESSAGE_HANDLER(PluginMsg_DidReceiveManualResponse,
OnDidReceiveManualResponse)
@@ -195,6 +196,9 @@ void WebPluginDelegateStub::OnInit(const PluginMsg_Init_Params& params,
params.load_manually);
#if defined(OS_MACOSX)
delegate_->SetFocusNotifier(FocusNotifier);
+ delegate_->WindowFrameChanged(params.containing_window_frame,
+ params.containing_content_frame);
+ delegate_->SetWindowHasFocus(params.containing_window_has_focus);
#endif
}
}
@@ -345,8 +349,21 @@ void WebPluginDelegateStub::OnSetWindowFocus(bool has_focus) {
delegate_->SetWindowHasFocus(has_focus);
}
-void WebPluginDelegateStub::OnSetContainerVisibility(bool is_visible) {
- delegate_->SetContainerVisibility(is_visible);
+void WebPluginDelegateStub::OnContainerHidden() {
+ delegate_->SetContainerVisibility(false);
+}
+
+void WebPluginDelegateStub::OnContainerShown(gfx::Rect window_frame,
+ gfx::Rect view_frame,
+ bool has_focus) {
+ delegate_->WindowFrameChanged(window_frame, view_frame);
+ delegate_->SetContainerVisibility(true);
+ delegate_->SetWindowHasFocus(has_focus);
+}
+
+void WebPluginDelegateStub::OnWindowFrameChanged(gfx::Rect window_frame,
+ gfx::Rect view_frame) {
+ delegate_->WindowFrameChanged(window_frame, view_frame);
}
#endif // OS_MACOSX
diff --git a/chrome/plugin/webplugin_delegate_stub.h b/chrome/plugin/webplugin_delegate_stub.h
index 5a04758..efe93c10 100644
--- a/chrome/plugin/webplugin_delegate_stub.h
+++ b/chrome/plugin/webplugin_delegate_stub.h
@@ -80,7 +80,10 @@ class WebPluginDelegateStub : public IPC::Channel::Listener,
#if defined(OS_MACOSX)
void OnSetWindowFocus(bool has_focus);
- void OnSetContainerVisibility(bool is_visible);
+ void OnContainerHidden();
+ void OnContainerShown(gfx::Rect window_frame, gfx::Rect view_frame,
+ bool has_focus);
+ void OnWindowFrameChanged(gfx::Rect window_frame, gfx::Rect view_frame);
#endif
void OnDidReceiveManualResponse(
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index aa433bd..08cb4e0 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -579,6 +579,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(ViewMsg_SetWindowVisibility, OnSetWindowVisibility)
+ IPC_MESSAGE_HANDLER(ViewMsg_WindowFrameChanged, OnWindowFrameChanged)
#endif
IPC_MESSAGE_HANDLER(ViewMsg_SetEditCommandsForNextKeyEvent,
OnSetEditCommandsForNextKeyEvent)
@@ -3812,6 +3813,16 @@ void RenderView::OnSetWindowVisibility(bool visible) {
(*plugin_it)->SetContainerVisibility(visible);
}
}
+
+void RenderView::OnWindowFrameChanged(gfx::Rect window_frame,
+ gfx::Rect view_frame) {
+ // Inform plugins that their window's frame has changed.
+ std::set<WebPluginDelegateProxy*>::iterator plugin_it;
+ for (plugin_it = plugin_delegates_.begin();
+ plugin_it != plugin_delegates_.end(); ++plugin_it) {
+ (*plugin_it)->WindowFrameChanged(window_frame, view_frame);
+ }
+}
#endif // OS_MACOSX
void RenderView::SendExtensionRequest(const std::string& name,
@@ -4335,6 +4346,20 @@ void RenderView::OnWasRestored(bool needs_repainting) {
(*plugin_it)->SetContainerVisibility(true);
}
}
+
+void RenderView::OnSetFocus(bool enable) {
+ RenderWidget::OnSetFocus(enable);
+
+ // RenderWidget's call to setFocus can cause the underlying webview's
+ // activation state to change just like a call to setIsActive.
+ if (enable && webview() && webview()->isActive()) {
+ std::set<WebPluginDelegateProxy*>::iterator plugin_it;
+ for (plugin_it = plugin_delegates_.begin();
+ plugin_it != plugin_delegates_.end(); ++plugin_it) {
+ (*plugin_it)->SetWindowFocus(true);
+ }
+ }
+}
#endif // OS_MACOSX
void RenderView::EnsureDocumentTag() {
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 7245df1..0066bf3 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -484,6 +484,7 @@ class RenderView : public RenderWidget,
virtual void DidPaint();
virtual void DidHandleKeyEvent();
#if OS_MACOSX
+ virtual void OnSetFocus(bool enable);
virtual void OnWasHidden();
virtual void OnWasRestored(bool needs_repainting);
#endif
@@ -725,6 +726,10 @@ class RenderView : public RenderWidget,
#if defined(OS_MACOSX)
void OnSetWindowVisibility(bool visible);
+
+ // Notifies the view that window frame has been updated. window_frame and
+ // view_frame are in screen coordinates.
+ void OnWindowFrameChanged(gfx::Rect window_frame, gfx::Rect view_frame);
#endif
// Execute custom context menu action.
diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h
index 86f2a17..27086a4 100644
--- a/chrome/renderer/render_widget.h
+++ b/chrome/renderer/render_widget.h
@@ -146,7 +146,7 @@ class RenderWidget : public IPC::Channel::Listener,
void OnRequestMoveAck();
void OnHandleInputEvent(const IPC::Message& message);
void OnMouseCaptureLost();
- void OnSetFocus(bool enable);
+ virtual void OnSetFocus(bool enable);
void OnImeSetInputMode(bool is_active);
void OnImeSetComposition(WebKit::WebCompositionCommand command,
int cursor_position,
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 2c87077..f4063e4 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -283,6 +283,18 @@ bool WebPluginDelegateProxy::Initialize(const GURL& url,
params.arg_names.push_back("wmode");
params.arg_values.push_back("opaque");
}
+
+ params.containing_window_frame = render_view_->rootWindowRect();
+ // If the renderer isn't currently visible, don't bother asking for anything
+ // else; the plugin will get real data when its renderer becomes visible.
+ if (params.containing_window_frame.IsEmpty()) {
+ params.containing_content_frame = gfx::Rect();
+ params.containing_window_has_focus = false;
+ } else {
+ params.containing_content_frame = render_view_->windowRect();
+ WebKit::WebView* webview = render_view_->webview();
+ params.containing_window_has_focus = webview && webview->isActive();
+ }
#endif
params.load_manually = load_manually;
@@ -874,16 +886,32 @@ void WebPluginDelegateProxy::SetWindowFocus(bool window_has_focus) {
}
void WebPluginDelegateProxy::SetContainerVisibility(bool is_visible) {
- // TODO(stuartmorgan): Split this into two messages, and send location and
- // focus information with the "became visible" version since the plugins in a
- // hidden tab will not have been getting live updates.
- IPC::Message* msg = new PluginMsg_SetContainerVisibility(instance_id_,
- is_visible);
+ IPC::Message* msg;
+ if (is_visible) {
+ gfx::Rect window_frame = render_view_->rootWindowRect();
+ gfx::Rect view_frame = render_view_->windowRect();
+ WebKit::WebView* webview = render_view_->webview();
+ msg = new PluginMsg_ContainerShown(instance_id_, window_frame, view_frame,
+ webview && webview->isActive());
+ } else {
+ msg = new PluginMsg_ContainerHidden(instance_id_);
+ }
// Make sure visibility events are delivered in the right order relative to
// sync messages they might interact with (Paint, HandleEvent, etc.).
msg->set_unblock(true);
Send(msg);
}
+
+void WebPluginDelegateProxy::WindowFrameChanged(gfx::Rect window_frame,
+ gfx::Rect view_frame) {
+ IPC::Message* msg = new PluginMsg_WindowFrameChanged(instance_id_,
+ window_frame,
+ view_frame);
+ // Make sure frame events are delivered in the right order relative to
+ // sync messages they might interact with (e.g., HandleEvent).
+ msg->set_unblock(true);
+ Send(msg);
+}
#endif // OS_MACOSX
void WebPluginDelegateProxy::OnSetWindow(gfx::PluginWindowHandle window) {
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index 1afbacd9..98eb1ee 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -75,6 +75,8 @@ class WebPluginDelegateProxy
virtual void SetWindowFocus(bool window_has_focus);
// Inform the plugin that its container (window/tab) has changed visibility.
virtual void SetContainerVisibility(bool is_visible);
+ // Inform the plugin that its enclosing window's frame has changed.
+ virtual void WindowFrameChanged(gfx::Rect window_frame, gfx::Rect view_frame);
#endif
// IPC::Channel::Listener implementation:
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index 32dca05..7978964 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -134,6 +134,9 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
bool GetWindowHasFocus() const { return containing_window_has_focus_; }
// Informs the plugin that its tab or window has been hidden or shown.
void SetContainerVisibility(bool is_visible);
+ // Informs the plugin that its containing window's frame has changed.
+ // Frames are in screen coordinates.
+ void WindowFrameChanged(gfx::Rect window_frame, gfx::Rect view_frame);
// Informs the delegate that the plugin set a Carbon ThemeCursor.
void SetThemeCursor(ThemeCursor cursor);
// Informs the delegate that the plugin set a Carbon Cursor.
@@ -336,45 +339,40 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
LPWSTR class_name, LPDWORD class_size, PFILETIME last_write_time);
#elif defined(OS_MACOSX)
-
- // Updates the internal information about where the plugin is located on
- // the screen.
- void UpdatePluginLocation(const WebKit::WebMouseEvent& event);
+ // Sets window_rect_ to |rect|
+ void SetPluginRect(const gfx::Rect& rect);
+ // Sets content_area_origin to |origin|
+ void SetContentAreaOrigin(const gfx::Point& origin);
+ // Updates everything that depends on the plugin's absolute screen location.
+ void PluginScreenLocationChanged();
#ifndef NP_NO_CARBON
- // Moves our dummy window to the given offset relative to the last known
- // location of the real renderer window's content view.
- // If new_width or new_height is non-zero, the window size (content region)
- // will be updated accordingly; if they are zero, the existing size will be
- // preserved.
- void UpdateDummyWindowBoundsWithOffset(int x_offset, int y_offset,
- int new_width, int new_height);
+ // Moves our dummy window to match the current screen location of the plugin.
+ void UpdateDummyWindowBounds(const gfx::Point& plugin_origin);
// Adjusts the idle event rate for a Carbon plugin based on its current
// visibility.
void UpdateIdleEventRate();
#endif // !NP_NO_CARBON
- // The most recently seen offset between global and browser-window-local
- // coordinates. We use this to keep the placeholder Carbon WindowRef's origin
- // in sync with the actual browser window, without having to pass that
- // geometry over IPC.
- int last_window_x_offset_;
- int last_window_y_offset_;
+ // Note: the following coordinates are all in screen coordinates, relative an
+ // upper-left (0,0).
+ // The frame of the window containing this plugin.
+ gfx::Rect containing_window_frame_;
+ // The upper-left corner of the web content area.
+ gfx::Point content_area_origin_;
- // Last mouse position within the plugin's rect (used for null events).
- int last_mouse_x_;
- int last_mouse_y_;
// True if the plugin thinks it has keyboard focus
bool have_focus_;
// A function to call when we want to accept keyboard focus
void (*focus_notifier_)(WebPluginDelegateImpl* notifier);
bool containing_window_has_focus_;
+ bool initial_window_focus_;
bool container_is_visible_;
bool have_called_set_window_;
gfx::Rect cached_clip_rect_;
-#endif
+#endif // OS_MACOSX
// Called by the message filter hook when the plugin enters a modal loop.
void OnModalLoopEntered();
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
index a7d93f9..2955ec5 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
+++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
@@ -176,13 +176,10 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
instance_(instance),
parent_(containing_view),
quirks_(0),
- last_window_x_offset_(0),
- last_window_y_offset_(0),
- last_mouse_x_(0),
- last_mouse_y_(0),
have_focus_(false),
focus_notifier_(NULL),
containing_window_has_focus_(false),
+ initial_window_focus_(false),
container_is_visible_(false),
have_called_set_window_(false),
handle_event_depth_(0),
@@ -354,7 +351,7 @@ void WebPluginDelegateImpl::WindowlessUpdateGeometry(
bool new_clip_is_empty = clip_rect_.IsEmpty();
// Only resend to the instance if the geometry has changed (see note in
- // WindowlesSetWindow for why we only care about the clip rect switching
+ // WindowlessSetWindow for why we only care about the clip rect switching
// empty state).
if (window_rect == window_rect_ && old_clip_was_empty == new_clip_is_empty)
return;
@@ -367,7 +364,7 @@ void WebPluginDelegateImpl::WindowlessUpdateGeometry(
}
#endif
- window_rect_ = window_rect;
+ SetPluginRect(window_rect);
WindowlessSetWindow(true);
}
@@ -459,19 +456,12 @@ void WebPluginDelegateImpl::WindowlessSetWindow(bool force_set_window) {
window_.clipRect.bottom += window_.height;
}
- UpdateDummyWindowBoundsWithOffset(window_rect_.x(), window_rect_.y(),
- window_rect_.width(),
- window_rect_.height());
-
NPError err = instance()->NPP_SetWindow(&window_);
- // Plugins expect to get an initial window focus call if they are in an active
- // window when they get their first SetWindow call.
+ // Send an appropriate window focus event after the first SetWindow.
if (!have_called_set_window_) {
- // TODO(stuartmorgan): We need real window information about the initial
- // window state; for now, assume window focus.
- SetWindowHasFocus(true);
have_called_set_window_ = true;
+ SetWindowHasFocus(initial_window_focus_);
}
DCHECK(err == NPERR_NO_ERROR);
@@ -525,6 +515,13 @@ void WebPluginDelegateImpl::SetFocus() {
}
void WebPluginDelegateImpl::SetWindowHasFocus(bool has_focus) {
+ // If we get a window focus event before calling SetWindow, just remember the
+ // states (WindowlessSetWindow will then send it on the first call).
+ if (!have_called_set_window_) {
+ initial_window_focus_ = has_focus;
+ return;
+ }
+
if (has_focus == containing_window_has_focus_)
return;
containing_window_has_focus_ = has_focus;
@@ -587,6 +584,12 @@ void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) {
}
}
+void WebPluginDelegateImpl::WindowFrameChanged(gfx::Rect window_frame,
+ gfx::Rect view_frame) {
+ containing_window_frame_ = window_frame;
+ SetContentAreaOrigin(gfx::Point(view_frame.x(), view_frame.y()));
+}
+
void WebPluginDelegateImpl::SetThemeCursor(ThemeCursor cursor) {
current_windowless_cursor_.InitFromThemeCursor(cursor);
}
@@ -599,48 +602,52 @@ void WebPluginDelegateImpl::SetNSCursor(NSCursor* cursor) {
current_windowless_cursor_.InitFromNSCursor(cursor);
}
-void WebPluginDelegateImpl::UpdatePluginLocation(const WebMouseEvent& event) {
- instance()->set_plugin_origin(gfx::Point(event.globalX - event.x,
- event.globalY - event.y));
+void WebPluginDelegateImpl::SetPluginRect(const gfx::Rect& rect) {
+ window_rect_ = rect;
+ PluginScreenLocationChanged();
+}
- if (instance()->event_model() == NPEventModelCarbon) {
- last_window_x_offset_ = event.globalX - event.windowX;
- last_window_y_offset_ = event.globalY - event.windowY;
- last_mouse_x_ = event.globalX;
- last_mouse_y_ = event.globalY;
+void WebPluginDelegateImpl::SetContentAreaOrigin(const gfx::Point& origin) {
+ content_area_origin_ = origin;
+ PluginScreenLocationChanged();
+}
+
+void WebPluginDelegateImpl::PluginScreenLocationChanged() {
+ gfx::Point plugin_origin(content_area_origin_.x() + window_rect_.x(),
+ content_area_origin_.y() + window_rect_.y());
+ instance()->set_plugin_origin(plugin_origin);
#ifndef NP_NO_CARBON
- UpdateDummyWindowBoundsWithOffset(event.windowX - event.x,
- event.windowY - event.y, 0, 0);
+ if (instance()->event_model() == NPEventModelCarbon) {
+ UpdateDummyWindowBounds(plugin_origin);
}
#endif
}
#ifndef NP_NO_CARBON
-void WebPluginDelegateImpl::UpdateDummyWindowBoundsWithOffset(
- int x_offset, int y_offset, int new_width, int new_height) {
- if (instance()->event_model() == NPEventModelCocoa)
- return;
-
- int target_x = last_window_x_offset_ + x_offset;
- int target_y = last_window_y_offset_ + y_offset;
+void WebPluginDelegateImpl::UpdateDummyWindowBounds(
+ const gfx::Point& plugin_origin) {
WindowRef window = reinterpret_cast<WindowRef>(cg_context_.window);
- Rect window_bounds;
- GetWindowBounds(window, kWindowContentRgn, &window_bounds);
- int old_width = window_bounds.right - window_bounds.left;
- int old_height = window_bounds.bottom - window_bounds.top;
- if (window_bounds.left != target_x ||
- window_bounds.top != target_y ||
- (new_width && new_width != old_width) ||
- (new_height && new_height != old_height)) {
- int height = new_height ? new_height : old_height;
- int width = new_width ? new_width : old_width;
- window_bounds.left = target_x;
- window_bounds.top = target_y;
- window_bounds.right = window_bounds.left + width;
- window_bounds.bottom = window_bounds.top + height;
- SetWindowBounds(window, kWindowContentRgn, &window_bounds);
+ Rect current_bounds;
+ GetWindowBounds(window, kWindowContentRgn, &current_bounds);
+
+ Rect new_bounds;
+ // We never want to resize the window to 0x0, so if the plugin is 0x0 just
+ // move the window without resizing it.
+ if (window_rect_.width() > 0 && window_rect_.height() > 0) {
+ SetRect(&new_bounds, 0, 0, window_rect_.width(), window_rect_.height());
+ OffsetRect(&new_bounds, plugin_origin.x(), plugin_origin.y());
+ } else {
+ new_bounds = current_bounds;
+ OffsetRect(&new_bounds, plugin_origin.x() - current_bounds.left,
+ plugin_origin.y() - current_bounds.top);
}
+
+ if (new_bounds.left != current_bounds.left ||
+ new_bounds.top != current_bounds.top ||
+ new_bounds.right != current_bounds.right ||
+ new_bounds.bottom != current_bounds.bottom)
+ SetWindowBounds(window, kWindowContentRgn, &new_bounds);
}
void WebPluginDelegateImpl::UpdateIdleEventRate() {
@@ -932,12 +939,19 @@ bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event,
#endif
if (WebInputEventIsWebMouseEvent(event)) {
- // Make sure we update our plugin location tracking before we send the
- // event to the plugin, so that any coordinate conversion the plugin does
- // will work out.
+ // Check our plugin location before we send the event to the plugin, just
+ // in case we somehow missed a plugin frame change.
const WebMouseEvent* mouse_event =
static_cast<const WebMouseEvent*>(&event);
- UpdatePluginLocation(*mouse_event);
+ gfx::Point content_origin(
+ mouse_event->globalX - mouse_event->x - window_rect_.x(),
+ mouse_event->globalY - mouse_event->y - window_rect_.y());
+ if (content_origin.x() != content_area_origin_.x() ||
+ content_origin.y() != content_area_origin_.y()) {
+ DLOG(WARNING) << "Stale plugin location: " << content_area_origin_
+ << " instead of " << content_origin;
+ SetContentAreaOrigin(content_area_origin_);
+ }
current_windowless_cursor_.GetCursorInfo(cursor);
}
@@ -1057,8 +1071,10 @@ void WebPluginDelegateImpl::FireIdleEvent() {
np_event.modifiers = GetCurrentKeyModifiers();
if (!Button())
np_event.modifiers |= btnState;
- np_event.where.h = last_mouse_x_;
- np_event.where.v = last_mouse_y_;
+ HIPoint mouse_location;
+ HIGetMousePosition(kHICoordSpaceScreenPixel, NULL, &mouse_location);
+ np_event.where.h = mouse_location.x;
+ np_event.where.v = mouse_location.y;
instance()->NPP_HandleEvent(&np_event);
}