From 4723ab36275f342cdb78eef37b8548875a6c6a04 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 17 Dec 2007 20:57:17 +1100 Subject: [PATCH] This patch is a first draft of independently targetable textboxes, and a protocol to speak to them. Given a textbox widget definition like this: textbox mail { default = 0 } textbox time {} We can update the boxes individually by going: echo 0 tell_widget mail 10 echo 0 tell_widget time 12:01 Text boxes will dynamically resize to fit their contents. A textbox can be cleared by going: echo 0 tell_widget name A text-box containing no text will take up 0 space in the bar, i.e. it will not be visible at all Textboxes now supersede statusbar_set_text, so this call has been removed. --- config.c | 12 +++----- config.h | 4 +-- draw.c | 2 ++ statusbar.c | 11 -------- statusbar.h | 1 - uicb.c | 1 - widget.c | 45 +++++++++++++++++++++++++---- widget.h | 5 ++-- widgets/focustitle.c | 5 ++-- widgets/layoutinfo.c | 5 ++-- widgets/taglist.c | 5 ++-- widgets/textbox.c | 67 +++++++++++++++++++++++++++++++++----------- 12 files changed, 110 insertions(+), 53 deletions(-) diff --git a/config.c b/config.c index 53227a8e..89640c33 100644 --- a/config.c +++ b/config.c @@ -294,17 +294,16 @@ create_widgets(cfg_t* cfg_statusbar, Statusbar *statusbar) qsort(widgets, numwidgets, sizeof(cfg_t), cmp_widget_cfg); for (i = 0; i < numwidgets; i++){ - widget_new = name_func_lookup(cfg_name(widgets + i), WidgetList); + wptr = widgets + i; + widget_new = name_func_lookup(cfg_name(wptr), WidgetList); if (widget_new) if(!widget){ - widget = widget_new(statusbar, - cfg_title(widgets + i)); + widget = widget_new(statusbar, wptr); statusbar->widgets = widget; } else { - widget->next = widget_new(statusbar, - cfg_title(widgets + i)); + widget->next = widget_new(statusbar, wptr); widget = widget->next; } else @@ -509,9 +508,6 @@ config_parse(const char *confpatharg) for(screen = 0; screen < get_screen_count(globalconf.display); screen++) { virtscreen = &globalconf.screens[screen]; - a_strcpy(virtscreen->statustext, - sizeof(virtscreen->statustext), - "awesome-" VERSION " (" RELEASE ")"); snprintf(buf, sizeof(buf), "%d", screen); cfg_screen = cfg_gettsec(cfg, "screen", buf); if(!cfg_screen) diff --git a/config.h b/config.h index 83d5be11..a1628e7f 100644 --- a/config.h +++ b/config.h @@ -189,8 +189,6 @@ typedef struct typedef struct { - /** Text displayed in bar */ - char statustext[256]; /** Number of pixels to snap windows */ int snap; /** Border size */ @@ -225,8 +223,10 @@ struct Widget { char *name; int (*draw)(Widget *, DrawCtx *, int, int); + void (*tell)(Widget *, char *); Statusbar *statusbar; int alignment; + void *data; Widget *next; }; diff --git a/draw.c b/draw.c index 839c3dd5..73b71745 100644 --- a/draw.c +++ b/draw.c @@ -205,6 +205,8 @@ textwidth_primitive(Display *display, XftFont *font, char *text) unsigned short textwidth(DrawCtx *ctx, XftFont *font, char *text) { + if (!text) + return 0; return textwidth_primitive(ctx->display, font, text); } diff --git a/statusbar.c b/statusbar.c index fa9ffbf1..04c8c607 100644 --- a/statusbar.c +++ b/statusbar.c @@ -205,15 +205,4 @@ uicb_statusbar_set_position(int screen, char *arg) statusbar_update_position(globalconf.display, globalconf.screens[screen].statusbar, &globalconf.screens[screen].padding); } -void -uicb_statusbar_set_text(int screen, char *arg) -{ - if(!arg) - return; - a_strncpy(globalconf.screens[screen].statustext, - sizeof(globalconf.screens[screen].statustext), arg, a_strlen(arg)); - - statusbar_draw(screen); -} - // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 diff --git a/statusbar.h b/statusbar.h index d6cd8234..79eb92ab 100644 --- a/statusbar.h +++ b/statusbar.h @@ -31,7 +31,6 @@ void statusbar_update_position(Display *, Statusbar, Padding *); UICB_PROTO(uicb_statusbar_toggle); UICB_PROTO(uicb_statusbar_set_position); -UICB_PROTO(uicb_statusbar_set_text); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 diff --git a/uicb.c b/uicb.c index ced4c383..6a36d5b1 100644 --- a/uicb.c +++ b/uicb.c @@ -75,7 +75,6 @@ const NameFuncLink UicbList[] = /* statusbar.c */ {"statusbar_toggle", uicb_statusbar_toggle}, {"statusbar_set_position", uicb_statusbar_set_position}, - {"statusbar_set_text", uicb_statusbar_set_text}, /* mouse.c */ {"client_movemouse", uicb_client_movemouse}, {"client_resizemouse", uicb_client_resizemouse}, diff --git a/widget.c b/widget.c index 043cfbc2..25486ddf 100644 --- a/widget.c +++ b/widget.c @@ -1,5 +1,7 @@ +#include #include "util.h" #include "widget.h" +#include "statusbar.h" extern awesome_config globalconf; @@ -54,22 +56,43 @@ find_widget(char *name, int screen) return NULL; } -void -common_new(Widget *widget, Statusbar *statusbar, const char *name) + +static void +common_tell(Widget *widget, char *command __attribute__ ((unused))) { + warn("%s widget does not accept commands.\n", widget->name); +} + + +void +common_new(Widget *widget, Statusbar *statusbar, cfg_t* config) +{ + const char *name; widget->statusbar = statusbar; + + name = cfg_title(config); widget->name = p_new(char, strlen(name)+1); + widget->tell = common_tell; strncpy(widget->name, name, strlen(name)); } + void uicb_widget_tell(int screen, char *arg) { Widget *widget; - char *p; + char *p, *command; + int len; + + if (!arg){ + warn("Must specify a widget.\n"); + return; + } + + len = strlen(arg); p = strtok(arg, " "); if (!p){ - warn("Ignoring malformed widget command."); + warn("Ignoring malformed widget command.\n"); return; } widget = find_widget(p, screen); @@ -78,8 +101,18 @@ uicb_widget_tell(int screen, char *arg) return; } - /* To be continued... */ - + if (p+strlen(p) < arg+len) + { + p = p + strlen(p) + 1; + command = p_new(char, strlen(p)+1); + strncpy(command, p, strlen(p)); + widget->tell(widget, command); + p_delete(&command); + } + else + widget->tell(widget, NULL); + statusbar_draw(screen); + return; } // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 diff --git a/widget.h b/widget.h index 27519fb4..fb21bf69 100644 --- a/widget.h +++ b/widget.h @@ -1,17 +1,18 @@ #ifndef AWESOME_WIDGET_H #define AWESOME_WIDGET_H +#include #include "config.h" #include "draw.h" #include "common.h" enum { AlignLeft, AlignRight, AlignFlex }; -typedef Widget *(WidgetConstructor)(Statusbar*, const char*); +typedef Widget *(WidgetConstructor)(Statusbar*, cfg_t*); int calculate_offset(int, int, int, int); void calculate_alignments(Widget *widget); -void common_new(Widget *, Statusbar *, const char *); +void common_new(Widget*, Statusbar*, cfg_t*); WidgetConstructor layoutinfo_new; WidgetConstructor taglist_new; diff --git a/widgets/focustitle.c b/widgets/focustitle.c index 7e4774e8..7bed7497 100644 --- a/widgets/focustitle.c +++ b/widgets/focustitle.c @@ -1,4 +1,5 @@ #include +#include #include "util.h" #include "widget.h" #include "layout.h" @@ -36,13 +37,13 @@ focustitle_draw(Widget *widget, DrawCtx *ctx, int offset, int used) } Widget * -focustitle_new(Statusbar *statusbar, const char *name) +focustitle_new(Statusbar *statusbar, cfg_t *config) { Widget *w; w = p_new(Widget, 1); + common_new(w, statusbar, config); w->draw = focustitle_draw; w->alignment = AlignFlex; - common_new(w, statusbar, name); return w; } diff --git a/widgets/layoutinfo.c b/widgets/layoutinfo.c index c201f769..14db8475 100644 --- a/widgets/layoutinfo.c +++ b/widgets/layoutinfo.c @@ -1,3 +1,4 @@ +#include #include "widget.h" #include "util.h" #include "layout.h" @@ -30,12 +31,12 @@ layoutinfo_draw(Widget *widget, Widget * -layoutinfo_new(Statusbar *statusbar, const char* name) +layoutinfo_new(Statusbar *statusbar, cfg_t* config) { Widget *w; w = p_new(Widget, 1); + common_new(w, statusbar, config); w->draw = (void*) layoutinfo_draw; - common_new(w, statusbar, name); return w; } diff --git a/widgets/taglist.c b/widgets/taglist.c index 5a63603b..bea66f60 100644 --- a/widgets/taglist.c +++ b/widgets/taglist.c @@ -1,3 +1,4 @@ +#include #include "config.h" #include "util.h" #include "widget.h" @@ -68,12 +69,12 @@ taglist_draw(Widget *widget, } Widget * -taglist_new(Statusbar *statusbar, const char *name) +taglist_new(Statusbar *statusbar, cfg_t *config) { Widget *w; w = p_new(Widget, 1); + common_new(w, statusbar, config); w->draw = taglist_draw; - common_new(w, statusbar, name); return w; } diff --git a/widgets/textbox.c b/widgets/textbox.c index 9831002a..dac6f308 100644 --- a/widgets/textbox.c +++ b/widgets/textbox.c @@ -1,33 +1,68 @@ +#include #include "util.h" #include "widget.h" extern awesome_config globalconf; + +typedef struct Data Data; +struct Data +{ + char *text; +}; + + +static void +update(Widget *widget, char *text){ + Data *d; + d = (Data*) widget->data; + if (d->text) + p_delete(&d->text); + d->text = a_strdup(text); +} + + static int -textbox_draw(Widget *widget, - DrawCtx *ctx, - int offset, +textbox_draw(Widget *widget, DrawCtx *ctx, int offset, int used __attribute__ ((unused))) { VirtScreen vscreen = globalconf.screens[widget->statusbar->screen]; - int width = textwidth(ctx, vscreen.font, vscreen.statustext); - int location = calculate_offset(vscreen.statusbar.width, - width, - offset, - widget->alignment); + int width, location; + Data *d; + d = (Data*) widget->data; + width = textwidth(ctx, vscreen.font, d->text); + location = calculate_offset(vscreen.statusbar.width, + width, + offset, + widget->alignment); drawtext(ctx, location, 0, width, vscreen.statusbar.height, - vscreen.font, vscreen.statustext, vscreen.colors_normal); + vscreen.font, d->text, vscreen.colors_normal); return width; } -Widget * -textbox_new(Statusbar *statusbar, const char *name) + +static void +textbox_tell(Widget *widget, char *command) { - Widget *w; - w = p_new(Widget, 1); - w->draw = textbox_draw; - common_new(w, statusbar, name); - return w; + update(widget, command); } + +Widget * +textbox_new(Statusbar *statusbar, cfg_t *config) +{ + Widget *w; + Data *d; + + w = p_new(Widget, 1); + common_new(w, statusbar, config); + w->draw = textbox_draw; + w->tell = textbox_tell; + + d = p_new(Data, 1); + w->data = (void*) d; + + update(w, cfg_getstr(config, "default")); + return w; +} // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99