Add option to shrink panel (fixes issue #333)

This commit is contained in:
o9000 2016-10-08 14:45:00 +02:00
parent 8c7f4cc825
commit 61a80b996f
17 changed files with 636 additions and 267 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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"));

View file

@ -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,

View file

@ -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 */

View file

@ -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,

View file

@ -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);