diff options
Diffstat (limited to 'webkit/glue/plugins/webplugin_delegate_impl_gtk.cc')
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_gtk.cc | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc index 741ba99..58207c6 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc @@ -21,6 +21,7 @@ #include <gtk/gtk.h> #include <gdk/gdkx.h> +#include "base/basictypes.h" #include "base/file_util.h" #include "base/message_loop.h" #include "base/process_util.h" @@ -241,13 +242,60 @@ void WebPluginDelegateImpl::WindowedUpdateGeometry( namespace { +// This is just a GtkSocket, with size_request overridden, so that we always +// control the size of the widget. +class GtkFixedSocket { + public: + // Create a new instance of our GTK widget object. + static GtkWidget* CreateNewWidget() { + return GTK_WIDGET(g_object_new(GetType(), NULL)); + } + + private: + // Create and register our custom container type with GTK. + static GType GetType() { + static GType type = 0; // We only want to register our type once. + if (!type) { + static const GTypeInfo info = { + sizeof(GtkSocketClass), + NULL, NULL, + static_cast<GClassInitFunc>(&ClassInit), + NULL, NULL, + sizeof(GtkSocket), // We are identical to a GtkSocket. + 0, NULL, + }; + type = g_type_register_static(GTK_TYPE_SOCKET, + "GtkFixedSocket", + &info, + static_cast<GTypeFlags>(0)); + } + return type; + } + + // Implementation of the class initializer. + static void ClassInit(gpointer klass, gpointer class_data_unusued) { + GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(klass); + widget_class->size_request = &HandleSizeRequest; + } + + // Report our allocation size during size requisition. This means we control + // the size, from calling gtk_widget_size_allocate in WindowedReposition(). + static void HandleSizeRequest(GtkWidget* widget, + GtkRequisition* requisition) { + requisition->width = widget->allocation.width; + requisition->height = widget->allocation.height; + } + + DISALLOW_IMPLICIT_CONSTRUCTORS(GtkFixedSocket); +}; + gboolean PlugRemovedCallback(GtkSocket* socket) { // This is called when the other side of the socket goes away. // We return TRUE to indicate that we don't want to destroy our side. return TRUE; } -} +} // namespace bool WebPluginDelegateImpl::WindowedCreatePlugin() { DCHECK(!windowed_handle_); @@ -260,16 +308,18 @@ bool WebPluginDelegateImpl::WindowedCreatePlugin() { return false; } - windowed_handle_ = gtk_socket_new(); - gtk_widget_set_parent(windowed_handle_, parent_); + windowed_handle_ = GtkFixedSocket::CreateNewWidget(); g_signal_connect(GTK_SOCKET(windowed_handle_), "plug-removed", G_CALLBACK(PlugRemovedCallback), NULL); + gtk_container_add(GTK_CONTAINER(parent_), windowed_handle_); // TODO(evanm): connect to signals on the socket, like when the other side // goes away. + gtk_widget_show(windowed_handle_); + gtk_widget_realize(windowed_handle_); + window_.window = GINT_TO_POINTER( gtk_socket_get_id(GTK_SOCKET(windowed_handle_))); - gtk_widget_show(windowed_handle_); NPSetWindowCallbackStruct* extra = new NPSetWindowCallbackStruct; extra->display = GDK_WINDOW_XDISPLAY(windowed_handle_->window); @@ -303,6 +353,9 @@ bool WebPluginDelegateImpl::WindowedReposition( // Clipping is handled by WebPlugin. GtkAllocation allocation = { window_rect.x(), window_rect.y(), window_rect.width(), window_rect.height() }; + // Tell our parent GtkFixed container where to place the widget. + gtk_fixed_move( + GTK_FIXED(parent_), windowed_handle_, window_rect.x(), window_rect.y()); gtk_widget_size_allocate(windowed_handle_, &allocation); window_rect_ = window_rect; |