summaryrefslogtreecommitdiffstats
path: root/ui/base/gtk
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-23 18:10:18 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-23 18:10:18 +0000
commit3c56b38d2055b16592d499ea4933c27cbb0fd809 (patch)
tree82c593ce4c84e4d0c538d10cd89da3f001ac67c7 /ui/base/gtk
parent03eb9d27a79f876a039ca30eba54d1155ab5500b (diff)
downloadchromium_src-3c56b38d2055b16592d499ea4933c27cbb0fd809.zip
chromium_src-3c56b38d2055b16592d499ea4933c27cbb0fd809.tar.gz
chromium_src-3c56b38d2055b16592d499ea4933c27cbb0fd809.tar.bz2
content: Move render_widget_host_view_gtk to content/ try 2.
This was r97750, which was reverted at r97756. This patch, in addition to all the other things it did, marks OwnedWidgetGtk for export and moves it to the ui:: namespace. Original list of things this patch does: - OwnedWidgetGtk now goes in ui/base/gtk/ - TruncateString moved from l10n_util:: to ui:: - GtkIMContextWrapper has part of its code split into chrome/ (IDC using code goes in RenderViewContextMenu) and the rest go in content/ (gtk using code goes with GtkIMContextWrapper). - gtk_key_bindings_handler[_unittest] now goes in content, as it's a utility class to RenderWidgetHostGtk. BUG=93804 TEST=existing unit tests Original Review URL: http://codereview.chromium.org/7669040 Review URL: http://codereview.chromium.org/7708021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97889 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/gtk')
-rw-r--r--ui/base/gtk/owned_widget_gtk.cc45
-rw-r--r--ui/base/gtk/owned_widget_gtk.h96
2 files changed, 141 insertions, 0 deletions
diff --git a/ui/base/gtk/owned_widget_gtk.cc b/ui/base/gtk/owned_widget_gtk.cc
new file mode 100644
index 0000000..6a129a2
--- /dev/null
+++ b/ui/base/gtk/owned_widget_gtk.cc
@@ -0,0 +1,45 @@
+// 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.
+
+#include "ui/base/gtk/owned_widget_gtk.h"
+
+#include <gtk/gtk.h>
+
+#include "base/logging.h"
+
+namespace ui {
+
+OwnedWidgetGtk::~OwnedWidgetGtk() {
+ Destroy();
+}
+
+void OwnedWidgetGtk::Own(GtkWidget* widget) {
+ if (!widget)
+ return;
+
+ DCHECK(!widget_);
+ // We want to make sure that Own() was called properly, right after the
+ // widget was created. There should be a floating reference.
+ DCHECK(g_object_is_floating(widget));
+
+ // Sink the floating reference, we should now own this reference.
+ g_object_ref_sink(widget);
+ widget_ = widget;
+}
+
+void OwnedWidgetGtk::Destroy() {
+ if (!widget_)
+ return;
+
+ GtkWidget* widget = widget_;
+ widget_ = NULL;
+ gtk_widget_destroy(widget);
+
+ DCHECK(!g_object_is_floating(widget));
+ // NOTE: Assumes some implementation details about glib internals.
+ DCHECK_EQ(G_OBJECT(widget)->ref_count, 1U);
+ g_object_unref(widget);
+}
+
+} // namespace ui
diff --git a/ui/base/gtk/owned_widget_gtk.h b/ui/base/gtk/owned_widget_gtk.h
new file mode 100644
index 0000000..73e5f31
--- /dev/null
+++ b/ui/base/gtk/owned_widget_gtk.h
@@ -0,0 +1,96 @@
+// 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.
+
+// This class assists you in dealing with a specific situation when managing
+// ownership between a C++ object and a GTK widget. It is common to have a
+// C++ object which encapsulates a GtkWidget, and that widget is exposed from
+// the object for use outside of the class. In this situation, you commonly
+// want the GtkWidget's lifetime to match its C++ object's lifetime. Using an
+// OwnedWigetGtk will take ownership over the initial reference of the
+// GtkWidget, so that it is "owned" by the C++ object. Example usage:
+//
+// class FooViewGtk() {
+// public:
+// FooViewGtk() { }
+// ~FooViewGtk() { }
+// void Init() { vbox_.Own(gtk_vbox_new()); }
+// GtkWidget* widget() { return vbox_.get() }; // Host my widget!
+// private:
+// OwnedWidgetGtk vbox_;
+// };
+//
+// This design will ensure that the widget stays alive from the call to Own()
+// until the call to Destroy().
+//
+// - Details of the problem and OwnedWidgetGtk's solution:
+// In order to make passing ownership more convenient for newly created
+// widgets, GTK has a concept of a "floating" reference. All GtkObjects (and
+// thus GtkWidgets) inherit from GInitiallyUnowned. When they are created, the
+// object starts with a reference count of 1, but has its floating flag set.
+// When it is put into a container for the first time, that container will
+// "sink" the floating reference, and the count will still be 1. Now the
+// container owns the widget, and if we remove the widget from the container,
+// the widget is destroyed. This style of ownership often causes problems when
+// you have an object encapsulating the widget. If we just use a raw
+// GtkObject* with no specific ownership management, we push the widget's
+// ownership onto the user of the class. Now the C++ object can't depend on
+// the widget being valid, since it doesn't manage its lifetime. If the widget
+// was removed from a container, removing its only reference, it would be
+// destroyed (from the C++ object's perspective) unexpectedly destroyed. The
+// solution is fairly simple, make sure that the C++ object owns the widget,
+// and thus it is also responsible for destroying it. This boils down to:
+// GtkWidget* widget = gtk_widget_new();
+// g_object_ref_sink(widget); // Claim the initial floating reference.
+// ...
+// gtk_destroy_widget(widget); // Ask all code to destroy their references.
+// g_object_unref(widget); // Destroy the initial reference we had claimed.
+
+#ifndef UI_BASE_GTK_OWNED_WIDGET_GTK_H_
+#define UI_BASE_GTK_OWNED_WIDGET_GTK_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "ui/base/ui_export.h"
+
+typedef struct _GtkWidget GtkWidget;
+
+namespace ui {
+
+class UI_EXPORT OwnedWidgetGtk {
+ public:
+ // Create an instance that isn't managing any ownership.
+ OwnedWidgetGtk() : widget_(NULL) { }
+ // Create an instance that owns |widget|.
+ explicit OwnedWidgetGtk(GtkWidget* widget) : widget_(NULL) { Own(widget); }
+
+ ~OwnedWidgetGtk();
+
+ // Return the currently owned widget, or NULL if no widget is owned.
+ GtkWidget* get() const { return widget_; }
+ GtkWidget* operator->() const { return widget_; }
+
+ // Takes ownership of a widget, by taking the initial floating reference of
+ // the GtkWidget. It is expected that Own() is called right after the widget
+ // has been created, and before any other references to the widget might have
+ // been added. It is valid to never call Own(), in which case Destroy() will
+ // do nothing. If Own() has been called, you must explicitly call Destroy().
+ void Own(GtkWidget* widget);
+
+ // You may call Destroy() after you have called Own(). Calling Destroy()
+ // will call gtk_widget_destroy(), and drop our reference to the widget.
+ // Destroy() is also called in this object's destructor.
+ // After a call to Destroy(), you may call Own() again. NOTE: It is expected
+ // that after gtk_widget_destroy we will be holding the only reference left
+ // on the object. We assert this in debug mode to help catch any leaks.
+ void Destroy();
+
+ private:
+ GtkWidget* widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(OwnedWidgetGtk);
+};
+
+} // namespace ui
+
+#endif // UI_BASE_GTK_OWNED_WIDGET_GTK_H_