summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2021-05-06 13:36:46 +0300
committerMarco Trevisan <mail@3v1n0.net>2021-05-10 15:38:02 +0000
commitc786d24b37b17c65869e4f2a7c282fbf32bca601 (patch)
treecec921e599ccc98339f59c58f2c5663a187a30b0
parentd34848986293b47a4816656de4b1b117f021e82c (diff)
downloadlibwnck-c786d24b37b17c65869e4f2a7c282fbf32bca601.tar.gz
tasklist: set size request mode
Use GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH mode for vertical tasklist and GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT mode for horizontal tasklist. Original wnck_tasklist_size_request function has been renamed to wnck_tasklist_update_size_hints and used only to update size hints.
-rw-r--r--libwnck/tasklist.c405
1 files changed, 300 insertions, 105 deletions
diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c
index 64aa5fb..8791b10 100644
--- a/libwnck/tasklist.c
+++ b/libwnck/tasklist.c
@@ -210,9 +210,6 @@ struct _WnckTasklistPrivate
GHashTable *class_group_hash;
GHashTable *win_hash;
- gint max_button_width;
- gint max_button_height;
-
gboolean switch_workspace_on_unminimize;
gboolean middle_click_close;
@@ -306,9 +303,17 @@ static void wnck_tasklist_finalize (GObject *object);
static void wnck_tasklist_get_preferred_width (GtkWidget *widget,
int *minimum_width,
int *natural_width);
+static void wnck_tasklist_get_preferred_height_for_width (GtkWidget *widget,
+ int width,
+ int *minimum_height,
+ int *natural_height);
static void wnck_tasklist_get_preferred_height (GtkWidget *widget,
int *minimum_height,
int *natural_height);
+static void wnck_tasklist_get_preferred_width_for_height (GtkWidget *widget,
+ int height,
+ int *minimum_width,
+ int *natural_width);
static void wnck_tasklist_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void wnck_tasklist_realize (GtkWidget *widget);
@@ -867,6 +872,19 @@ wnck_tasklist_init (WnckTasklist *tasklist)
#endif
}
+static GtkSizeRequestMode
+wnck_tasklist_get_request_mode (GtkWidget *widget)
+{
+ WnckTasklist *self;
+
+ self = WNCK_TASKLIST (widget);
+
+ if (self->priv->orientation == GTK_ORIENTATION_VERTICAL)
+ return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+
+ return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+
static void
wnck_tasklist_class_init (WnckTasklistClass *klass)
{
@@ -876,8 +894,11 @@ wnck_tasklist_class_init (WnckTasklistClass *klass)
object_class->finalize = wnck_tasklist_finalize;
+ widget_class->get_request_mode = wnck_tasklist_get_request_mode;
widget_class->get_preferred_width = wnck_tasklist_get_preferred_width;
+ widget_class->get_preferred_height_for_width = wnck_tasklist_get_preferred_height_for_width;
widget_class->get_preferred_height = wnck_tasklist_get_preferred_height;
+ widget_class->get_preferred_width_for_height = wnck_tasklist_get_preferred_width_for_height;
widget_class->size_allocate = wnck_tasklist_size_allocate;
widget_class->realize = wnck_tasklist_realize;
widget_class->unrealize = wnck_tasklist_unrealize;
@@ -1294,31 +1315,21 @@ wnck_tasklist_set_icon_loader (WnckTasklist *tasklist,
tasklist->priv->free_icon_loader_data = free_data_func;
}
-/* returns the maximal possible button width (i.e. if you
- * don't want to stretch the buttons to fill the alloctions
- * the width can be smaller) */
-static int
-wnck_tasklist_layout (GtkAllocation *allocation,
- int max_width,
- int max_height,
- int n_buttons,
- GtkOrientation orientation,
- int *n_cols_out,
- int *n_rows_out)
+static void
+get_layout (GtkOrientation orientation,
+ int for_size,
+ int max_size,
+ int n_buttons,
+ int *n_cols_out,
+ int *n_rows_out)
{
- int n_cols, n_rows;
-
- if (n_buttons == 0)
- {
- *n_cols_out = 0;
- *n_rows_out = 0;
- return 0;
- }
+ int n_cols;
+ int n_rows;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
/* How many rows fit in the allocation */
- n_rows = allocation->height / max_height;
+ n_rows = for_size / max_size;
/* Don't have more rows than buttons */
n_rows = MIN (n_rows, n_buttons);
@@ -1335,7 +1346,7 @@ wnck_tasklist_layout (GtkAllocation *allocation,
else
{
/* How many cols fit in the allocation */
- n_cols = allocation->width / max_width;
+ n_cols = for_size / max_size;
/* Don't have more cols than buttons */
n_cols = MIN (n_cols, n_buttons);
@@ -1350,6 +1361,53 @@ wnck_tasklist_layout (GtkAllocation *allocation,
n_rows = MAX (n_rows, 1);
}
+ if (n_cols_out != NULL)
+ *n_cols_out = n_cols;
+
+ if (n_rows_out != NULL)
+ *n_rows_out = n_rows;
+}
+
+/* returns the maximal possible button width (i.e. if you
+ * don't want to stretch the buttons to fill the alloctions
+ * the width can be smaller) */
+static int
+wnck_tasklist_layout (GtkAllocation *allocation,
+ int max_width,
+ int max_height,
+ int n_buttons,
+ GtkOrientation orientation,
+ int *n_cols_out,
+ int *n_rows_out)
+{
+ int n_cols, n_rows;
+
+ if (n_buttons == 0)
+ {
+ *n_cols_out = 0;
+ *n_rows_out = 0;
+ return 0;
+ }
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ get_layout (GTK_ORIENTATION_HORIZONTAL,
+ allocation->height,
+ max_height,
+ n_buttons,
+ &n_cols,
+ &n_rows);
+ }
+ else
+ {
+ get_layout (GTK_ORIENTATION_VERTICAL,
+ allocation->width,
+ max_width,
+ n_buttons,
+ &n_cols,
+ &n_rows);
+ }
+
*n_cols_out = n_cols;
*n_rows_out = n_rows;
@@ -1445,39 +1503,27 @@ wnck_task_get_highest_scored (GList *ungrouped_class_groups,
}
static void
-wnck_tasklist_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
+calculate_max_button_size (WnckTasklist *self,
+ int *max_width_out,
+ int *max_height_out)
{
- WnckTasklist *tasklist;
- GtkRequisition child_min_req;
- GtkRequisition child_nat_req;
- GtkAllocation tasklist_allocation;
- GtkAllocation fake_allocation;
- int max_height = 1;
- int max_width = 1;
- /* int u_width, u_height; */
+ int max_width;
+ int max_height;
GList *l;
- GArray *array;
- GList *ungrouped_class_groups;
- int n_windows;
- int n_startup_sequences;
- int n_rows;
- int n_cols, last_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);
+ max_width = 0;
+ max_height = 0;
- /* Calculate max needed height and width of the buttons */
#define GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS(list) \
l = list; \
+ \
while (l != NULL) \
{ \
- WnckTask *task = WNCK_TASK (l->data); \
+ WnckTask *task; \
+ GtkRequisition child_min_req; \
+ GtkRequisition child_nat_req; \
+ \
+ task = WNCK_TASK (l->data); \
\
gtk_widget_get_preferred_size (task->button, \
&child_min_req, \
@@ -1489,9 +1535,38 @@ wnck_tasklist_size_request (GtkWidget *widget,
l = l->next; \
}
- GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS (tasklist->priv->windows)
- GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS (tasklist->priv->class_groups)
- GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS (tasklist->priv->startup_sequences)
+ GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS (self->priv->windows)
+ GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS (self->priv->class_groups)
+ GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS (self->priv->startup_sequences)
+
+#undef GET_MAX_WIDTH_HEIGHT_FROM_BUTTONS
+
+ if (max_width_out != NULL)
+ *max_width_out = max_width;
+
+ if (max_height_out != NULL)
+ *max_height_out = max_height;
+}
+
+static void
+wnck_tasklist_update_size_hints (WnckTasklist *tasklist)
+{
+ GtkAllocation tasklist_allocation;
+ GtkAllocation fake_allocation;
+ int max_height = 1;
+ int max_width = 1;
+ GArray *array;
+ GList *ungrouped_class_groups;
+ int n_windows;
+ int n_startup_sequences;
+ int n_rows;
+ int n_cols, last_n_cols;
+ int n_grouped_buttons;
+ gboolean score_set;
+ int val;
+ WnckTask *class_group_task;
+ int lowest_range;
+ int grouping_limit;
/* 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
@@ -1499,8 +1574,7 @@ wnck_tasklist_size_request (GtkWidget *widget,
* wouldn't work since our call to gtk_widget_size_request() does not take
* into account the hidden widgets.
*/
- tasklist->priv->max_button_width = max_width;
- tasklist->priv->max_button_height = max_height;
+ calculate_max_button_size (tasklist, &max_width, &max_height);
gtk_widget_get_allocation (GTK_WIDGET (tasklist), &tasklist_allocation);
@@ -1517,13 +1591,12 @@ wnck_tasklist_size_request (GtkWidget *widget,
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);
+ grouping_limit = MIN (tasklist->priv->grouping_limit, max_width);
/* Try ungrouped mode */
wnck_tasklist_layout (&fake_allocation,
- tasklist->priv->max_button_width,
- tasklist->priv->max_button_height,
+ max_width,
+ max_height,
n_windows + n_startup_sequences,
tasklist->priv->orientation,
&n_cols, &n_rows);
@@ -1534,7 +1607,7 @@ wnck_tasklist_size_request (GtkWidget *widget,
{
if (tasklist->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
- val = n_cols * tasklist->priv->max_button_width;
+ val = n_cols * max_width;
g_array_insert_val (array, array->len, val);
val = n_cols * grouping_limit;
g_array_insert_val (array, array->len, val);
@@ -1544,7 +1617,7 @@ wnck_tasklist_size_request (GtkWidget *widget,
}
else
{
- val = n_rows * tasklist->priv->max_button_height;
+ val = n_rows * max_height;
g_array_insert_val (array, array->len, val);
val = n_rows * grouping_limit;
g_array_insert_val (array, array->len, val);
@@ -1568,8 +1641,8 @@ wnck_tasklist_size_request (GtkWidget *widget,
n_grouped_buttons += g_list_length (class_group_task->windows) - 1;
wnck_tasklist_layout (&fake_allocation,
- tasklist->priv->max_button_width,
- tasklist->priv->max_button_height,
+ max_width,
+ max_height,
n_startup_sequences + n_windows - n_grouped_buttons,
tasklist->priv->orientation,
&n_cols, &n_rows);
@@ -1580,7 +1653,7 @@ wnck_tasklist_size_request (GtkWidget *widget,
(tasklist->priv->grouping == WNCK_TASKLIST_AUTO_GROUP ||
ungrouped_class_groups == NULL))
{
- val = n_cols * tasklist->priv->max_button_width;
+ val = n_cols * max_width;
if (val >= lowest_range)
{
/* Overlaps old range */
@@ -1606,7 +1679,7 @@ wnck_tasklist_size_request (GtkWidget *widget,
(tasklist->priv->grouping == WNCK_TASKLIST_AUTO_GROUP ||
ungrouped_class_groups == NULL))
{
- val = n_rows * tasklist->priv->max_button_height;
+ val = n_rows * max_height;
if (val >= lowest_range)
{
/* Overlaps old range */
@@ -1647,17 +1720,48 @@ wnck_tasklist_size_request (GtkWidget *widget,
tasklist->priv->size_hints_len = array->len;
tasklist->priv->size_hints = (int *)g_array_free (array, FALSE);
+}
- if (tasklist->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+static int
+get_n_buttons (WnckTasklist *self)
+{
+ int n_windows;
+ int n_startup_sequences;
+ int n_buttons;
+
+ n_windows = g_list_length (self->priv->windows);
+ n_startup_sequences = g_list_length (self->priv->startup_sequences);
+
+ if (self->priv->grouping == WNCK_TASKLIST_ALWAYS_GROUP &&
+ self->priv->class_groups != NULL)
{
- requisition->width = tasklist->priv->size_hints[0];
- requisition->height = fake_allocation.height;
+ GList *ungrouped_class_groups;
+ int n_grouped_buttons;
+
+ ungrouped_class_groups = g_list_copy (self->priv->class_groups);
+ n_grouped_buttons = 0;
+
+ wnck_tasklist_score_groups (self, ungrouped_class_groups);
+
+ while (ungrouped_class_groups != NULL)
+ {
+ WnckTask *task;
+
+ ungrouped_class_groups = wnck_task_get_highest_scored (ungrouped_class_groups,
+ &task);
+
+ n_grouped_buttons += g_list_length (task->windows) - 1;
+ }
+
+ n_buttons = n_startup_sequences + n_windows - n_grouped_buttons;
+ g_list_free (ungrouped_class_groups);
}
else
{
- requisition->width = fake_allocation.width;
- requisition->height = tasklist->priv->size_hints[0];
+ n_buttons = n_windows + n_startup_sequences;
}
+
+ return n_buttons;
}
static void
@@ -1680,49 +1784,135 @@ get_minimum_button_size (int *minimum_width,
}
static void
-wnck_tasklist_get_preferred_width (GtkWidget *widget,
- int *minimum_width,
- int *natural_width)
+get_preferred_size (WnckTasklist *self,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum,
+ int *natural)
{
- WnckTasklist *self;
- GtkRequisition req;
+ int n_buttons;
+ int max_button_width;
+ int max_button_height;
- self = WNCK_TASKLIST (widget);
+ *minimum = 0;
+ *natural = 0;
- wnck_tasklist_size_request (widget, &req);
+ n_buttons = get_n_buttons (self);
+ if (n_buttons == 0)
+ return;
+
+ calculate_max_button_size (self, &max_button_width, &max_button_height);
- if (self->priv->windows == NULL &&
- self->priv->startup_sequences == NULL)
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
- *minimum_width = *natural_width = 0;
- return;
+ int min_button_width;
+
+ get_minimum_button_size (&min_button_width, NULL);
+
+ if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ int n_cols;
+
+ if (for_size < 0)
+ {
+ n_cols = n_buttons;
+ }
+ else
+ {
+ get_layout (GTK_ORIENTATION_HORIZONTAL,
+ for_size,
+ max_button_height,
+ n_buttons,
+ &n_cols,
+ NULL);
+ }
+
+ *minimum = min_button_width;
+ *natural = n_cols * max_button_width;
+ }
+ else
+ {
+ *minimum = *natural = min_button_width;
+ }
}
+ else
+ {
+ if (self->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ *minimum = *natural = max_button_height;
+ }
+ else
+ {
+ int n_rows;
- get_minimum_button_size (minimum_width, NULL);
- *natural_width = req.width;
+ if (for_size < 0)
+ {
+ n_rows = n_buttons;
+ }
+ else
+ {
+ get_layout (GTK_ORIENTATION_VERTICAL,
+ for_size,
+ max_button_width,
+ n_buttons,
+ NULL,
+ &n_rows);
+ }
+
+ *minimum = max_button_height;
+ *natural = n_rows * max_button_height;
+ }
+ }
}
static void
-wnck_tasklist_get_preferred_height (GtkWidget *widget,
- int *minimum_height,
- int *natural_height)
+wnck_tasklist_get_preferred_width (GtkWidget *widget,
+ int *minimum_width,
+ int *natural_width)
{
- WnckTasklist *self;
- GtkRequisition req;
-
- self = WNCK_TASKLIST (widget);
+ get_preferred_size (WNCK_TASKLIST (widget),
+ GTK_ORIENTATION_HORIZONTAL,
+ -1,
+ minimum_width,
+ natural_width);
+}
- wnck_tasklist_size_request (widget, &req);
+static void
+wnck_tasklist_get_preferred_width_for_height (GtkWidget *widget,
+ int height,
+ int *minimum_width,
+ int *natural_width)
+{
+ get_preferred_size (WNCK_TASKLIST (widget),
+ GTK_ORIENTATION_HORIZONTAL,
+ height,
+ minimum_width,
+ natural_width);
+}
- if (self->priv->windows == NULL &&
- self->priv->startup_sequences == NULL)
- {
- *minimum_height = *natural_height = 0;
- return;
- }
+static void
+wnck_tasklist_get_preferred_height (GtkWidget *widget,
+ int *minimum_height,
+ int *natural_height)
+{
+ get_preferred_size (WNCK_TASKLIST (widget),
+ GTK_ORIENTATION_VERTICAL,
+ -1,
+ minimum_height,
+ natural_height);
+}
- get_minimum_button_size (NULL, minimum_height);
- *natural_height = req.height;
+static void
+wnck_tasklist_get_preferred_height_for_width (GtkWidget *widget,
+ int width,
+ int *minimum_height,
+ int *natural_height)
+{
+ get_preferred_size (WNCK_TASKLIST (widget),
+ GTK_ORIENTATION_VERTICAL,
+ width,
+ minimum_height,
+ natural_height);
}
/**
@@ -1749,6 +1939,8 @@ wnck_tasklist_get_size_hint_list (WnckTasklist *tasklist,
g_return_val_if_fail (WNCK_IS_TASKLIST (tasklist), NULL);
g_return_val_if_fail (n_elements != NULL, NULL);
+ wnck_tasklist_update_size_hints (tasklist);
+
*n_elements = tasklist->priv->size_hints_len;
return tasklist->priv->size_hints;
}
@@ -1762,6 +1954,8 @@ wnck_tasklist_size_allocate (GtkWidget *widget,
WnckTask *class_group_task;
int n_windows;
int n_startup_sequences;
+ int max_height = 1;
+ int max_width = 1;
GList *l;
int button_width;
int total_width;
@@ -1784,13 +1978,14 @@ wnck_tasklist_size_allocate (GtkWidget *widget,
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);
+ calculate_max_button_size (tasklist, &max_width, &max_height);
+
+ grouping_limit = MIN (tasklist->priv->grouping_limit, max_width);
/* Try ungrouped mode */
button_width = wnck_tasklist_layout (allocation,
- tasklist->priv->max_button_width,
- tasklist->priv->max_button_height,
+ max_width,
+ max_height,
n_startup_sequences + n_windows,
tasklist->priv->orientation,
&n_cols, &n_rows);
@@ -1835,8 +2030,8 @@ wnck_tasklist_size_allocate (GtkWidget *widget,
}
button_width = wnck_tasklist_layout (allocation,
- tasklist->priv->max_button_width,
- tasklist->priv->max_button_height,
+ max_width,
+ max_height,
n_startup_sequences + n_windows - n_grouped_buttons,
tasklist->priv->orientation,
&n_cols, &n_rows);
@@ -1876,7 +2071,7 @@ wnck_tasklist_size_allocate (GtkWidget *widget,
/* Allocate children */
l = visible_tasks;
i = 0;
- total_width = tasklist->priv->max_button_width * n_cols;
+ total_width = max_width * n_cols;
total_width = MIN (total_width, allocation->width);
/* FIXME: this is obviously wrong, but if we don't this, some space that the
* panel allocated to us won't have the panel popup menu, but the tasklist