diff options
Diffstat (limited to 'Source/WebCore/plugins/gtk/PluginViewGtk.cpp')
-rw-r--r-- | Source/WebCore/plugins/gtk/PluginViewGtk.cpp | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/Source/WebCore/plugins/gtk/PluginViewGtk.cpp b/Source/WebCore/plugins/gtk/PluginViewGtk.cpp index 5166151..75a51c5 100644 --- a/Source/WebCore/plugins/gtk/PluginViewGtk.cpp +++ b/Source/WebCore/plugins/gtk/PluginViewGtk.cpp @@ -322,12 +322,14 @@ void PluginView::initXEvent(XEvent* xEvent) xEvent->xany.serial = 0; // we are unaware of the last request processed by X Server xEvent->xany.send_event = false; - xEvent->xany.display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); - // NOTE: event->xany.window doesn't always correspond to the .window property of other XEvent's - // but does in the case of KeyPress, KeyRelease, ButtonPress, ButtonRelease, and MotionNotify - // events; thus, this is right: GtkWidget* widget = m_parentFrame->view()->hostWindow()->platformPageClient(); - xEvent->xany.window = widget ? GDK_WINDOW_XWINDOW(gtk_widget_get_window(widget)) : 0; + xEvent->xany.display = GDK_DISPLAY_XDISPLAY(gtk_widget_get_display(widget)); + + // Mozilla also sends None here for windowless plugins. See nsObjectFrame.cpp in the Mozilla sources. + // This method also sets up FocusIn and FocusOut events for windows plugins, but Mozilla doesn't + // even send these types of events to windowed plugins. In the future, it may be good to only + // send them to windowless plugins. + xEvent->xany.window = None; } static void setXButtonEventSpecificFields(XEvent* xEvent, MouseEvent* event, const IntPoint& postZoomPos, Frame* parentFrame) @@ -415,8 +417,14 @@ void PluginView::handleMouseEvent(MouseEvent* event) setXButtonEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame.get()); else if (event->type() == eventNames().mousemoveEvent) setXMotionEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame.get()); - else if (event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mouseoverEvent) + else if (event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mouseoverEvent) { setXCrossingEventSpecificFields(&xEvent, event, postZoomPos, m_parentFrame.get()); + + // This is a work-around for plugins which change the cursor. When that happens we + // get out of sync with GDK somehow. Resetting the cursor here seems to fix the issue. + if (event->type() == eventNames().mouseoutEvent) + gdk_window_set_cursor(gtk_widget_get_window(m_parentFrame->view()->hostWindow()->platformPageClient()), 0); + } else return; #endif @@ -513,16 +521,27 @@ void PluginView::setNPWindowIfNeeded() setCallingPlugin(false); PluginView::setCurrentPluginView(0); - if (m_isWindowed) { - GtkAllocation allocation = { m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height() }; - gtk_widget_size_allocate(platformPluginWidget(), &allocation); + if (!m_isWindowed) + return; + #if defined(XP_UNIX) - if (!m_needsXEmbed) { - gtk_xtbin_set_position(GTK_XTBIN(platformPluginWidget()), m_windowRect.x(), m_windowRect.y()); - gtk_xtbin_resize(platformPluginWidget(), m_windowRect.width(), m_windowRect.height()); - } + // GtkXtBin will call gtk_widget_size_allocate, so we don't need to do it here. + if (!m_needsXEmbed) { + gtk_xtbin_set_position(GTK_XTBIN(platformPluginWidget()), m_windowRect.x(), m_windowRect.y()); + gtk_xtbin_resize(platformPluginWidget(), m_windowRect.width(), m_windowRect.height()); + return; + } #endif + + GtkAllocation allocation = { m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height() }; + + // If the window has not been embedded yet (the plug added), we delay setting its allocation until + // that point. This fixes issues with some Java plugin instances not rendering immediately. + if (!m_plugAdded) { + m_delayedAllocation = allocation; + return; } + gtk_widget_size_allocate(platformPluginWidget(), &allocation); } void PluginView::setParentVisible(bool visible) @@ -636,15 +655,11 @@ bool PluginView::platformGetValue(NPNVariable variable, void* value, NPError* re #endif case NPNVnetscapeWindow: { + GdkWindow* gdkWindow = gtk_widget_get_window(m_parentFrame->view()->hostWindow()->platformPageClient()); #if defined(XP_UNIX) - void* w = reinterpret_cast<void*>(value); - GtkWidget* widget = m_parentFrame->view()->hostWindow()->platformPageClient(); - *((XID *)w) = GDK_WINDOW_XWINDOW(gtk_widget_get_window(widget)); -#endif -#ifdef GDK_WINDOWING_WIN32 - HGDIOBJ* w = reinterpret_cast<HGDIOBJ*>(value); - GtkWidget* widget = m_parentFrame->view()->hostWindow()->platformPageClient(); - *w = GDK_WINDOW_HWND(gtk_widget_get_window(widget)); + *static_cast<Window*>(value) = GDK_WINDOW_XWINDOW(gdk_window_get_toplevel(gdkWindow)); +#elif defined(GDK_WINDOWING_WIN32) + *static_cast<HGIOBJ*>(value) = GDK_WINDOW_HWND(gdkWindow); #endif *result = NPERR_NO_ERROR; return true; @@ -743,25 +758,23 @@ static void getVisualAndColormap(int depth, Visual** visual, Colormap* colormap) } #endif -static gboolean plugRemovedCallback(GtkSocket* socket, gpointer) +gboolean PluginView::plugRemovedCallback(GtkSocket* socket, PluginView* view) { + view->m_plugAdded = false; return TRUE; } -static void plugAddedCallback(GtkSocket* socket, PluginView* view) +void PluginView::plugAddedCallback(GtkSocket* socket, PluginView* view) { - if (!socket || !view) - return; + ASSERT(socket); + ASSERT(view); - // FIXME: Java Plugins do not seem to draw themselves properly the - // first time unless we do a size-allocate after they have done - // the plug operation on their side, which in general does not - // happen since we do size-allocates before setting the - // NPWindow. Apply this workaround until we figure out a better - // solution, if any. - IntRect rect = view->frameRect(); - GtkAllocation allocation = { rect.x(), rect.y(), rect.width(), rect.height() }; - gtk_widget_size_allocate(GTK_WIDGET(socket), &allocation); + view->m_plugAdded = true; + if (!view->m_delayedAllocation.isEmpty()) { + GtkAllocation allocation(view->m_delayedAllocation); + gtk_widget_size_allocate(GTK_WIDGET(socket), &allocation); + view->m_delayedAllocation.setSize(IntSize()); + } } bool PluginView::platformStart() @@ -790,10 +803,11 @@ bool PluginView::platformStart() if (!gtk_widget_get_parent(pageClient)) return false; + m_plugAdded = false; setPlatformWidget(gtk_socket_new()); gtk_container_add(GTK_CONTAINER(pageClient), platformPluginWidget()); - g_signal_connect(platformPluginWidget(), "plug-added", G_CALLBACK(plugAddedCallback), this); - g_signal_connect(platformPluginWidget(), "plug-removed", G_CALLBACK(plugRemovedCallback), NULL); + g_signal_connect(platformPluginWidget(), "plug-added", G_CALLBACK(PluginView::plugAddedCallback), this); + g_signal_connect(platformPluginWidget(), "plug-removed", G_CALLBACK(PluginView::plugRemovedCallback), this); } else setPlatformWidget(gtk_xtbin_new(pageClient, 0)); #else |