summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsuzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-21 05:59:08 +0000
committersuzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-21 05:59:08 +0000
commit623630cfea007bcacf01950c44d46c412d9ced8b (patch)
tree78bdd9d97037a04e13d400e05b9a43b66b7170f2
parent53d3f3046205f2d6151f61b8ef835ad708215761 (diff)
downloadchromium_src-623630cfea007bcacf01950c44d46c412d9ced8b.zip
chromium_src-623630cfea007bcacf01950c44d46c412d9ced8b.tar.gz
chromium_src-623630cfea007bcacf01950c44d46c412d9ced8b.tar.bz2
Re-land http://codereview.chromium.org/507022.
Fix failed Linux Views and ChromeOS build. BUG=11258 TEST=See bug report. Review URL: http://codereview.chromium.org/503065 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35079 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc8
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.cc4
-rw-r--r--chrome/browser/gtk/gtk_expanded_container.cc192
-rw-r--r--chrome/browser/gtk/gtk_expanded_container.h70
-rw-r--r--chrome/browser/gtk/gtk_expanded_container_unittest.cc159
-rw-r--r--chrome/browser/gtk/infobar_gtk.cc23
-rw-r--r--chrome/browser/gtk/slide_animator_gtk.cc43
-rw-r--r--chrome/browser/gtk/tab_contents_container_gtk.cc46
-rw-r--r--chrome/browser/gtk/tab_contents_container_gtk.h19
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.cc4
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc50
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.h24
-rwxr-xr-xchrome/chrome_browser.gypi2
-rwxr-xr-xchrome/chrome_tests.gypi2
14 files changed, 528 insertions, 118 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 1279dac..83c4d52 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -1583,14 +1583,6 @@ void BrowserWindowGtk::BookmarkBarIsFloating(bool is_floating) {
}
void BrowserWindowGtk::SetGeometryHints() {
- // Do not allow the user to resize us arbitrarily small. When using the
- // custom frame, the window can disappear entirely while resizing, or get
- // to a size that's very hard to resize.
- GdkGeometry geometry;
- geometry.min_width = 100;
- geometry.min_height = 100;
- gtk_window_set_geometry_hints(window_, NULL, &geometry, GDK_HINT_MIN_SIZE);
-
// If we call gtk_window_maximize followed by gtk_window_present, compiz gets
// confused and maximizes the window, but doesn't set the
// GDK_WINDOW_STATE_MAXIMIZED bit. So instead, we keep track of whether to
diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc
index 6d94b9f..0aa3c23 100644
--- a/chrome/browser/gtk/download_shelf_gtk.cc
+++ b/chrome/browser/gtk/download_shelf_gtk.cc
@@ -62,7 +62,9 @@ DownloadShelfGtk::DownloadShelfGtk(Browser* browser, GtkWidget* parent)
// Create |hbox_|.
hbox_.Own(gtk_hbox_new(FALSE, kDownloadItemPadding));
- gtk_widget_set_size_request(hbox_.get(), -1, kDownloadItemHeight);
+ // We want the download shelf to be horizontally shrinkable, so that the
+ // Chrome window can be resized freely even with many download items.
+ gtk_widget_set_size_request(hbox_.get(), 0, kDownloadItemHeight);
// Get the padding and background color for |hbox_| right.
GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
diff --git a/chrome/browser/gtk/gtk_expanded_container.cc b/chrome/browser/gtk/gtk_expanded_container.cc
new file mode 100644
index 0000000..dbcb15e
--- /dev/null
+++ b/chrome/browser/gtk/gtk_expanded_container.cc
@@ -0,0 +1,192 @@
+// Copyright (c) 2009 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 "chrome/browser/gtk/gtk_expanded_container.h"
+
+#include <gtk/gtk.h>
+#include <algorithm>
+
+namespace {
+
+enum {
+ CHILD_SIZE_REQUEST,
+ LAST_SIGNAL
+};
+
+guint expanded_container_signals[LAST_SIGNAL] = { 0 };
+
+struct SizeAllocateData {
+ GtkWidget* container;
+ GtkAllocation* allocation;
+ int border_width;
+};
+
+void GetChildPosition(GtkWidget* container, GtkWidget* child, int* x, int* y) {
+ GValue v = { 0 };
+ g_value_init(&v, G_TYPE_INT);
+ gtk_container_child_get_property(GTK_CONTAINER(container), child, "x", &v);
+ *x = g_value_get_int(&v);
+ gtk_container_child_get_property(GTK_CONTAINER(container), child, "y", &v);
+ *y = g_value_get_int(&v);
+ g_value_unset(&v);
+}
+
+void ChildSizeAllocate(GtkWidget* child, gpointer userdata) {
+ if (!GTK_WIDGET_VISIBLE(child))
+ return;
+
+ SizeAllocateData* data = reinterpret_cast<SizeAllocateData*>(userdata);
+
+ GtkRequisition child_requisition;
+ child_requisition.width = data->allocation->width - data->border_width * 2;
+ child_requisition.height = data->allocation->height - data->border_width * 2;
+
+ // We need to give whoever is pulling our strings a chance to adjust the
+ // size of our children.
+ g_signal_emit(data->container,
+ expanded_container_signals[CHILD_SIZE_REQUEST], 0,
+ child, &child_requisition);
+
+ GtkAllocation child_allocation;
+ child_allocation.width = child_requisition.width;
+ child_allocation.height = child_requisition.height;
+ if (child_allocation.width < 0 || child_allocation.height < 0) {
+ gtk_widget_get_child_requisition(child, &child_requisition);
+ if (child_allocation.width < 0)
+ child_allocation.width = child_requisition.width;
+ if (child_allocation.height < 0)
+ child_allocation.height = child_requisition.height;
+ }
+
+ int x, y;
+ GetChildPosition(data->container, child, &x, &y);
+
+ child_allocation.x = x + data->border_width;
+ child_allocation.y = y + data->border_width;
+
+ if (GTK_WIDGET_NO_WINDOW(data->container)) {
+ child_allocation.x += data->allocation->x;
+ child_allocation.y += data->allocation->y;
+ }
+ gtk_widget_size_allocate(child, &child_allocation);
+}
+
+void Marshal_VOID__OBJECT_BOXED(GClosure* closure,
+ GValue* return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data) {
+ typedef void (*GMarshalFunc_VOID__OBJECT_BOXED) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_VOID__OBJECT_BOXED callback;
+ register GCClosure *cc = reinterpret_cast<GCClosure*>(closure);
+ register gpointer data1, data2;
+
+ g_return_if_fail(n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA(closure)) {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer(param_values + 0);
+ } else {
+ data1 = g_value_peek_pointer(param_values + 0);
+ data2 = closure->data;
+ }
+
+ callback = reinterpret_cast<GMarshalFunc_VOID__OBJECT_BOXED>(
+ marshal_data ? marshal_data : cc->callback);
+
+ callback(data1,
+ g_value_get_object(param_values + 1),
+ g_value_get_boxed(param_values + 2),
+ data2);
+}
+
+} // namespace
+
+G_BEGIN_DECLS
+
+static void gtk_expanded_container_size_allocate(GtkWidget* widget,
+ GtkAllocation* allocation);
+
+G_DEFINE_TYPE(GtkExpandedContainer, gtk_expanded_container, GTK_TYPE_FIXED)
+
+static void gtk_expanded_container_class_init(
+ GtkExpandedContainerClass *klass) {
+ GtkObjectClass* object_class =
+ reinterpret_cast<GtkObjectClass*>(klass);
+
+ GtkWidgetClass* widget_class =
+ reinterpret_cast<GtkWidgetClass*>(klass);
+ widget_class->size_allocate = gtk_expanded_container_size_allocate;
+
+ expanded_container_signals[CHILD_SIZE_REQUEST] =
+ g_signal_new("child-size-request",
+ G_OBJECT_CLASS_TYPE(object_class),
+ static_cast<GSignalFlags>(G_SIGNAL_RUN_FIRST),
+ NULL,
+ NULL, NULL,
+ Marshal_VOID__OBJECT_BOXED,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_WIDGET,
+ GTK_TYPE_REQUISITION | G_SIGNAL_TYPE_STATIC_SCOPE);
+}
+
+static void gtk_expanded_container_init(GtkExpandedContainer* container) {
+}
+
+static void gtk_expanded_container_size_allocate(GtkWidget* widget,
+ GtkAllocation* allocation) {
+ widget->allocation = *allocation;
+
+ if (!GTK_WIDGET_NO_WINDOW(widget) && GTK_WIDGET_REALIZED(widget)) {
+ gdk_window_move_resize(widget->window,
+ allocation->x,
+ allocation->y,
+ allocation->width,
+ allocation->height);
+ }
+
+ SizeAllocateData data;
+ data.container = widget;
+ data.allocation = allocation;
+ data.border_width = gtk_container_get_border_width(GTK_CONTAINER(widget));
+
+ gtk_container_foreach(GTK_CONTAINER(widget), ChildSizeAllocate, &data);
+}
+
+GtkWidget* gtk_expanded_container_new() {
+ return GTK_WIDGET(g_object_new(GTK_TYPE_EXPANDED_CONTAINER, NULL));
+}
+
+void gtk_expanded_container_put(GtkExpandedContainer* container,
+ GtkWidget* widget, gint x, gint y) {
+ g_return_if_fail(GTK_IS_EXPANDED_CONTAINER(container));
+ g_return_if_fail(GTK_IS_WIDGET(widget));
+ gtk_fixed_put(GTK_FIXED(container), widget, x, y);
+}
+
+void gtk_expanded_container_move(GtkExpandedContainer* container,
+ GtkWidget* widget, gint x, gint y) {
+ g_return_if_fail(GTK_IS_EXPANDED_CONTAINER(container));
+ g_return_if_fail(GTK_IS_WIDGET(widget));
+ gtk_fixed_move(GTK_FIXED(container), widget, x, y);
+}
+
+void gtk_expanded_container_set_has_window(GtkExpandedContainer* container,
+ gboolean has_window) {
+ g_return_if_fail(GTK_IS_EXPANDED_CONTAINER(container));
+ g_return_if_fail(!GTK_WIDGET_REALIZED(container));
+ gtk_fixed_set_has_window(GTK_FIXED(container), has_window);
+}
+
+gboolean gtk_expanded_container_get_has_window(
+ GtkExpandedContainer* container) {
+ g_return_val_if_fail(GTK_IS_EXPANDED_CONTAINER(container), FALSE);
+ return gtk_fixed_get_has_window(GTK_FIXED(container));
+}
+
+G_END_DECLS
diff --git a/chrome/browser/gtk/gtk_expanded_container.h b/chrome/browser/gtk/gtk_expanded_container.h
new file mode 100644
index 0000000..396177e
--- /dev/null
+++ b/chrome/browser/gtk/gtk_expanded_container.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_GTK_GTK_EXPANDED_CONTAINER_H_
+#define CHROME_BROWSER_GTK_GTK_EXPANDED_CONTAINER_H_
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+// A specialized container derived from GtkFixed, which expands the size of its
+// children to fill the container, in one or both directions. The usage of this
+// container is similar to GtkFixed.
+//
+// The "child-size-request" signal is optional, if you want to expand child
+// widgets to customized size other than the container's size. It should have
+// the following signature:
+//
+// void (*child_size_request)(GtkExpandedContainer* container,
+// GtkWidget* child,
+// GtkRequisition* requisition);
+//
+// This signal is emitted for each child with the requisition set to the size of
+// the container. Your handler may adjust the value of the requisition. If the
+// width or height is set to -1, then that direction will not be expanded, and
+// the original size request of the child will be used.
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_EXPANDED_CONTAINER \
+ (gtk_expanded_container_get_type())
+#define GTK_EXPANDED_CONTAINER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_EXPANDED_CONTAINER, \
+ GtkExpandedContainer))
+#define GTK_EXPANDED_CONTAINER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_EXPANDED_CONTAINER, \
+ GtkExpandedContainerClass))
+#define GTK_IS_EXPANDED_CONTAINER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_EXPANDED_CONTAINER))
+#define GTK_IS_EXPANDED_CONTAINER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_EXPANDED_CONTAINER))
+#define GTK_EXPANDED_CONTAINER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_EXPANDED_CONTAINER, \
+ GtkExpandedContainerClass))
+
+typedef struct _GtkExpandedContainer GtkExpandedContainer;
+typedef struct _GtkExpandedContainerClass GtkExpandedContainerClass;
+
+struct _GtkExpandedContainer {
+ // Parent class.
+ GtkFixed fixed;
+};
+
+struct _GtkExpandedContainerClass {
+ GtkFixedClass parent_class;
+};
+
+GType gtk_expanded_container_get_type() G_GNUC_CONST;
+GtkWidget* gtk_expanded_container_new();
+void gtk_expanded_container_put(GtkExpandedContainer* container,
+ GtkWidget* widget, gint x, gint y);
+void gtk_expanded_container_move(GtkExpandedContainer* container,
+ GtkWidget* widget, gint x, gint y);
+void gtk_expanded_container_set_has_window(GtkExpandedContainer* container,
+ gboolean has_window);
+gboolean gtk_expanded_container_get_has_window(GtkExpandedContainer* container);
+
+G_END_DECLS
+
+#endif // CHROME_BROWSER_GTK_GTK_EXPANDED_CONTAINER_H_
diff --git a/chrome/browser/gtk/gtk_expanded_container_unittest.cc b/chrome/browser/gtk/gtk_expanded_container_unittest.cc
new file mode 100644
index 0000000..d400bb1
--- /dev/null
+++ b/chrome/browser/gtk/gtk_expanded_container_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright (c) 2009 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 "chrome/browser/gtk/gtk_expanded_container.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+class GtkExpandedContainerTest : public testing::Test {
+ protected:
+ GtkExpandedContainerTest()
+ : window_(gtk_window_new(GTK_WINDOW_TOPLEVEL)),
+ expanded_(gtk_expanded_container_new()) {
+ gtk_window_set_default_size(GTK_WINDOW(window_), 200, 200);
+ gtk_container_add(GTK_CONTAINER(window_), expanded_);
+ }
+ ~GtkExpandedContainerTest() {
+ gtk_widget_destroy(window_);
+ }
+
+ bool FindChild(GtkWidget* widget) {
+ GList* children = gtk_container_get_children(GTK_CONTAINER(expanded_));
+ for (GList* child = children; child; child = child->next) {
+ if (GTK_WIDGET(child->data) == widget) {
+ g_list_free(children);
+ return true;
+ }
+ }
+ g_list_free(children);
+ return false;
+ }
+
+ int GetChildX(GtkWidget* widget) {
+ GValue x = { 0 };
+ g_value_init(&x, G_TYPE_INT);
+ gtk_container_child_get_property(GTK_CONTAINER(expanded_), widget, "x", &x);
+ return g_value_get_int(&x);
+ }
+
+ int GetChildY(GtkWidget* widget) {
+ GValue y = { 0 };
+ g_value_init(&y, G_TYPE_INT);
+ gtk_container_child_get_property(GTK_CONTAINER(expanded_), widget, "y", &y);
+ return g_value_get_int(&y);
+ }
+
+ protected:
+ GtkWidget* window_;
+ GtkWidget* expanded_;
+};
+
+TEST_F(GtkExpandedContainerTest, AddRemove) {
+ GtkWidget* child1 = gtk_fixed_new();
+ GtkWidget* child2 = gtk_fixed_new();
+ gtk_container_add(GTK_CONTAINER(expanded_), child1);
+ ASSERT_TRUE(FindChild(child1));
+
+ gtk_container_add(GTK_CONTAINER(expanded_), child2);
+ ASSERT_TRUE(FindChild(child2));
+ ASSERT_TRUE(FindChild(child1));
+
+ gtk_container_remove(GTK_CONTAINER(expanded_), child1);
+ ASSERT_FALSE(FindChild(child1));
+ ASSERT_TRUE(FindChild(child2));
+
+ gtk_container_remove(GTK_CONTAINER(expanded_), child2);
+ ASSERT_FALSE(FindChild(child2));
+}
+
+TEST_F(GtkExpandedContainerTest, Expand) {
+ GtkWidget* child1 = gtk_fixed_new();
+ GtkWidget* child2 = gtk_fixed_new();
+ gtk_container_add(GTK_CONTAINER(expanded_), child1);
+ gtk_expanded_container_put(GTK_EXPANDED_CONTAINER(expanded_),
+ child2, 10, 20);
+ gtk_widget_show_all(window_);
+
+ GtkAllocation allocation = { 0, 0, 50, 100 };
+ gtk_widget_size_allocate(expanded_, &allocation);
+
+ EXPECT_EQ(0, child1->allocation.x);
+ EXPECT_EQ(0, child1->allocation.y);
+ EXPECT_EQ(50, child1->allocation.width);
+ EXPECT_EQ(100, child1->allocation.height);
+
+ EXPECT_EQ(10, child2->allocation.x);
+ EXPECT_EQ(20, child2->allocation.y);
+ EXPECT_EQ(50, child2->allocation.width);
+ EXPECT_EQ(100, child2->allocation.height);
+
+ allocation.x = 10;
+ allocation.y = 20;
+ gtk_widget_size_allocate(expanded_, &allocation);
+
+ EXPECT_EQ(10, child1->allocation.x);
+ EXPECT_EQ(20, child1->allocation.y);
+ EXPECT_EQ(20, child2->allocation.x);
+ EXPECT_EQ(40, child2->allocation.y);
+}
+
+// Test if the size allocation for children still works when using own
+// GdkWindow. In this case, the children's origin starts from (0, 0) rather
+// than the container's origin.
+TEST_F(GtkExpandedContainerTest, HasWindow) {
+ GtkWidget* child = gtk_fixed_new();
+ gtk_container_add(GTK_CONTAINER(expanded_), child);
+ gtk_expanded_container_set_has_window(GTK_EXPANDED_CONTAINER(expanded_),
+ TRUE);
+ gtk_widget_show_all(window_);
+
+ GtkAllocation allocation = { 10, 10, 50, 100 };
+ gtk_widget_size_allocate(expanded_, &allocation);
+
+ EXPECT_EQ(0, child->allocation.x);
+ EXPECT_EQ(0, child->allocation.y);
+ EXPECT_EQ(50, child->allocation.width);
+ EXPECT_EQ(100, child->allocation.height);
+}
+
+static void OnChildSizeRequest(GtkExpandedContainer* container,
+ GtkWidget* child,
+ GtkRequisition* requisition,
+ gpointer userdata) {
+ ASSERT_EQ(child, GTK_WIDGET(userdata));
+ requisition->width = 250;
+ requisition->height = -1;
+}
+
+TEST_F(GtkExpandedContainerTest, ChildSizeRequest) {
+ GtkWidget* child = gtk_fixed_new();
+ gtk_widget_set_size_request(child, 10, 25);
+ g_signal_connect(expanded_, "child-size-request",
+ G_CALLBACK(OnChildSizeRequest), child);
+ gtk_container_add(GTK_CONTAINER(expanded_), child);
+ gtk_widget_show_all(window_);
+
+ GtkAllocation allocation = { 0, 0, 300, 100 };
+ gtk_widget_size_allocate(expanded_, &allocation);
+
+ EXPECT_EQ(0, child->allocation.x);
+ EXPECT_EQ(0, child->allocation.y);
+ EXPECT_EQ(250, child->allocation.width);
+ EXPECT_EQ(25, child->allocation.height);
+}
+
+TEST_F(GtkExpandedContainerTest, ChildPosition) {
+ GtkWidget* child = gtk_fixed_new();
+ gtk_expanded_container_put(GTK_EXPANDED_CONTAINER(expanded_),
+ child, 10, 20);
+ gtk_widget_show_all(window_);
+
+ EXPECT_EQ(10, GetChildX(child));
+ EXPECT_EQ(20, GetChildY(child));
+
+ gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(expanded_),
+ child, 40, 50);
+ EXPECT_EQ(40, GetChildX(child));
+ EXPECT_EQ(50, GetChildY(child));
+}
diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc
index 6562bbc..c360aef 100644
--- a/chrome/browser/gtk/infobar_gtk.cc
+++ b/chrome/browser/gtk/infobar_gtk.cc
@@ -188,8 +188,13 @@ class AlertInfoBar : public InfoBar {
: InfoBar(delegate) {
std::wstring text = delegate->GetMessageText();
GtkWidget* label = gtk_label_new(WideToUTF8(text).c_str());
+ // We want the label to be horizontally shrinkable, so that the Chrome
+ // window can be resized freely even with a very long message.
+ gtk_widget_set_size_request(label, 0, -1);
+ gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
- gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox_), label, TRUE, TRUE, 0);
gtk_widget_show_all(border_bin_.get());
}
@@ -215,13 +220,23 @@ class LinkInfoBar : public InfoBar {
G_CALLBACK(OnLinkClick), this);
gtk_util::SetButtonTriggersNavigation(link_button);
+ GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
+ // We want the link to be horizontally shrinkable, so that the Chrome
+ // window can be resized freely even with a very long link.
+ gtk_widget_set_size_request(hbox, 0, -1);
+ gtk_box_pack_start(GTK_BOX(hbox_), hbox, TRUE, TRUE, 0);
// If link_offset is npos, we right-align the link instead of embedding it
// in the text.
if (link_offset == std::wstring::npos) {
- gtk_box_pack_end(GTK_BOX(hbox_), link_button, FALSE, FALSE, 0);
+ gtk_box_pack_end(GTK_BOX(hbox), link_button, FALSE, FALSE, 0);
GtkWidget* label = gtk_label_new(WideToUTF8(display_text).c_str());
+ // In order to avoid the link_button and the label overlapping with each
+ // other, we make the label shrinkable.
+ gtk_widget_set_size_request(label, 0, -1);
+ gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
- gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
} else {
GtkWidget* initial_label = gtk_label_new(
WideToUTF8(display_text.substr(0, link_offset)).c_str());
@@ -233,11 +248,9 @@ class LinkInfoBar : public InfoBar {
// We don't want any spacing between the elements, so we pack them into
// this hbox that doesn't use kElementPadding.
- GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0);
gtk_util::CenterWidgetInHBox(hbox, link_button, false, 0);
gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox_), hbox, FALSE, FALSE, 0);
}
gtk_widget_show_all(border_bin_.get());
diff --git a/chrome/browser/gtk/slide_animator_gtk.cc b/chrome/browser/gtk/slide_animator_gtk.cc
index 329aaa4..ba48e46 100644
--- a/chrome/browser/gtk/slide_animator_gtk.cc
+++ b/chrome/browser/gtk/slide_animator_gtk.cc
@@ -8,14 +8,20 @@
#include "app/slide_animation.h"
#include "base/logging.h"
+#include "chrome/browser/gtk/gtk_expanded_container.h"
+
namespace {
-void OnFixedSizeAllocate(GtkWidget* fixed,
- GtkAllocation* allocation,
- GtkWidget* child) {
- // The size of the GtkFixed has changed. We want |child_| to match widths,
- // but the height should not change.
- gtk_widget_set_size_request(child, allocation->width, -1);
+void OnChildSizeRequest(GtkWidget* expanded,
+ GtkWidget* child,
+ GtkRequisition* requisition,
+ gpointer control_child_size) {
+ // If |control_child_size| is true, then we want |child_| to match the width
+ // of the |widget_|, but the height of |child_| should not change.
+ if (!GPOINTER_TO_INT(control_child_size)) {
+ requisition->width = -1;
+ }
+ requisition->height = -1;
}
} // namespace
@@ -29,16 +35,16 @@ SlideAnimatorGtk::SlideAnimatorGtk(GtkWidget* child,
: child_(child),
direction_(direction),
delegate_(delegate) {
- widget_.Own(gtk_fixed_new());
- gtk_fixed_put(GTK_FIXED(widget_.get()), child, 0, 0);
+ widget_.Own(gtk_expanded_container_new());
+ gtk_container_add(GTK_CONTAINER(widget_.get()), child);
gtk_widget_set_size_request(widget_.get(), -1, 0);
- if (control_child_size) {
- // If the child requests it, we will manually set the size request for
- // |child_| every time the GtkFixed changes sizes. This is mainly useful
- // for bars, where we want the child to expand to fill all available space.
- g_signal_connect(widget_.get(), "size-allocate",
- G_CALLBACK(OnFixedSizeAllocate), child_);
- }
+
+ // If the child requests it, we will manually set the size request for
+ // |child_| every time the |widget_| changes sizes. This is mainly useful
+ // for bars, where we want the child to expand to fill all available space.
+ g_signal_connect(widget_.get(), "child-size-request",
+ G_CALLBACK(OnChildSizeRequest),
+ GINT_TO_POINTER(control_child_size));
// We connect to this signal to set an initial position for our child widget.
// The reason we connect to this signal rather than setting the initial
@@ -106,8 +112,8 @@ void SlideAnimatorGtk::AnimationProgressed(const Animation* animation) {
int showing_height = static_cast<int>(req.height *
animation_->GetCurrentValue());
if (direction_ == DOWN) {
- gtk_fixed_move(GTK_FIXED(widget_.get()), child_, 0,
- showing_height - req.height);
+ gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(widget_.get()),
+ child_, 0, showing_height - req.height);
child_needs_move_ = false;
}
gtk_widget_set_size_request(widget_.get(), -1, showing_height);
@@ -126,7 +132,8 @@ void SlideAnimatorGtk::OnChildSizeAllocate(GtkWidget* child,
GtkAllocation* allocation,
SlideAnimatorGtk* slider) {
if (slider->child_needs_move_) {
- gtk_fixed_move(GTK_FIXED(slider->widget()), child, 0, -allocation->height);
+ gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(slider->widget()),
+ child, 0, -allocation->height);
slider->child_needs_move_ = false;
}
}
diff --git a/chrome/browser/gtk/tab_contents_container_gtk.cc b/chrome/browser/gtk/tab_contents_container_gtk.cc
index a4fe973..fcf6a3d 100644
--- a/chrome/browser/gtk/tab_contents_container_gtk.cc
+++ b/chrome/browser/gtk/tab_contents_container_gtk.cc
@@ -6,30 +6,13 @@
#include "app/gfx/native_widget_types.h"
#include "app/l10n_util.h"
+#include "chrome/browser/gtk/gtk_expanded_container.h"
#include "chrome/browser/gtk/gtk_floating_container.h"
#include "chrome/browser/gtk/status_bubble_gtk.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/common/notification_service.h"
-namespace {
-
-// Allocates all normal tab contents views to the size of the passed in
-// |allocation|.
-void ResizeChildren(GtkWidget* widget, void* param) {
- GtkAllocation* allocation = reinterpret_cast<GtkAllocation*>(param);
- if (!GTK_WIDGET_VISIBLE(widget))
- return;
-
- if (widget->allocation.width != allocation->width ||
- widget->allocation.height != allocation->height) {
- gtk_widget_set_size_request(widget, allocation->width,
- allocation->height);
- }
-}
-
-} // namespace
-
TabContentsContainerGtk::TabContentsContainerGtk(StatusBubbleGtk* status_bubble)
: tab_contents_(NULL),
status_bubble_(status_bubble) {
@@ -44,7 +27,7 @@ void TabContentsContainerGtk::Init() {
// A high level overview of the TabContentsContainer:
//
// +- GtkFloatingContainer |floating_| -------------------------------+
- // |+- GtkFixedContainer |fixed_| -----------------------------------+|
+ // |+- GtkExpandedContainer |expanded_| -----------------------------+|
// || ||
// || ||
// || ||
@@ -57,10 +40,8 @@ void TabContentsContainerGtk::Init() {
floating_.Own(gtk_floating_container_new());
gtk_widget_set_name(floating_.get(), "chrome-tab-contents-container");
- fixed_ = gtk_fixed_new();
- g_signal_connect(fixed_, "size-allocate",
- G_CALLBACK(OnFixedSizeAllocate), this);
- gtk_container_add(GTK_CONTAINER(floating_.get()), fixed_);
+ expanded_ = gtk_expanded_container_new();
+ gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_);
if (status_bubble_) {
gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()),
@@ -69,7 +50,7 @@ void TabContentsContainerGtk::Init() {
G_CALLBACK(OnSetFloatingPosition), this);
}
- gtk_widget_show(fixed_);
+ gtk_widget_show(expanded_);
gtk_widget_show(floating_.get());
ViewIDUtil::SetDelegateForWidget(widget(), this);
@@ -105,8 +86,8 @@ void TabContentsContainerGtk::SetTabContents(TabContents* tab_contents) {
gfx::NativeView widget = tab_contents_->GetNativeView();
if (widget) {
- if (widget->parent != fixed_)
- gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0);
+ if (widget->parent != expanded_)
+ gtk_container_add(GTK_CONTAINER(expanded_), widget);
gtk_widget_show(widget);
}
@@ -127,8 +108,8 @@ void TabContentsContainerGtk::DetachTabContents(TabContents* tab_contents) {
// It is possible to detach an unrealized, unparented TabContents if you
// slow things down enough in valgrind. Might happen in the real world, too.
if (widget && widget->parent) {
- DCHECK_EQ(widget->parent, fixed_);
- gtk_container_remove(GTK_CONTAINER(fixed_), widget);
+ DCHECK_EQ(widget->parent, expanded_);
+ gtk_container_remove(GTK_CONTAINER(expanded_), widget);
}
}
@@ -176,15 +157,6 @@ GtkWidget* TabContentsContainerGtk::GetWidgetForViewID(ViewID view_id) {
// -----------------------------------------------------------------------------
// static
-void TabContentsContainerGtk::OnFixedSizeAllocate(
- GtkWidget* fixed,
- GtkAllocation* allocation,
- TabContentsContainerGtk* container) {
- // Set all the tab contents GtkWidgets to the size of the allocation.
- gtk_container_foreach(GTK_CONTAINER(fixed), ResizeChildren, allocation);
-}
-
-// static
void TabContentsContainerGtk::OnSetFloatingPosition(
GtkFloatingContainer* floating_container, GtkAllocation* allocation,
TabContentsContainerGtk* tab_contents_container) {
diff --git a/chrome/browser/gtk/tab_contents_container_gtk.h b/chrome/browser/gtk/tab_contents_container_gtk.h
index 8a7a8c7..91c2301 100644
--- a/chrome/browser/gtk/tab_contents_container_gtk.h
+++ b/chrome/browser/gtk/tab_contents_container_gtk.h
@@ -58,15 +58,6 @@ class TabContentsContainerGtk : public NotificationObserver,
// get notified.
void TabContentsDestroyed(TabContents* contents);
- // Implements our hack around a GtkFixed. The entire size of the GtkFixed is
- // allocated to normal tab contents views, while the status bubble is
- // informed of its parent and its parent's allocation (it makes a decision
- // about layout later.)
- static void OnFixedSizeAllocate(
- GtkWidget* fixed,
- GtkAllocation* allocation,
- TabContentsContainerGtk* container);
-
// Handler for |floating_|'s "set-floating-position" signal. During this
// callback, we manually set the position of the status bubble.
static void OnSetFloatingPosition(
@@ -82,16 +73,16 @@ class TabContentsContainerGtk : public NotificationObserver,
StatusBubbleGtk* status_bubble_;
// Top of the TabContentsContainerGtk widget hierarchy. A cross between a
- // GtkBin and a GtkFixed, |floating_| has |fixed_| as its one "real" child,
+ // GtkBin and a GtkFixed, |floating_| has |expanded_| as its one "real" child,
// and the various things that hang off the bottom (status bubble, etc) have
// their positions manually set in OnSetFloatingPosition.
OwnedWidgetGtk floating_;
- // We insert and remove TabContents GtkWidgets into this fixed_. This should
- // not be a GtkVBox since there were errors with timing where the vbox was
- // horizontally split with the top half displaying the current TabContents
+ // We insert and remove TabContents GtkWidgets into this expanded_. This
+ // should not be a GtkVBox since there were errors with timing where the vbox
+ // was horizontally split with the top half displaying the current TabContents
// and bottom half displaying the loading page.
- GtkWidget* fixed_;
+ GtkWidget* expanded_;
DISALLOW_COPY_AND_ASSIGN(TabContentsContainerGtk);
};
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index 0993372..2f2aa0e 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -711,7 +711,9 @@ void TabStripGtk::Init() {
tabstrip_.Own(gtk_fixed_new());
ViewIDUtil::SetID(tabstrip_.get(), VIEW_ID_TAB_STRIP);
- gtk_widget_set_size_request(tabstrip_.get(), -1,
+ // We want the tab strip to be horizontally shrinkable, so that the Chrome
+ // window can be resized freely.
+ gtk_widget_set_size_request(tabstrip_.get(), 0,
TabGtk::GetMinimumUnselectedSize().height());
gtk_widget_set_app_paintable(tabstrip_.get(), TRUE);
gtk_drag_dest_set(tabstrip_.get(), GTK_DEST_DEFAULT_ALL,
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
index f37e3e6..2c94b7d 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
@@ -19,6 +19,7 @@
#include "chrome/browser/gtk/blocked_popup_container_view_gtk.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/constrained_window_gtk.h"
+#include "chrome/browser/gtk/gtk_expanded_container.h"
#include "chrome/browser/gtk/gtk_floating_container.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/sad_tab_gtk.h"
@@ -100,16 +101,6 @@ gboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
return FALSE;
}
-// Used with gtk_container_foreach to change the sizes of the children of
-// |fixed_|.
-void SetSizeRequest(GtkWidget* widget, gpointer userdata) {
- gfx::Size* size = static_cast<gfx::Size*>(userdata);
- if (widget->allocation.width != size->width() ||
- widget->allocation.height != size->height()) {
- gtk_widget_set_size_request(widget, size->width(), size->height());
- }
-}
-
} // namespace
// static
@@ -120,16 +111,18 @@ TabContentsView* TabContentsView::Create(TabContents* tab_contents) {
TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents)
: TabContentsView(tab_contents),
floating_(gtk_floating_container_new()),
- fixed_(gtk_fixed_new()),
+ expanded_(gtk_expanded_container_new()),
popup_view_(NULL) {
- gtk_widget_set_name(fixed_, "chrome-tab-contents-view");
- g_signal_connect(fixed_, "size-allocate",
+ gtk_widget_set_name(expanded_, "chrome-tab-contents-view");
+ g_signal_connect(expanded_, "size-allocate",
G_CALLBACK(OnSizeAllocate), this);
+ g_signal_connect(expanded_, "child-size-request",
+ G_CALLBACK(OnChildSizeRequest), this);
g_signal_connect(floating_.get(), "set-floating-position",
G_CALLBACK(OnSetFloatingPosition), this);
- gtk_container_add(GTK_CONTAINER(floating_.get()), fixed_);
- gtk_widget_show(fixed_);
+ gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_);
+ gtk_widget_show(expanded_);
gtk_widget_show(floating_.get());
registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED,
Source<TabContents>(tab_contents));
@@ -179,8 +172,6 @@ void TabContentsViewGtk::RemoveConstrainedWindow(
void TabContentsViewGtk::CreateView(const gfx::Size& initial_size) {
requested_size_ = initial_size;
- gtk_widget_set_size_request(fixed_, requested_size_.width(),
- requested_size_.height());
}
RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget(
@@ -241,9 +232,9 @@ void TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const {
// animation.
int x = 0;
int y = 0;
- if (fixed_->window)
- gdk_window_get_origin(fixed_->window, &x, &y);
- out->SetRect(x + fixed_->allocation.x, y + fixed_->allocation.y,
+ if (expanded_->window)
+ gdk_window_get_origin(expanded_->window, &x, &y);
+ out->SetRect(x + expanded_->allocation.x, y + expanded_->allocation.y,
requested_size_.width(), requested_size_.height());
}
@@ -360,7 +351,7 @@ void TabContentsViewGtk::StartDragging(const WebDropData& drop_data,
// -----------------------------------------------------------------------------
void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) {
- gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0);
+ gtk_container_add(GTK_CONTAINER(expanded_), widget);
}
gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget,
@@ -369,9 +360,19 @@ gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget,
return FALSE;
}
-gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
- GtkAllocation* allocation,
+void TabContentsViewGtk::OnChildSizeRequest(GtkWidget* widget,
+ GtkWidget* child,
+ GtkRequisition* requisition,
TabContentsViewGtk* view) {
+ if (view->tab_contents()->delegate()) {
+ requisition->height +=
+ view->tab_contents()->delegate()->GetExtraRenderViewHeight();
+ }
+}
+
+void TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
+ GtkAllocation* allocation,
+ TabContentsViewGtk* view) {
int width = allocation->width;
int height = allocation->height;
// |delegate()| can be NULL here during browser teardown.
@@ -379,7 +380,6 @@ gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
height += view->tab_contents()->delegate()->GetExtraRenderViewHeight();
gfx::Size size(width, height);
view->requested_size_ = size;
- gtk_container_foreach(GTK_CONTAINER(widget), SetSizeRequest, &size);
// We manually tell our RWHV to resize the renderer content. This avoids
// spurious resizes from GTK+.
@@ -387,8 +387,6 @@ gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
view->tab_contents()->render_widget_host_view()->SetSize(size);
if (view->tab_contents()->interstitial_page())
view->tab_contents()->interstitial_page()->SetSize(size);
-
- return FALSE;
}
// static
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h
index 61e5e21..5b1d820 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.h
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h
@@ -89,22 +89,30 @@ class TabContentsViewGtk : public TabContentsView,
static gboolean OnMouseDown(GtkWidget* widget,
GdkEventButton* event, TabContentsViewGtk* view);
- // Used to propagate size changes on |fixed_| to its children.
- static gboolean OnSizeAllocate(GtkWidget* widget,
- GtkAllocation* config,
+ // Used to adjust the size of its children when the size of |expanded_| is
+ // changed.
+ static void OnChildSizeRequest(GtkWidget* widget,
+ GtkWidget* child,
+ GtkRequisition* requisition,
TabContentsViewGtk* view);
+ // Used to propagate the size change of |expanded_| to our RWHV to resize the
+ // renderer content.
+ static void OnSizeAllocate(GtkWidget* widget,
+ GtkAllocation* allocation,
+ TabContentsViewGtk* view);
+
static void OnSetFloatingPosition(
GtkFloatingContainer* floating_container, GtkAllocation* allocation,
TabContentsViewGtk* tab_contents_view);
- // Contains |fixed_| as its GtkBin member and a possible floating widget from
- // |popup_view_|.
+ // Contains |expanded_| as its GtkBin member and a possible floating widget
+ // from |popup_view_|.
OwnedWidgetGtk floating_;
- // This container holds the tab's web page views. It is a GtkFixed so that we
- // can control the size of the web pages.
- GtkWidget* fixed_;
+ // This container holds the tab's web page views. It is a GtkExpandedContainer
+ // so that we can control the size of the web pages.
+ GtkWidget* expanded_;
// The context menu is reset every time we show it, but we keep a pointer to
// between uses so that it won't go out of scope before we're done with it.
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 1214947..baf2cdd 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -860,6 +860,8 @@
'browser/gtk/gtk_chrome_button.h',
'browser/gtk/gtk_chrome_link_button.cc',
'browser/gtk/gtk_chrome_link_button.h',
+ 'browser/gtk/gtk_expanded_container.cc',
+ 'browser/gtk/gtk_expanded_container.h',
'browser/gtk/gtk_floating_container.cc',
'browser/gtk/gtk_floating_container.h',
'browser/gtk/gtk_theme_provider.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index aad10e6..b46f985 100755
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -686,6 +686,7 @@
'browser/google_update_settings_posix_unittest.cc',
'browser/gtk/bookmark_bar_gtk_unittest.cc',
'browser/gtk/bookmark_editor_gtk_unittest.cc',
+ 'browser/gtk/gtk_expanded_container_unittest.cc',
'browser/gtk/gtk_theme_provider_unittest.cc',
'browser/gtk/go_button_gtk_unittest.cc',
'browser/gtk/keyword_editor_view_unittest.cc',
@@ -902,6 +903,7 @@
['exclude', 'browser/gtk/bookmark_bar_gtk_unittest\\.cc$'],
['exclude', 'browser/gtk/bookmark_editor_gtk_unittest\\.cc$'],
['exclude', 'browser/gtk/go_button_gtk_unittest\\.cc$'],
+ ['exclude', 'browser/gtk/gtk_expanded_container_unittest\\.cc$'],
['exclude', 'browser/gtk/tabs/tab_renderer_gtk_unittest\\.cc$'],
['exclude', 'browser/gtk/options/cookies_view_unittest\\.cc$'],
['exclude', 'browser/gtk/options/languages_page_gtk_unittest\\.cc$'],