From 61a80b996fe92cb06e25aa77e7d94c4f0e61ea90 Mon Sep 17 00:00:00 2001 From: o9000 Date: Sat, 8 Oct 2016 14:45:00 +0200 Subject: [PATCH] Add option to shrink panel (fixes issue #333) --- src/battery/battery.c | 57 ++++++++++- src/clock/clock.c | 119 ++++++++++++++--------- src/config.c | 2 + src/execplugin/execplugin.c | 82 +++++++++++++++- src/freespace/freespace.c | 11 +++ src/launcher/launcher.c | 133 +++++++++++++++++--------- src/panel.c | 172 ++++++++++++++++++++-------------- src/panel.h | 4 + src/systray/systraybar.c | 136 ++++++++++++++++----------- src/taskbar/task.c | 10 ++ src/taskbar/taskbarname.c | 42 +++++++-- src/tint.c | 27 ++++-- src/tint2conf/properties.c | 15 ++- src/tint2conf/properties.h | 2 +- src/tint2conf/properties_rw.c | 6 ++ src/util/area.c | 79 ++++++++++------ src/util/area.h | 6 ++ 17 files changed, 636 insertions(+), 267 deletions(-) diff --git a/src/battery/battery.c b/src/battery/battery.c index cf2bcd0..ac1458a 100644 --- a/src/battery/battery.c +++ b/src/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 @@ void init_battery_panel(void *p) 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,16 +289,61 @@ int update_battery() 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) { strcpy(buf_bat_time, "Full"); @@ -346,6 +393,8 @@ gboolean resize_battery(void *obj) ret = 1; } } + + schedule_redraw(&battery->area); return ret; } diff --git a/src/clock/clock.c b/src/clock/clock.c index bb2e03f..13b3c7b 100644 --- a/src/clock/clock.c +++ b/src/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 @@ void init_clock_panel(void *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 @@ void clock_default_font_changed() 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 @@ gboolean resize_clock(void *obj) 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 draw_clock(void *obj, cairo_t *c) 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) diff --git a/src/config.c b/src/config.c index f6ea001..e13cacd 100644 --- a/src/config.c +++ b/src/config.c @@ -431,6 +431,8 @@ void add_entry(char *key, char *value) 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); diff --git a/src/execplugin/execplugin.c b/src/execplugin/execplugin.c index abe1e16..4a5eb5a 100644 --- a/src/execplugin/execplugin.c +++ b/src/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 @@ void init_execp_panel(void *p) 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 @@ gboolean reload_icon(Execp *execp) 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)) { @@ -406,6 +478,8 @@ gboolean resize_execp(void *obj) } } + schedule_redraw(&execp->area); + return result; } diff --git a/src/freespace/freespace.c b/src/freespace/freespace.c index 91fdddf..639f030 100644 --- a/src/freespace/freespace.c +++ b/src/freespace/freespace.c @@ -30,6 +30,8 @@ #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 @@ void init_freespace_panel(void *p) 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 @@ void cleanup_freespace(Panel *panel) 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; @@ -91,6 +96,12 @@ int freespace_get_max_size(Panel *p) 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) { FreeSpace *freespace = (FreeSpace *)obj; diff --git a/src/launcher/launcher.c b/src/launcher/launcher.c index 138daa7..0b4172f 100644 --- a/src/launcher/launcher.c +++ b/src/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 @@ void init_launcher_panel(void *p) 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 @@ void cleanup_launcher_theme(Launcher *launcher) 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; - if (panel_horizontal) { - icon_size = launcher->area.height; - } else { - icon_size = launcher->area.width; - } + 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; +} + +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) { + 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 { + 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); + } + } +} + +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 @@ gboolean resize_launcher(void *obj) } 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 @@ void launcher_icon_on_change_layout(void *obj) 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 draw_launcher_icon(void *obj, cairo_t *c) 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 @@ void launcher_action(LauncherIcon *icon, XEvent *evt) free(cmd); } + + // Populates the list_icons list from the list_apps list void launcher_load_icons(Launcher *launcher) { @@ -432,6 +476,7 @@ void launcher_load_icons(Launcher *launcher) 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 @@ void launcher_reload_icon_image(Launcher *launcher, LauncherIcon *launcherIcon) 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); } } diff --git a/src/panel.c b/src/panel.c index 9d6d422..8c1680e 100644 --- a/src/panel.c +++ b/src/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 @@ void default_panel() 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 @@ void init_panel() 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 @@ void init_panel_size_and_position(Panel *panel) 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 @@ void init_panel_size_and_position(Panel *panel) } 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 @@ void init_panel_size_and_position(Panel *panel) // 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 @@ void replace_panel_all_desktops(Panel *p) 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 @@ void set_panel_properties(Panel *p) (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 @@ void autohide_show(void *p) 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 @@ void autohide_hide(void *p) 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; } @@ -979,6 +983,34 @@ void autohide_trigger_hide(Panel *p) 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) { relayout(&panel->area); diff --git a/src/panel.h b/src/panel.h index aea3963..39a19ce 100644 --- a/src/panel.h +++ b/src/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 @@ typedef struct Panel { 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(); 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); diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c index 7c1055d..ef28310 100644 --- a/src/systray/systraybar.c +++ b/src/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 @@ void init_systray_panel(void *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,19 +128,56 @@ void init_systray_panel(void *p) instantiate_area_gradients(&systray.area); } +void systray_compute_geometry(int *size) +{ + 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); + + int count = 0; + for (GSList *l = systray.list_icons; l; l = l->next) { + 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; + systray.icons_per_row = count / systray.icons_per_column + (count % systray.icons_per_column != 0); + *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; + systray.icons_per_column = count / systray.icons_per_row + (count % systray.icons_per_row != 0); + *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__); - if (panel_horizontal) - systray.icon_size = systray.area.height; - else - systray.icon_size = 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); + int size; + systray_compute_geometry(&size); if (systray.icon_size > 0) { long icon_size = systray.icon_size; @@ -152,40 +191,27 @@ gboolean resize_systray(void *obj) 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; - 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); - } 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; - 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); - } - + 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,29 +1433,31 @@ on_systray_error: 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); error = FALSE; diff --git a/src/taskbar/task.c b/src/taskbar/task.c index 33a1a51..5b31602 100644 --- a/src/taskbar/task.c +++ b/src/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 *add_task(Window win) 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; @@ -465,6 +467,14 @@ void task_dump_geometry(void *obj, int indent) 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) { Task *task = (Task *)obj; diff --git a/src/taskbar/taskbarname.c b/src/taskbar/taskbarname.c index d05e42b..b7eebf4 100644 --- a/src/taskbar/taskbarname.c +++ b/src/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 @@ void init_taskbarname_panel(void *p) 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,11 @@ void cleanup_taskbarname() } } -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; - - schedule_redraw(&taskbar_name->area); get_text_size2(panel_config.taskbarname_font_desc, &name_height_ink, &name_height, @@ -151,14 +150,41 @@ gboolean resize_taskbarname(void *obj) FALSE); if (panel_horizontal) { - int new_size = name_width + 2 * taskbar_name->area.paddingxlr + left_right_border_width(&taskbar_name->area); + 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, + &name_width, + panel->area.height, + panel->area.width, + taskbar_name->name, + strlen(taskbar_name->name), + PANGO_WRAP_WORD_CHAR, + PANGO_ELLIPSIZE_NONE, + FALSE); + + gboolean result = FALSE; + int new_size = taskbarname_compute_desired_size(obj); + if (panel_horizontal) { 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; diff --git a/src/tint.c b/src/tint.c index c4ab05e..8df142e 100644 --- a/src/tint.c +++ b/src/tint.c @@ -1568,6 +1568,7 @@ start: 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 @@ start: 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 @@ start: 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; @@ -1645,6 +1651,11 @@ start: 0); } } + if (first_render) { + first_render = FALSE; + if (panel_shrink) + panel_refresh = TRUE; + } if (debug_fps) ts_render_finished = get_time(); XFlush(server.display); diff --git a/src/tint2conf/properties.c b/src/tint2conf/properties.c index 5864bd5..83ca9cf 100644 --- a/src/tint2conf/properties.c +++ b/src/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; @@ -1385,6 +1385,19 @@ void create_panel(GtkWidget *parent) 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; label = gtk_label_new(_("Size")); diff --git a/src/tint2conf/properties.h b/src/tint2conf/properties.h index 3e85b28..4636c03 100644 --- a/src/tint2conf/properties.h +++ b/src/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, diff --git a/src/tint2conf/properties_rw.c b/src/tint2conf/properties_rw.c index ae16cec..8f1719c 100644 --- a/src/tint2conf/properties_rw.c +++ b/src/tint2conf/properties_rw.c @@ -274,6 +274,10 @@ void config_write_panel(FILE *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 @@ void add_entry(char *key, char *value) 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 */ diff --git a/src/util/area.c b/src/util/area.c index 2b00f49..9e42339 100644 --- a/src/util/area.c +++ b/src/util/area.c @@ -216,38 +216,34 @@ void relayout_dynamic(Area *a, int level) } } +int compute_desired_size(Area *a) +{ + if (!a->on_screen) + 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 (children_count > 0) + result += (children_count - 1) * a->paddingx; + return result; +} + void relayout(Area *a) { relayout_fixed(a); relayout_dynamic(a, 1); } -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); -} - int relayout_with_constraint(Area *a, int maximum_size) { int fixed_children_count = 0; @@ -359,6 +355,32 @@ void schedule_redraw(Area *a) 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) { Area *parent = (Area *)a->parent; @@ -818,13 +840,14 @@ void area_dump_geometry(Area *area, int 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, diff --git a/src/util/area.h b/src/util/area.h index 6dfea3b..ca40bf0 100644 --- a/src/util/area.h +++ b/src/util/area.h @@ -221,6 +221,10 @@ typedef struct 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); @@ -255,6 +259,8 @@ void relayout(Area *a); // 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); int left_right_border_width(Area *a);