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); 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.root);
cleanup_buttons(globalconf.buttons.client); cleanup_buttons(globalconf.buttons.client);

120
awesomerc
View File

@ -25,8 +25,68 @@ screen 0
{ {
position = "top" position = "top"
taglist mytaglist {} taglist mytaglist
layoutinfo mylayoutinfo {} {
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 {} netwmicon mynetwmicon {}
focustitle myfocustitle {} focustitle myfocustitle {}
textbox mytextbox { text = "awesome!" } textbox mytextbox { text = "awesome!" }
@ -43,62 +103,6 @@ rules
mouse 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 root
{ {
button = "3" button = "3"

View File

@ -286,17 +286,17 @@ create_widgets(cfg_t* cfg_statusbar, Statusbar *statusbar)
{ {
wptr = widgets + i; wptr = widgets + i;
widget_new = name_func_lookup(cfg_name(wptr), WidgetList); widget_new = name_func_lookup(cfg_name(wptr), WidgetList);
if (widget_new) if(widget_new)
if(!widget)
{ {
widget = widget_new(statusbar, wptr); if(!widget)
statusbar->widgets = widget; statusbar->widgets = widget = widget_new(statusbar, wptr);
}
else else
{ {
widget->next = widget_new(statusbar, wptr); widget->next = widget_new(statusbar, wptr);
widget = widget->next; widget = widget->next;
} }
widget->buttons = parse_mouse_bindings(wptr, "mouse", a_strcmp(cfg_name(wptr), "taglist"));
}
else else
warn("Ignoring unknown widget: %s.\n", cfg_name(widgets + i)); 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_STR((char *) "tab_border", (char *) "#ff0000", CFGF_NONE),
CFG_END() 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[] = 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() CFG_END()
}; };
static cfg_opt_t widget_iconbox_opts[] = 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_STR((char *) "image", (char *) NULL, CFGF_NONE),
CFG_END() CFG_END()
}; };
static cfg_opt_t widget_textbox_opts[] = 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 *) "text", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE), CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "bg", (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[] = static cfg_opt_t widget_progressbar_opts[] =
{ {
CFG_SEC((char *) "mouse", mouse_generic_opts, CFGF_MULTI),
CFG_INT((char *) "width", 102, CFGF_NONE), CFG_INT((char *) "width", 102, CFGF_NONE),
CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE), CFG_STR((char *) "fg", (char *) NULL, CFGF_NONE),
CFG_STR((char *) "bg", (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_STR((char *) "position", (char *) "top", CFGF_NONE),
CFG_SEC((char *) "textbox", widget_textbox_opts, CFGF_TITLE | CFGF_MULTI), 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 *) "focustitle", widget_opts, CFGF_TITLE | CFGF_MULTI),
CFG_SEC((char *) "layoutinfo", 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), 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_SEC((char *) "keylist", keylist_opts, CFGF_MULTI),
CFG_END() 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[] = 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 *) "root", mouse_generic_opts, CFGF_MULTI),
CFG_SEC((char *) "client", mouse_generic_opts, CFGF_MULTI), CFG_SEC((char *) "client", mouse_generic_opts, CFGF_MULTI),
CFG_END() CFG_END()
@ -675,16 +681,6 @@ config_parse(const char *confpatharg)
compileregs(globalconf.rules); 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 */ /* Mouse: root window click bindings */
globalconf.buttons.root = parse_mouse_bindings(cfg_mouse, "root", True); globalconf.buttons.root = parse_mouse_bindings(cfg_mouse, "root", True);

View File

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

20
draw.c
View File

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

47
event.c
View File

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

View File

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

View File

@ -23,6 +23,7 @@
#include "util.h" #include "util.h"
#include "widget.h" #include "widget.h"
#include "statusbar.h" #include "statusbar.h"
#include "event.h"
extern AwesomeConf globalconf; extern AwesomeConf globalconf;
@ -80,6 +81,16 @@ widget_find(char *name, int screen)
return NULL; 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 static void
widget_common_tell(Widget *widget, char *command __attribute__ ((unused))) 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); name = cfg_title(config);
widget->name = a_strdup(name); widget->name = a_strdup(name);
widget->tell = widget_common_tell; widget->tell = widget_common_tell;
widget->button_press = widget_common_button_press;
} }
/** Send command to widget /** Send command to widget

View File

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

View File

@ -24,6 +24,7 @@
#include "util.h" #include "util.h"
#include "widget.h" #include "widget.h"
#include "tag.h" #include "tag.h"
#include "event.h"
extern AwesomeConf globalconf; extern AwesomeConf globalconf;
@ -71,7 +72,7 @@ taglist_draw(Widget *widget,
flagsize = (vscreen.font->height + 2) / 4; flagsize = (vscreen.font->height + 2) / 4;
for(tag = vscreen.tags; tag; tag = tag->next) 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->location = widget_calculate_offset(widget->statusbar->width,
widget->width, widget->width,
@ -81,7 +82,7 @@ taglist_draw(Widget *widget,
widget->width = 0; widget->width = 0;
for(tag = vscreen.tags; tag; tag = tag->next) for(tag = vscreen.tags; tag; tag = tag->next)
{ {
w = textwidth(ctx, vscreen.font, tag->name); w = textwidth(vscreen.font, tag->name);
if(tag->selected) if(tag->selected)
colors = vscreen.colors_selected; colors = vscreen.colors_selected;
else if(isurgent(widget->statusbar->screen, tag)) else if(isurgent(widget->statusbar->screen, tag))
@ -105,6 +106,33 @@ taglist_draw(Widget *widget,
return widget->width; 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 * Widget *
taglist_new(Statusbar *statusbar, cfg_t *config) taglist_new(Statusbar *statusbar, cfg_t *config)
{ {
@ -112,6 +140,7 @@ taglist_new(Statusbar *statusbar, cfg_t *config)
w = p_new(Widget, 1); w = p_new(Widget, 1);
widget_common_new(w, statusbar, config); widget_common_new(w, statusbar, config);
w->draw = taglist_draw; w->draw = taglist_draw;
w->button_press = taglist_button_press;
return w; return w;
} }

View File

@ -49,7 +49,7 @@ textbox_draw(Widget *widget, DrawCtx *ctx, int offset,
VirtScreen vscreen = globalconf.screens[widget->statusbar->screen]; VirtScreen vscreen = globalconf.screens[widget->statusbar->screen];
Data *d = widget->data; 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->location = widget_calculate_offset(widget->statusbar->width,
widget->width, widget->width,
offset, offset,