Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1261)

Unified Diff: webkit/glue/plugins/gtk_plugin_container_host.cc

Issue 146078: linux: OOP windowed plugins (Closed)
Patch Set: new version Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/glue/plugins/gtk_plugin_container_host.h ('k') | webkit/glue/plugins/webplugin_delegate_impl_gtk.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/glue/plugins/gtk_plugin_container_host.cc
diff --git a/webkit/glue/plugins/gtk_plugin_container_host.cc b/webkit/glue/plugins/gtk_plugin_container_host.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e47e1c4146e9056521dd4da8a13eea8decf6696a
--- /dev/null
+++ b/webkit/glue/plugins/gtk_plugin_container_host.cc
@@ -0,0 +1,138 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/plugins/gtk_plugin_container_host.h"
+
+#include <gtk/gtk.h>
+#include "base/gfx/gtk_util.h"
+#include "base/logging.h"
+#include "webkit/glue/plugins/gtk_plugin_container.h"
+#include "webkit/glue/webplugin.h"
+
+// Helper function that always returns true. Used to prevent Gtk from
+// destroying our socket when the plug goes away: we manage it ourselves.
+static gboolean AlwaysTrue(void *unused) {
+ return TRUE;
+}
+
+gfx::PluginWindowHandle GtkPluginContainerHost::CreatePluginContainer() {
+ DCHECK(host_widget_);
+ // If the current view hasn't been attached to a top-level window (e.g. it is
+ // loaded in a background tab), it can't be realized without asserting in
+ // Gtk, so we can't get the XID for the socket. Instead, don't create one.
+ // We'll never see the plugin but it's better than crashing.
+ // TODO(piman@google.com): figure out how to add the background tab to the
+ // widget hierarchy, so that it can be realized. It doesn't have to be
+ // visible.
+ if (!gtk_widget_get_ancestor(host_widget_, GTK_TYPE_WINDOW)) {
+ NOTIMPLEMENTED() << "Can't create plugins in background tabs.";
+ return 0;
+ }
+
+ GtkWidget* plugin_container = gtk_plugin_container_new();
+ g_signal_connect(G_OBJECT(plugin_container), "plug-removed",
+ G_CALLBACK(AlwaysTrue), NULL);
+ // Add a connection to the "unrealize" signal so that if the parent widget
+ // gets destroyed before the DestroyPluginContainer gets called, bad things
+ // don't happen.
+ g_signal_connect(G_OBJECT(plugin_container), "unrealize",
+ G_CALLBACK(UnrealizeCallback), this);
+ gtk_container_add(GTK_CONTAINER(host_widget_), plugin_container);
+ gtk_widget_show(plugin_container);
+ gtk_widget_realize(plugin_container);
+
+ gfx::PluginWindowHandle id = gtk_socket_get_id(GTK_SOCKET(plugin_container));
+
+ plugin_window_to_widget_map_.insert(std::make_pair(id, plugin_container));
+
+ return id;
+}
+
+void GtkPluginContainerHost::DestroyPluginContainer(
+ gfx::PluginWindowHandle container) {
+ GtkWidget* plugin_container = MapIDToWidget(container);
+ if (!plugin_container)
+ return;
+
+ // This will call the UnrealizeCallback that will remove plugin_container
+ // from the map.
+ gtk_widget_destroy(plugin_container);
+}
+
+void GtkPluginContainerHost::MovePluginContainer(
+ const WebPluginGeometry& move) {
+ DCHECK(host_widget_);
+ GtkWidget *widget = MapIDToWidget(move.window);
+ if (!widget)
+ return;
+
+ DCHECK(!GTK_WIDGET_NO_WINDOW(widget));
+ DCHECK(GTK_WIDGET_REALIZED(widget));
+
+ if (!move.visible) {
+ gtk_widget_hide(widget);
+ return;
+ } else {
+ gtk_widget_show(widget);
+ }
+
+ GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle();
+ GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
+ gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects);
+ gdk_window_shape_combine_region(widget->window, clip_region, 0, 0);
+ gdk_region_destroy(clip_region);
+
+ // Update the window position. Resizing is handled by WebPluginDelegate.
+ // TODO(deanm): Verify that we only need to move and not resize.
+ // TODO(evanm): we should cache the last shape and position and skip all
+ // of this business in the common case where nothing has changed.
+ int current_x, current_y;
+
+ // Until the above TODO is resolved, we can grab the last position
+ // off of the GtkFixed with a bit of hackery.
+ GValue value = {0};
+ g_value_init(&value, G_TYPE_INT);
+ gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget,
+ "x", &value);
+ current_x = g_value_get_int(&value);
+ gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget,
+ "y", &value);
+ current_y = g_value_get_int(&value);
+ g_value_unset(&value);
+
+ if (move.window_rect.x() != current_x ||
+ move.window_rect.y() != current_y) {
+ // Calling gtk_fixed_move unnecessarily is a no-no, as it causes the
+ // parent window to repaint!
+ gtk_fixed_move(GTK_FIXED(host_widget_),
+ widget,
+ move.window_rect.x(),
+ move.window_rect.y());
+ }
+
+ gtk_plugin_container_set_size(widget,
+ move.window_rect.width(),
+ move.window_rect.height());
+}
+
+GtkWidget* GtkPluginContainerHost::MapIDToWidget(gfx::PluginWindowHandle id) {
+ PluginWindowToWidgetMap::const_iterator i =
+ plugin_window_to_widget_map_.find(id);
+ if (i != plugin_window_to_widget_map_.end())
+ return i->second;
+
+ LOG(ERROR) << "Request for widget host for unknown window id " << id;
+
+ return NULL;
+}
+
+gboolean GtkPluginContainerHost::UnrealizeCallback(GtkWidget *widget,
+ void *user_data) {
+ // This is the last chance to get the XID for the widget. Remove it from the
+ // map here.
+ GtkPluginContainerHost* plugin_container_host =
+ static_cast<GtkPluginContainerHost*>(user_data);
+ gfx::PluginWindowHandle id = gtk_socket_get_id(GTK_SOCKET(widget));
+ plugin_container_host->plugin_window_to_widget_map_.erase(id);
+}
« no previous file with comments | « webkit/glue/plugins/gtk_plugin_container_host.h ('k') | webkit/glue/plugins/webplugin_delegate_impl_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698