add mouse bindings to status bar

This commit is contained in:
Julien Danjou 2007-12-27 15:49:00 +01:00
parent 0d75586ed5
commit c900e37843
12 changed files with 180 additions and 141 deletions

View File

@ -129,9 +129,6 @@ cleanup()
p_delete(&k);
}
cleanup_buttons(globalconf.buttons.tag);
cleanup_buttons(globalconf.buttons.title);
cleanup_buttons(globalconf.buttons.layout);
cleanup_buttons(globalconf.buttons.root);
cleanup_buttons(globalconf.buttons.client);

120
awesomerc
View File

@ -25,8 +25,68 @@ screen 0
{
position = "top"
taglist mytaglist {}
layoutinfo mylayoutinfo {}
taglist mytaglist
{
mouse
{
button = "1"
command = "tag_view"
}
mouse
{
button = "1"
modkey = {"Mod4"}
command = "client_tag"
}
mouse
{
button = "3"
command = "tag_toggleview"
}
mouse
{
button = "3"
modkey = {"Mod4"}
command = "client_toggletag"
}
mouse
{
button = "4"
command = "tag_viewnext"
}
mouse
{
button = "5"
command = "tag_viewprev"
}
}
layoutinfo mylayoutinfo
{
mouse
{
button = "1"
command = "tag_setlayout"
arg = "+1"
}
mouse
{
button = "4"
command = "tag_setlayout"
arg = "+1"
}
mouse
{
button = "3"
command = "tag_setlayout"
arg = "-1"
}
mouse
{
button = "5"
command = "tag_setlayout"
arg = "-1"
}
}
netwmicon mynetwmicon {}
focustitle myfocustitle {}
textbox mytextbox { text = "awesome!" }
@ -43,62 +103,6 @@ rules
mouse
{
tag
{
button = "1"
command = "tag_view"
}
tag
{
button = "1"
modkey = {"Mod4"}
command = "client_tag"
}
tag
{
button = "3"
command = "tag_toggleview"
}
tag
{
button = "3"
modkey = {"Mod4"}
command = "client_toggletag"
}
tag
{
button = "4"
command = "tag_viewnext"
}
tag
{
button = "5"
command = "tag_viewprev"
}
layout
{
button = "1"
command = "tag_setlayout"
arg = "+1"
}
layout
{
button = "4"
command = "tag_setlayout"
arg = "+1"
}
layout
{
button = "3"
command = "tag_setlayout"
arg = "-1"
}
layout
{
button = "5"
command = "tag_setlayout"
arg = "-1"
}
root
{
button = "3"

View File

@ -286,17 +286,17 @@ create_widgets(cfg_t* cfg_statusbar, Statusbar *statusbar)
{
wptr = widgets + i;
widget_new = name_func_lookup(cfg_name(wptr), WidgetList);
if (widget_new)
if(widget_new)
{
if(!widget)
{
widget = widget_new(statusbar, wptr);
statusbar->widgets = widget;
}
statusbar->widgets = widget = widget_new(statusbar, wptr);
else
{
widget->next = widget_new(statusbar, wptr);
widget = widget->next;
}
widget->buttons = parse_mouse_bindings(wptr, "mouse", a_strcmp(cfg_name(wptr), "taglist"));
}
else
warn("Ignoring unknown widget: %s.\n", cfg_name(widgets + i));
}
@ -332,17 +332,40 @@ config_parse(const char *confpatharg)
CFG_STR((char *) "tab_border", (char *) "#ff0000", CFGF_NONE),
CFG_END()
};
static cfg_opt_t mouse_taglist_opts[] =
{
CFG_STR_LIST((char *) "modkey", (char *) "{}", CFGF_NONE),
CFG_STR((char *) "button", (char *) "None", CFGF_NONE),
CFG_STR((char *) "command", (char *) "", CFGF_NONE),
CFG_END()
};
static cfg_opt_t mouse_generic_opts[] =
{
CFG_STR_LIST((char *) "modkey", (char *) "{}", CFGF_NONE),
CFG_STR((char *) "button", (char *) "None", CFGF_NONE),
CFG_STR((char *) "command", (char *) "", CFGF_NONE),
CFG_STR((char *) "arg", NULL, CFGF_NONE),
CFG_END()
};
static cfg_opt_t widget_opts[] =
{
CFG_SEC((char *) "mouse", mouse_generic_opts, CFGF_MULTI),
CFG_END()
};
static cfg_opt_t widget_taglist_opts[] =
{
CFG_SEC((char *) "mouse", mouse_taglist_opts, CFGF_MULTI),
CFG_END()
};
static cfg_opt_t widget_iconbox_opts[] =
{
CFG_SEC((char *) "mouse", mouse_generic_opts, CFGF_MULTI),
CFG_STR((char *) "image", (char *) NULL, CFGF_NONE),
CFG_END()
};
static cfg_opt_t widget_textbox_opts[] =
{
CFG_SEC((char *) "mouse", mouse_generic_opts, CFGF_MULTI),
CFG_STR((char *) "text", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "bg", (char *) NULL, CFGF_NONE),
@ -350,6 +373,7 @@ config_parse(const char *confpatharg)
};
static cfg_opt_t widget_progressbar_opts[] =
{
CFG_SEC((char *) "mouse", mouse_generic_opts, CFGF_MULTI),
CFG_INT((char *) "width", 102, CFGF_NONE),
CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "bg", (char *) NULL, CFGF_NONE),
@ -359,7 +383,7 @@ config_parse(const char *confpatharg)
{
CFG_STR((char *) "position", (char *) "top", CFGF_NONE),
CFG_SEC((char *) "textbox", widget_textbox_opts, CFGF_TITLE | CFGF_MULTI),
CFG_SEC((char *) "taglist", widget_opts, CFGF_TITLE | CFGF_MULTI),
CFG_SEC((char *) "taglist", widget_taglist_opts, CFGF_TITLE | CFGF_MULTI),
CFG_SEC((char *) "focustitle", widget_opts, CFGF_TITLE | CFGF_MULTI),
CFG_SEC((char *) "layoutinfo", widget_opts, CFGF_TITLE | CFGF_MULTI),
CFG_SEC((char *) "iconbox", widget_iconbox_opts, CFGF_TITLE | CFGF_MULTI),
@ -443,26 +467,8 @@ config_parse(const char *confpatharg)
CFG_SEC((char *) "keylist", keylist_opts, CFGF_MULTI),
CFG_END()
};
static cfg_opt_t mouse_tag_opts[] =
{
CFG_STR_LIST((char *) "modkey", (char *) "{}", CFGF_NONE),
CFG_STR((char *) "button", (char *) "None", CFGF_NONE),
CFG_STR((char *) "command", (char *) "", CFGF_NONE),
CFG_END()
};
static cfg_opt_t mouse_generic_opts[] =
{
CFG_STR_LIST((char *) "modkey", (char *) "{}", CFGF_NONE),
CFG_STR((char *) "button", (char *) "None", CFGF_NONE),
CFG_STR((char *) "command", (char *) "", CFGF_NONE),
CFG_STR((char *) "arg", NULL, CFGF_NONE),
CFG_END()
};
static cfg_opt_t mouse_opts[] =
{
CFG_SEC((char *) "tag", mouse_tag_opts, CFGF_MULTI),
CFG_SEC((char *) "layout", mouse_generic_opts, CFGF_MULTI),
CFG_SEC((char *) "title", mouse_generic_opts, CFGF_MULTI),
CFG_SEC((char *) "root", mouse_generic_opts, CFGF_MULTI),
CFG_SEC((char *) "client", mouse_generic_opts, CFGF_MULTI),
CFG_END()
@ -675,16 +681,6 @@ config_parse(const char *confpatharg)
compileregs(globalconf.rules);
/* Mouse: tags click bindings */
globalconf.buttons.tag = parse_mouse_bindings(cfg_mouse, "tag", False);
/* Mouse: layout click bindings */
globalconf.buttons.layout = parse_mouse_bindings(cfg_mouse, "layout", True);
/* Mouse: title click bindings */
globalconf.buttons.title = parse_mouse_bindings(cfg_mouse, "title", True);
/* Mouse: root window click bindings */
globalconf.buttons.root = parse_mouse_bindings(cfg_mouse, "root", True);

View File

@ -229,11 +229,13 @@ struct Widget
char *name;
int (*draw)(Widget *, DrawCtx *, int, int);
void (*tell)(Widget *, char *);
void (*button_press)(Widget *, XButtonPressedEvent *);
Statusbar *statusbar;
int alignment;
void *data;
int location;
int width;
Button *buttons;
Widget *next;
};
@ -252,9 +254,6 @@ struct AwesomeConf
/** Mouse bindings list */
struct
{
Button *tag;
Button *title;
Button *layout;
Button *root;
Button *client;
} buttons;

20
draw.c
View File

@ -27,6 +27,8 @@
#include "util.h"
#include "draw.h"
extern AwesomeConf globalconf;
DrawCtx *
draw_get_context(Display *display, int phys_screen, int width, int height)
{
@ -77,7 +79,7 @@ draw_text(DrawCtx *ctx, int x, int y, int w, int h, XftFont *font, const char *t
len = sizeof(buf) - 1;
memcpy(buf, text, len);
buf[len] = 0;
while(len && (nw = textwidth(ctx, font, buf)) > w)
while(len && (nw = textwidth(font, buf)) > w)
buf[--len] = 0;
if(nw > w)
return; /* too long */
@ -244,18 +246,18 @@ draw_rotate(DrawCtx *ctx, int screen, double angle, int tx, int ty)
return newdrawable;
}
unsigned short
textwidth_primitive(Display *display, XftFont *font, char *text)
static unsigned short
textwidth_primitive(XftFont *font, char *text)
{
cairo_surface_t *surface;
cairo_t *cr;
cairo_font_face_t *font_face;
cairo_text_extents_t te;
surface = cairo_xlib_surface_create(display, DefaultScreen(display),
DefaultVisual(display, DefaultScreen(display)),
DisplayWidth(display, DefaultScreen(display)),
DisplayHeight(display, DefaultScreen(display)));
surface = cairo_xlib_surface_create(globalconf.display, DefaultScreen(globalconf.display),
DefaultVisual(globalconf.display, DefaultScreen(globalconf.display)),
DisplayWidth(globalconf.display, DefaultScreen(globalconf.display)),
DisplayHeight(globalconf.display, DefaultScreen(globalconf.display)));
cr = cairo_create(surface);
font_face = cairo_ft_font_face_create_for_pattern(font->pattern);
cairo_set_font_face(cr, font_face);
@ -269,11 +271,11 @@ textwidth_primitive(Display *display, XftFont *font, char *text)
}
unsigned short
textwidth(DrawCtx *ctx, XftFont *font, char *text)
textwidth(XftFont *font, char *text)
{
if (!a_strlen(text))
return 0;
return textwidth_primitive(ctx->display, font, text);
return textwidth_primitive(font, text);
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

3
draw.h
View File

@ -45,7 +45,6 @@ void draw_image(DrawCtx *, int, int, int, const char *);
void draw_image_from_argb_data(DrawCtx *, int, int, int, int, int, unsigned char *);
int draw_get_image_width(const char *filename);
Drawable draw_rotate(DrawCtx *, int, double, int, int);
unsigned short textwidth(DrawCtx *, XftFont *, char *);
unsigned short textwidth_primitive(Display*, XftFont*, char*);
unsigned short textwidth(XftFont *, char *);
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

55
event.c
View File

@ -40,8 +40,6 @@
extern AwesomeConf globalconf;
#define CLEANMASK(mask) (mask & ~(globalconf.numlockmask | LockMask))
static void
handle_mouse_button_press(int screen, unsigned int button, unsigned int state,
Button *buttons, char *arg)
@ -60,43 +58,44 @@ handle_mouse_button_press(int screen, unsigned int button, unsigned int state,
}
void
handle_event_buttonpress(XEvent * e)
handle_event_buttonpress(XEvent *e)
{
int i, screen, x = 0, y = 0;
unsigned int udummy;
Client *c;
Window wdummy;
char arg[256];
Tag *tag;
Widget *widget;
XButtonPressedEvent *ev = &e->xbutton;
for(screen = 0; screen < get_screen_count(); screen++)
if(globalconf.screens[screen].statusbar->window == ev->window)
{
for(i = 1, tag = globalconf.screens[screen].tags; tag; tag = tag->next, i++)
{
x += textwidth_primitive(e->xany.display, globalconf.screens[screen].font, tag->name);
if(((globalconf.screens[screen].statusbar->position == BarTop
|| globalconf.screens[screen].statusbar->position == BarBot)
&& ev->x < x)
|| (globalconf.screens[screen].statusbar->position == BarRight && ev->y < x)
|| (globalconf.screens[screen].statusbar->position == BarLeft && ev->y > globalconf.screens[screen].statusbar->width - x))
{
snprintf(arg, sizeof(arg), "%d", i);
handle_mouse_button_press(screen, ev->button, ev->state, globalconf.buttons.tag, arg);
return;
}
}
x += globalconf.screens[screen].statusbar->txtlayoutwidth;
if(((globalconf.screens[screen].statusbar->position == BarTop
if(globalconf.screens[screen].statusbar->position == BarTop
|| globalconf.screens[screen].statusbar->position == BarBot)
&& ev->x < x)
|| (globalconf.screens[screen].statusbar->position == BarRight && ev->y < x)
|| (globalconf.screens[screen].statusbar->position == BarLeft && ev->y > globalconf.screens[screen].statusbar->width - x))
handle_mouse_button_press(screen, ev->button, ev->state, globalconf.buttons.layout, NULL);
else
handle_mouse_button_press(screen, ev->button, ev->state, globalconf.buttons.title, NULL);
return;
for(widget = globalconf.screens[screen].statusbar->widgets; widget; widget = widget->next)
if(ev->x >= widget->location && ev->x <= widget->location + widget->width)
{
widget->button_press(widget, ev);
return;
}
if(globalconf.screens[screen].statusbar->position == BarRight)
for(widget = globalconf.screens[screen].statusbar->widgets; widget; widget = widget->next)
if(ev->y >= widget->location && ev->y <= widget->location + widget->width)
{
widget->button_press(widget, ev);
return;
}
if(globalconf.screens[screen].statusbar->position == BarLeft)
for(widget = globalconf.screens[screen].statusbar->widgets; widget; widget = widget->next)
if(globalconf.screens[screen].statusbar->width - ev->y >= widget->location
&& globalconf.screens[screen].statusbar->width - ev->y
<= widget->location + widget->width)
{
widget->button_press(widget, ev);
return;
}
}
if((c = get_client_bywin(globalconf.clients, ev->window)))

View File

@ -24,6 +24,8 @@
#include "config.h"
#define CLEANMASK(mask) (mask & ~(globalconf.numlockmask | LockMask))
void grabkeys(int);
void handle_event_buttonpress(XEvent *);

View File

@ -23,6 +23,7 @@
#include "util.h"
#include "widget.h"
#include "statusbar.h"
#include "event.h"
extern AwesomeConf globalconf;
@ -80,6 +81,16 @@ widget_find(char *name, int screen)
return NULL;
}
static void
widget_common_button_press(Widget *widget, XButtonPressedEvent *ev)
{
Button *b;
for(b = widget->buttons; b; b = b->next)
if(ev->button == b->button && CLEANMASK(ev->state) == b->mod && b->func)
b->func(widget->statusbar->screen, b->arg);
}
static void
widget_common_tell(Widget *widget, char *command __attribute__ ((unused)))
{
@ -95,6 +106,7 @@ widget_common_new(Widget *widget, Statusbar *statusbar, cfg_t* config)
name = cfg_title(config);
widget->name = a_strdup(name);
widget->tell = widget_common_tell;
widget->button_press = widget_common_button_press;
}
/** Send command to widget

View File

@ -56,7 +56,7 @@ layoutinfo_new(Statusbar *statusbar, cfg_t* config)
Widget *w;
w = p_new(Widget, 1);
widget_common_new(w, statusbar, config);
w->draw = (void*) layoutinfo_draw;
w->draw = layoutinfo_draw;
return w;
}

View File

@ -24,6 +24,7 @@
#include "util.h"
#include "widget.h"
#include "tag.h"
#include "event.h"
extern AwesomeConf globalconf;
@ -71,7 +72,7 @@ taglist_draw(Widget *widget,
flagsize = (vscreen.font->height + 2) / 4;
for(tag = vscreen.tags; tag; tag = tag->next)
widget->width += textwidth(ctx, vscreen.font, tag->name);
widget->width += textwidth(vscreen.font, tag->name);
widget->location = widget_calculate_offset(widget->statusbar->width,
widget->width,
@ -81,7 +82,7 @@ taglist_draw(Widget *widget,
widget->width = 0;
for(tag = vscreen.tags; tag; tag = tag->next)
{
w = textwidth(ctx, vscreen.font, tag->name);
w = textwidth(vscreen.font, tag->name);
if(tag->selected)
colors = vscreen.colors_selected;
else if(isurgent(widget->statusbar->screen, tag))
@ -105,6 +106,33 @@ taglist_draw(Widget *widget,
return widget->width;
}
static void
taglist_button_press(Widget *widget, XButtonPressedEvent *ev)
{
VirtScreen vscreen = globalconf.screens[widget->statusbar->screen];
Button *b;
Tag *tag;
char buf[4];
int prev_width = 0, width = 0, i = 1;
for(b = widget->buttons; b; b = b->next)
if(ev->button == b->button && CLEANMASK(ev->state) == b->mod && b->func)
for(tag = vscreen.tags; tag; tag = tag->next, i++)
{
width = textwidth(vscreen.font, tag->name);
if(widget->statusbar->position == BarTop
|| widget->statusbar->position == BarBot)
if(ev->x >= widget->location + prev_width
&& ev->x <= widget->location + prev_width + width)
{
snprintf(buf, sizeof(buf), "%d", i);
b->func(widget->statusbar->screen, buf);
return;
}
prev_width += width;
}
}
Widget *
taglist_new(Statusbar *statusbar, cfg_t *config)
{
@ -112,6 +140,7 @@ taglist_new(Statusbar *statusbar, cfg_t *config)
w = p_new(Widget, 1);
widget_common_new(w, statusbar, config);
w->draw = taglist_draw;
w->button_press = taglist_button_press;
return w;
}

View File

@ -49,7 +49,7 @@ textbox_draw(Widget *widget, DrawCtx *ctx, int offset,
VirtScreen vscreen = globalconf.screens[widget->statusbar->screen];
Data *d = widget->data;
widget->width = textwidth(ctx, vscreen.font, d->text);
widget->width = textwidth(vscreen.font, d->text);
widget->location = widget_calculate_offset(widget->statusbar->width,
widget->width,
offset,