diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2021-05-06 13:36:46 +0300 |
---|---|---|
committer | Marco Trevisan <mail@3v1n0.net> | 2021-05-10 15:38:02 +0000 |
commit | c786d24b37b17c65869e4f2a7c282fbf32bca601 (patch) | |
tree | cec921e599ccc98339f59c58f2c5663a187a30b0 /libwnck/tasklist.c | |
parent | d34848986293b47a4816656de4b1b117f021e82c (diff) | |
download | libwnck-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.
Diffstat (limited to 'libwnck/tasklist.c')
-rw-r--r-- | libwnck/tasklist.c | 405 |
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 |