summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);