From bbec33ce1a15b555a737f2fefe7bdfb6a8881705 Mon Sep 17 00:00:00 2001 From: Thierry Lorthiois Date: Tue, 21 Sep 2010 09:54:19 +0000 Subject: [PATCH] cleanup : Area posx/posy managed by layering engine (area.c) --- src/battery/battery.c | 8 +-- src/clock/clock.c | 99 +++++++++++--------------------- src/launcher/launcher.c | 11 +--- src/panel.c | 2 +- src/systray/systraybar.c | 19 ++----- src/util/area.c | 119 ++++++++++++++++++++++++++++++++++++++- src/util/area.h | 7 ++- src/util/window.c | 26 +++++++++ src/util/window.h | 1 + 9 files changed, 192 insertions(+), 100 deletions(-) diff --git a/src/battery/battery.c b/src/battery/battery.c index 086b6d0..0514a51 100644 --- a/src/battery/battery.c +++ b/src/battery/battery.c @@ -80,7 +80,6 @@ void update_batterys(void* arg) else { if (panel1[i].battery.area.on_screen == 0) { panel1[i].battery.area.on_screen = 1; - panel1[i].area.resize = 1; } } if (panel1[i].battery.area.on_screen == 1) { @@ -238,15 +237,14 @@ void init_battery_panel(void *p) get_text_size(bat1_font_desc, &bat_percentage_height_ink, &bat_percentage_height, panel->area.height, buf_bat_percentage, strlen(buf_bat_percentage)); get_text_size(bat2_font_desc, &bat_time_height_ink, &bat_time_height, panel->area.height, buf_bat_time, strlen(buf_bat_time)); + if (panel_horizontal) { - // panel horizonal => fixed height and posy - battery->area.posy = panel->area.bg->border.width + panel->area.paddingy; + // panel horizonal => fixed height battery->area.height = panel->area.height - (2 * battery->area.posy); } else { - // panel vertical => fixed width, height, posy and posx - battery->area.posx = panel->area.bg->border.width + panel->area.paddingy; + // panel vertical => fixed width, height battery->area.width = panel->area.width - (2 * panel->area.bg->border.width) - (2 * panel->area.paddingy); } diff --git a/src/clock/clock.c b/src/clock/clock.c index cfd9aed..55e5e45 100644 --- a/src/clock/clock.c +++ b/src/clock/clock.c @@ -142,7 +142,6 @@ void init_clock_panel(void *p) { Panel *panel =(Panel*)p; Clock *clock = &panel->clock; - int time_height, time_height_ink, date_height, date_height_ink; clock->area.parent = p; clock->area.panel = p; @@ -156,33 +155,6 @@ void init_clock_panel(void *p) return; clock->area.on_screen = 1; - strftime(buf_time, sizeof(buf_time), time1_format, clock_gettime_for_tz(time1_timezone)); - get_text_size(time1_font_desc, &time_height_ink, &time_height, panel->area.height, buf_time, strlen(buf_time)); - if (time2_format) { - strftime(buf_date, sizeof(buf_date), time2_format, clock_gettime_for_tz(time2_timezone)); - get_text_size(time2_font_desc, &date_height_ink, &date_height, panel->area.height, buf_date, strlen(buf_date)); - } - - if (panel_horizontal) { - // panel horizonal => fixed height and posy - clock->area.posy = panel->area.bg->border.width + panel->area.paddingy; - clock->area.height = panel->area.height - (2 * clock->area.posy); - } - else { - // panel vertical => fixed width, posx, height - clock->area.posx = panel->area.bg->border.width + panel->area.paddingy; - clock->area.width = panel->area.width - (2 * panel->area.bg->border.width) - (2 * panel->area.paddingy); - clock->area.height = time_height + date_height + (2 * clock->area.paddingxlr) + (2*clock->area.bg->border.width); - } - - clock->time1_posy = (clock->area.height - time_height) / 2; - if (time2_format) { - strftime(buf_date, sizeof(buf_date), time2_format, clock_gettime_for_tz(time2_timezone)); - get_text_size(time2_font_desc, &date_height_ink, &date_height, panel->area.height, buf_date, strlen(buf_date)); - - clock->time1_posy -= ((date_height_ink + 2) / 2); - clock->time2_posy = clock->time1_posy + time_height + 2 - (time_height - time_height_ink)/2 - (date_height - date_height_ink)/2; - } if (time_tooltip_format) { clock->area._get_tooltip_text = clock_get_tooltip; @@ -228,53 +200,46 @@ void draw_clock (void *obj, cairo_t *c) int resize_clock (void *obj) { Clock *clock = obj; - PangoLayout *layout; - int time_width, date_width, ret = 0; + Panel *panel = clock->area.panel; + int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width, ret = 0; clock->area.redraw = 1; - time_width = date_width = 0; + strftime(buf_time, sizeof(buf_time), time1_format, clock_gettime_for_tz(time1_timezone)); - if (time2_format) + get_text_size2(time1_font_desc, &time_height_ink, &time_height, &time_width, panel->area.height, panel->area.width, buf_time, strlen(buf_time)); + if (time2_format) { strftime(buf_date, sizeof(buf_date), time2_format, clock_gettime_for_tz(time2_timezone)); - - // vertical panel doen't adjust width - if (!panel_horizontal) return ret; + get_text_size2(time2_font_desc, &date_height_ink, &date_height, &date_width, panel->area.height, panel->area.width, buf_date, strlen(buf_date)); + } - //printf(" resize_clock\n"); - cairo_surface_t *cs; - cairo_t *c; - Pixmap pmap; - pmap = XCreatePixmap (server.dsp, server.root_win, clock->area.width, clock->area.height, server.depth); - - cs = cairo_xlib_surface_create (server.dsp, pmap, server.visual, clock->area.width, clock->area.height); - c = cairo_create (cs); - layout = pango_cairo_create_layout (c); - - // check width/height - pango_layout_set_font_description (layout, time1_font_desc); - pango_layout_set_indent(layout, 0); - pango_layout_set_text (layout, buf_time, strlen(buf_time)); - pango_layout_get_pixel_size (layout, &time_width, NULL); - if (time2_format) { - pango_layout_set_font_description (layout, time2_font_desc); - pango_layout_set_indent(layout, 0); - pango_layout_set_text (layout, buf_date, strlen(buf_date)); - pango_layout_get_pixel_size (layout, &date_width, NULL); + if (panel_horizontal) { + int new_size = (time_width > date_width) ? time_width : date_width; + new_size += (2*clock->area.paddingxlr) + (2*clock->area.bg->border.width); + if (new_size > clock->area.width || new_size < (clock->area.width-6)) { + // we try to limit the number of resize + clock->area.width = new_size + 1; + clock->time1_posy = (clock->area.height - time_height) / 2; + if (time2_format) { + clock->time1_posy -= ((date_height_ink + 2) / 2); + clock->time2_posy = clock->time1_posy + time_height + 2 - (time_height - time_height_ink)/2 - (date_height - date_height_ink)/2; + } + ret = 1; + } } - - int new_width = (time_width > date_width) ? time_width : date_width; - new_width += (2*clock->area.paddingxlr) + (2*clock->area.bg->border.width); - if (new_width > clock->area.width || new_width < (clock->area.width-6)) { - // we try to limit the number of resize - clock->area.width = new_width + 1; - ret = 1; - panel_refresh = 1; + else { + int new_size = time_height + date_height + (2 * (clock->area.paddingxlr + clock->area.bg->border.width)); + if (new_size != clock->area.height) { + // we try to limit the number of resize + clock->area.height = new_size; + clock->time1_posy = (clock->area.height - time_height) / 2; + if (time2_format) { + clock->time1_posy -= ((date_height_ink + 2) / 2); + clock->time2_posy = clock->time1_posy + time_height + 2 - (time_height - time_height_ink)/2 - (date_height - date_height_ink)/2; + } + ret = 1; + } } - g_object_unref (layout); - cairo_destroy (c); - cairo_surface_destroy (cs); - XFreePixmap (server.dsp, pmap); return ret; } diff --git a/src/launcher/launcher.c b/src/launcher/launcher.c index ea45654..630a74e 100644 --- a/src/launcher/launcher.c +++ b/src/launcher/launcher.c @@ -76,16 +76,7 @@ void init_launcher_panel(void *p) return; launcher->area.on_screen = 1; - if (panel_horizontal) { - // panel horizonal => fixed height and posy - launcher->area.posy = panel->area.bg->border.width + panel->area.paddingy; - launcher->area.height = panel->area.height - (2 * launcher->area.posy); - } - else { - // panel vertical => fixed width, height, posy and posx - launcher->area.posx = panel->area.bg->border.width + panel->area.paddingxlr; - launcher->area.width = panel->area.width - (2 * panel->area.bg->border.width) - (2 * panel->area.paddingy); - } + panel_refresh = 1; fprintf(stderr, "Loading themes...\n"); launcher_load_themes(launcher); diff --git a/src/panel.c b/src/panel.c index 2d34c57..b618bf1 100644 --- a/src/panel.c +++ b/src/panel.c @@ -221,7 +221,6 @@ void init_panel() add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p); } - panel_refresh = 1; visible_object(); task_refresh_tasklist(); active_task(); @@ -497,6 +496,7 @@ void set_panel_items_order(Panel *p) if (panel_items_order[k] == 'C') p->area.list = g_slist_append(p->area.list, &p->clock); } + init_rendering(&p->area, 0); } diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c index 0b92bb0..2d13af4 100644 --- a/src/systray/systraybar.c +++ b/src/systray/systraybar.c @@ -97,14 +97,6 @@ void init_systray_panel(void *p) { Panel *panel =(Panel*)p; - if (panel_horizontal) { - systray.area.posy = panel->area.bg->border.width + panel->area.paddingy; - systray.area.height = panel->area.height - (2 * systray.area.posy); - } - else { - systray.area.posx = panel->area.bg->border.width + panel->area.paddingy; - systray.area.width = panel->area.width - (2 * panel->area.bg->border.width) - (2 * panel->area.paddingy); - } systray.area.parent = p; systray.area.panel = p; @@ -442,7 +434,6 @@ gboolean add_icon(Window id) systray.list_icons = g_slist_append(systray.list_icons, traywin); else systray.list_icons = g_slist_insert_sorted(systray.list_icons, traywin, compare_traywindows); - systray.area.resize = 1; //printf("add_icon id %lx, %d\n", id, g_slist_length(systray.list_icons)); // watch for the icon trying to resize itself! @@ -458,8 +449,8 @@ gboolean add_icon(Window id) if (!traywin->hide && !panel->is_hidden) XMapRaised(server.dsp, traywin->id); - // changed in systray force resize on panel - panel->area.resize = 1; + // changed in systray + systray.area.resize = 1; panel_refresh = 1; return TRUE; } @@ -471,7 +462,6 @@ void remove_icon(TrayWindow *traywin) // remove from our list systray.list_icons = g_slist_remove(systray.list_icons, traywin); - systray.area.resize = 1; //printf("remove_icon id %lx, %d\n", traywin->id); XSelectInput(server.dsp, traywin->tray_id, NoEventMask); @@ -502,9 +492,8 @@ void remove_icon(TrayWindow *traywin) systray.area.on_screen = 0; systray.area.width = 0; } - // changed in systray force resize on panel - Panel *panel = systray.area.panel; - panel->area.resize = 1; + // changed in systray + systray.area.resize = 1; panel_refresh = 1; } diff --git a/src/util/area.c b/src/util/area.c index 62417fe..0320bbb 100644 --- a/src/util/area.c +++ b/src/util/area.c @@ -51,7 +51,9 @@ * DRAWING AND LAYERING ENGINE : * Redrawing an object (like the clock) could come from an 'external event' (date change) * or from a 'layering event' (position change). - * The following 'drawing engine' take care of all 'layering event'. + * The following 'drawing engine' take care of : + * - posx/posy of all Area + * - 'layering event' propagation between object * 1) browse tree SIZE_BY_CONTENT * - resize SIZE_BY_CONTENT node : children are resized before parent * - if 'size' changed then 'resize = 1' on the parent @@ -70,6 +72,28 @@ * ************************************************************/ +void init_rendering(void *obj, int pos) +{ + Area *a = (Area*)obj; + + // initialize fixed position/size + GSList *l; + for (l = a->list; l ; l = l->next) { + Area *child = ((Area*)l->data); + if (panel_horizontal) { + child->posy = pos + a->bg->border.width + a->paddingy; + child->height = a->height - (2 * (a->bg->border.width + a->paddingy)); + init_rendering(child, child->posy); + } + else { + child->posx = pos + a->bg->border.width + a->paddingy; + child->width = a->width - (2 * (a->bg->border.width + a->paddingy)); + init_rendering(child, child->posx); + } + } +} + + void rendering(void *obj) { Panel *panel = (Panel*)obj; @@ -191,6 +215,99 @@ void refresh (Area *a) } +int resize_by_layout(void *obj) +{ + Taskbar *taskbar = (Taskbar*)obj; + Panel *panel = (Panel*)taskbar->area.panel; + Task *tsk; + GSList *l; + int task_count, border_width; + + //printf("resize_taskbar : posx et width des taches\n"); + taskbar->area.redraw = 1; + + border_width = taskbar->area.bg->border.width; + + if (panel_horizontal) { + int pixel_width, modulo_width=0; + int taskbar_width; + + // new task width for 'desktop' + task_count = g_slist_length(taskbar->area.list); + if (!task_count) pixel_width = panel->g_task.maximum_width; + else { + taskbar_width = taskbar->area.width - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr); + if (task_count>1) taskbar_width -= ((task_count-1) * panel->g_taskbar.area.paddingx); + + pixel_width = taskbar_width / task_count; + if (pixel_width > panel->g_task.maximum_width) + pixel_width = panel->g_task.maximum_width; + else + modulo_width = taskbar_width % task_count; + } + + taskbar->task_width = pixel_width; + taskbar->task_modulo = modulo_width; + taskbar->text_width = pixel_width - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx; + + // change pos_x and width for all tasks + for (l = taskbar->area.list; l ; l = l->next) { + tsk = l->data; + if (!tsk->area.on_screen) continue; + set_task_redraw(tsk); // always redraw task, because the background could have changed (taskbar_active_id) + tsk->area.width = pixel_width; +// TODO : move later (when posx is known) +// long value[] = { panel->posx+x, panel->posy, pixel_width, panel->area.height }; +// XChangeProperty (server.dsp, tsk->win, server.atom._NET_WM_ICON_GEOMETRY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)value, 4); + + if (modulo_width) { + tsk->area.width++; + modulo_width--; + } + } + } + else { + int pixel_height, modulo_height=0; + int taskbar_height; + + // new task width for 'desktop' + task_count = g_slist_length(taskbar->area.list); + if (!task_count) pixel_height = panel->g_task.maximum_height; + else { + taskbar_height = taskbar->area.height - (2 * border_width) - (2 * panel->g_taskbar.area.paddingxlr); + if (task_count>1) taskbar_height -= ((task_count-1) * panel->g_taskbar.area.paddingx); + + pixel_height = taskbar_height / task_count; + if (pixel_height > panel->g_task.maximum_height) + pixel_height = panel->g_task.maximum_height; + else + modulo_height = taskbar_height % task_count; + } + + taskbar->task_width = pixel_height; + taskbar->task_modulo = modulo_height; + taskbar->text_width = taskbar->area.width - (2 * panel->g_taskbar.area.paddingy) - panel->g_task.text_posx - panel->g_task.area.bg->border.width - panel->g_task.area.paddingx; + + // change pos_y and height for all tasks + for (l = taskbar->area.list; l ; l = l->next) { + tsk = l->data; + if (!tsk->area.on_screen) continue; + set_task_redraw(tsk); // always redraw task, because the background could have changed (taskbar_active_id) + tsk->area.height = pixel_height; +// TODO : move later (when posy is known) +// long value[] = { panel->posx, panel->posy+y, panel->area.width, pixel_height }; +// XChangeProperty (server.dsp, tsk->win, server.atom._NET_WM_ICON_GEOMETRY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)value, 4); + + if (modulo_height) { + tsk->area.height++; + modulo_height--; + } + } + } + return 0; +} + + void set_redraw (Area *a) { a->redraw = 1; diff --git a/src/util/area.h b/src/util/area.h index 16465b2..a5d1434 100644 --- a/src/util/area.h +++ b/src/util/area.h @@ -89,13 +89,18 @@ typedef struct { const char* (*_get_tooltip_text)(void *obj); } Area; +// on startup, initialize fixed pos/size +void init_rendering(void *obj, int pos); -void rendering(void *panel); +void rendering(void *obj); void size_by_content (Area *a); void size_by_layout (Area *a, int pos, int level); // draw background and foreground void refresh (Area *a); +// generic resize for SIZE_BY_LAYOUT objects +int resize_by_layout(void *obj); + // set 'redraw' on an area and childs void set_redraw (Area *a); diff --git a/src/util/window.c b/src/util/window.c index 98e3075..0466236 100644 --- a/src/util/window.c +++ b/src/util/window.c @@ -310,3 +310,29 @@ void get_text_size(PangoFontDescription *font, int *height_ink, int *height, int } +void get_text_size2(PangoFontDescription *font, int *height_ink, int *height, int *width, int panel_height, int panel_with, char *text, int len) +{ + PangoRectangle rect_ink, rect; + + Pixmap pmap = XCreatePixmap (server.dsp, server.root_win, panel_height, panel_height, server.depth); + + cairo_surface_t *cs = cairo_xlib_surface_create (server.dsp, pmap, server.visual, panel_height, panel_with); + cairo_t *c = cairo_create (cs); + + PangoLayout *layout = pango_cairo_create_layout (c); + pango_layout_set_font_description (layout, font); + pango_layout_set_text (layout, text, len); + + pango_layout_get_pixel_extents(layout, &rect_ink, &rect); + *height_ink = rect_ink.height; + *height = rect.height; + *width = rect.width; + //printf("dimension : %d - %d\n", rect_ink.height, rect.height); + + g_object_unref (layout); + cairo_destroy (c); + cairo_surface_destroy (cs); + XFreePixmap (server.dsp, pmap); +} + + diff --git a/src/util/window.h b/src/util/window.h index 074079e..db6d3a9 100644 --- a/src/util/window.h +++ b/src/util/window.h @@ -32,6 +32,7 @@ int window_get_monitor (Window win); Window window_get_active (); void get_text_size(PangoFontDescription *font, int *height_ink, int *height, int panel_height, char *text, int len); +void get_text_size2(PangoFontDescription *font, int *height_ink, int *height, int *width, int panel_height, int panel_with, char *text, int len); #endif -- 2.43.0