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.
This commit is contained in:
Aldo Cortesi 2007-12-17 20:57:17 +11:00 committed by Julien Danjou
parent ff84907b38
commit 4723ab3627
12 changed files with 110 additions and 53 deletions

View File

@ -294,17 +294,16 @@ create_widgets(cfg_t* cfg_statusbar, Statusbar *statusbar)
qsort(widgets, numwidgets, sizeof(cfg_t), cmp_widget_cfg); qsort(widgets, numwidgets, sizeof(cfg_t), cmp_widget_cfg);
for (i = 0; i < numwidgets; i++){ 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_new)
if(!widget){ if(!widget){
widget = widget_new(statusbar, widget = widget_new(statusbar, wptr);
cfg_title(widgets + i));
statusbar->widgets = widget; statusbar->widgets = widget;
} }
else else
{ {
widget->next = widget_new(statusbar, widget->next = widget_new(statusbar, wptr);
cfg_title(widgets + i));
widget = widget->next; widget = widget->next;
} }
else else
@ -509,9 +508,6 @@ config_parse(const char *confpatharg)
for(screen = 0; screen < get_screen_count(globalconf.display); screen++) for(screen = 0; screen < get_screen_count(globalconf.display); screen++)
{ {
virtscreen = &globalconf.screens[screen]; virtscreen = &globalconf.screens[screen];
a_strcpy(virtscreen->statustext,
sizeof(virtscreen->statustext),
"awesome-" VERSION " (" RELEASE ")");
snprintf(buf, sizeof(buf), "%d", screen); snprintf(buf, sizeof(buf), "%d", screen);
cfg_screen = cfg_gettsec(cfg, "screen", buf); cfg_screen = cfg_gettsec(cfg, "screen", buf);
if(!cfg_screen) if(!cfg_screen)

View File

@ -189,8 +189,6 @@ typedef struct
typedef struct typedef struct
{ {
/** Text displayed in bar */
char statustext[256];
/** Number of pixels to snap windows */ /** Number of pixels to snap windows */
int snap; int snap;
/** Border size */ /** Border size */
@ -225,8 +223,10 @@ struct Widget
{ {
char *name; char *name;
int (*draw)(Widget *, DrawCtx *, int, int); int (*draw)(Widget *, DrawCtx *, int, int);
void (*tell)(Widget *, char *);
Statusbar *statusbar; Statusbar *statusbar;
int alignment; int alignment;
void *data;
Widget *next; Widget *next;
}; };

2
draw.c
View File

@ -205,6 +205,8 @@ textwidth_primitive(Display *display, XftFont *font, char *text)
unsigned short unsigned short
textwidth(DrawCtx *ctx, XftFont *font, char *text) textwidth(DrawCtx *ctx, XftFont *font, char *text)
{ {
if (!text)
return 0;
return textwidth_primitive(ctx->display, font, text); return textwidth_primitive(ctx->display, font, text);
} }

View File

@ -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); 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 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99

View File

@ -31,7 +31,6 @@ void statusbar_update_position(Display *, Statusbar, Padding *);
UICB_PROTO(uicb_statusbar_toggle); UICB_PROTO(uicb_statusbar_toggle);
UICB_PROTO(uicb_statusbar_set_position); UICB_PROTO(uicb_statusbar_set_position);
UICB_PROTO(uicb_statusbar_set_text);
#endif #endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99

1
uicb.c
View File

@ -75,7 +75,6 @@ const NameFuncLink UicbList[] =
/* statusbar.c */ /* statusbar.c */
{"statusbar_toggle", uicb_statusbar_toggle}, {"statusbar_toggle", uicb_statusbar_toggle},
{"statusbar_set_position", uicb_statusbar_set_position}, {"statusbar_set_position", uicb_statusbar_set_position},
{"statusbar_set_text", uicb_statusbar_set_text},
/* mouse.c */ /* mouse.c */
{"client_movemouse", uicb_client_movemouse}, {"client_movemouse", uicb_client_movemouse},
{"client_resizemouse", uicb_client_resizemouse}, {"client_resizemouse", uicb_client_resizemouse},

View File

@ -1,5 +1,7 @@
#include <confuse.h>
#include "util.h" #include "util.h"
#include "widget.h" #include "widget.h"
#include "statusbar.h"
extern awesome_config globalconf; extern awesome_config globalconf;
@ -54,22 +56,43 @@ find_widget(char *name, int screen)
return NULL; 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; widget->statusbar = statusbar;
name = cfg_title(config);
widget->name = p_new(char, strlen(name)+1); widget->name = p_new(char, strlen(name)+1);
widget->tell = common_tell;
strncpy(widget->name, name, strlen(name)); strncpy(widget->name, name, strlen(name));
} }
void void
uicb_widget_tell(int screen, char *arg) uicb_widget_tell(int screen, char *arg)
{ {
Widget *widget; Widget *widget;
char *p; char *p, *command;
int len;
if (!arg){
warn("Must specify a widget.\n");
return;
}
len = strlen(arg);
p = strtok(arg, " "); p = strtok(arg, " ");
if (!p){ if (!p){
warn("Ignoring malformed widget command."); warn("Ignoring malformed widget command.\n");
return; return;
} }
widget = find_widget(p, screen); widget = find_widget(p, screen);
@ -78,8 +101,18 @@ uicb_widget_tell(int screen, char *arg)
return; 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 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99

View File

@ -1,17 +1,18 @@
#ifndef AWESOME_WIDGET_H #ifndef AWESOME_WIDGET_H
#define AWESOME_WIDGET_H #define AWESOME_WIDGET_H
#include <confuse.h>
#include "config.h" #include "config.h"
#include "draw.h" #include "draw.h"
#include "common.h" #include "common.h"
enum { AlignLeft, AlignRight, AlignFlex }; enum { AlignLeft, AlignRight, AlignFlex };
typedef Widget *(WidgetConstructor)(Statusbar*, const char*); typedef Widget *(WidgetConstructor)(Statusbar*, cfg_t*);
int calculate_offset(int, int, int, int); int calculate_offset(int, int, int, int);
void calculate_alignments(Widget *widget); void calculate_alignments(Widget *widget);
void common_new(Widget *, Statusbar *, const char *); void common_new(Widget*, Statusbar*, cfg_t*);
WidgetConstructor layoutinfo_new; WidgetConstructor layoutinfo_new;
WidgetConstructor taglist_new; WidgetConstructor taglist_new;

View File

@ -1,4 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <confuse.h>
#include "util.h" #include "util.h"
#include "widget.h" #include "widget.h"
#include "layout.h" #include "layout.h"
@ -36,13 +37,13 @@ focustitle_draw(Widget *widget, DrawCtx *ctx, int offset, int used)
} }
Widget * Widget *
focustitle_new(Statusbar *statusbar, const char *name) focustitle_new(Statusbar *statusbar, cfg_t *config)
{ {
Widget *w; Widget *w;
w = p_new(Widget, 1); w = p_new(Widget, 1);
common_new(w, statusbar, config);
w->draw = focustitle_draw; w->draw = focustitle_draw;
w->alignment = AlignFlex; w->alignment = AlignFlex;
common_new(w, statusbar, name);
return w; return w;
} }

View File

@ -1,3 +1,4 @@
#include <confuse.h>
#include "widget.h" #include "widget.h"
#include "util.h" #include "util.h"
#include "layout.h" #include "layout.h"
@ -30,12 +31,12 @@ layoutinfo_draw(Widget *widget,
Widget * Widget *
layoutinfo_new(Statusbar *statusbar, const char* name) layoutinfo_new(Statusbar *statusbar, cfg_t* config)
{ {
Widget *w; Widget *w;
w = p_new(Widget, 1); w = p_new(Widget, 1);
common_new(w, statusbar, config);
w->draw = (void*) layoutinfo_draw; w->draw = (void*) layoutinfo_draw;
common_new(w, statusbar, name);
return w; return w;
} }

View File

@ -1,3 +1,4 @@
#include <confuse.h>
#include "config.h" #include "config.h"
#include "util.h" #include "util.h"
#include "widget.h" #include "widget.h"
@ -68,12 +69,12 @@ taglist_draw(Widget *widget,
} }
Widget * Widget *
taglist_new(Statusbar *statusbar, const char *name) taglist_new(Statusbar *statusbar, cfg_t *config)
{ {
Widget *w; Widget *w;
w = p_new(Widget, 1); w = p_new(Widget, 1);
common_new(w, statusbar, config);
w->draw = taglist_draw; w->draw = taglist_draw;
common_new(w, statusbar, name);
return w; return w;
} }

View File

@ -1,33 +1,68 @@
#include <confuse.h>
#include "util.h" #include "util.h"
#include "widget.h" #include "widget.h"
extern awesome_config globalconf; 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 static int
textbox_draw(Widget *widget, textbox_draw(Widget *widget, DrawCtx *ctx, int offset,
DrawCtx *ctx,
int offset,
int used __attribute__ ((unused))) int used __attribute__ ((unused)))
{ {
VirtScreen vscreen = globalconf.screens[widget->statusbar->screen]; VirtScreen vscreen = globalconf.screens[widget->statusbar->screen];
int width = textwidth(ctx, vscreen.font, vscreen.statustext); int width, location;
int location = calculate_offset(vscreen.statusbar.width, Data *d;
width, d = (Data*) widget->data;
offset, width = textwidth(ctx, vscreen.font, d->text);
widget->alignment); location = calculate_offset(vscreen.statusbar.width,
width,
offset,
widget->alignment);
drawtext(ctx, location, 0, width, vscreen.statusbar.height, drawtext(ctx, location, 0, width, vscreen.statusbar.height,
vscreen.font, vscreen.statustext, vscreen.colors_normal); vscreen.font, d->text, vscreen.colors_normal);
return width; return width;
} }
Widget *
textbox_new(Statusbar *statusbar, const char *name) static void
textbox_tell(Widget *widget, char *command)
{ {
Widget *w; update(widget, command);
w = p_new(Widget, 1);
w->draw = textbox_draw;
common_new(w, statusbar, name);
return w;
} }
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 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99