diff options
author | stuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-08 15:52:13 +0000 |
---|---|---|
committer | stuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-08 15:52:13 +0000 |
commit | 1e6e3c99f8ca2ef9d8e86ddddec20dadc0fbf467 (patch) | |
tree | 95f198cfa03484708e1df0d75a909e4e99ad3134 /webkit/glue/plugins | |
parent | 0e4898dee7088bf0e0e775ededf342fad6fe9606 (diff) | |
download | chromium_src-1e6e3c99f8ca2ef9d8e86ddddec20dadc0fbf467.zip chromium_src-1e6e3c99f8ca2ef9d8e86ddddec20dadc0fbf467.tar.gz chromium_src-1e6e3c99f8ca2ef9d8e86ddddec20dadc0fbf467.tar.bz2 |
Send window frame information to Mac plugins via IPC
Sends any window frame and relevent content view location changes to the plugin process via IPC, so that the plugin process always knows where the plugin is rather than only knowing when the mouse is within the plugin area. This will be necessary for supporting NPN_ConvertPoint, and for supporting Java2 as currently implemented.
Related changes:
- Now that window information is being sent on init and un-hide, use that to get correct initial window focus information.
- Add a missing window focus change notification uncovered by the above.
- Use live mouse location for idle events, instead of a cached location, now that we have live plugin frame information.
- Refactor and simplify the logic for moving the plugin.
Note that containing_window_frame_ is currently unused, but will be shortly for NPN_ConvertPoint, and is so closely related to the added IPC that I added it now rather than having to immediately change the new messages and functions.
BUG=34046,31858,31543,29457
TEST=Mouse tracking in Carbon plugins should still work correctly, even across window moves, info/bookmark bar show/hides, etc. (Automated tests of location tracking will follow shortly with full NPN_ConvertPoint implementation.)
Review URL: http://codereview.chromium.org/573015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38361 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 40 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 122 |
2 files changed, 88 insertions, 74 deletions
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, ¤t_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); } |