summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc4
-rw-r--r--views/controls/native/native_view_host_gtk.cc5
-rw-r--r--views/widget/widget_gtk.cc50
-rw-r--r--views/widget/widget_gtk.h16
4 files changed, 70 insertions, 5 deletions
diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc
index 2b2bdb9..18f815c 100644
--- a/chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc
@@ -30,6 +30,7 @@
#include "views/focus/view_storage.h"
#include "views/screen.h"
#include "views/widget/root_view.h"
+#include "views/widget/widget_gtk.h"
using WebKit::WebDragOperation;
using WebKit::WebDragOperationsMask;
@@ -189,6 +190,9 @@ RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget(
gtk_widget_add_events(view->native_view(), GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
+ // Let widget know that the tab contents has been painted.
+ views::WidgetGtk::RegisterChildExposeHandler(view->native_view());
+
// Renderer target DnD.
if (tab_contents()->ShouldAcceptDragAndDrop())
drag_dest_.reset(new WebDragDestGtk(tab_contents(), view->native_view()));
diff --git a/views/controls/native/native_view_host_gtk.cc b/views/controls/native/native_view_host_gtk.cc
index 4a6d155..d5e4110 100644
--- a/views/controls/native/native_view_host_gtk.cc
+++ b/views/controls/native/native_view_host_gtk.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -111,6 +111,9 @@ void NativeViewHostGtk::NativeViewAttached() {
else
gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view());
+ // Let the widget know that the native component has been painted.
+ views::WidgetGtk::RegisterChildExposeHandler(host_->native_view());
+
if (!destroy_signal_id_) {
destroy_signal_id_ = g_signal_connect(host_->native_view(),
"destroy", G_CALLBACK(CallDestroy),
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index 6a31bb8..d6655da 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -60,14 +60,20 @@ namespace {
// Links the GtkWidget to its NativeWidget.
const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
+
// A g_object data key to associate a CompositePainter object to a GtkWidget.
const char* kCompositePainterKey = "__VIEWS_COMPOSITE_PAINTER__";
+
// A g_object data key to associate the flag whether or not the widget
// is composited to a GtkWidget. gtk_widget_is_composited simply tells
// if x11 supports composition and cannot be used to tell if given widget
// is composited.
const char* kCompositeEnabledKey = "__VIEWS_COMPOSITE_ENABLED__";
+// A g_object data key to associate the expose handler id that is
+// used to remove FREEZE_UPDATE property on the window.
+const char* kExposeHandlerIdKey = "__VIEWS_EXPOSE_HANDLER_ID__";
+
// CompositePainter draws a composited child widgets image into its
// drawing area. This object is created at most once for a widget and kept
// until the widget is destroyed.
@@ -164,6 +170,15 @@ void EnumerateChildWidgetsForNativeWidgets(GtkWidget* child_widget,
}
}
+void RemoveExposeHandlerIfExists(GtkWidget* widget) {
+ gulong id = reinterpret_cast<gulong>(g_object_get_data(G_OBJECT(widget),
+ kExposeHandlerIdKey));
+ if (id) {
+ g_signal_handler_disconnect(G_OBJECT(widget), id);
+ g_object_set_data(G_OBJECT(widget), kExposeHandlerIdKey, 0);
+ }
+}
+
} // namespace
// During drag and drop GTK sends a drag-leave during a drop. This means we
@@ -713,9 +728,6 @@ void WidgetGtk::EnableDebugPaint() {
void WidgetGtk::UpdateFreezeUpdatesProperty(GtkWindow* window, bool enable) {
if (!GTK_WIDGET_REALIZED(GTK_WIDGET(window)))
gtk_widget_realize(GTK_WIDGET(window));
-#if 0
- // Temporarily disabling the FREEZE_UPDATE as this is causing
- // problem in panels. see crosbug.com/13750.
GdkWindow* gdk_window = GTK_WIDGET(window)->window;
static GdkAtom freeze_atom_ =
@@ -736,7 +748,15 @@ void WidgetGtk::UpdateFreezeUpdatesProperty(GtkWindow* window, bool enable) {
GDK_WINDOW_XID(gdk_window);
gdk_property_delete(gdk_window, freeze_atom_);
}
-#endif
+}
+
+// static
+void WidgetGtk::RegisterChildExposeHandler(GtkWidget* child) {
+ RemoveExposeHandlerIfExists(child);
+ gulong id = g_signal_connect_after(child, "expose-event",
+ G_CALLBACK(&ChildExposeHandler), NULL);
+ g_object_set_data(G_OBJECT(child), kExposeHandlerIdKey,
+ reinterpret_cast<void*>(id));
}
////////////////////////////////////////////////////////////////////////////////
@@ -1380,6 +1400,28 @@ gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) {
return false;
}
+void WidgetGtk::OnChildExpose(GtkWidget* child) {
+ DCHECK(type_ != TYPE_CHILD);
+ if (!painted_) {
+ painted_ = true;
+ UpdateFreezeUpdatesProperty(GTK_WINDOW(widget_), false /* remove */);
+ }
+ RemoveExposeHandlerIfExists(child);
+}
+
+// static
+gboolean WidgetGtk::ChildExposeHandler(GtkWidget* widget,
+ GdkEventExpose* event) {
+ GtkWidget* toplevel = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
+ CHECK(toplevel);
+ NativeWidget* native_widget =
+ NativeWidget::GetNativeWidgetForNativeView(toplevel);
+ CHECK(native_widget);
+ WidgetGtk* widget_gtk = static_cast<WidgetGtk*>(native_widget);
+ widget_gtk->OnChildExpose(widget);
+ return false;
+}
+
// static
Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) {
GtkWidget* parent = widget;
diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h
index 14eab68..597ec58 100644
--- a/views/widget/widget_gtk.h
+++ b/views/widget/widget_gtk.h
@@ -187,6 +187,17 @@ class WidgetGtk : public Widget,
// which does not support this property.
static void UpdateFreezeUpdatesProperty(GtkWindow* window, bool enable);
+ // Registers a expose handler that removes FREEZE_UPDATES property.
+ // If you are adding a GtkWidget with its own GdkWindow that may
+ // fill the entire area of the WidgetGtk to the view hierachy, you
+ // need use this function to tell WM that when the widget is ready
+ // to be shown.
+ // Caller of this method do not need to disconnect this because the
+ // handler will be removed upon the first invocation of the handler,
+ // or when the widget is re-attached, and expose won't be emitted on
+ // detached widget.
+ static void RegisterChildExposeHandler(GtkWidget* widget);
+
// Overridden from NativeWidget:
virtual void SetCreateParams(const CreateParams& params) OVERRIDE;
virtual Widget* GetWidget() OVERRIDE;
@@ -298,6 +309,11 @@ class WidgetGtk : public Widget,
// This is called only when the window is transparent.
CHROMEGTK_CALLBACK_1(WidgetGtk, gboolean, OnWindowPaint, GdkEventExpose*);
+ // Callbacks for expose event on child widgets. See the description of
+ // RegisterChildChildExposeHandler.
+ void OnChildExpose(GtkWidget* child);
+ static gboolean ChildExposeHandler(GtkWidget* widget, GdkEventExpose* event);
+
// Returns the first ancestor of |widget| that is a window.
static Window* GetWindowImpl(GtkWidget* widget);