From 5c9291ff0b0036b05b7e339af7fb2501e72903de Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 7 Jan 2008 18:12:38 +0100 Subject: [PATCH] use a cache system for status bar --- awesome.c | 8 +++++--- client.c | 9 ++++++--- config.h | 6 ++++++ event.c | 11 ++++++----- ewmh.c | 4 ++-- layout.c | 7 +++---- mouse.c | 2 -- screen.c | 5 ----- statusbar.c | 43 ++++++++++++++++++++++++++++++------------- statusbar.h | 3 ++- uicb.c | 2 +- widget.c | 16 +++++++++++++++- widget.h | 6 ++++++ widgets/focustitle.c | 3 +++ widgets/layoutinfo.c | 4 ++++ widgets/netwmicon.c | 3 +++ widgets/taglist.c | 4 ++++ widgets/tasklist.c | 3 +++ 18 files changed, 99 insertions(+), 40 deletions(-) diff --git a/awesome.c b/awesome.c index b23261f67..4f8529522 100644 --- a/awesome.c +++ b/awesome.c @@ -341,13 +341,13 @@ main(int argc, char *argv[]) if(csfd >= 0 && FD_ISSET(csfd, &rd)) switch (r = recv(csfd, buf, sizeof(buf)-1, MSG_TRUNC)) { - case -1: + case -1: perror("awesome: error reading UNIX domain socket"); csfd = -1; break; - case 0: + case 0: break; - default: + default: if(r >= ssizeof(buf)) break; buf[r] = '\0'; @@ -360,6 +360,8 @@ main(int argc, char *argv[]) if(handler[ev.type]) handler[ev.type](&ev); /* call handler */ } + + statusbar_refresh(); } if(csfd > 0 && close(csfd)) diff --git a/client.c b/client.c index a663b1399..b5c52d4b0 100644 --- a/client.c +++ b/client.c @@ -29,11 +29,11 @@ #include "rules.h" #include "util.h" #include "xutil.h" -#include "statusbar.h" #include "window.h" #include "focus.h" #include "ewmh.h" #include "screen.h" +#include "widget.h" #include "layouts/floating.h" @@ -244,6 +244,7 @@ focus(Client *c, Bool selscreen, int screen) /* unfocus current selected client */ if(globalconf.focus->client) { + widget_invalidate_cache(globalconf.focus->client->screen, WIDGET_CACHE_CLIENTS); window_grabbuttons(get_phys_screen(globalconf.focus->client->screen), globalconf.focus->client->win, False, True); XSetWindowBorder(globalconf.display, globalconf.focus->client->win, @@ -274,7 +275,7 @@ focus(Client *c, Bool selscreen, int screen) /* save sel in focus history */ focus_add_client(c); - statusbar_draw_all(screen); + widget_invalidate_cache(screen, WIDGET_CACHE_CLIENTS); if(globalconf.focus->client) { @@ -889,19 +890,21 @@ client_maximize(Client *c, Area geometry) * coords */ c->isfloating = True; restack(c->screen); + widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); } else if(c->wasfloating) { c->isfloating = True; client_resize(c, c->m_geometry, False); restack(c->screen); + widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); } else { c->isfloating = False; arrange(c->screen); + widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); } - statusbar_draw_all(c->screen); } /** Toggle maximize for client diff --git a/config.h b/config.h index 2b065c540..c5db1ae97 100644 --- a/config.h +++ b/config.h @@ -114,6 +114,12 @@ struct Widget Button *buttons; /** Font */ XftFont *font; + /** Cache */ + struct + { + Bool needs_update; + int flags; + } cache; /** Next widget */ Widget *next; }; diff --git a/event.c b/event.c index 0057d01c8..7ad67c75a 100644 --- a/event.c +++ b/event.c @@ -34,6 +34,7 @@ #include "mouse.h" #include "ewmh.h" #include "client.h" +#include "widget.h" #include "layouts/tile.h" #include "layouts/floating.h" @@ -166,10 +167,10 @@ handle_event_configurerequest(XEvent * e) if(old_screen != c->screen) { - statusbar_draw_all(old_screen); + widget_invalidate_cache(old_screen, WIDGET_CACHE_CLIENTS); arrange(old_screen); } - statusbar_draw_all(c->screen); + widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); arrange(c->screen); } else @@ -213,7 +214,7 @@ handle_event_configurenotify(XEvent * e) globalconf.screens[screen].statusbar->width, globalconf.screens[screen].statusbar->height); - statusbar_draw_all(screen); + widget_invalidate_cache(screen, WIDGET_CACHE_ALL); arrange(screen); } } @@ -375,14 +376,14 @@ handle_event_propertynotify(XEvent * e) break; case XA_WM_HINTS: client_updatewmhints(c); - statusbar_draw_all(c->screen); + widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); break; } if(ev->atom == XA_WM_NAME || ev->atom == XInternAtom(globalconf.display, "_NET_WM_NAME", False)) { client_updatetitle(c); if(c == globalconf.focus->client) - statusbar_draw_all(c->screen); + widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); } } } diff --git a/ewmh.c b/ewmh.c index 6e86cf06a..532f6e6ff 100644 --- a/ewmh.c +++ b/ewmh.c @@ -28,7 +28,7 @@ #include "focus.h" #include "screen.h" #include "client.h" -#include "statusbar.h" +#include "widget.h" extern AwesomeConf globalconf; @@ -265,7 +265,7 @@ ewmh_process_state_atom(Client *c, Atom state, int set) c->ismax = True; c->isfloating = True; } - statusbar_draw_all(c->screen); + widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); client_resize(c, geometry, False); XRaiseWindow(globalconf.display, c->win); arrange(c->screen); diff --git a/layout.c b/layout.c index abab034b2..d441d4634 100644 --- a/layout.c +++ b/layout.c @@ -26,7 +26,7 @@ #include "util.h" #include "xutil.h" #include "focus.h" -#include "statusbar.h" +#include "widget.h" #include "ewmh.h" #include "client.h" #include "screen.h" @@ -163,8 +163,6 @@ restack(int screen) XWindowChanges wc; Tag **curtags; - statusbar_draw_all(screen); - if(!sel) return; @@ -253,7 +251,7 @@ uicb_tag_setlayout(int screen, char *arg) if(globalconf.focus->client) arrange(screen); else - statusbar_draw_all(screen); + widget_invalidate_cache(screen, WIDGET_CACHE_LAYOUTS); saveawesomeprops(screen); } @@ -279,6 +277,7 @@ uicb_client_togglefloating(int screen, char *arg) else if(sel->ismax) client_resize(sel, sel->m_geometry, False); + widget_invalidate_cache(sel->screen, WIDGET_CACHE_CLIENTS); client_saveprops(sel); arrange(screen); } diff --git a/mouse.c b/mouse.c index b1d624768..83eac08cd 100644 --- a/mouse.c +++ b/mouse.c @@ -28,7 +28,6 @@ #include "util.h" #include "event.h" #include "window.h" -#include "statusbar.h" #include "client.h" #include "layouts/floating.h" #include "layouts/tile.h" @@ -78,7 +77,6 @@ uicb_client_movemouse(int screen, char *arg __attribute__ ((unused))) RootWindow(globalconf.display, phys_screen), &dummy, &dummy, &x1, &y, &di, &di, &dui); c->ismax = False; - statusbar_draw_all(c->screen); for(;;) { XMaskEvent(globalconf.display, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); diff --git a/screen.c b/screen.c index 1a9f2cab0..09cd9cff2 100644 --- a/screen.c +++ b/screen.c @@ -25,7 +25,6 @@ #include "screen.h" #include "tag.h" #include "focus.h" -#include "statusbar.h" #include "client.h" #include "layouts/floating.h" @@ -254,10 +253,6 @@ move_client_to_screen(Client *c, int new_screen, Bool doresize) } focus(c, True, c->screen); - - /* redraw statusbar on all screens */ - statusbar_draw_all(old_screen); - statusbar_draw_all(new_screen); } /** Move mouse pointer to x_org and y_xorg of specified screen diff --git a/statusbar.c b/statusbar.c index 2019fc38a..8460a228f 100644 --- a/statusbar.c +++ b/statusbar.c @@ -30,13 +30,13 @@ extern AwesomeConf globalconf; -static void +void statusbar_draw(Statusbar *statusbar) { int phys_screen = get_phys_screen(statusbar->screen); Widget *widget, *last_drawn = NULL; int left = 0, right = 0; - + /* don't waste our time */ if(statusbar->position == Off) return; @@ -52,12 +52,16 @@ statusbar_draw(Statusbar *statusbar) for(widget = statusbar->widgets; widget; widget = widget->next) if (widget->alignment == AlignLeft) + { + widget->cache.needs_update = False; left += widget->draw(widget, ctx, left, (left + right)); + } /* renders right widget from last to first */ for(widget = statusbar->widgets; widget; widget = widget->next) if (widget->alignment == AlignRight && last_drawn == widget->next) { + widget->cache.needs_update = False; right += widget->draw(widget, ctx, right, (left + right)); last_drawn = widget; widget = statusbar->widgets; @@ -65,7 +69,10 @@ statusbar_draw(Statusbar *statusbar) for(widget = statusbar->widgets; widget; widget = widget->next) if (widget->alignment == AlignFlex) + { + widget->cache.needs_update = False; left += widget->draw(widget, ctx, left, (left + right)); + } if(statusbar->position == Right || statusbar->position == Left) @@ -87,15 +94,6 @@ statusbar_draw(Statusbar *statusbar) statusbar_display(statusbar); } -void -statusbar_draw_all(int screen) -{ - Statusbar *statusbar; - - for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) - statusbar_draw(statusbar); -} - void statusbar_display(Statusbar *statusbar) { @@ -243,6 +241,26 @@ statusbar_update_position(Statusbar *statusbar) while(XCheckMaskEvent(globalconf.display, EnterWindowMask, &ev)); } + +void +statusbar_refresh() +{ + int screen; + Statusbar *statusbar; + Widget *widget; + + for(screen = 0; screen < get_screen_count(); screen++) + for(statusbar = globalconf.screens[screen].statusbar; + statusbar; + statusbar = statusbar->next) + for(widget = statusbar->widgets; widget; widget = widget->next) + if(widget->cache.needs_update) + { + statusbar_draw(statusbar); + break; + } +} + Position statusbar_get_position_from_str(const char *pos) { @@ -269,7 +287,6 @@ get_statusbar_byname(int screen, const char *name) return NULL; } - static void statusbar_toggle(Statusbar *statusbar) { @@ -283,7 +300,7 @@ statusbar_toggle(Statusbar *statusbar) /** Toggle statusbar * \param screen Screen ID - * \param arg Unused + * \param arg statusbar name * \ingroup ui_callback */ void diff --git a/statusbar.h b/statusbar.h index 3774e0a05..0bab9baba 100644 --- a/statusbar.h +++ b/statusbar.h @@ -24,7 +24,8 @@ #include "config.h" -void statusbar_draw_all(int); +void statusbar_refresh(void); +void statusbar_draw(Statusbar *); void statusbar_init(Statusbar *, int); void statusbar_display(Statusbar *); Position statusbar_get_position_from_str(const char *); diff --git a/uicb.c b/uicb.c index d67aac2c2..2f717e5ae 100644 --- a/uicb.c +++ b/uicb.c @@ -144,7 +144,7 @@ parse_control(char *cmd) if(!a_strlen(cmd)) return -1; - + while((p = strchr(curcmd, '\n'))) { *p = '\0'; diff --git a/widget.c b/widget.c index 9a54d68a1..7858eff5b 100644 --- a/widget.c +++ b/widget.c @@ -122,6 +122,19 @@ widget_common_new(Widget *widget, Statusbar *statusbar, cfg_t* config) widget->user_supplied_y = (widget->area.y != (int) 0xffffffff); } +void +widget_invalidate_cache(int screen, int flags) +{ + Statusbar *statusbar; + Widget *widget; + + for(statusbar = globalconf.screens[screen].statusbar; + statusbar; + statusbar = statusbar->next) + for(widget = statusbar->widgets; widget; widget = widget->next) + widget->cache.needs_update = (widget->cache.flags & flags); +} + /** Send command to widget * \param screen Screen ID * \param arg Widget command. Syntax depends on specific widget. @@ -166,7 +179,8 @@ uicb_widget_tell(int screen, char *arg) else widget->tell(widget, NULL); - statusbar_draw_all(screen); + widget->cache.needs_update = True; + return; } diff --git a/widget.h b/widget.h index 2e679a419..8ac1b834c 100644 --- a/widget.h +++ b/widget.h @@ -27,8 +27,14 @@ #include "config.h" +#define WIDGET_CACHE_CLIENTS 1<<0 +#define WIDGET_CACHE_LAYOUTS 1<<1 +#define WIDGET_CACHE_TAGS 1<<2 +#define WIDGET_CACHE_ALL (WIDGET_CACHE_CLIENTS | WIDGET_CACHE_LAYOUTS | WIDGET_CACHE_TAGS) + typedef Widget *(WidgetConstructor)(Statusbar *, cfg_t *); +void widget_invalidate_cache(int, int); int widget_calculate_offset(int, int, int, int); void widget_calculate_alignments(Widget *); void widget_common_new(Widget*, Statusbar *, cfg_t *); diff --git a/widgets/focustitle.c b/widgets/focustitle.c index 4f7bca3e1..f647da529 100644 --- a/widgets/focustitle.c +++ b/widgets/focustitle.c @@ -108,6 +108,9 @@ focustitle_new(Statusbar *statusbar, cfg_t *config) if(!w->font) w->font = globalconf.screens[statusbar->screen].font; + /* Set cache property */ + w->cache.flags = WIDGET_CACHE_CLIENTS | WIDGET_CACHE_TAGS; + return w; } diff --git a/widgets/layoutinfo.c b/widgets/layoutinfo.c index 3b3aaa383..9ed11e938 100644 --- a/widgets/layoutinfo.c +++ b/widgets/layoutinfo.c @@ -64,6 +64,10 @@ layoutinfo_new(Statusbar *statusbar, cfg_t* config) w = p_new(Widget, 1); widget_common_new(w, statusbar, config); w->draw = layoutinfo_draw; + + /* Set cache property */ + w->cache.flags = WIDGET_CACHE_LAYOUTS; + return w; } diff --git a/widgets/netwmicon.c b/widgets/netwmicon.c index 976897ba3..cbbe7b4e0 100644 --- a/widgets/netwmicon.c +++ b/widgets/netwmicon.c @@ -105,6 +105,9 @@ netwmicon_new(Statusbar *statusbar, cfg_t *config) widget_common_new(w, statusbar, config); w->draw = netwmicon_draw; + /* Set cache property */ + w->cache.flags = WIDGET_CACHE_CLIENTS; + return w; } // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/widgets/taglist.c b/widgets/taglist.c index f04a085b9..2cb42bac1 100644 --- a/widgets/taglist.c +++ b/widgets/taglist.c @@ -182,6 +182,10 @@ taglist_new(Statusbar *statusbar, cfg_t *config) widget_common_new(w, statusbar, config); w->draw = taglist_draw; w->button_press = taglist_button_press; + + /* Set cache property */ + w->cache.flags = WIDGET_CACHE_TAGS; + return w; } diff --git a/widgets/tasklist.c b/widgets/tasklist.c index f2e3280d2..7fe5b5a54 100644 --- a/widgets/tasklist.c +++ b/widgets/tasklist.c @@ -253,6 +253,9 @@ tasklist_new(Statusbar *statusbar, cfg_t *config) if(!w->font) w->font = globalconf.screens[statusbar->screen].font; + /* Set cache property */ + w->cache.flags = WIDGET_CACHE_CLIENTS; + return w; }