summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-15 17:19:26 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-15 17:19:26 +0000
commit47aeffb5c6da28dacae6d0457b6ae8966c169e23 (patch)
tree6ecbf5ed9aa921577890a1a0c1d87fee579a6bbb /views
parentf4abfbb568e292857badbf4cfd1787ca66e02376 (diff)
downloadchromium_src-47aeffb5c6da28dacae6d0457b6ae8966c169e23.zip
chromium_src-47aeffb5c6da28dacae6d0457b6ae8966c169e23.tar.gz
chromium_src-47aeffb5c6da28dacae6d0457b6ae8966c169e23.tar.bz2
Fixes two related bugs:
. Native buttons were adding 8 pixels to each side of the preferred size. This isn't necessary on Gtk as the preferred size already includes padding. . I changed WidgetGtk so that it no longer needs to explicitly set a size request. Explicitly setting a size request is a bit of pain because it means you can't ask for the widget real size request without unsetting the explicit size request. Instead I've subclassed GtkFixed so that you can either have the default behavior, or use the allocated size rather than current size. CHROME_OS_BUG=1003 TEST=see bug Review URL: http://codereview.chromium.org/504003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34564 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/controls/button/native_button.cc8
-rw-r--r--views/views.gyp2
-rw-r--r--views/widget/gtk_views_fixed.cc79
-rw-r--r--views/widget/gtk_views_fixed.h49
-rw-r--r--views/widget/widget_gtk.cc12
5 files changed, 143 insertions, 7 deletions
diff --git a/views/controls/button/native_button.cc b/views/controls/button/native_button.cc
index a8f22dd..141cf328 100644
--- a/views/controls/button/native_button.cc
+++ b/views/controls/button/native_button.cc
@@ -16,13 +16,17 @@
namespace views {
-static const int kButtonBorderHWidth = 8;
-
#if defined(OS_WIN)
// The min size in DLUs comes from
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14e.asp
static const int kMinWidthDLUs = 50;
static const int kMinHeightDLUs = 14;
+
+// Horizontal padding (on each side).
+static const int kButtonBorderHWidth = 8;
+#else
+// Horizontal padding (on each side).
+static const int kButtonBorderHWidth = 0;
#endif
// static
diff --git a/views/views.gyp b/views/views.gyp
index 11058f1..dc0de4d 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -254,6 +254,8 @@
'widget/drop_target_gtk.h',
'widget/drop_target_win.cc',
'widget/drop_target_win.h',
+ 'widget/gtk_views_fixed.cc',
+ 'widget/gtk_views_fixed.h',
'widget/root_view.cc',
'widget/root_view.h',
'widget/root_view_gtk.cc',
diff --git a/views/widget/gtk_views_fixed.cc b/views/widget/gtk_views_fixed.cc
new file mode 100644
index 0000000..0b322bb
--- /dev/null
+++ b/views/widget/gtk_views_fixed.cc
@@ -0,0 +1,79 @@
+// 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 "views/widget/gtk_views_fixed.h"
+
+// We store whether we use the widget's allocated size as a property. Ideally
+// we would stash this in GtkFixedChild, but GtkFixed doesn't allow subclassing
+// gtk_fixed_put. Alternatively we could subclass GtkContainer and use our own
+// API (effectively duplicating GtkFixed), but that means folks could no longer
+// use the GtkFixed API else where in Chrome. For now I'm going with this route.
+static const char* kUseAllocatedSize = "__VIEWS_USE_ALLOCATED_SIZE__";
+
+G_BEGIN_DECLS
+
+G_DEFINE_TYPE(GtkViewsFixed, gtk_views_fixed, GTK_TYPE_FIXED)
+
+static void gtk_views_fixed_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);
+ }
+
+ int border_width = GTK_CONTAINER(widget)->border_width;
+ GList* children = GTK_FIXED(widget)->children;
+ while (children) {
+ GtkFixedChild* child = reinterpret_cast<GtkFixedChild*>(children->data);
+ children = children->next;
+
+ if (GTK_WIDGET_VISIBLE(child->widget)) {
+ GtkAllocation child_allocation;
+
+ gpointer use_allocated_size = g_object_get_data(G_OBJECT(child->widget),
+ kUseAllocatedSize);
+ if (use_allocated_size) {
+ // NOTE: even though the size isn't changing, we have to call
+ // size_allocate, otherwise things like buttons won't repaint.
+ child_allocation.width = child->widget->allocation.width;
+ child_allocation.height = child->widget->allocation.height;
+ } else {
+ GtkRequisition child_requisition;
+ gtk_widget_get_child_requisition(child->widget, &child_requisition);
+ child_allocation.width = child_requisition.width;
+ child_allocation.height = child_requisition.height;
+ }
+ child_allocation.x = child->x + border_width;
+ child_allocation.y = child->y + border_width;
+
+ if (GTK_WIDGET_NO_WINDOW(widget)) {
+ child_allocation.x += widget->allocation.x;
+ child_allocation.y += widget->allocation.y;
+ }
+
+ gtk_widget_size_allocate(child->widget, &child_allocation);
+ }
+ }
+}
+
+static void gtk_views_fixed_class_init(GtkViewsFixedClass* views_fixed_class) {
+ GtkWidgetClass* widget_class =
+ reinterpret_cast<GtkWidgetClass*>(views_fixed_class);
+ widget_class->size_allocate = gtk_views_fixed_size_allocate;
+}
+
+static void gtk_views_fixed_init(GtkViewsFixed* fixed) {
+}
+
+GtkWidget* gtk_views_fixed_new(void) {
+ return GTK_WIDGET(g_object_new(GTK_TYPE_VIEWS_FIXED, NULL));
+}
+
+void gtk_views_fixed_set_use_allocated_size(GtkWidget* widget, bool value) {
+ g_object_set_data(G_OBJECT(widget), kUseAllocatedSize,
+ reinterpret_cast<gpointer>(value ? 1 : 0));
+}
+
+G_END_DECLS
diff --git a/views/widget/gtk_views_fixed.h b/views/widget/gtk_views_fixed.h
new file mode 100644
index 0000000..8fa3b80
--- /dev/null
+++ b/views/widget/gtk_views_fixed.h
@@ -0,0 +1,49 @@
+// 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 VIEWS_WIDGET_GTK_VIEWS_FIXED_H_
+#define VIEWS_WIDGET_GTK_VIEWS_FIXED_H_
+
+#include <gdk/gdk.h>
+#include <gtk/gtkfixed.h>
+
+// GtkViewsFixed is a subclass of GtkFixed that can give child widgets their
+// current size rather than their requested size. This behavior is controlled
+// by gtk_views_fixed_set_use_allocated_size; the default is to use the
+// Widget's requested size.
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_VIEWS_FIXED (gtk_views_fixed_get_type ())
+#define GTK_VIEWS_FIXED(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_VIEWS_FIXED, GtkViewsFixed))
+#define GTK_VIEWS_FIXED_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_VIEWS_FIXED, GtkViewsFixedClass))
+#define GTK_IS_VIEWS_FIXED(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VIEWS_FIXED))
+#define GTK_IS_VIEWS_FIXED_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_VIEWS_FIXED))
+#define GTK_VIEWS_FIXED_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VIEWS_FIXED, GtkViewsFixed))
+
+typedef struct _GtkViewsFixed GtkViewsFixed;
+typedef struct _GtkViewsFixedClass GtkViewsFixedClass;
+
+struct _GtkViewsFixed {
+ GtkFixed fixed;
+};
+
+struct _GtkViewsFixedClass {
+ GtkFixedClass parent_class;
+};
+
+GtkWidget* gtk_views_fixed_new();
+
+GType gtk_views_fixed_get_type();
+
+void gtk_views_fixed_set_use_allocated_size(GtkWidget* widget, bool value);
+
+G_END_DECLS
+
+#endif // VIEWS_WIDGET_GTK_VIEWS_FIXED_H
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index 4cb54a5..8274e2d 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -14,6 +14,7 @@
#include "base/string_util.h"
#include "views/widget/default_theme_provider.h"
#include "views/widget/drop_target_gtk.h"
+#include "views/widget/gtk_views_fixed.h"
#include "views/widget/root_view.h"
#include "views/widget/tooltip_manager_gtk.h"
#include "views/window/window_gtk.h"
@@ -149,8 +150,10 @@ void WidgetGtk::RemoveChild(GtkWidget* child) {
// We can be called after the contents widget has been destroyed, e.g. any
// NativeViewHost not removed from the view hierarchy before the window is
// closed.
- if (GTK_IS_CONTAINER(window_contents_))
+ if (GTK_IS_CONTAINER(window_contents_)) {
gtk_container_remove(GTK_CONTAINER(window_contents_), child);
+ gtk_views_fixed_set_use_allocated_size(child, false);
+ }
}
void WidgetGtk::ReparentChild(GtkWidget* child) {
@@ -159,9 +162,8 @@ void WidgetGtk::ReparentChild(GtkWidget* child) {
void WidgetGtk::PositionChild(GtkWidget* child, int x, int y, int w, int h) {
GtkAllocation alloc = { x, y, w, h };
- // For some reason we need to do both of these to size a widget.
gtk_widget_size_allocate(child, &alloc);
- gtk_widget_set_size_request(child, w, h);
+ gtk_views_fixed_set_use_allocated_size(child, true);
gtk_fixed_move(GTK_FIXED(window_contents_), child, x, y);
}
@@ -1165,7 +1167,7 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) {
// that if we use GTK's double buffering and we tried to expand the dirty
// region, it wouldn't get painted.
if (type_ == TYPE_CHILD) {
- window_contents_ = widget_ = gtk_fixed_new();
+ window_contents_ = widget_ = gtk_views_fixed_new();
gtk_widget_set_name(widget_, "views-gtkwidget-child-fixed");
GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED);
gtk_fixed_set_has_window(GTK_FIXED(widget_), true);
@@ -1200,7 +1202,7 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) {
}
SetWindowForNative(widget_, static_cast<WindowGtk*>(this));
- window_contents_ = gtk_fixed_new();
+ window_contents_ = gtk_views_fixed_new();
gtk_widget_set_name(window_contents_, "views-gtkwidget-window-fixed");
GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED);
gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true);