Group :: System/Libraries
RPM: libwnck
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: libwnck-2.30.0-rotate-windowlist.patch
Download
Download
Index: tasklist.c
===================================================================
--- libwnck/tasklist.c (révision 1379)
+++ libwnck/tasklist.c (copie de travail)
@@ -35,6 +35,7 @@
#include "workspace.h"
#include "xutils.h"
#include "private.h"
+#include "obox.h"
/**
* SECTION:tasklist
@@ -118,6 +119,7 @@ struct _WnckTask
GtkWidget *button;
GtkWidget *image;
GtkWidget *label;
+ GtkWidget *obox;
WnckTaskType type;
@@ -198,6 +200,9 @@ struct _WnckTasklistPrivate
GHashTable *class_group_hash;
GHashTable *win_hash;
+ gboolean vertical_mode;
+ gboolean rotated;
+
gint max_button_width;
gint max_button_height;
@@ -677,6 +682,9 @@ wnck_tasklist_init (WnckTasklist *taskli
tasklist->priv->class_group_hash = g_hash_table_new (NULL, NULL);
tasklist->priv->win_hash = g_hash_table_new (NULL, NULL);
+ tasklist->priv->vertical_mode = FALSE;
+ tasklist->priv->rotated = FALSE;
+
tasklist->priv->max_button_width = 0;
tasklist->priv->max_button_height = 0;
@@ -1000,6 +1008,31 @@ wnck_tasklist_set_include_all_workspaces
}
/**
+ * wnck_tasklist_set_vertical_mode:
+ * @tasklist: a #WnckTasklist.
+ * @vertical_mode: whether to put @tasklist in vertical mode.
+ *
+ * Activates or deactivates the vertical mode of @tasklist according to
+ * @vertical_mode. The vertical mode is a specific mode for #WnckTasklist
+ * widgets, to be used when they are on vertical panels, for example. The task
+ * buttons will be rotated if there is not enough space for them to be
+ * horizontal, and the size hints will return a value for the height instead of
+ * the width.
+ */
+void
+wnck_tasklist_set_vertical_mode (WnckTasklist *tasklist,
+ gboolean vertical_mode)
+{
+ g_return_if_fail (WNCK_IS_TASKLIST (tasklist));
+
+ if (tasklist->priv->vertical_mode == vertical_mode)
+ return;
+
+ tasklist->priv->vertical_mode = vertical_mode;
+ gtk_widget_queue_resize (GTK_WIDGET (tasklist));
+}
+
+/**
* wnck_tasklist_set_grouping_limit:
* @tasklist: a #WnckTasklist.
* @limit: a size in pixels.
@@ -1231,28 +1264,48 @@ wnck_task_get_highest_scored (GList
return g_list_remove (ungrouped_class_groups, best_task);
}
-static int
-wnck_tasklist_get_button_size (GtkWidget *widget)
+/* This function returns value that are valid for an horizontal button.
+ * If the button gets rotated, returned values should be swapped */
+static void
+wnck_tasklist_get_button_size (GtkWidget *widget,
+ int *width,
+ int *height)
{
PangoContext *context;
PangoFontMetrics *metrics;
- gint char_width;
- gint text_width;
- gint width;
+ int ascent;
+ int descent;
+ int char_width;
+ int text_width;
+ int focus_width = 0;
+ int focus_pad = 0;
+ int thickness;
gtk_widget_ensure_style (widget);
context = gtk_widget_get_pango_context (widget);
metrics = pango_context_get_metrics (context, widget->style->font_desc,
pango_context_get_language (context));
+ ascent = pango_font_metrics_get_ascent (metrics);
+ descent = pango_font_metrics_get_descent (metrics);
char_width = pango_font_metrics_get_approximate_char_width (metrics);
pango_font_metrics_unref (metrics);
+
text_width = PANGO_PIXELS (TASKLIST_TEXT_MAX_WIDTH * char_width);
- width = text_width + 2 * TASKLIST_BUTTON_PADDING
- + MINI_ICON_SIZE + 2 * TASKLIST_BUTTON_PADDING;
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ thickness = MAX (widget->style->ythickness, widget->style->xthickness);
+
+ *width = text_width + 2 * TASKLIST_BUTTON_PADDING
+ + MINI_ICON_SIZE + 2 * TASKLIST_BUTTON_PADDING
+ + 2 * (focus_width + focus_pad + thickness);
- return width;
+ *height = MAX (MINI_ICON_SIZE, PANGO_PIXELS (ascent + descent))
+ + 2 * (focus_width + focus_pad + thickness);
}
static void
@@ -1260,41 +1313,45 @@ wnck_tasklist_size_request (GtkWidget
GtkRequisition *requisition)
{
WnckTasklist *tasklist;
- GtkRequisition child_req;
GtkAllocation fake_allocation;
int max_height = 1;
int max_width = 1;
- /* int u_width, u_height; */
+ int grouping_limit;
+ gboolean vertical_orientation;
GList *l;
+
+ /* for size hints */
+ int *n_rows_or_cols; /* this points to n_cols in horizontal mode,
+ and n_rows in vertical mode. The size hints depends
+ on the number of rows in vertical mode. */
+ int last_n_rows_or_cols;
+ int max_size_for_button;
+ int min_size_for_button;
GArray *array;
GList *ungrouped_class_groups;
int n_windows;
int n_startup_sequences;
int n_rows;
- int n_cols, last_n_cols;
+ int n_cols;
int n_grouped_buttons;
gboolean score_set;
int val;
WnckTask *class_group_task;
int lowest_range;
- int grouping_limit;
tasklist = WNCK_TASKLIST (widget);
- /* Calculate max needed height and width of the buttons */
+ /* we need to request the size of the buttons to get the labels properly
+ * aligned. FIXME: why? */
#define GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS(list) \
l = list; \
while (l != NULL) \
{ \
+ GtkRequisition child_req; \
WnckTask *task = WNCK_TASK (l->data); \
\
gtk_widget_size_request (task->button, &child_req); \
\
- max_height = MAX (child_req.height, \
- max_height); \
- max_width = MAX (child_req.width, \
- max_width); \
- \
l = l->next; \
}
@@ -1302,17 +1359,47 @@ wnck_tasklist_size_request (GtkWidget
GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS (tasklist->priv->class_groups)
GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS (tasklist->priv->startup_sequences)
- /* Note that the fact that we nearly don't care about the width/height
- * requested by the buttons makes it possible to hide/show the label/image
- * in wnck_task_size_allocated(). If we really cared about those, this
- * wouldn't work since our call to gtk_widget_size_request() does not take
- * into account the hidden widgets.
- */
- tasklist->priv->max_button_width = wnck_tasklist_get_button_size (widget);
+ wnck_tasklist_get_button_size (widget, &max_width, &max_height);
+
+ grouping_limit = MIN (tasklist->priv->grouping_limit, max_width);
+
+ tasklist->priv->max_button_width = max_width;
tasklist->priv->max_button_height = max_height;
- fake_allocation.width = GTK_WIDGET (tasklist)->allocation.width;
- fake_allocation.height = GTK_WIDGET (tasklist)->allocation.height;
+ /* if we're in vertical mode, the width will most often not change, so we
+ * can assume the current width is okay */
+ if (tasklist->priv->vertical_mode &&
+ GTK_WIDGET (tasklist)->allocation.width < grouping_limit)
+ vertical_orientation = TRUE;
+ else
+ vertical_orientation = FALSE;
+
+ /* changing orientation is just rotating everything */
+ if (!tasklist->priv->vertical_mode || vertical_orientation)
+ {
+ n_rows_or_cols = &n_cols;
+ min_size_for_button = grouping_limit;
+ max_size_for_button = tasklist->priv->max_button_width;
+ }
+ else
+ {
+ n_rows_or_cols = &n_rows;
+ min_size_for_button = max_height;
+ max_size_for_button = max_height;
+ }
+
+ if (!vertical_orientation)
+ {
+ fake_allocation.width = GTK_WIDGET (tasklist)->allocation.width;
+ fake_allocation.height = GTK_WIDGET (tasklist)->allocation.height;
+ }
+ else
+ {
+ /* swap width and height, since changing orientation means just rotating
+ * everything */
+ fake_allocation.width = GTK_WIDGET (tasklist)->allocation.height;
+ fake_allocation.height = GTK_WIDGET (tasklist)->allocation.width;
+ }
array = g_array_new (FALSE, FALSE, sizeof (int));
@@ -1324,26 +1411,32 @@ wnck_tasklist_size_request (GtkWidget
ungrouped_class_groups = g_list_copy (tasklist->priv->class_groups);
score_set = FALSE;
- grouping_limit = MIN (tasklist->priv->grouping_limit,
- tasklist->priv->max_button_width);
-
/* Try ungrouped mode */
- wnck_tasklist_layout (&fake_allocation,
- tasklist->priv->max_button_width,
- tasklist->priv->max_button_height,
- n_windows + n_startup_sequences,
- &n_cols, &n_rows);
+ if (!tasklist->priv->vertical_mode || vertical_orientation)
+ {
+ wnck_tasklist_layout (&fake_allocation,
+ tasklist->priv->max_button_width,
+ tasklist->priv->max_button_height,
+ n_windows + n_startup_sequences,
+ &n_cols, &n_rows);
+ }
+ else
+ {
+ /* We want all tasks in one high column. */
+ n_cols = 1;
+ n_rows = n_windows + n_startup_sequences;
+ }
- last_n_cols = G_MAXINT;
+ last_n_rows_or_cols = G_MAXINT;
lowest_range = G_MAXINT;
if (tasklist->priv->grouping != WNCK_TASKLIST_ALWAYS_GROUP)
{
- val = n_cols * tasklist->priv->max_button_width;
+ val = *n_rows_or_cols * max_size_for_button;
g_array_insert_val (array, array->len, val);
- val = n_cols * grouping_limit;
+ val = *n_rows_or_cols * min_size_for_button;
g_array_insert_val (array, array->len, val);
- last_n_cols = n_cols;
+ last_n_rows_or_cols = *n_rows_or_cols;
lowest_range = val;
}
@@ -1365,27 +1449,28 @@ wnck_tasklist_size_request (GtkWidget
tasklist->priv->max_button_height,
n_startup_sequences + n_windows - n_grouped_buttons,
&n_cols, &n_rows);
- if (n_cols != last_n_cols &&
+ if (*n_rows_or_cols != last_n_rows_or_cols &&
(tasklist->priv->grouping == WNCK_TASKLIST_AUTO_GROUP ||
ungrouped_class_groups == NULL))
{
- val = n_cols * tasklist->priv->max_button_width;
+ val = *n_rows_or_cols * max_size_for_button;
+
if (val >= lowest_range)
{ /* Overlaps old range */
g_assert (array->len > 0);
- lowest_range = n_cols * grouping_limit;
+ lowest_range = *n_rows_or_cols * min_size_for_button;
g_array_index(array, int, array->len-1) = lowest_range;
}
else
{
/* Full new range */
g_array_insert_val (array, array->len, val);
- val = n_cols * grouping_limit;
+ val = *n_rows_or_cols * min_size_for_button;
g_array_insert_val (array, array->len, val);
lowest_range = val;
}
- last_n_cols = n_cols;
+ last_n_rows_or_cols = *n_rows_or_cols;
}
}
@@ -1408,8 +1493,16 @@ wnck_tasklist_size_request (GtkWidget
tasklist->priv->size_hints = (int *)g_array_free (array, FALSE);
- requisition->width = tasklist->priv->size_hints[0];
- requisition->height = fake_allocation.height;
+ if (!tasklist->priv->vertical_mode)
+ {
+ requisition->width = tasklist->priv->size_hints[0];
+ requisition->height = n_rows * tasklist->priv->max_button_height;
+ }
+ else
+ {
+ requisition->width = fake_allocation.width;
+ requisition->height = tasklist->priv->size_hints[0];
+ }
}
/**
@@ -1444,17 +1537,29 @@ wnck_task_size_allocated (GtkWidget
gpointer data)
{
WnckTask *task = WNCK_TASK (data);
- int min_image_width;
+ int min_image_size;
+ int size;
- min_image_width = MINI_ICON_SIZE +
- 2 * widget->style->xthickness +
- 2 * TASKLIST_BUTTON_PADDING;
+ if (!task->tasklist->priv->rotated)
+ {
+ size = allocation->width;
+ min_image_size = MINI_ICON_SIZE +
+ 2 * widget->style->xthickness +
+ 2 * TASKLIST_BUTTON_PADDING;
+ }
+ else
+ {
+ size = allocation->height;
+ min_image_size = MINI_ICON_SIZE +
+ 2 * widget->style->ythickness +
+ 2 * TASKLIST_BUTTON_PADDING;
+ }
- if ((allocation->width < min_image_width + 2 * TASKLIST_BUTTON_PADDING) &&
- (allocation->width >= min_image_width)) {
+ if ((size < min_image_size + 2 * TASKLIST_BUTTON_PADDING) &&
+ (size >= min_image_size)) {
gtk_widget_show (task->image);
gtk_widget_hide (task->label);
- } else if (allocation->width < min_image_width) {
+ } else if (size < min_image_size) {
gtk_widget_hide (task->image);
gtk_widget_show (task->label);
} else {
@@ -1467,6 +1572,7 @@ static void
wnck_tasklist_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
+ GtkAllocation maybe_rotated_allocation;
GtkAllocation child_allocation;
WnckTasklist *tasklist;
WnckTask *class_group_task;
@@ -1485,6 +1591,7 @@ wnck_tasklist_size_allocate (GtkWidget
GList *visible_tasks = NULL;
GList *windows_sorted = NULL;
int grouping_limit;
+ gdouble angle;
tasklist = WNCK_TASKLIST (widget);
@@ -1497,8 +1604,45 @@ wnck_tasklist_size_allocate (GtkWidget
grouping_limit = MIN (tasklist->priv->grouping_limit,
tasklist->priv->max_button_width);
+ //FIXME: initial size is wrong in vertical mode
+ if (gtk_widget_get_realized (widget) &&
+ tasklist->priv->vertical_mode && allocation->width < grouping_limit)
+ {
+ GdkScreen *screen;
+ int xpos;
+ int ypos;
+
+ tasklist->priv->rotated = TRUE;
+
+ gdk_window_get_origin (widget->window, &xpos, &ypos);
+
+ //FIXME: is not updated when panel changes from right to left
+ screen = _wnck_screen_get_gdk_screen (tasklist->priv->screen);
+ if (xpos + (allocation->x + allocation->width) / 2
+ < gdk_screen_get_width (screen) / 2)
+ angle = 90;
+ else
+ angle = 270;
+ }
+ else
+ {
+ tasklist->priv->rotated = FALSE;
+ angle = 0;
+ }
+
+ if (!tasklist->priv->rotated)
+ {
+ maybe_rotated_allocation.width = allocation->width;
+ maybe_rotated_allocation.height = allocation->height;
+ }
+ else
+ {
+ maybe_rotated_allocation.width = allocation->height;
+ maybe_rotated_allocation.height = allocation->width;
+ }
+
/* Try ungrouped mode */
- button_width = wnck_tasklist_layout (allocation,
+ button_width = wnck_tasklist_layout (&maybe_rotated_allocation,
tasklist->priv->max_button_width,
tasklist->priv->max_button_height,
n_startup_sequences + n_windows,
@@ -1532,8 +1676,8 @@ wnck_tasklist_size_allocate (GtkWidget
{
win_task = WNCK_TASK (l->data);
- gtk_widget_set_child_visible (GTK_WIDGET (win_task->button), FALSE);
-
+ gtk_widget_set_child_visible (GTK_WIDGET (win_task->button),
+ FALSE);
cleanup_screenshots (win_task);
l = l->next;
@@ -1541,13 +1685,14 @@ wnck_tasklist_size_allocate (GtkWidget
}
else
{
- visible_tasks = g_list_prepend (visible_tasks, class_group_task->windows->data);
- gtk_widget_set_child_visible (GTK_WIDGET (class_group_task->button), FALSE);
-
+ visible_tasks = g_list_prepend (visible_tasks,
+ class_group_task->windows->data);
+ gtk_widget_set_child_visible (GTK_WIDGET (class_group_task->button),
+ FALSE);
cleanup_screenshots (class_group_task);
}
- button_width = wnck_tasklist_layout (allocation,
+ button_width = wnck_tasklist_layout (&maybe_rotated_allocation,
tasklist->priv->max_button_width,
tasklist->priv->max_button_height,
n_startup_sequences + n_windows - n_grouped_buttons,
@@ -1560,34 +1705,45 @@ wnck_tasklist_size_allocate (GtkWidget
{
class_group_task = WNCK_TASK (l->data);
- visible_tasks = g_list_concat (visible_tasks, g_list_copy (class_group_task->windows));
- gtk_widget_set_child_visible (GTK_WIDGET (class_group_task->button), FALSE);
-
+ visible_tasks = g_list_concat (visible_tasks,
+ g_list_copy (class_group_task->windows));
+ gtk_widget_set_child_visible (GTK_WIDGET (class_group_task->button),
+ FALSE);
cleanup_screenshots (class_group_task);
l = l->next;
}
/* Add all windows that are ungrouped because they don't belong to any class
* group */
l = tasklist->priv->windows_without_class_group;
while (l != NULL)
{
WnckTask *task;
task = WNCK_TASK (l->data);
visible_tasks = g_list_append (visible_tasks, task);
l = l->next;
}
/* Add all startup sequences */
- visible_tasks = g_list_concat (visible_tasks, g_list_copy (tasklist->priv->startup_sequences));
+ visible_tasks = g_list_concat (visible_tasks,
+ g_list_copy (tasklist->priv->startup_sequences));
/* Sort */
visible_tasks = g_list_sort (visible_tasks, wnck_task_compare);
/* Allocate children */
+ if (tasklist->priv->rotated)
+ {
+ int buf;
+
+ buf = n_rows;
+ n_rows = n_cols;
+ n_cols = buf;
+ }
+
l = visible_tasks;
i = 0;
total_width = tasklist->priv->max_button_width * n_cols;
@@ -1586,12 +1742,40 @@ wnck_tasklist_size_allocate (GtkWidget
while (l != NULL)
{
WnckTask *task = WNCK_TASK (l->data);
- int row = i % n_rows;
- int col = i / n_rows;
+ int row;
+ int col;
+
+ if (!tasklist->priv->rotated)
+ {
+ row = i % n_rows;
+ col = i / n_rows;
+ }
+ else
+ {
+ row = i % n_cols;
+ col = i / n_cols;
+ }
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
col = n_cols - col - 1;
+ if (angle == 270)
+ {
+ int buf;
+
+ buf = row;
+ row = col;
+ col = n_cols - buf - 1;
+ }
+ else if (angle == 90)
+ {
+ int buf;
+
+ buf = row;
+ row = n_rows - col - 1;
+ col = buf;
+ }
+
child_allocation.x = total_width*col / n_cols;
child_allocation.y = allocation->height*row / n_rows;
child_allocation.width = total_width*(col + 1) / n_cols - child_allocation.x;
@@ -1602,6 +1786,29 @@ wnck_tasklist_size_allocate (GtkWidget
gtk_widget_size_allocate (task->button, &child_allocation);
gtk_widget_set_child_visible (GTK_WIDGET (task->button), TRUE);
+ wnck_obox_set_orientation (WNCK_OBOX (task->obox),
+ tasklist->priv->rotated ?
+ GTK_ORIENTATION_VERTICAL :
+ GTK_ORIENTATION_HORIZONTAL);
+ //FIXME: this is wrong for japanese!
+ wnck_obox_set_reverse_order (WNCK_OBOX (task->obox), angle == 90);
+ if (angle == 0)
+ {
+ gtk_label_set_ellipsize (GTK_LABEL (task->label),
+ PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment (GTK_MISC (task->label), 0.0, 0.5);
+ }
+ else
+ {
+ //FIXME: This is a workaround because GTK+ is not nice with us and
+ //doesn't accept rotated + ellipsized text.
+ gtk_label_set_ellipsize (GTK_LABEL (task->label),
+ PANGO_ELLIPSIZE_NONE);
+ gtk_misc_set_alignment (GTK_MISC (task->label), 0.5,
+ angle == 90 ? 1.0 : 0.0);
+ }
+ gtk_label_set_angle (GTK_LABEL (task->label), angle);
+
if (task->type != WNCK_TASK_STARTUP_SEQUENCE)
{
GList *ll;
@@ -2605,7 +2812,8 @@ wnck_task_position_menu (GtkMenu *menu
gboolean *push_in,
gpointer user_data)
{
- GtkWidget *widget = GTK_WIDGET (user_data);
+ WnckTask *task = WNCK_TASK (user_data);
+ GtkWidget *widget = task->button;
GtkRequisition requisition;
gint menu_xpos;
gint menu_ypos;
@@ -2619,7 +2827,7 @@ wnck_task_position_menu (GtkMenu *menu
menu_xpos += widget->allocation.x;
menu_ypos += widget->allocation.y;
- if (menu_ypos > gdk_screen_height () / 2)
+ if (menu_ypos > gdk_screen_get_height (_wnck_screen_get_gdk_screen (task->tasklist->priv->screen)) / 2)
menu_ypos -= requisition.height;
else
menu_ypos += widget->allocation.height;
@@ -3007,7 +3215,7 @@ wnck_task_popup_menu (WnckTask *task,
gtk_widget_show (menu);
gtk_menu_popup (GTK_MENU (menu),
NULL, NULL,
- wnck_task_position_menu, task->button,
+ wnck_task_position_menu, task,
1, gtk_get_current_event_time ());
}
@@ -3613,7 +3821,7 @@ wnck_task_button_press_event (GtkWidget
gtk_widget_show (task->action_menu);
gtk_menu_popup (GTK_MENU (task->action_menu),
NULL, NULL,
- wnck_task_position_menu, task->button,
+ wnck_task_position_menu, task,
event->button,
gtk_get_current_event_time ());
@@ -3638,7 +3846,6 @@ wnck_task_expose (GtkWidget *widg
static void
wnck_task_create_widgets (WnckTask *task, GtkReliefStyle relief)
{
- GtkWidget *hbox;
GdkPixbuf *pixbuf;
char *text;
static GQuark disable_sound_quark = 0;
@@ -3678,7 +3885,7 @@ wnck_task_create_widgets (WnckTask *task
gtk_drag_dest_set (GTK_WIDGET (task->button), 0,
NULL, 0, GDK_ACTION_DEFAULT);
- hbox = gtk_hbox_new (FALSE, 0);
+ task->obox = wnck_obox_new ();
pixbuf = wnck_task_get_icon (task);
if (pixbuf)
@@ -3705,13 +3912,13 @@ wnck_task_create_widgets (WnckTask *task
gtk_widget_show (task->label);
- gtk_box_pack_start (GTK_BOX (hbox), task->image, FALSE, FALSE,
+ gtk_box_pack_start (GTK_BOX (task->obox), task->image, FALSE, FALSE,
TASKLIST_BUTTON_PADDING);
- gtk_box_pack_start (GTK_BOX (hbox), task->label, TRUE, TRUE,
+ gtk_box_pack_start (GTK_BOX (task->obox), task->label, TRUE, TRUE,
TASKLIST_BUTTON_PADDING);
- gtk_container_add (GTK_CONTAINER (task->button), hbox);
- gtk_widget_show (hbox);
+ gtk_container_add (GTK_CONTAINER (task->button), task->obox);
+ gtk_widget_show (task->obox);
g_free (text);
text = wnck_task_get_text (task, FALSE, FALSE);
Index: tasklist.h
===================================================================
--- libwnck/tasklist.h (révision 1378)
+++ libwnck/tasklist.h (copie de travail)
@@ -98,6 +98,9 @@ void wnck_tasklist_set_include_all_works
gboolean include_all_workspaces);
void wnck_tasklist_set_button_relief (WnckTasklist *tasklist,
GtkReliefStyle relief);
+void wnck_tasklist_set_vertical_mode (WnckTasklist *tasklist,
+ gboolean vertical_mode);
+
#ifndef WNCK_DISABLE_DEPRECATED
void wnck_tasklist_set_minimum_width (WnckTasklist *tasklist, gint size);
gint wnck_tasklist_get_minimum_width (WnckTasklist *tasklist);
Index: obox.c
===================================================================
--- libwnck/obox.c (révision 0)
+++ libwnck/obox.c (révision 0)
@@ -0,0 +1,151 @@
+/* OBox Copyright (C) 2002 Red Hat Inc. based on GtkHBox */
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "obox.h"
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+
+static void wnck_obox_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void wnck_obox_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+
+
+G_DEFINE_TYPE (WnckOBox, wnck_obox, GTK_TYPE_BOX)
+
+static void
+wnck_obox_class_init (WnckOBoxClass *class)
+{
+ GtkWidgetClass *widget_class;
+
+ widget_class = (GtkWidgetClass*) class;
+
+ widget_class->size_request = wnck_obox_size_request;
+ widget_class->size_allocate = wnck_obox_size_allocate;
+}
+
+static void
+wnck_obox_init (WnckOBox *obox)
+{
+ obox->orientation = GTK_ORIENTATION_HORIZONTAL;
+ obox->reverse_order = FALSE;
+}
+
+GtkWidget*
+wnck_obox_new (void)
+{
+ WnckOBox *obox;
+
+ obox = g_object_new (WNCK_TYPE_OBOX, NULL);
+
+ return GTK_WIDGET (obox);
+}
+
+static GtkWidgetClass*
+get_class (WnckOBox *obox)
+{
+ GtkWidgetClass *klass;
+
+ switch (obox->orientation)
+ {
+ case GTK_ORIENTATION_HORIZONTAL:
+ klass = GTK_WIDGET_CLASS (gtk_type_class (GTK_TYPE_HBOX));
+ break;
+ case GTK_ORIENTATION_VERTICAL:
+ klass = GTK_WIDGET_CLASS (gtk_type_class (GTK_TYPE_VBOX));
+ break;
+ default:
+ g_assert_not_reached ();
+ klass = NULL;
+ break;
+ }
+
+ return klass;
+}
+
+static void
+wnck_obox_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ GtkWidgetClass *klass;
+ WnckOBox *obox;
+
+ obox = WNCK_OBOX (widget);
+
+ klass = get_class (obox);
+
+ klass->size_request (widget, requisition);
+}
+
+static void
+wnck_obox_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkWidgetClass *klass;
+ WnckOBox *obox;
+
+ obox = WNCK_OBOX (widget);
+
+ klass = get_class (obox);
+
+ klass->size_allocate (widget, allocation);
+}
+
+void
+wnck_obox_set_orientation (WnckOBox *obox,
+ GtkOrientation orientation)
+{
+ g_return_if_fail (WNCK_IS_OBOX (obox));
+
+ if (obox->orientation == orientation)
+ return;
+
+ g_print ("new orientation: %d\n", orientation);
+ obox->orientation = orientation;
+
+ gtk_widget_queue_resize (GTK_WIDGET (obox));
+}
+
+void
+wnck_obox_set_reverse_order (WnckOBox *obox,
+ gboolean reverse_order)
+{
+ GtkBox *box;
+
+ g_return_if_fail (WNCK_IS_OBOX (obox));
+
+ if (obox->reverse_order == reverse_order)
+ return;
+
+ g_print ("reverse order: %d\n", reverse_order);
+ obox->reverse_order = reverse_order;
+ box = GTK_BOX (obox);
+ box->children = g_list_reverse (box->children);
+
+ gtk_widget_queue_resize (GTK_WIDGET (obox));
+}
Index: obox.h
===================================================================
--- libwnck/obox.h (révision 0)
+++ libwnck/obox.h (révision 0)
@@ -0,0 +1,75 @@
+/* OBox Copyright (C) 2002 Red Hat Inc. based on GtkHBox */
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __WNCK_OBOX_H__
+#define __WNCK_OBOX_H__
+
+#include <gtk/gtkbox.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define WNCK_TYPE_OBOX (wnck_obox_get_type ())
+#define WNCK_OBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WNCK_TYPE_OBOX, WnckOBox))
+#define WNCK_OBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WNCK_TYPE_OBOX, WnckOBoxClass))
+#define WNCK_IS_OBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WNCK_TYPE_OBOX))
+#define WNCK_IS_OBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WNCK_TYPE_OBOX))
+#define WNCK_OBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WNCK_TYPE_OBOX, WnckOBoxClass))
+
+
+typedef struct _WnckOBox WnckOBox;
+typedef struct _WnckOBoxClass WnckOBoxClass;
+
+struct _WnckOBox
+{
+ GtkBox box;
+
+ GtkOrientation orientation;
+ gboolean reverse_order;
+};
+
+struct _WnckOBoxClass
+{
+ GtkBoxClass parent_class;
+};
+
+
+GType wnck_obox_get_type (void) G_GNUC_CONST;
+GtkWidget* wnck_obox_new (void);
+
+void wnck_obox_set_orientation (WnckOBox *obox,
+ GtkOrientation orientation);
+void wnck_obox_set_reverse_order (WnckOBox *obox,
+ gboolean reverse_order);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __WNCK_OBOX_H__ */
Index: Makefile.am
===================================================================
--- libwnck/Makefile.am.rotate-window-list 2010-03-09 04:56:30.000000000 +0300
+++ libwnck/Makefile.am 2010-03-09 13:03:22.000000000 +0300
@@ -55,6 +55,8 @@
$(wnck_built_cfiles) \
$(wnck_sources) \
inlinepixbufs.h \
+ obox.c \
+ obox.h \
private.h \
xutils.c \
xutils.h \