Chromium Code Reviews| Index: gfx/gtk_native_view_id_manager.cc |
| diff --git a/gfx/gtk_native_view_id_manager.cc b/gfx/gtk_native_view_id_manager.cc |
| index 6aa460c6c90ac41ada1a6b05cf4832fa21ce0b5d..b20302302cf04b235ddb9e64aea5f87308918b83 100644 |
| --- a/gfx/gtk_native_view_id_manager.cc |
| +++ b/gfx/gtk_native_view_id_manager.cc |
| @@ -64,7 +64,9 @@ gfx::NativeViewId GtkNativeViewManager::GetIdForWidget(gfx::NativeView widget) { |
| if (GTK_WIDGET_REALIZED(widget)) { |
| GdkWindow *gdk_window = widget->window; |
| CHECK(gdk_window); |
| - info.x_window_id = GDK_WINDOW_XID(gdk_window); |
| + XID xid = GDK_WINDOW_XID(gdk_window); |
| + info.x_window_id = xid; |
| + xid_to_native_view_[xid] = widget; |
| } |
| native_view_to_id_[widget] = new_id; |
| @@ -102,17 +104,42 @@ bool GtkNativeViewManager::GetPermanentXIDForId(XID* output, |
| // We only return permanent XIDs for widgets that allow us to guarantee that |
| // the XID will not change. |
| - if (!GTK_IS_PRESERVE_WINDOW(i->second.widget)) |
| - return false; |
| + CHECK(GTK_IS_PRESERVE_WINDOW(i->second.widget)); |
|
piman
2010/11/29 21:59:01
I'm not sure that this CHECK (and other below) rea
jonathan.backer
2010/11/30 13:09:31
Done.
|
| GtkPreserveWindow* widget = |
| reinterpret_cast<GtkPreserveWindow*>(i->second.widget); |
| gtk_preserve_window_set_preserve(widget, TRUE); |
| *output = GDK_WINDOW_XID(i->second.widget->window); |
| + |
| + // It's possible that we were not realized before this call, in which |
| + // case we must place an entry in the lookup table. |
| + xid_to_native_view_[*output] = i->second.widget; |
| + |
| return true; |
| } |
| +void GtkNativeViewManager::ReleasePermanentXID(XID xid) { |
| + AutoLock locked(lock_); |
| + |
| + std::map<XID, gfx::NativeView>::iterator i = |
| + xid_to_native_view_.find(xid); |
| + |
| + if (i == xid_to_native_view_.end()) |
| + return; |
| + |
| + if (i->second) { |
| + CHECK(GTK_IS_PRESERVE_WINDOW(i->second)); |
| + GtkPreserveWindow* preserve_window = |
| + reinterpret_cast<GtkPreserveWindow*>(i->second); |
| + gtk_preserve_window_set_preserve(preserve_window, FALSE); |
| + } else { |
| + GdkWindow* window = reinterpret_cast<GdkWindow*>(gdk_xid_table_lookup(xid)); |
| + CHECK(window); |
| + gdk_window_destroy(window); |
| + } |
| +} |
| + |
| // ----------------------------------------------------------------------------- |
| @@ -140,6 +167,21 @@ void GtkNativeViewManager::OnRealize(gfx::NativeView widget) { |
| CHECK(widget->window); |
| i->second.x_window_id = GDK_WINDOW_XID(widget->window); |
| + |
| + // See if the XID is already associated with a widget. |
| + // If so, there had better be a lock on that window. |
| + XID xid = GDK_WINDOW_XID(widget->window); |
| + std::map<XID, gfx::NativeView>::iterator j = |
| + xid_to_native_view_.find(xid); |
| + |
| + if (j != xid_to_native_view_.end()) { |
| + CHECK(GTK_IS_PRESERVE_WINDOW(j->second)); |
| + GtkPreserveWindow* preserve_window = |
| + reinterpret_cast<GtkPreserveWindow*>(j->second); |
| + CHECK(gtk_preserve_window_get_preserve(preserve_window)); |
| + } else { |
| + xid_to_native_view_[xid] = widget; |
|
piman
2010/11/29 21:59:01
We're effectively doing the lookup into the map tw
jonathan.backer
2010/11/30 13:09:31
Done.
|
| + } |
| } |
| void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) { |
| @@ -152,7 +194,19 @@ void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) { |
| CHECK(i != id_to_info_.end()); |
| + XID xid = i->second.x_window_id; |
| i->second.x_window_id = 0; |
| + |
| + // Remove XID from lookup table unless it will be preserved. |
| + std::map<XID, gfx::NativeView>::iterator j = |
| + xid_to_native_view_.find(xid); |
| + |
| + CHECK(j != xid_to_native_view_.end()); |
| + if (!GTK_IS_PRESERVE_WINDOW(j->second) || |
| + !gtk_preserve_window_get_preserve( |
| + reinterpret_cast<GtkPreserveWindow*>(j->second))) { |
| + xid_to_native_view_.erase(j); |
| + } |
| } |
| void GtkNativeViewManager::OnDestroy(gfx::NativeView widget) { |
| @@ -166,6 +220,13 @@ void GtkNativeViewManager::OnDestroy(gfx::NativeView widget) { |
| id_to_info_.find(i->second); |
| CHECK(j != id_to_info_.end()); |
| + // If the XID is supposed to outlive the widget, mark it |
| + // in the lookup table. |
| + if (GTK_IS_PRESERVE_WINDOW(widget) && |
| + gtk_preserve_window_get_preserve( |
| + reinterpret_cast<GtkPreserveWindow*>(widget))) |
| + xid_to_native_view_[GDK_WINDOW_XID(widget->window)] = NULL; |
| + |
| native_view_to_id_.erase(i); |
| id_to_info_.erase(j); |
| } |