diff options
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); } |