all repos — tint2 @ 61a80b996fe92cb06e25aa77e7d94c4f0e61ea90

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

Add option to shrink panel (fixes issue #333)
o9000 mrovi9000@gmail.com
commit

61a80b996fe92cb06e25aa77e7d94c4f0e61ea90

parent

8c7f4cc825fb78ed30f9bbe8aa26eafca8cdb869

M src/battery/battery.csrc/battery/battery.c

@@ -58,6 +58,7 @@ gboolean battery_found;

void battery_init_fonts(); char *battery_get_tooltip(void *obj); +int battery_compute_desired_size(void *obj); void battery_dump_geometry(void *obj, int indent); void default_battery()

@@ -155,6 +156,7 @@ snprintf(battery->area.name, sizeof(battery->area.name), "Battery");

battery->area._draw_foreground = draw_battery; battery->area.size_mode = LAYOUT_FIXED; battery->area._resize = resize_battery; + battery->area._compute_desired_size = battery_compute_desired_size; battery->area._is_under_mouse = full_width_area_is_under_mouse; battery->area.on_screen = TRUE; battery->area.resize_needed = 1;

@@ -287,15 +289,60 @@

return err; } +int battery_compute_desired_size(void *obj) +{ + Battery *battery = (Battery *)obj; + Panel *panel = (Panel *)battery->area.panel; + int bat_percentage_height, bat_percentage_width, bat_percentage_height_ink; + int bat_time_height, bat_time_width, bat_time_height_ink; + + snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage); + if (battery_state.state == BATTERY_FULL) { + strcpy(buf_bat_time, "Full"); + } else { + snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes); + } + get_text_size2(bat1_font_desc, + &bat_percentage_height_ink, + &bat_percentage_height, + &bat_percentage_width, + panel->area.height, + panel->area.width, + buf_bat_percentage, + strlen(buf_bat_percentage), + PANGO_WRAP_WORD_CHAR, + PANGO_ELLIPSIZE_NONE, + FALSE); + get_text_size2(bat2_font_desc, + &bat_time_height_ink, + &bat_time_height, + &bat_time_width, + panel->area.height, + panel->area.width, + buf_bat_time, + strlen(buf_bat_time), + PANGO_WRAP_WORD_CHAR, + PANGO_ELLIPSIZE_NONE, + FALSE); + + if (panel_horizontal) { + int new_size = (bat_percentage_width > bat_time_width) ? bat_percentage_width : bat_time_width; + new_size += 2 * battery->area.paddingxlr + left_right_border_width(&battery->area); + return new_size; + } else { + int new_size = bat_percentage_height + bat_time_height + 2 * battery->area.paddingxlr + + top_bottom_border_width(&battery->area); + return new_size; + } +} + gboolean resize_battery(void *obj) { - Battery *battery = obj; - Panel *panel = battery->area.panel; + Battery *battery = (Battery *)obj; + Panel *panel = (Panel *)battery->area.panel; int bat_percentage_height, bat_percentage_width, bat_percentage_height_ink; int bat_time_height, bat_time_width, bat_time_height_ink; int ret = 0; - - schedule_redraw(&battery->area); snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage); if (battery_state.state == BATTERY_FULL) {

@@ -346,6 +393,8 @@ battery->bat2_posy = battery->bat1_posy + bat_percentage_height + 2;

ret = 1; } } + + schedule_redraw(&battery->area); return ret; }
M src/clock/clock.csrc/clock/clock.c

@@ -55,6 +55,7 @@ static timeout *clock_timeout;

void clock_init_fonts(); char *clock_get_tooltip(void *obj); +int clock_compute_desired_size(void *obj); void clock_dump_geometry(void *obj, int indent); void default_clock()

@@ -184,11 +185,12 @@ clock->area.panel = p;

snprintf(clock->area.name, sizeof(clock->area.name), "Clock"); clock->area._is_under_mouse = full_width_area_is_under_mouse; clock->area.has_mouse_press_effect = clock->area.has_mouse_over_effect = - panel_config.mouse_effects && (clock_lclick_command || clock_mclick_command || clock_rclick_command || - clock_uwheel_command || clock_dwheel_command); + panel_config.mouse_effects && (clock_lclick_command || clock_mclick_command || clock_rclick_command || + clock_uwheel_command || clock_dwheel_command); clock->area._draw_foreground = draw_clock; clock->area.size_mode = LAYOUT_FIXED; clock->area._resize = resize_clock; + clock->area._compute_desired_size = clock_compute_desired_size; clock->area._dump_geometry = clock_dump_geometry; // check consistency if (!time1_format)

@@ -240,46 +242,85 @@ }

panel_refresh = TRUE; } -gboolean resize_clock(void *obj) +void clock_compute_text_geometry(Panel *panel, + int *time_height_ink, + int *time_height, + int *time_width, + int *date_height_ink, + int *date_height, + int *date_width) { - Clock *clock = obj; - Panel *panel = clock->area.panel; - int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width; - gboolean result = FALSE; - - schedule_redraw(&clock->area); - - date_height = date_width = 0; + *date_height = *date_width = 0; strftime(buf_time, sizeof(buf_time), time1_format, clock_gettime_for_tz(time1_timezone)); get_text_size2(time1_font_desc, - &time_height_ink, - &time_height, - &time_width, - panel->area.height, - panel->area.width, - buf_time, - strlen(buf_time), - PANGO_WRAP_WORD_CHAR, - PANGO_ELLIPSIZE_NONE, - FALSE); + time_height_ink, + time_height, + time_width, + panel->area.height, + panel->area.width, + buf_time, + strlen(buf_time), + PANGO_WRAP_WORD_CHAR, + PANGO_ELLIPSIZE_NONE, + FALSE); if (time2_format) { strftime(buf_date, sizeof(buf_date), time2_format, clock_gettime_for_tz(time2_timezone)); get_text_size2(time2_font_desc, - &date_height_ink, - &date_height, - &date_width, - panel->area.height, - panel->area.width, - buf_date, - strlen(buf_date), - PANGO_WRAP_WORD_CHAR, - PANGO_ELLIPSIZE_NONE, - FALSE); + date_height_ink, + date_height, + date_width, + panel->area.height, + panel->area.width, + buf_date, + strlen(buf_date), + PANGO_WRAP_WORD_CHAR, + PANGO_ELLIPSIZE_NONE, + FALSE); } +} + +int clock_compute_desired_size(void *obj) +{ + Clock *clock = (Clock *)obj; + Panel *panel = (Panel *)clock->area.panel; + int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width; + clock_compute_text_geometry(panel, + &time_height_ink, + &time_height, + &time_width, + &date_height_ink, + &date_height, + &date_width); if (panel_horizontal) { int new_size = (time_width > date_width) ? time_width : date_width; new_size += 2 * clock->area.paddingxlr + left_right_border_width(&clock->area); + return new_size; + } else { + int new_size = time_height + date_height + 2 * clock->area.paddingxlr + top_bottom_border_width(&clock->area); + return new_size; + } +} + +gboolean resize_clock(void *obj) +{ + Clock *clock = (Clock *)obj; + Panel *panel = (Panel *)clock->area.panel; + gboolean result = FALSE; + + schedule_redraw(&clock->area); + + int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width; + clock_compute_text_geometry(panel, + &time_height_ink, + &time_height, + &time_width, + &date_height_ink, + &date_height, + &date_width); + + int new_size = clock_compute_desired_size(clock); + if (panel_horizontal) { if (new_size > clock->area.width || new_size < (clock->area.width - 6)) { // we try to limit the number of resizes clock->area.width = new_size + 1;

@@ -291,7 +332,6 @@ }

result = TRUE; } } else { - int new_size = time_height + date_height + 2 * clock->area.paddingxlr + top_bottom_border_width(&clock->area); if (new_size != clock->area.height) { // we try to limit the number of resizes clock->area.height = new_size;

@@ -340,21 +380,10 @@

void clock_dump_geometry(void *obj, int indent) { Clock *clock = (Clock *)obj; - fprintf(stderr, - "%*sText 1: y = %d, text = %s\n", - indent, - "", - clock->time1_posy, - buf_time); + fprintf(stderr, "%*sText 1: y = %d, text = %s\n", indent, "", clock->time1_posy, buf_time); if (time2_format) { - fprintf(stderr, - "%*sText 2: y = %d, text = %s\n", - indent, - "", - clock->time2_posy, - buf_date); + fprintf(stderr, "%*sText 2: y = %d, text = %s\n", indent, "", clock->time2_posy, buf_date); } - } char *clock_get_tooltip(void *obj)
M src/config.csrc/config.c

@@ -431,6 +431,8 @@ else if (strcmp(key, "panel_monitor") == 0) {

panel_config.monitor = config_get_monitor(value); } else if (strcmp(key, "primary_monitor_first") == 0) { primary_monitor_first = atoi(value); + } else if (strcmp(key, "panel_shrink") == 0) { + panel_shrink = atoi(value); } else if (strcmp(key, "panel_size") == 0) { extract_values(value, &value1, &value2, &value3);
M src/execplugin/execplugin.csrc/execplugin/execplugin.c

@@ -21,6 +21,7 @@

void execp_timer_callback(void *arg); char *execp_get_tooltip(void *obj); void execp_init_fonts(); +int execp_compute_desired_size(void *obj); void execp_dump_geometry(void *obj, int indent); void default_execp()

@@ -165,6 +166,7 @@ execp->area.paddingxlr = execp->backend->paddingxlr;

execp->area.parent = panel; execp->area.panel = panel; execp->area._dump_geometry = execp_dump_geometry; + execp->area._compute_desired_size = execp_compute_desired_size; snprintf(execp->area.name, sizeof(execp->area.name), "Execp %s",

@@ -288,15 +290,85 @@ }

return FALSE; } -gboolean resize_execp(void *obj) +int execp_compute_desired_size(void *obj) { - Execp *execp = obj; - Panel *panel = execp->area.panel; + Execp *execp = (Execp *)obj; + Panel *panel = (Panel *)execp->area.panel; int horiz_padding = (panel_horizontal ? execp->area.paddingxlr : execp->area.paddingy); int vert_padding = (panel_horizontal ? execp->area.paddingy : execp->area.paddingxlr); int interior_padding = execp->area.paddingx; - schedule_redraw(&execp->area); + int icon_w, icon_h; + if (reload_icon(execp)) { + if (execp->backend->icon) { + imlib_context_set_image(execp->backend->icon); + icon_w = imlib_image_get_width(); + icon_h = imlib_image_get_height(); + } else { + icon_w = icon_h = 0; + } + } else { + icon_w = icon_h = 0; + } + + int text_next_line = !panel_horizontal && icon_w > execp->area.width / 2; + + int txt_height_ink, txt_height, txt_width; + if (panel_horizontal) { + get_text_size2(execp->backend->font_desc, + &txt_height_ink, + &txt_height, + &txt_width, + panel->area.height, + panel->area.width, + execp->backend->text, + strlen(execp->backend->text), + PANGO_WRAP_WORD_CHAR, + PANGO_ELLIPSIZE_NONE, + execp->backend->has_markup); + } else { + get_text_size2(execp->backend->font_desc, + &txt_height_ink, + &txt_height, + &txt_width, + panel->area.height, + !text_next_line + ? execp->area.width - icon_w - (icon_w ? interior_padding : 0) - 2 * horiz_padding - + left_right_border_width(&execp->area) + : execp->area.width - 2 * horiz_padding - left_right_border_width(&execp->area), + execp->backend->text, + strlen(execp->backend->text), + PANGO_WRAP_WORD_CHAR, + PANGO_ELLIPSIZE_NONE, + execp->backend->has_markup); + } + + if (panel_horizontal) { + int new_size = txt_width; + if (icon_w) + new_size += interior_padding + icon_w; + new_size += 2 * horiz_padding + left_right_border_width(&execp->area); + return new_size; + } else { + int new_size; + if (!text_next_line) { + new_size = txt_height + 2 * vert_padding + top_bottom_border_width(&execp->area); + new_size = MAX(new_size, icon_h + 2 * vert_padding + top_bottom_border_width(&execp->area)); + } else { + new_size = + icon_h + interior_padding + txt_height + 2 * vert_padding + top_bottom_border_width(&execp->area); + } + return new_size; + } +} + +gboolean resize_execp(void *obj) +{ + Execp *execp = (Execp *)obj; + Panel *panel = (Panel *)execp->area.panel; + int horiz_padding = (panel_horizontal ? execp->area.paddingxlr : execp->area.paddingy); + int vert_padding = (panel_horizontal ? execp->area.paddingy : execp->area.paddingxlr); + int interior_padding = execp->area.paddingx; int icon_w, icon_h; if (reload_icon(execp)) {

@@ -405,6 +477,8 @@ execp->frontend->texty = (execp->area.height - txt_height) / 2;

execp->frontend->textx = left_border_width(&execp->area) + horiz_padding; } } + + schedule_redraw(&execp->area); return result; }
M src/freespace/freespace.csrc/freespace/freespace.c

@@ -30,6 +30,8 @@ #include "panel.h"

#include "freespace.h" #include "common.h" +int freespace_area_compute_desired_size(void *obj); + void init_freespace_panel(void *p) { Panel *panel = (Panel *)p;

@@ -51,6 +53,7 @@ freespace->area.size_mode = LAYOUT_FIXED;

freespace->area.resize_needed = 1; freespace->area.on_screen = TRUE; freespace->area._resize = resize_freespace; + freespace->area._compute_desired_size = freespace_area_compute_desired_size; } } }

@@ -64,6 +67,8 @@ }

int freespace_get_max_size(Panel *p) { + if (panel_shrink) + return 0; // Get space used by every element except the freespace int size = 0; int spacers = 0;

@@ -89,6 +94,12 @@ else

size = p->area.height - size - top_bottom_border_width(&p->area) - p->area.paddingxlr; return size / spacers; +} + +int freespace_area_compute_desired_size(void *obj) +{ + FreeSpace *freespace = (FreeSpace *) obj; + return freespace_get_max_size((Panel *)freespace->area.panel); } gboolean resize_freespace(void *obj)
M src/launcher/launcher.csrc/launcher/launcher.c

@@ -62,6 +62,7 @@ void launcher_reload_icon(Launcher *launcher, LauncherIcon *launcherIcon);

void launcher_reload_icon_image(Launcher *launcher, LauncherIcon *launcherIcon); void launcher_reload_hidden_icons(Launcher *launcher); void launcher_icon_on_change_layout(void *obj); +int launcher_compute_desired_size(void *obj); void default_launcher() {

@@ -94,6 +95,7 @@ snprintf(launcher->area.name, sizeof(launcher->area.name), "Launcher");

launcher->area._draw_foreground = NULL; launcher->area.size_mode = LAYOUT_FIXED; launcher->area._resize = resize_launcher; + launcher->area._compute_desired_size = launcher_compute_desired_size; launcher->area.resize_needed = 1; schedule_redraw(&launcher->area); if (!launcher->area.bg)

@@ -161,21 +163,76 @@ free_themes(launcher->icon_theme_wrapper);

launcher->icon_theme_wrapper = NULL; } -gboolean resize_launcher(void *obj) +int launcher_compute_icon_size(Launcher *launcher) { - Launcher *launcher = obj; - int icons_per_column = 1, icons_per_row = 1, margin = 0; + int icon_size = panel_horizontal ? launcher->area.height : launcher->area.width; + icon_size = icon_size - MAX(left_right_border_width(&launcher->area), top_bottom_border_width(&launcher->area)) - + (2 * launcher->area.paddingy); + if (launcher_max_icon_size > 0 && icon_size > launcher_max_icon_size) + icon_size = launcher_max_icon_size; + return icon_size; +} - int icon_size; +void launcher_compute_geometry(Launcher *launcher, + int *size, + int *icon_size, + int *icons_per_column, + int *icons_per_row, + int *margin) +{ + int count = 0; + for (GSList *l = launcher->list_icons; l; l = l->next) { + LauncherIcon *launcherIcon = (LauncherIcon *)l->data; + if (launcherIcon->area.on_screen) + count++; + } + + *icon_size = launcher_compute_icon_size(launcher); + *icons_per_column = 1; + *icons_per_row = 1; + *margin = 0; if (panel_horizontal) { - icon_size = launcher->area.height; + if (!count) { + *size = 0; + } else { + int height = launcher->area.height - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy; + // here icons_per_column always higher than 0 + *icons_per_column = (height + launcher->area.paddingx) / (*icon_size + launcher->area.paddingx); + *margin = height - (*icons_per_column - 1) * (*icon_size + launcher->area.paddingx) - *icon_size; + *icons_per_row = count / *icons_per_column + (count % *icons_per_column != 0); + *size = left_right_border_width(&launcher->area) + 2 * launcher->area.paddingxlr + + (*icon_size * *icons_per_row) + ((*icons_per_row - 1) * launcher->area.paddingx); + } } else { - icon_size = launcher->area.width; + if (!count) { + *size = 0; + } else { + int width = launcher->area.width - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy; + // here icons_per_row always higher than 0 + *icons_per_row = (width + launcher->area.paddingx) / (*icon_size + launcher->area.paddingx); + *margin = width - (*icons_per_row - 1) * (*icon_size + launcher->area.paddingx) - *icon_size; + *icons_per_column = count / *icons_per_row + (count % *icons_per_row != 0); + *size = top_bottom_border_width(&launcher->area) + 2 * launcher->area.paddingxlr + + (*icon_size * *icons_per_column) + ((*icons_per_column - 1) * launcher->area.paddingx); + } } - icon_size = icon_size - MAX(left_right_border_width(&launcher->area), top_bottom_border_width(&launcher->area)) - - (2 * launcher->area.paddingy); - if (launcher_max_icon_size > 0 && icon_size > launcher_max_icon_size) - icon_size = launcher_max_icon_size; +} + +int launcher_compute_desired_size(void *obj) +{ + Launcher *launcher = (Launcher *)obj; + + int size, icon_size, icons_per_column, icons_per_row, margin; + launcher_compute_geometry(launcher, &size, &icon_size, &icons_per_column, &icons_per_row, &margin); + return size; +} + +gboolean resize_launcher(void *obj) +{ + Launcher *launcher = (Launcher *)obj; + + int size, icon_size, icons_per_column, icons_per_row, margin; + launcher_compute_geometry(launcher, &size, &icon_size, &icons_per_column, &icons_per_row, &margin); // Resize icons if necessary for (GSList *l = launcher->list_icons; l; l = l->next) {

@@ -197,29 +254,13 @@ count++;

} if (panel_horizontal) { - if (!count) { - launcher->area.width = 0; - } else { - int height = launcher->area.height - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy; - // here icons_per_column always higher than 0 - icons_per_column = (height + launcher->area.paddingx) / (icon_size + launcher->area.paddingx); - margin = height - (icons_per_column - 1) * (icon_size + launcher->area.paddingx) - icon_size; - icons_per_row = count / icons_per_column + (count % icons_per_column != 0); - launcher->area.width = left_right_border_width(&launcher->area) + 2 * launcher->area.paddingxlr + - (icon_size * icons_per_row) + ((icons_per_row - 1) * launcher->area.paddingx); - } + if (launcher->area.width == size) + return FALSE; + launcher->area.width = size; } else { - if (!count) { - launcher->area.height = 0; - } else { - int width = launcher->area.width - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy; - // here icons_per_row always higher than 0 - icons_per_row = (width + launcher->area.paddingx) / (icon_size + launcher->area.paddingx); - margin = width - (icons_per_row - 1) * (icon_size + launcher->area.paddingx) - icon_size; - icons_per_column = count / icons_per_row + (count % icons_per_row != 0); - launcher->area.height = top_bottom_border_width(&launcher->area) + 2 * launcher->area.paddingxlr + - (icon_size * icons_per_column) + ((icons_per_column - 1) * launcher->area.paddingx); - } + if (launcher->area.height == size) + return FALSE; + launcher->area.height = size; } int posx, posy;

@@ -283,6 +324,12 @@ launcherIcon->area.width = launcherIcon->icon_size;

launcherIcon->area.height = launcherIcon->icon_size; } +int launcher_icon_compute_desired_size(void *obj) +{ + LauncherIcon *icon = (LauncherIcon *)obj; + return icon->icon_size; +} + char *launcher_icon_get_tooltip_text(void *obj) { LauncherIcon *launcherIcon = (LauncherIcon *)obj;

@@ -312,12 +359,7 @@

void launcher_icon_dump_geometry(void *obj, int indent) { LauncherIcon *launcherIcon = (LauncherIcon *)obj; - fprintf(stderr, - "%*sIcon: w = h = %d, name = %s\n", - indent, - "", - launcherIcon->icon_size, - launcherIcon->icon_name); + fprintf(stderr, "%*sIcon: w = h = %d, name = %s\n", indent, "", launcherIcon->icon_size, launcherIcon->icon_name); } Imlib_Image scale_icon(Imlib_Image original, int icon_size)

@@ -419,6 +461,8 @@ }

free(cmd); } + + // Populates the list_icons list from the list_apps list void launcher_load_icons(Launcher *launcher) {

@@ -432,6 +476,7 @@ launcherIcon->area.panel = launcher->area.panel;

launcherIcon->area._draw_foreground = draw_launcher_icon; launcherIcon->area.size_mode = LAYOUT_FIXED; launcherIcon->area._resize = NULL; + launcherIcon->area._compute_desired_size = launcher_icon_compute_desired_size; sprintf(launcherIcon->area.name, "LauncherIcon %d", index); launcherIcon->area.resize_needed = 0; launcherIcon->area.has_mouse_over_effect = panel_config.mouse_effects;

@@ -523,13 +568,13 @@ // fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);

if (panel_config.mouse_effects) { launcherIcon->image_hover = adjust_icon(launcherIcon->image, - panel_config.mouse_over_alpha, - panel_config.mouse_over_saturation, - panel_config.mouse_over_brightness); + panel_config.mouse_over_alpha, + panel_config.mouse_over_saturation, + panel_config.mouse_over_brightness); launcherIcon->image_pressed = adjust_icon(launcherIcon->image, - panel_config.mouse_pressed_alpha, - panel_config.mouse_pressed_saturation, - panel_config.mouse_pressed_brightness); + panel_config.mouse_pressed_alpha, + panel_config.mouse_pressed_saturation, + panel_config.mouse_pressed_brightness); } }
M src/panel.csrc/panel.c

@@ -62,6 +62,7 @@ gboolean panel_autohide;

int panel_autohide_show_timeout; int panel_autohide_hide_timeout; int panel_autohide_height; +gboolean panel_shrink; Strut panel_strut_policy; char *panel_items_order;

@@ -92,6 +93,7 @@ panel_autohide = FALSE;

panel_autohide_show_timeout = 0; panel_autohide_hide_timeout = 0; panel_autohide_height = 5; // for vertical panels this is of course the width + panel_shrink = FALSE; panel_strut_policy = STRUT_FOLLOW_SIZE; panel_dock = FALSE; // default not in the dock panel_layer = BOTTOM_LAYER; // default is bottom layer

@@ -298,9 +300,8 @@ reset_active_task();

update_all_taskbars_visibility(); } -void init_panel_size_and_position(Panel *panel) +void panel_compute_size(Panel *panel) { - // detect panel size if (panel_horizontal) { if (panel->area.width == 0) { panel->fractional_width = TRUE;

@@ -353,17 +354,22 @@ panel->area.width = server.monitors[panel->monitor].width - panel->marginx;

if (panel->area.height + panel->marginy > server.monitors[panel->monitor].height) panel->area.height = server.monitors[panel->monitor].height - panel->marginy; + panel->max_size = panel_horizontal ? panel->area.width : panel->area.height; +} + +void panel_compute_position(Panel *panel) +{ // panel position determined here if (panel_position & LEFT) { panel->posx = server.monitors[panel->monitor].x + panel->marginx; } else { if (panel_position & RIGHT) { panel->posx = server.monitors[panel->monitor].x + server.monitors[panel->monitor].width - - panel->area.width - panel->marginx; + panel->area.width - panel->marginx; } else { if (panel_horizontal) panel->posx = server.monitors[panel->monitor].x + - ((server.monitors[panel->monitor].width - panel->area.width) / 2); + ((server.monitors[panel->monitor].width - panel->area.width) / 2); else panel->posx = server.monitors[panel->monitor].x + panel->marginx; }

@@ -373,10 +379,10 @@ panel->posy = server.monitors[panel->monitor].y + panel->marginy;

} else { if (panel_position & BOTTOM) { panel->posy = server.monitors[panel->monitor].y + server.monitors[panel->monitor].height - - panel->area.height - panel->marginy; + panel->area.height - panel->marginy; } else { panel->posy = - server.monitors[panel->monitor].y + ((server.monitors[panel->monitor].height - panel->area.height) / 2); + server.monitors[panel->monitor].y + ((server.monitors[panel->monitor].height - panel->area.height) / 2); } }

@@ -393,6 +399,12 @@ // printf("panel : posx %d, posy %d, width %d, height %d\n", panel->posx, panel->posy, panel->area.width,

// panel->area.height); } +void init_panel_size_and_position(Panel *panel) +{ + panel_compute_size(panel); + panel_compute_position(panel); +} + gboolean resize_panel(void *obj) { Panel *panel = (Panel *)obj;

@@ -660,6 +672,58 @@ XSendEvent(server.display, server.root_win, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&m);

XSync(server.display, False); } +void set_panel_window_geometry(Panel *panel) +{ + update_strut(panel); + + // Fixed position and non-resizable window + // Allow panel move and resize when tint2 reload config file + int minwidth = panel_autohide ? panel->hidden_width : panel->area.width; + int minheight = panel_autohide ? panel->hidden_height : panel->area.height; + XSizeHints size_hints; + size_hints.flags = PPosition | PMinSize | PMaxSize; + size_hints.min_width = minwidth; + size_hints.max_width = panel->area.width; + size_hints.min_height = minheight; + size_hints.max_height = panel->area.height; + XSetWMNormalHints(server.display, panel->main_win, &size_hints); + + if (!panel->is_hidden) { + if (panel_horizontal) { + XMoveResizeWindow(server.display, + panel->main_win, + panel->posx, + panel->posy, + panel->area.width, + panel->area.height); + } else { + XMoveResizeWindow(server.display, + panel->main_win, + panel->posx, + panel->posy, + panel->area.width, + panel->area.height); + } + } else { + int diff = (panel_horizontal ? panel->area.height : panel->area.width) - panel_autohide_height; + if (panel_horizontal) { + XMoveResizeWindow(server.display, + panel->main_win, + panel->posx, + panel->posy + diff, + panel->hidden_width, + panel->hidden_height); + } else { + XMoveResizeWindow(server.display, + panel->main_win, + panel->posx + diff, + panel->posy, + panel->hidden_width, + panel->hidden_height); + } + } +} + void set_panel_properties(Panel *p) { XStoreName(server.display, p->main_win, panel_window_name);

@@ -736,26 +800,14 @@ PropModeReplace,

(unsigned char *)&version, 1); - update_strut(p); - - // Fixed position and non-resizable window - // Allow panel move and resize when tint2 reload config file - int minwidth = panel_autohide ? p->hidden_width : p->area.width; - int minheight = panel_autohide ? p->hidden_height : p->area.height; - XSizeHints size_hints; - size_hints.flags = PPosition | PMinSize | PMaxSize; - size_hints.min_width = minwidth; - size_hints.max_width = p->area.width; - size_hints.min_height = minheight; - size_hints.max_height = p->area.height; - XSetWMNormalHints(server.display, p->main_win, &size_hints); - // Set WM_CLASS XClassHint *classhint = XAllocClassHint(); classhint->res_name = (char *)"tint2"; classhint->res_class = (char *)"Tint2"; XSetClassHint(server.display, p->main_win, classhint); XFree(classhint); + + set_panel_window_geometry(p); } void panel_clear_background(void *obj)

@@ -893,31 +945,8 @@ {

Panel *panel = (Panel *)p; stop_autohide_timeout(panel); panel->is_hidden = 0; - XMapSubwindows(server.display, panel->main_win); // systray windows - if (panel_horizontal) { - if (panel_position & TOP) - XResizeWindow(server.display, panel->main_win, panel->area.width, panel->area.height); - else - XMoveResizeWindow(server.display, - panel->main_win, - panel->posx, - panel->posy, - panel->area.width, - panel->area.height); - } else { - if (panel_position & LEFT) - XResizeWindow(server.display, panel->main_win, panel->area.width, panel->area.height); - else - XMoveResizeWindow(server.display, - panel->main_win, - panel->posx, - panel->posy, - panel->area.width, - panel->area.height); - } - if (panel_strut_policy == STRUT_FOLLOW_SIZE) - update_strut(panel); + set_panel_window_geometry(panel); refresh_systray = TRUE; // ugly hack, because we actually only need to call XSetBackgroundPixmap panel_refresh = TRUE; }

@@ -927,33 +956,8 @@ {

Panel *panel = (Panel *)p; stop_autohide_timeout(panel); panel->is_hidden = TRUE; - if (panel_strut_policy == STRUT_FOLLOW_SIZE) - update_strut(panel); - XUnmapSubwindows(server.display, panel->main_win); // systray windows - int diff = (panel_horizontal ? panel->area.height : panel->area.width) - panel_autohide_height; - // printf("autohide_hide : diff %d, w %d, h %d\n", diff, panel->hidden_width, panel->hidden_height); - if (panel_horizontal) { - if (panel_position & TOP) - XResizeWindow(server.display, panel->main_win, panel->hidden_width, panel->hidden_height); - else - XMoveResizeWindow(server.display, - panel->main_win, - panel->posx, - panel->posy + diff, - panel->hidden_width, - panel->hidden_height); - } else { - if (panel_position & LEFT) - XResizeWindow(server.display, panel->main_win, panel->hidden_width, panel->hidden_height); - else - XMoveResizeWindow(server.display, - panel->main_win, - panel->posx + diff, - panel->posy, - panel->hidden_width, - panel->hidden_height); - } + set_panel_window_geometry(panel); panel_refresh = TRUE; }

@@ -977,6 +981,34 @@ if (child)

return; // mouse over one of the system tray icons change_timeout(&p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p); +} + +void shrink_panel(Panel *panel) +{ + if (!panel_shrink) + return; + int size = MIN(compute_desired_size(&panel->area), panel->max_size); + gboolean update = FALSE; + if (panel_horizontal) { + if (panel->area.width != size) { + panel->area.width = size; + update = TRUE; + } + } else { + if (panel->area.height != size) { + panel->area.height = size; + update = TRUE; + } + } + if (update) { + panel_compute_position(panel); + set_panel_window_geometry(panel); + set_panel_background(panel); + panel->area.resize_needed = TRUE; + systray.area.resize_needed = TRUE; + schedule_redraw(&systray.area); + refresh_systray = TRUE; + } } void render_panel(Panel *panel)
M src/panel.hsrc/panel.h

@@ -79,6 +79,7 @@ extern gboolean panel_autohide;

extern int panel_autohide_show_timeout; extern int panel_autohide_hide_timeout; extern int panel_autohide_height; // for vertical panels this is of course the width +extern gboolean panel_shrink; extern Strut panel_strut_policy; extern char *panel_items_order; extern int max_tick_urgent;

@@ -100,6 +101,7 @@ // position relative to root window

int posx, posy; int marginx, marginy; gboolean fractional_width, fractional_height; + int max_size; int monitor; int font_shadow; gboolean mouse_effects;

@@ -156,11 +158,13 @@

void init_panel_size_and_position(Panel *panel); gboolean resize_panel(void *obj); void render_panel(Panel *panel); +void shrink_panel(Panel *panel); void set_panel_items_order(Panel *p); void place_panel_all_desktops(Panel *p); void replace_panel_all_desktops(Panel *p); void set_panel_properties(Panel *p); +void set_panel_window_geometry(Panel *panel); // draw background panel void set_panel_background(Panel *p);
M src/systray/systraybar.csrc/systray/systraybar.c

@@ -65,6 +65,7 @@ const int slow_resize_period = 5000;

const int min_bad_resize_events = 3; const int max_bad_resize_events = 10; +int systray_compute_desired_size(void *obj); void systray_dump_geometry(void *obj, int indent); void default_systray()

@@ -117,6 +118,7 @@ Panel *panel = (Panel *)p;

systray.area.parent = panel; systray.area.panel = panel; systray.area._dump_geometry = systray_dump_geometry; + systray.area._compute_desired_size = systray_compute_desired_size; snprintf(systray.area.name, sizeof(systray.area.name), "Systray"); if (!systray.area.bg) systray.area.bg = &g_array_index(backgrounds, Background, 0);

@@ -126,66 +128,90 @@ refresh_systray = TRUE;

instantiate_area_gradients(&systray.area); } -gboolean resize_systray(void *obj) +void systray_compute_geometry(int *size) { - if (systray_profile) - fprintf(stderr, "[%f] %s:%d\n", profiling_get_time(), __FUNCTION__, __LINE__); - - if (panel_horizontal) - systray.icon_size = systray.area.height; - else - systray.icon_size = systray.area.width; + systray.icon_size = panel_horizontal ? systray.area.height : systray.area.width; systray.icon_size -= MAX(left_right_border_width(&systray.area), top_bottom_border_width(&systray.area)) + 2 * systray.area.paddingy; if (systray_max_icon_size > 0) systray.icon_size = MIN(systray.icon_size, systray_max_icon_size); - if (systray.icon_size > 0) { - long icon_size = systray.icon_size; - XChangeProperty(server.display, - net_sel_win, - server.atom._NET_SYSTEM_TRAY_ICON_SIZE, - XA_CARDINAL, - 32, - PropModeReplace, - (unsigned char *)&icon_size, - 1); - } - int count = 0; for (GSList *l = systray.list_icons; l; l = l->next) { count++; } - if (systray_profile) - fprintf(stderr, BLUE "%s:%d number of icons = %d" RESET "\n", __FUNCTION__, __LINE__, count); if (panel_horizontal) { int height = systray.area.height - top_bottom_border_width(&systray.area) - 2 * systray.area.paddingy; // here icons_per_column always higher than 0 systray.icons_per_column = (height + systray.area.paddingx) / (systray.icon_size + systray.area.paddingx); systray.margin = - height - (systray.icons_per_column - 1) * (systray.icon_size + systray.area.paddingx) - systray.icon_size; + height - (systray.icons_per_column - 1) * (systray.icon_size + systray.area.paddingx) - systray.icon_size; systray.icons_per_row = count / systray.icons_per_column + (count % systray.icons_per_column != 0); - systray.area.width = left_right_border_width(&systray.area) + 2 * systray.area.paddingxlr + - (systray.icon_size * systray.icons_per_row) + - ((systray.icons_per_row - 1) * systray.area.paddingx); + *size = left_right_border_width(&systray.area) + 2 * systray.area.paddingxlr + + (systray.icon_size * systray.icons_per_row) + + ((systray.icons_per_row - 1) * systray.area.paddingx); } else { int width = systray.area.width - left_right_border_width(&systray.area) - 2 * systray.area.paddingy; // here icons_per_row always higher than 0 systray.icons_per_row = (width + systray.area.paddingx) / (systray.icon_size + systray.area.paddingx); systray.margin = - width - (systray.icons_per_row - 1) * (systray.icon_size + systray.area.paddingx) - systray.icon_size; + width - (systray.icons_per_row - 1) * (systray.icon_size + systray.area.paddingx) - systray.icon_size; systray.icons_per_column = count / systray.icons_per_row + (count % systray.icons_per_row != 0); - systray.area.height = top_bottom_border_width(&systray.area) + (2 * systray.area.paddingxlr) + - (systray.icon_size * systray.icons_per_column) + - ((systray.icons_per_column - 1) * systray.area.paddingx); + *size = top_bottom_border_width(&systray.area) + (2 * systray.area.paddingxlr) + + (systray.icon_size * systray.icons_per_column) + + ((systray.icons_per_column - 1) * systray.area.paddingx); } +} +int systray_compute_desired_size(void *obj) +{ + int size; + systray_compute_geometry(&size); + return size; +} + +gboolean resize_systray(void *obj) +{ + if (systray_profile) + fprintf(stderr, "[%f] %s:%d\n", profiling_get_time(), __FUNCTION__, __LINE__); + + int size; + systray_compute_geometry(&size); + + if (systray.icon_size > 0) { + long icon_size = systray.icon_size; + XChangeProperty(server.display, + net_sel_win, + server.atom._NET_SYSTEM_TRAY_ICON_SIZE, + XA_CARDINAL, + 32, + PropModeReplace, + (unsigned char *)&icon_size, + 1); + } + + gboolean result = refresh_systray; if (net_sel_win == None) { start_net(); + result = TRUE; } - return TRUE; + if (panel_horizontal) { + if (systray.area.width != size) { + systray.area.width = size; + result = TRUE; + } + } else { + if (systray.area.height != size) { + systray.area.height = size; + result = TRUE; + } + } + + on_change_systray(&systray.area); + + return result; } void draw_systray(void *obj, cairo_t *c)

@@ -1407,28 +1433,30 @@

void systray_render_icon(void *t) { TrayWindow *traywin = t; - if (systray_profile) - fprintf(stderr, - "[%f] %s:%d win = %lu (%s)\n", - profiling_get_time(), - __FUNCTION__, - __LINE__, - traywin->win, - traywin->name); if (!traywin->reparented || !traywin->embedded) { - if (systray_profile) - fprintf(stderr, - YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n", - profiling_get_time(), - __FUNCTION__, - __LINE__, - traywin->win, - traywin->name); +// if (systray_profile) +// fprintf(stderr, +// YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n", +// profiling_get_time(), +// __FUNCTION__, +// __LINE__, +// traywin->win, +// traywin->name); stop_timeout(traywin->render_timeout); traywin->render_timeout = add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout); return; } + + if (systray_profile) + fprintf(stderr, + "[%f] %s:%d win = %lu (%s)\n", + profiling_get_time(), + __FUNCTION__, + __LINE__, + traywin->win, + traywin->name); + if (systray_composited) { XSync(server.display, False);
M src/taskbar/task.csrc/taskbar/task.c

@@ -39,6 +39,7 @@ timeout *urgent_timeout;

GSList *urgent_list; void task_dump_geometry(void *obj, int indent); +int task_compute_desired_size(void *obj); char *task_get_tooltip(void *obj) {

@@ -108,6 +109,7 @@ task_instance->area.has_mouse_over_effect = panel_config.mouse_effects;

task_instance->area.has_mouse_press_effect = panel_config.mouse_effects; task_instance->area._dump_geometry = task_dump_geometry; task_instance->area._is_under_mouse = full_width_area_is_under_mouse; + task_instance->area._compute_desired_size = task_compute_desired_size; task_instance->win = task_template.win; task_instance->desktop = task_template.desktop; task_instance->win_x = task_template.win_x;

@@ -463,6 +465,14 @@ "",

task->_icon_x, task->_icon_y, panel->g_task.icon_size1); +} + +int task_compute_desired_size(void *obj) +{ + Task *task = (Task *)obj; + Panel *panel = (Panel *)task->area.panel; + int size = panel_horizontal ? panel->g_task.maximum_width : panel->g_task.maximum_height; + return size; } void on_change_task(void *obj)
M src/taskbar/taskbarname.csrc/taskbar/taskbarname.c

@@ -37,6 +37,7 @@ Color taskbarname_font;

Color taskbarname_active_font; void taskbarname_init_fonts(); +int taskbarname_compute_desired_size(void *obj); void default_taskbarname() {

@@ -60,6 +61,7 @@ memcpy(&taskbar->bar_name.area, &panel->g_taskbar.area_name, sizeof(Area));

taskbar->bar_name.area.parent = taskbar; taskbar->bar_name.area.has_mouse_over_effect = panel_config.mouse_effects; taskbar->bar_name.area.has_mouse_press_effect = panel_config.mouse_effects; + taskbar->bar_name.area._compute_desired_size = taskbarname_compute_desired_size; if (j == server.desktop) { taskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_ACTIVE]; taskbar->bar_name.area.gradients = g_list_copy(panel->g_taskbar.gradient_name[TASKBAR_ACTIVE]);

@@ -130,14 +132,38 @@ }

} } -gboolean resize_taskbarname(void *obj) +int taskbarname_compute_desired_size(void *obj) { - TaskbarName *taskbar_name = obj; - Panel *panel = taskbar_name->area.panel; + TaskbarName *taskbar_name = (TaskbarName *)obj; + Panel *panel = (Panel *)taskbar_name->area.panel; int name_height, name_width, name_height_ink; - gboolean result = FALSE; + get_text_size2(panel_config.taskbarname_font_desc, + &name_height_ink, + &name_height, + &name_width, + panel->area.height, + panel->area.width, + taskbar_name->name, + strlen(taskbar_name->name), + PANGO_WRAP_WORD_CHAR, + PANGO_ELLIPSIZE_NONE, + FALSE); + + if (panel_horizontal) { + return name_width + 2 * taskbar_name->area.paddingxlr + left_right_border_width(&taskbar_name->area); + } else { + return name_height + 2 * taskbar_name->area.paddingxlr + top_bottom_border_width(&taskbar_name->area); + } +} + +gboolean resize_taskbarname(void *obj) +{ + TaskbarName *taskbar_name = (TaskbarName *)obj; + Panel *panel = (Panel *)taskbar_name->area.panel; schedule_redraw(&taskbar_name->area); + + int name_height, name_width, name_height_ink; get_text_size2(panel_config.taskbarname_font_desc, &name_height_ink, &name_height,

@@ -150,15 +176,15 @@ PANGO_WRAP_WORD_CHAR,

PANGO_ELLIPSIZE_NONE, FALSE); + gboolean result = FALSE; + int new_size = taskbarname_compute_desired_size(obj); if (panel_horizontal) { - int new_size = name_width + 2 * taskbar_name->area.paddingxlr + left_right_border_width(&taskbar_name->area); if (new_size != taskbar_name->area.width) { taskbar_name->area.width = new_size; taskbar_name->posy = (taskbar_name->area.height - name_height) / 2; result = TRUE; } } else { - int new_size = name_height + 2 * taskbar_name->area.paddingxlr + top_bottom_border_width(&taskbar_name->area); if (new_size != taskbar_name->area.height) { taskbar_name->area.height = new_size; taskbar_name->posy = (taskbar_name->area.height - name_height) / 2;
M src/tint.csrc/tint.c

@@ -1568,6 +1568,7 @@ double ts_event_processed = 0;

double ts_render_finished = 0; double ts_flush_finished = 0; double fps_sum = 0, fps_count = 0; + gboolean first_render = TRUE; while (1) { if (panel_refresh) { if (debug_fps)

@@ -1582,6 +1583,19 @@ panel_refresh = FALSE;

for (int i = 0; i < num_panels; i++) { Panel *panel = &panels[i]; + if (!first_render) + shrink_panel(panel); + + if (!panel->is_hidden || panel->area.resize_needed) { + if (panel->temp_pmap) + XFreePixmap(server.display, panel->temp_pmap); + panel->temp_pmap = XCreatePixmap(server.display, + server.root_win, + panel->area.width, + panel->area.height, + server.depth); + render_panel(panel); + } if (panel->is_hidden) { if (!panel->hidden_pixmap) {

@@ -1618,14 +1632,6 @@ 0,

0); XSetWindowBackgroundPixmap(server.display, panel->main_win, panel->hidden_pixmap); } else { - if (panel->temp_pmap) - XFreePixmap(server.display, panel->temp_pmap); - panel->temp_pmap = XCreatePixmap(server.display, - server.root_win, - panel->area.width, - panel->area.height, - server.depth); - render_panel(panel); if (panel == (Panel *)systray.area.panel) { if (refresh_systray && panel && !panel->is_hidden) { refresh_systray = FALSE;

@@ -1644,6 +1650,11 @@ panel->area.height,

0, 0); } + } + if (first_render) { + first_render = FALSE; + if (panel_shrink) + panel_refresh = TRUE; } if (debug_fps) ts_render_finished = get_time();
M src/tint2conf/properties.csrc/tint2conf/properties.c

@@ -40,7 +40,7 @@ GtkWidget *panel_window_name, *disable_transparency;

GtkWidget *panel_mouse_effects; GtkWidget *mouse_hover_icon_opacity, *mouse_hover_icon_saturation, *mouse_hover_icon_brightness; GtkWidget *mouse_pressed_icon_opacity, *mouse_pressed_icon_saturation, *mouse_pressed_icon_brightness; -GtkWidget *panel_primary_monitor_first; +GtkWidget *panel_primary_monitor_first, *panel_shrink; GtkListStore *panel_items, *all_items; GtkWidget *panel_items_view, *all_items_view;

@@ -1384,6 +1384,19 @@ gtk_combo_box_append_text(GTK_COMBO_BOX(panel_combo_width_type), _("Percent"));

gtk_combo_box_append_text(GTK_COMBO_BOX(panel_combo_width_type), _("Pixels")); gtk_combo_box_set_active(GTK_COMBO_BOX(panel_combo_width_type), 0); gtk_tooltips_set_tip(tooltips, panel_combo_width_type, _("The units used to specify the length of the panel: pixels or percentage of the monitor size"), NULL); + + row++; + col = 2; + label = gtk_label_new(_("Shrink")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + col++; + + panel_shrink = gtk_check_button_new(); + gtk_widget_show(panel_shrink); + gtk_table_attach(GTK_TABLE(table), panel_shrink, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + col++; row++; col = 2;
M src/tint2conf/properties.hsrc/tint2conf/properties.h

@@ -17,7 +17,7 @@ extern GtkWidget *panel_window_name, *disable_transparency;

extern GtkWidget *panel_mouse_effects; extern GtkWidget *mouse_hover_icon_opacity, *mouse_hover_icon_saturation, *mouse_hover_icon_brightness; extern GtkWidget *mouse_pressed_icon_opacity, *mouse_pressed_icon_saturation, *mouse_pressed_icon_brightness; -extern GtkWidget *panel_primary_monitor_first; +extern GtkWidget *panel_primary_monitor_first, *panel_shrink; enum { itemsColName = 0,
M src/tint2conf/properties_rw.csrc/tint2conf/properties_rw.c

@@ -274,6 +274,10 @@ fprintf(fp,

"primary_monitor_first = %d\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel_primary_monitor_first)) ? 1 : 0); + fprintf(fp, + "panel_shrink = %d\n", + gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel_shrink)) ? 1 : 0); + fprintf(fp, "autohide = %d\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel_autohide)) ? 1 : 0); fprintf(fp, "autohide_show_timeout = %g\n", gtk_spin_button_get_value(GTK_SPIN_BUTTON(panel_autohide_show_time))); fprintf(fp, "autohide_hide_timeout = %g\n", gtk_spin_button_get_value(GTK_SPIN_BUTTON(panel_autohide_hide_time)));

@@ -1196,6 +1200,8 @@ else if (strcmp(value, "6") == 0)

gtk_combo_box_set_active(GTK_COMBO_BOX(panel_combo_monitor), 6); } else if (strcmp(key, "primary_monitor_first") == 0) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel_primary_monitor_first), atoi(value)); + } else if (strcmp(key, "primary_shrink") == 0) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel_shrink), atoi(value)); } /* autohide options */
M src/util/area.csrc/util/area.c

@@ -216,36 +216,32 @@ a->_on_change_layout(a);

} } -void relayout(Area *a) -{ - relayout_fixed(a); - relayout_dynamic(a, 1); -} - -void draw_tree(Area *a) +int compute_desired_size(Area *a) { if (!a->on_screen) - return; - - if (a->_redraw_needed) { - a->_redraw_needed = FALSE; - draw(a); + return 0; + if (a->_compute_desired_size) + return a->_compute_desired_size(a); + if (a->size_mode == LAYOUT_FIXED) + fprintf(stderr, YELLOW "Area %s does not set desired size!" RESET "\n", a->name); + int result = 2 * a->paddingxlr + (panel_horizontal ? left_right_border_width(a) : top_bottom_border_width(a)); + int children_count = 0; + for (GList *l = a->children; l != NULL; l = l->next) { + Area *child = (Area *)l->data; + if (child->on_screen) { + result += compute_desired_size(child); + children_count++; + } } - - if (a->pix) - XCopyArea(server.display, - a->pix, - ((Panel *)a->panel)->temp_pmap, - server.gc, - 0, - 0, - a->width, - a->height, - a->posx, - a->posy); + if (children_count > 0) + result += (children_count - 1) * a->paddingx; + return result; +} - for (GList *l = a->children; l; l = l->next) - draw_tree((Area *)l->data); +void relayout(Area *a) +{ + relayout_fixed(a); + relayout_dynamic(a, 1); } int relayout_with_constraint(Area *a, int maximum_size)

@@ -357,6 +353,32 @@

for (GList *l = a->children; l; l = l->next) schedule_redraw((Area *)l->data); panel_refresh = TRUE; +} + +void draw_tree(Area *a) +{ + if (!a->on_screen) + return; + + if (a->_redraw_needed) { + a->_redraw_needed = FALSE; + draw(a); + } + + if (a->pix) + XCopyArea(server.display, + a->pix, + ((Panel *)a->panel)->temp_pmap, + server.gc, + 0, + 0, + a->width, + a->height, + a->posx, + a->posy); + + for (GList *l = a->children; l; l = l->next) + draw_tree((Area *)l->data); } void hide(Area *a)

@@ -818,13 +840,14 @@ fprintf(stderr, "%*shidden\n", indent, "");

return; } fprintf(stderr, - "%*sBox: x = %d, y = %d, w = %d, h = %d\n", + "%*sBox: x = %d, y = %d, w = %d, h = %d, desired size = %d\n", indent, "", area->posx, area->posy, area->width, - area->height); + area->height, + compute_desired_size(area)); fprintf(stderr, "%*sBorder: left = %d, right = %d, top = %d, bottom = %d\n", indent,
M src/util/area.hsrc/util/area.h

@@ -221,6 +221,10 @@ // Called on resize, obj = pointer to the Area

// Returns 1 if the new size is different than the previous size. gboolean (*_resize)(void *obj); + // Called before resize, obj = pointer to the Area + // Returns the desired size of the Area + int (*_compute_desired_size)(void *obj); + // Implemented only to override the default layout algorithm for this widget. // For example, if this widget is a cell in a table, its position and size should be computed here. void (*_on_change_layout)(void *obj);

@@ -254,6 +258,8 @@

// Distributes the Area's size to its children, repositioning them as needed. // If maximum_size > 0, it is an upper limit for the child size. int relayout_with_constraint(Area *a, int maximum_size); + +int compute_desired_size(Area *a); int left_border_width(Area *a); int right_border_width(Area *a);