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

Unified Diff: views/controls/native/native_view_host_gtk.cc

Issue 7171025: Fix flicker on tab switch on chromeos. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Null out host_widget_ after removing it Created 9 years, 6 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
Index: views/controls/native/native_view_host_gtk.cc
diff --git a/views/controls/native/native_view_host_gtk.cc b/views/controls/native/native_view_host_gtk.cc
index 50255f916e604dbe4401b9e1d460155c4fe99233..e63948f702c4bf26aca75ab3aaff86344488d5a9 100644
--- a/views/controls/native/native_view_host_gtk.cc
+++ b/views/controls/native/native_view_host_gtk.cc
@@ -95,36 +95,53 @@ NativeViewHostGtk::NativeViewHostGtk(NativeViewHost* host)
installed_clip_(false),
destroy_signal_id_(0),
focus_signal_id_(0),
- fixed_(NULL) {
+ fixed_(NULL),
+ host_widget_(NULL) {
CreateFixed(false);
}
NativeViewHostGtk::~NativeViewHostGtk() {
- if (fixed_)
+ if (fixed_) {
+ if (host_widget_ &&
+ GTK_IS_WIDGET(host_widget_) &&
+ gtk_widget_get_parent(host_widget_) == fixed_)
+ gtk_container_remove(GTK_CONTAINER(fixed_), host_widget_);
sky 2011/07/01 20:00:38 Does this mean the host_widget_ is leaked if someo
DaveMoore 2011/07/01 20:13:34 If we don't remove it here it will get destroyed w
gtk_widget_destroy(fixed_);
+ }
}
////////////////////////////////////////////////////////////////////////////////
// NativeViewHostGtk, NativeViewHostWrapper implementation:
void NativeViewHostGtk::NativeViewAttached() {
- DCHECK(host_->native_view());
- if (gtk_widget_get_parent(host_->native_view()))
- gtk_widget_reparent(host_->native_view(), fixed_);
- else
- gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());
+ host_widget_ = host_->native_view();
+ DCHECK(host_widget_);
+
+ GtkWidget* host_parent = gtk_widget_get_parent(host_widget_);
+ if (host_parent) {
+ if (host_parent != fixed_)
+ gtk_widget_reparent(host_widget_, fixed_);
+ } else {
+ gtk_container_add(GTK_CONTAINER(fixed_), host_widget_);
+ }
+
+ // We need to clear the background so we don't get flicker on tab switching.
+ // To do that we must realize the widget if it's not already.
+ if (!GTK_WIDGET_REALIZED(host_widget_))
+ gtk_widget_realize(host_widget_);
+ gdk_window_set_back_pixmap(host_widget_->window, NULL, false);
// Let the widget know that the native component has been painted.
- views::NativeWidgetGtk::RegisterChildExposeHandler(host_->native_view());
+ views::NativeWidgetGtk::RegisterChildExposeHandler(host_widget_);
if (!destroy_signal_id_) {
- destroy_signal_id_ = g_signal_connect(host_->native_view(),
+ destroy_signal_id_ = g_signal_connect(host_widget_,
"destroy", G_CALLBACK(CallDestroy),
this);
}
if (!focus_signal_id_) {
- focus_signal_id_ = g_signal_connect(host_->native_view(),
+ focus_signal_id_ = g_signal_connect(host_widget_,
"focus-in-event",
G_CALLBACK(CallFocusIn), this);
}
@@ -134,33 +151,23 @@ void NativeViewHostGtk::NativeViewAttached() {
// We own the native view as long as it's attached, so that we can safely
// reparent it in multiple passes.
- gtk_widget_ref(host_->native_view());
+ gtk_widget_ref(host_widget_);
// TODO(port): figure out focus.
}
void NativeViewHostGtk::NativeViewDetaching(bool destroyed) {
- DCHECK(host_->native_view());
+ DCHECK(host_widget_);
- g_signal_handler_disconnect(G_OBJECT(host_->native_view()),
- destroy_signal_id_);
+ g_signal_handler_disconnect(G_OBJECT(host_widget_), destroy_signal_id_);
destroy_signal_id_ = 0;
- g_signal_handler_disconnect(G_OBJECT(host_->native_view()),
- focus_signal_id_);
+ g_signal_handler_disconnect(G_OBJECT(host_widget_), focus_signal_id_);
focus_signal_id_ = 0;
installed_clip_ = false;
- if (fixed_ && !destroyed) {
- DCHECK_NE(static_cast<gfx::NativeView>(NULL),
- gtk_widget_get_parent(host_->native_view()));
- gtk_container_remove(GTK_CONTAINER(fixed_), host_->native_view());
- DCHECK_EQ(
- 0U, g_list_length(gtk_container_get_children(GTK_CONTAINER(fixed_))));
- }
-
- g_object_unref(G_OBJECT(host_->native_view()));
+ g_object_unref(G_OBJECT(host_widget_));
}
void NativeViewHostGtk::AddedToWidget() {
@@ -174,15 +181,18 @@ void NativeViewHostGtk::AddedToWidget() {
if (!host_->native_view())
return;
- if (gtk_widget_get_parent(host_->native_view()))
- gtk_widget_reparent(host_->native_view(), fixed_);
+ host_widget_ = host_->native_view();
+ if (gtk_widget_get_parent(host_widget_))
+ gtk_widget_reparent(host_widget_, fixed_);
else
- gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());
+ gtk_container_add(GTK_CONTAINER(fixed_), host_widget_);
- if (host_->IsVisibleInRootView())
+ if (host_->IsVisibleInRootView()) {
+ gtk_widget_show(host_widget_);
gtk_widget_show(fixed_);
- else
+ } else {
gtk_widget_hide(fixed_);
+ }
host_->Layout();
}
@@ -239,14 +249,14 @@ void NativeViewHostGtk::ShowWidget(int x, int y, int w, int h) {
// middle of a re-size, and it kicks off another re-size, and you
// get flashing. Instead, we'll set the desired size as properties
// on the widget and queue the re-size.
- gtk_views_fixed_set_widget_size(host_->native_view(), child_w, child_h);
- gtk_fixed_move(GTK_FIXED(fixed_), host_->native_view(), child_x, child_y);
+ gtk_views_fixed_set_widget_size(host_widget_, child_w, child_h);
+ gtk_fixed_move(GTK_FIXED(fixed_), host_widget_, child_x, child_y);
// Size and place the fixed_.
GetHostWidget()->PositionChild(fixed_, fixed_x, fixed_y, fixed_w, fixed_h);
+ gtk_widget_show(host_widget_);
gtk_widget_show(fixed_);
- gtk_widget_show(host_->native_view());
}
void NativeViewHostGtk::HideWidget() {
@@ -255,8 +265,8 @@ void NativeViewHostGtk::HideWidget() {
}
void NativeViewHostGtk::SetFocus() {
- DCHECK(host_->native_view());
- gtk_widget_grab_focus(host_->native_view());
+ DCHECK(host_widget_);
+ gtk_widget_grab_focus(host_widget_);
}
gfx::NativeViewAccessible NativeViewHostGtk::GetNativeViewAccessible() {
@@ -290,19 +300,26 @@ void NativeViewHostGtk::CreateFixed(bool needs_window) {
fixed_ = gtk_views_fixed_new();
gtk_widget_set_name(fixed_, "views-native-view-host-fixed");
gtk_fixed_set_has_window(GTK_FIXED(fixed_), needs_window);
+
// Defeat refcounting. We need to own the fixed.
gtk_widget_ref(fixed_);
NativeWidgetGtk* widget_gtk = GetHostWidget();
- if (widget_gtk)
+ if (widget_gtk) {
widget_gtk->AddChild(fixed_);
+ // Clear the background so we don't get flicker.
+ gtk_widget_realize(fixed_);
+ gdk_window_set_back_pixmap(fixed_->window, NULL, false);
+ }
- if (host_->native_view())
- gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());
+ if (host_->native_view()) {
+ host_widget_ = host_->native_view();
+ gtk_container_add(GTK_CONTAINER(fixed_), host_widget_);
+ }
- if (widget_gtk && host_->native_view() && focused_widget) {
+ if (widget_gtk && host_widget_ && focused_widget)
gtk_widget_grab_focus(focused_widget);
- }
+
if (focus_event_blocked) {
// Unblocking a signal handler that is not blocked fails.
// Unblock only when it's unblocked.
@@ -315,13 +332,14 @@ void NativeViewHostGtk::DestroyFixed() {
return;
gtk_widget_hide(fixed_);
- GetHostWidget()->RemoveChild(fixed_);
-
- if (host_->native_view()) {
+ if (host_widget_) {
// We can safely remove the widget from its container since we own the
// widget from the moment it is attached.
- gtk_container_remove(GTK_CONTAINER(fixed_), host_->native_view());
+ gtk_container_remove(GTK_CONTAINER(fixed_), host_widget_);
+ host_widget_ = NULL;
}
+ GetHostWidget()->RemoveChild(fixed_);
+
// fixed_ should not have any children this point.
DCHECK_EQ(0U,
g_list_length(gtk_container_get_children(GTK_CONTAINER(fixed_))));
« 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