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

Side by Side Diff: views/controls/native/native_view_host_gtk.cc

Issue 159751: Fix leak of GtkWidgets in NativeViewHost, and in doing so fix a crash on shut... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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 | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW
« views/controls/native/native_view_host_gtk.h ('K') | « views/controls/native/native_view_host_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698