[libwnck] pager: Improved geometry management
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libwnck] pager: Improved geometry management
- Date: Thu, 3 Feb 2011 14:11:14 +0000 (UTC)
commit 08f4209683ff4acfb8407c765eb8195725e7c23d
Author: Vincent Untz <vuntz gnome org>
Date: Thu Feb 3 14:47:42 2011 +0100
pager: Improved geometry management
Implement get_preferred_width_for_height() and
get_preferred_height_for_width(), by re-using bits from
wnck_pager_size_request().
Also implement get_request_mode(): we consider that a vertical
orientation means we have a hard constraint for the width, while an
horizontal orientation means a hard constraint for the height. Since the
orientation is mostly used for applets, this makes sense.
This should fix some weird initial size issues with the pager.
libwnck/pager.c | 349 +++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 263 insertions(+), 86 deletions(-)
---
diff --git a/libwnck/pager.c b/libwnck/pager.c
index 5a88ef0..edba751 100644
--- a/libwnck/pager.c
+++ b/libwnck/pager.c
@@ -111,12 +111,21 @@ static void wnck_pager_finalize (GObject *object);
static void wnck_pager_realize (GtkWidget *widget);
static void wnck_pager_unrealize (GtkWidget *widget);
+static GtkSizeRequestMode wnck_pager_get_request_mode (GtkWidget *widget);
static void wnck_pager_get_preferred_width (GtkWidget *widget,
int *minimum_width,
int *natural_width);
+static void wnck_pager_get_preferred_width_for_height (GtkWidget *widget,
+ int height,
+ int *minimum_width,
+ int *natural_width);
static void wnck_pager_get_preferred_height (GtkWidget *widget,
int *minimum_height,
int *natural_height);
+static void wnck_pager_get_preferred_height_for_width (GtkWidget *widget,
+ int width,
+ int *minimum_height,
+ int *natural_height);
static void wnck_pager_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean wnck_pager_draw (GtkWidget *widget,
@@ -250,8 +259,11 @@ wnck_pager_class_init (WnckPagerClass *klass)
widget_class->realize = wnck_pager_realize;
widget_class->unrealize = wnck_pager_unrealize;
+ widget_class->get_request_mode = wnck_pager_get_request_mode;
widget_class->get_preferred_width = wnck_pager_get_preferred_width;
+ widget_class->get_preferred_width_for_height = wnck_pager_get_preferred_width_for_height;
widget_class->get_preferred_height = wnck_pager_get_preferred_height;
+ widget_class->get_preferred_height_for_width = wnck_pager_get_preferred_height_for_width;
widget_class->size_allocate = wnck_pager_size_allocate;
widget_class->draw = wnck_pager_draw;
widget_class->button_press_event = wnck_pager_button_press;
@@ -392,6 +404,87 @@ wnck_pager_unrealize (GtkWidget *widget)
GTK_WIDGET_CLASS (wnck_pager_parent_class)->unrealize (widget);
}
+static int
+_wnck_pager_get_workspace_width_for_height (WnckPager *pager,
+ int workspace_height)
+{
+ int workspace_width = 0;
+
+ if (pager->priv->display_mode == WNCK_PAGER_DISPLAY_CONTENT)
+ {
+ WnckWorkspace *space;
+ double screen_aspect;
+
+ space = wnck_screen_get_workspace (pager->priv->screen, 0);
+
+ if (space) {
+ screen_aspect =
+ (double) wnck_workspace_get_width (space) /
+ (double) wnck_workspace_get_height (space);
+ } else {
+ screen_aspect =
+ (double) wnck_screen_get_width (pager->priv->screen) /
+ (double) wnck_screen_get_height (pager->priv->screen);
+ }
+
+ workspace_width = screen_aspect * workspace_height;
+ }
+ else
+ {
+ PangoLayout *layout;
+ WnckScreen *screen;
+ int n_spaces;
+ int i, w;
+
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (pager), NULL);
+ screen = pager->priv->screen;
+ n_spaces = wnck_screen_get_workspace_count (pager->priv->screen);
+ workspace_width = 1;
+
+ for (i = 0; i < n_spaces; i++)
+ {
+ pango_layout_set_text (layout,
+ wnck_workspace_get_name (wnck_screen_get_workspace (screen, i)),
+ -1);
+ pango_layout_get_pixel_size (layout, &w, NULL);
+ workspace_width = MAX (workspace_width, w);
+ }
+
+ g_object_unref (layout);
+
+ workspace_width += 2;
+ }
+
+ return workspace_width;
+}
+
+static int
+_wnck_pager_get_workspace_height_for_width (WnckPager *pager,
+ int workspace_width)
+{
+ int workspace_height = 0;
+ WnckWorkspace *space;
+ double screen_aspect;
+
+ /* TODO: Handle WNCK_PAGER_DISPLAY_NAME for this case */
+
+ space = wnck_screen_get_workspace (pager->priv->screen, 0);
+
+ if (space) {
+ screen_aspect =
+ (double) wnck_workspace_get_height (space) /
+ (double) wnck_workspace_get_width (space);
+ } else {
+ screen_aspect =
+ (double) wnck_screen_get_height (pager->priv->screen) /
+ (double) wnck_screen_get_width (pager->priv->screen);
+ }
+
+ workspace_height = screen_aspect * workspace_width;
+
+ return workspace_height;
+}
+
static void
wnck_pager_size_request (GtkWidget *widget,
GtkRequisition *requisition)
@@ -399,12 +492,9 @@ wnck_pager_size_request (GtkWidget *widget,
WnckPager *pager;
int n_spaces;
int spaces_per_row;
- double screen_aspect;
- int other_dimension_size;
- int size;
+ int workspace_width, workspace_height;
int n_rows;
int focus_width;
- WnckWorkspace *space;
pager = WNCK_PAGER (widget);
@@ -413,98 +503,38 @@ wnck_pager_size_request (GtkWidget *widget,
_wnck_pager_set_screen (pager);
g_assert (pager->priv->screen != NULL);
+ g_assert (pager->priv->n_rows > 0);
+
n_spaces = wnck_screen_get_workspace_count (pager->priv->screen);
- g_assert (pager->priv->n_rows > 0);
- spaces_per_row = (n_spaces + pager->priv->n_rows - 1) / pager->priv->n_rows;
- space = wnck_screen_get_workspace (pager->priv->screen, 0);
+ if (pager->priv->show_all_workspaces)
+ {
+ n_rows = pager->priv->n_rows;
+ spaces_per_row = (n_spaces + n_rows - 1) / n_rows;
+ }
+ else
+ {
+ n_rows = 1;
+ spaces_per_row = 1;
+ }
if (pager->priv->orientation == GTK_ORIENTATION_VERTICAL)
{
- if (space) {
- screen_aspect =
- (double) wnck_workspace_get_height (space) /
- (double) wnck_workspace_get_width (space);
- } else {
- screen_aspect =
- (double) wnck_screen_get_height (pager->priv->screen) /
- (double) wnck_screen_get_width (pager->priv->screen);
- }
-
- /* TODO: Handle WNCK_PAGER_DISPLAY_NAME for this case */
+ workspace_width = pager->priv->workspace_size;
+ workspace_height = _wnck_pager_get_workspace_height_for_width (pager,
+ workspace_width);
- if (pager->priv->show_all_workspaces)
- {
- size = pager->priv->workspace_size;
- n_rows = pager->priv->n_rows;
- }
- else
- {
- size = pager->priv->workspace_size;
- n_rows = 1;
- spaces_per_row = 1;
- }
-
- other_dimension_size = screen_aspect * size;
-
- requisition->width = size * n_rows + (n_rows - 1);
- requisition->height = other_dimension_size * spaces_per_row + (spaces_per_row - 1);
+ requisition->width = workspace_width * n_rows + (n_rows - 1);
+ requisition->height = workspace_height * spaces_per_row + (spaces_per_row - 1);
}
else
{
- if (space) {
- screen_aspect =
- (double) wnck_workspace_get_width (space) /
- (double) wnck_workspace_get_height (space);
- } else {
- screen_aspect =
- (double) wnck_screen_get_width (pager->priv->screen) /
- (double) wnck_screen_get_height (pager->priv->screen);
- }
+ workspace_height = pager->priv->workspace_size;
+ workspace_width = _wnck_pager_get_workspace_width_for_height (pager,
+ workspace_height);
- if (pager->priv->show_all_workspaces)
- {
- size = pager->priv->workspace_size;
- n_rows = pager->priv->n_rows;
- }
- else
- {
- size = pager->priv->workspace_size;
- n_rows = 1;
- spaces_per_row = 1;
- }
-
- if (pager->priv->display_mode == WNCK_PAGER_DISPLAY_CONTENT)
- {
- other_dimension_size = screen_aspect * size;
- }
- else
- {
- int n_spaces, i, w;
- WnckScreen *screen;
- PangoLayout *layout;
-
- n_spaces = wnck_screen_get_workspace_count (pager->priv->screen);
- layout = gtk_widget_create_pango_layout (widget, NULL);
- screen = pager->priv->screen;
- other_dimension_size = 1;
-
- for (i = 0; i < n_spaces; i++)
- {
- pango_layout_set_text (layout,
- wnck_workspace_get_name (wnck_screen_get_workspace (screen, i)),
- -1);
- pango_layout_get_pixel_size (layout, &w, NULL);
- other_dimension_size = MAX (other_dimension_size, w);
- }
-
- g_object_unref (layout);
-
- other_dimension_size += 2;
- }
-
- requisition->width = other_dimension_size * spaces_per_row + (spaces_per_row - 1);
- requisition->height = size * n_rows + (n_rows - 1);
+ requisition->width = workspace_width * spaces_per_row + (spaces_per_row - 1);
+ requisition->height = workspace_height * n_rows + (n_rows - 1);
}
if (pager->priv->shadow_type != GTK_SHADOW_NONE)
@@ -529,6 +559,19 @@ wnck_pager_size_request (GtkWidget *widget,
requisition->height += 2 * focus_width;
}
+static GtkSizeRequestMode
+wnck_pager_get_request_mode (GtkWidget *widget)
+{
+ WnckPager *pager;
+
+ pager = WNCK_PAGER (widget);
+
+ if (pager->priv->orientation == GTK_ORIENTATION_VERTICAL)
+ return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+ else
+ return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+
static void
wnck_pager_get_preferred_width (GtkWidget *widget,
int *minimum_width,
@@ -542,6 +585,73 @@ wnck_pager_get_preferred_width (GtkWidget *widget,
}
static void
+wnck_pager_get_preferred_width_for_height (GtkWidget *widget,
+ int height,
+ int *minimum_width,
+ int *natural_width)
+{
+ WnckPager *pager;
+ int n_spaces;
+ int n_rows;
+ int spaces_per_row;
+ int workspace_width, workspace_height;
+ int focus_width;
+ int width = 0;
+
+ pager = WNCK_PAGER (widget);
+
+ /* if we're not realized, we don't know about our screen yet */
+ if (pager->priv->screen == NULL)
+ _wnck_pager_set_screen (pager);
+ g_assert (pager->priv->screen != NULL);
+
+ g_assert (pager->priv->n_rows > 0);
+
+ n_spaces = wnck_screen_get_workspace_count (pager->priv->screen);
+
+ if (pager->priv->show_all_workspaces)
+ {
+ n_rows = pager->priv->n_rows;
+ spaces_per_row = (n_spaces + n_rows - 1) / n_rows;
+ }
+ else
+ {
+ n_rows = 1;
+ spaces_per_row = 1;
+ }
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ NULL);
+
+ height -= 2 * focus_width;
+ width += 2 * focus_width;
+
+ if (pager->priv->shadow_type != GTK_SHADOW_NONE)
+ {
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder padding;
+
+ state = gtk_widget_get_state_flags (widget);
+ context = gtk_widget_get_style_context (widget);
+ gtk_style_context_get_padding (context, state, &padding);
+
+ height -= padding.top + padding.bottom;
+ width += padding.left + padding.right;
+ }
+
+ height -= (n_rows - 1);
+ workspace_height = height / n_rows;
+
+ workspace_width = _wnck_pager_get_workspace_width_for_height (pager,
+ workspace_height);
+
+ width += workspace_width * spaces_per_row + (spaces_per_row - 1);
+ *natural_width = *minimum_width = width;
+}
+
+static void
wnck_pager_get_preferred_height (GtkWidget *widget,
int *minimum_height,
int *natural_height)
@@ -554,6 +664,73 @@ wnck_pager_get_preferred_height (GtkWidget *widget,
}
static void
+wnck_pager_get_preferred_height_for_width (GtkWidget *widget,
+ int width,
+ int *minimum_height,
+ int *natural_height)
+{
+ WnckPager *pager;
+ int n_spaces;
+ int n_rows;
+ int spaces_per_row;
+ int workspace_width, workspace_height;
+ int focus_width;
+ int height = 0;
+
+ pager = WNCK_PAGER (widget);
+
+ /* if we're not realized, we don't know about our screen yet */
+ if (pager->priv->screen == NULL)
+ _wnck_pager_set_screen (pager);
+ g_assert (pager->priv->screen != NULL);
+
+ g_assert (pager->priv->n_rows > 0);
+
+ n_spaces = wnck_screen_get_workspace_count (pager->priv->screen);
+
+ if (pager->priv->show_all_workspaces)
+ {
+ n_rows = pager->priv->n_rows;
+ spaces_per_row = (n_spaces + n_rows - 1) / n_rows;
+ }
+ else
+ {
+ n_rows = 1;
+ spaces_per_row = 1;
+ }
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ NULL);
+
+ width -= 2 * focus_width;
+ height += 2 * focus_width;
+
+ if (pager->priv->shadow_type != GTK_SHADOW_NONE)
+ {
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder padding;
+
+ state = gtk_widget_get_state_flags (widget);
+ context = gtk_widget_get_style_context (widget);
+ gtk_style_context_get_padding (context, state, &padding);
+
+ width -= padding.left + padding.right;
+ height += padding.top + padding.bottom;
+ }
+
+ width -= (n_rows - 1);
+ workspace_width = width / n_rows;
+
+ workspace_height = _wnck_pager_get_workspace_height_for_width (pager,
+ workspace_width);
+
+ height += workspace_height * spaces_per_row + (spaces_per_row - 1);
+ *natural_height = *minimum_height = height;
+}
+
+static void
wnck_pager_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]