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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/glue/plugins/gtk_plugin_container_host.h"
6
7 #include <gtk/gtk.h>
8 #include "base/gfx/gtk_util.h"
9 #include "base/logging.h"
10 #include "webkit/glue/plugins/gtk_plugin_container.h"
11 #include "webkit/glue/webplugin.h"
12
13 // Helper function that always returns true. Used to prevent Gtk from
14 // destroying our socket when the plug goes away: we manage it ourselves.
15 static gboolean AlwaysTrue(void *unused) {
16 return TRUE;
17 }
18
19 gfx::PluginWindowHandle GtkPluginContainerHost::CreatePluginContainer() {
20 DCHECK(host_widget_);
21 // If the current view hasn't been attached to a top-level window (e.g. it is
22 // loaded in a background tab), it can't be realized without asserting in
23 // Gtk, so we can't get the XID for the socket. Instead, don't create one.
24 // We'll never see the plugin but it's better than crashing.
25 // TODO(piman@google.com): figure out how to add the background tab to the
26 // widget hierarchy, so that it can be realized. It doesn't have to be
27 // visible.
28 if (!gtk_widget_get_ancestor(host_widget_, GTK_TYPE_WINDOW)) {
29 NOTIMPLEMENTED() << "Can't create plugins in background tabs.";
30 return 0;
31 }
32
33 GtkWidget* plugin_container = gtk_plugin_container_new();
34 g_signal_connect(G_OBJECT(plugin_container), "plug-removed",
35 G_CALLBACK(AlwaysTrue), NULL);
36 // Add a connection to the "unrealize" signal so that if the parent widget
37 // gets destroyed before the DestroyPluginContainer gets called, bad things
38 // don't happen.
39 g_signal_connect(G_OBJECT(plugin_container), "unrealize",
40 G_CALLBACK(UnrealizeCallback), this);
41 gtk_container_add(GTK_CONTAINER(host_widget_), plugin_container);
42 gtk_widget_show(plugin_container);
43 gtk_widget_realize(plugin_container);
44
45 gfx::PluginWindowHandle id = gtk_socket_get_id(GTK_SOCKET(plugin_container));
46
47 plugin_window_to_widget_map_.insert(std::make_pair(id, plugin_container));
48
49 return id;
50 }
51
52 void GtkPluginContainerHost::DestroyPluginContainer(
53 gfx::PluginWindowHandle container) {
54 GtkWidget* plugin_container = MapIDToWidget(container);
55 if (!plugin_container)
56 return;
57
58 // This will call the UnrealizeCallback that will remove plugin_container
59 // from the map.
60 gtk_widget_destroy(plugin_container);
61 }
62
63 void GtkPluginContainerHost::MovePluginContainer(
64 const WebPluginGeometry& move) {
65 DCHECK(host_widget_);
66 GtkWidget *widget = MapIDToWidget(move.window);
67 if (!widget)
68 return;
69
70 DCHECK(!GTK_WIDGET_NO_WINDOW(widget));
71 DCHECK(GTK_WIDGET_REALIZED(widget));
72
73 if (!move.visible) {
74 gtk_widget_hide(widget);
75 return;
76 } else {
77 gtk_widget_show(widget);
78 }
79
80 GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle();
81 GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
82 gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects);
83 gdk_window_shape_combine_region(widget->window, clip_region, 0, 0);
84 gdk_region_destroy(clip_region);
85
86 // Update the window position. Resizing is handled by WebPluginDelegate.
87 // TODO(deanm): Verify that we only need to move and not resize.
88 // TODO(evanm): we should cache the last shape and position and skip all
89 // of this business in the common case where nothing has changed.
90 int current_x, current_y;
91
92 // Until the above TODO is resolved, we can grab the last position
93 // off of the GtkFixed with a bit of hackery.
94 GValue value = {0};
95 g_value_init(&value, G_TYPE_INT);
96 gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget,
97 "x", &value);
98 current_x = g_value_get_int(&value);
99 gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget,
100 "y", &value);
101 current_y = g_value_get_int(&value);
102 g_value_unset(&value);
103
104 if (move.window_rect.x() != current_x ||
105 move.window_rect.y() != current_y) {
106 // Calling gtk_fixed_move unnecessarily is a no-no, as it causes the
107 // parent window to repaint!
108 gtk_fixed_move(GTK_FIXED(host_widget_),
109 widget,
110 move.window_rect.x(),
111 move.window_rect.y());
112 }
113
114 gtk_plugin_container_set_size(widget,
115 move.window_rect.width(),
116 move.window_rect.height());
117 }
118
119 GtkWidget* GtkPluginContainerHost::MapIDToWidget(gfx::PluginWindowHandle id) {
120 PluginWindowToWidgetMap::const_iterator i =
121 plugin_window_to_widget_map_.find(id);
122 if (i != plugin_window_to_widget_map_.end())
123 return i->second;
124
125 LOG(ERROR) << "Request for widget host for unknown window id " << id;
126
127 return NULL;
128 }
129
130 gboolean GtkPluginContainerHost::UnrealizeCallback(GtkWidget *widget,
131 void *user_data) {
132 // This is the last chance to get the XID for the widget. Remove it from the
133 // map here.
134 GtkPluginContainerHost* plugin_container_host =
135 static_cast<GtkPluginContainerHost*>(user_data);
136 gfx::PluginWindowHandle id = gtk_socket_get_id(GTK_SOCKET(widget));
137 plugin_container_host->plugin_window_to_widget_map_.erase(id);
138 }
OLDNEW
« 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