OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "views/controls/native/native_view_host_gtk.h" | 5 #include "views/controls/native/native_view_host_gtk.h" |
6 | 6 |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "views/controls/native/native_view_host.h" | 10 #include "views/controls/native/native_view_host.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 | 40 |
41 if (!destroy_signal_id_) { | 41 if (!destroy_signal_id_) { |
42 destroy_signal_id_ = g_signal_connect(G_OBJECT(host_->native_view()), | 42 destroy_signal_id_ = g_signal_connect(G_OBJECT(host_->native_view()), |
43 "destroy", G_CALLBACK(CallDestroy), | 43 "destroy", G_CALLBACK(CallDestroy), |
44 this); | 44 this); |
45 } | 45 } |
46 | 46 |
47 // Always layout though. | 47 // Always layout though. |
48 host_->Layout(); | 48 host_->Layout(); |
49 | 49 |
| 50 // We own the native view as long as it's attached, so that we can safely |
| 51 // reparent it in multiple passes. |
| 52 gtk_widget_ref(host_->native_view()); |
| 53 |
50 // TODO(port): figure out focus. | 54 // TODO(port): figure out focus. |
51 } | 55 } |
52 | 56 |
53 void NativeViewHostGtk::NativeViewDetaching() { | 57 void NativeViewHostGtk::NativeViewDetaching() { |
54 DCHECK(host_->native_view()); | 58 DCHECK(host_->native_view()); |
55 | 59 |
56 g_signal_handler_disconnect(G_OBJECT(host_->native_view()), | 60 g_signal_handler_disconnect(G_OBJECT(host_->native_view()), |
57 destroy_signal_id_); | 61 destroy_signal_id_); |
58 destroy_signal_id_ = 0; | 62 destroy_signal_id_ = 0; |
59 | 63 |
60 // TODO(port): focus. | 64 // TODO(port): focus. |
61 // FocusManager::UninstallFocusSubclass(native_view()); | 65 // FocusManager::UninstallFocusSubclass(native_view()); |
62 installed_clip_ = false; | 66 installed_clip_ = false; |
| 67 |
| 68 // Release ownership back to the caller. |
| 69 gtk_widget_unref(host_->native_view()); |
63 } | 70 } |
64 | 71 |
65 void NativeViewHostGtk::AddedToWidget() { | 72 void NativeViewHostGtk::AddedToWidget() { |
66 if (gtk_widget_get_parent(fixed_)) | 73 if (gtk_widget_get_parent(fixed_)) |
67 GetHostWidget()->ReparentChild(fixed_); | 74 GetHostWidget()->ReparentChild(fixed_); |
68 else | 75 else |
69 GetHostWidget()->AddChild(fixed_); | 76 GetHostWidget()->AddChild(fixed_); |
70 | 77 |
71 if (!host_->native_view()) | 78 if (!host_->native_view()) |
72 return; | 79 return; |
73 | 80 |
74 if (gtk_widget_get_parent(host_->native_view())) | 81 if (gtk_widget_get_parent(host_->native_view())) |
75 gtk_widget_reparent(host_->native_view(), fixed_); | 82 gtk_widget_reparent(host_->native_view(), fixed_); |
76 else | 83 else |
77 gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view()); | 84 gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view()); |
78 | 85 |
79 if (host_->IsVisibleInRootView()) | 86 if (host_->IsVisibleInRootView()) |
80 gtk_widget_show(fixed_); | 87 gtk_widget_show(fixed_); |
81 else | 88 else |
82 gtk_widget_hide(fixed_); | 89 gtk_widget_hide(fixed_); |
83 host_->Layout(); | 90 host_->Layout(); |
84 } | 91 } |
85 | 92 |
86 void NativeViewHostGtk::RemovedFromWidget() { | 93 void NativeViewHostGtk::RemovedFromWidget() { |
87 if (!host_->native_view()) | 94 if (!host_->native_view()) |
88 return; | 95 return; |
89 | 96 |
90 // TODO(beng): We leak host_->native_view() here. Fix: make all widgets not be | |
91 // refcounted. | |
92 DestroyFixed(); | 97 DestroyFixed(); |
93 } | 98 } |
94 | 99 |
95 void NativeViewHostGtk::InstallClip(int x, int y, int w, int h) { | 100 void NativeViewHostGtk::InstallClip(int x, int y, int w, int h) { |
96 DCHECK(w > 0 && h > 0); | 101 DCHECK(w > 0 && h > 0); |
97 installed_clip_bounds_.SetRect(x, y, w, h); | 102 installed_clip_bounds_.SetRect(x, y, w, h); |
98 installed_clip_ = true; | 103 installed_clip_ = true; |
99 | 104 |
100 // We only re-create the fixed with a window when a cliprect is installed. | 105 // We only re-create the fixed with a window when a cliprect is installed. |
101 // Because the presence of a X Window will prevent transparency from working | 106 // Because the presence of a X Window will prevent transparency from working |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 154 } |
150 | 155 |
151 void NativeViewHostGtk::SetFocus() { | 156 void NativeViewHostGtk::SetFocus() { |
152 NOTIMPLEMENTED(); | 157 NOTIMPLEMENTED(); |
153 } | 158 } |
154 | 159 |
155 //////////////////////////////////////////////////////////////////////////////// | 160 //////////////////////////////////////////////////////////////////////////////// |
156 // NativeViewHostGtk, private: | 161 // NativeViewHostGtk, private: |
157 | 162 |
158 void NativeViewHostGtk::CreateFixed(bool needs_window) { | 163 void NativeViewHostGtk::CreateFixed(bool needs_window) { |
159 bool native_view_addrefed = DestroyFixed(); | 164 DestroyFixed(); |
160 | 165 |
161 fixed_ = gtk_fixed_new(); | 166 fixed_ = gtk_fixed_new(); |
162 gtk_fixed_set_has_window(GTK_FIXED(fixed_), needs_window); | 167 gtk_fixed_set_has_window(GTK_FIXED(fixed_), needs_window); |
163 // Defeat refcounting. We need to own the fixed. | 168 // Defeat refcounting. We need to own the fixed. |
164 gtk_widget_ref(fixed_); | 169 gtk_widget_ref(fixed_); |
165 | 170 |
166 WidgetGtk* widget_gtk = GetHostWidget(); | 171 WidgetGtk* widget_gtk = GetHostWidget(); |
167 if (widget_gtk) | 172 if (widget_gtk) |
168 widget_gtk->AddChild(fixed_); | 173 widget_gtk->AddChild(fixed_); |
169 if (host_->native_view()) | 174 if (host_->native_view()) |
170 gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view()); | 175 gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view()); |
171 if (native_view_addrefed) | |
172 gtk_widget_unref(host_->native_view()); | |
173 } | 176 } |
174 | 177 |
175 bool NativeViewHostGtk::DestroyFixed() { | 178 void NativeViewHostGtk::DestroyFixed() { |
176 bool native_view_addrefed = false; | |
177 if (!fixed_) | 179 if (!fixed_) |
178 return native_view_addrefed; | 180 return; |
179 | 181 |
180 gtk_widget_hide(fixed_); | 182 gtk_widget_hide(fixed_); |
181 GetHostWidget()->RemoveChild(fixed_); | 183 GetHostWidget()->RemoveChild(fixed_); |
182 | 184 |
183 if (host_->native_view()) { | 185 if (host_->native_view()) { |
184 // We can't allow the hosted NativeView's refcount to drop to zero. | 186 // We can safely remove the widget from its container since we own the |
185 gtk_widget_ref(host_->native_view()); | 187 // widget from the moment it is attached. |
186 native_view_addrefed = true; | |
187 gtk_container_remove(GTK_CONTAINER(fixed_), host_->native_view()); | 188 gtk_container_remove(GTK_CONTAINER(fixed_), host_->native_view()); |
188 } | 189 } |
189 | 190 |
190 gtk_widget_destroy(fixed_); | 191 gtk_widget_destroy(fixed_); |
191 fixed_ = NULL; | 192 fixed_ = NULL; |
192 return native_view_addrefed; | |
193 } | 193 } |
194 | 194 |
195 WidgetGtk* NativeViewHostGtk::GetHostWidget() const { | 195 WidgetGtk* NativeViewHostGtk::GetHostWidget() const { |
196 return static_cast<WidgetGtk*>(host_->GetWidget()); | 196 return static_cast<WidgetGtk*>(host_->GetWidget()); |
197 } | 197 } |
198 | 198 |
199 // static | 199 // static |
200 void NativeViewHostGtk::CallDestroy(GtkObject* object, | 200 void NativeViewHostGtk::CallDestroy(GtkObject* object, |
201 NativeViewHostGtk* host) { | 201 NativeViewHostGtk* host) { |
202 return host->host_->NativeViewDestroyed(); | 202 return host->host_->NativeViewDestroyed(); |
203 } | 203 } |
204 | 204 |
205 //////////////////////////////////////////////////////////////////////////////// | 205 //////////////////////////////////////////////////////////////////////////////// |
206 // NativeViewHostWrapper, public: | 206 // NativeViewHostWrapper, public: |
207 | 207 |
208 // static | 208 // static |
209 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper( | 209 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper( |
210 NativeViewHost* host) { | 210 NativeViewHost* host) { |
211 return new NativeViewHostGtk(host); | 211 return new NativeViewHostGtk(host); |
212 } | 212 } |
213 | 213 |
214 } // namespace views | 214 } // namespace views |
OLD | NEW |