From f5f574b6bddc76ea777ec39c2b3827e4801b5f3b Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Fri, 20 Jan 2012 19:32:50 +0100 Subject: [PATCH] !CONFIG NEWS! Add multi mouse section in [tags] and new section [client] with multi mouse section --- src/client.c | 38 +++++++++++++++++--------------------- src/config.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- src/config.h | 1 + src/event.c | 2 ++ src/infobar.c | 6 +----- src/mouse.c | 15 +++++---------- src/tag.c | 11 +++++++++++ src/tag.h | 1 + src/wmfs.h | 15 ++++++++++++++- wmfsrc | 14 ++++++++++++++ 10 files changed, 113 insertions(+), 38 deletions(-) diff --git a/src/client.c b/src/client.c index 15e4f65..7c4ebc8 100644 --- a/src/client.c +++ b/src/client.c @@ -454,7 +454,7 @@ _client_tab(struct client *c, struct client *cm) { /* Do not tab already tabed client */ if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER) - || c->tag != cm->tag) + || c->tag != cm->tag || c == cm) return; layout_split_arrange_closed(c); @@ -704,6 +704,7 @@ uicb_client_focus_with_wid(Uicb cmd) static void client_frame_new(struct client *c) { + struct barwin *frameb; XSetWindowAttributes at = { .background_pixel = c->ncol.bg, @@ -712,32 +713,27 @@ client_frame_new(struct client *c) .event_mask = BARWIN_MASK | BARWIN_ENTERMASK }; - c->frame = XCreateWindow(W->dpy, W->root, - c->geo.x, c->geo.y, - c->geo.w, c->geo.h, - 0, CopyFromParent, - InputOutput, - CopyFromParent, - (CWOverrideRedirect | CWBackPixmap - | CWBackPixel | CWEventMask), &at); + /* Use a fake barwin only to store mousebinds of frame win */ + frameb = barwin_new(W->root, 0, 0, 1, 1, 0, 0, false); + + frameb->win = + c->frame = XCreateWindow(W->dpy, W->root, + c->geo.x, c->geo.y, + c->geo.w, c->geo.h, + 0, CopyFromParent, + InputOutput, + CopyFromParent, + (CWOverrideRedirect | CWBackPixmap + | CWBackPixel | CWEventMask), &at); + + frameb->mousebinds = W->tmp_head.client; if(c->tbarw > c->border) { - struct geo g; - Uicb cmd = (Uicb)&c->win; - c->titlebar = barwin_new(c->frame, 0, 0, 1, c->tbarw, c->ncol.fg, c->ncol.bg, true); - /* TODO: Refer to titlebar config */ - barwin_mousebind_new(c->titlebar, Button1, false, g, - uicb_client_focus_with_wid, cmd); - barwin_mousebind_new(c->titlebar, Button1, false, g, - uicb_mouse_move, cmd); - barwin_mousebind_new(c->titlebar, Button2, false, g, - uicb_mouse_tab, cmd); - barwin_mousebind_new(c->titlebar, Button3, false, g, - uicb_mouse_resize, cmd); + c->titlebar->mousebinds = W->tmp_head.client; } XReparentWindow(W->dpy, c->win, c->frame, c->border, c->tbarw); diff --git a/src/config.c b/src/config.c index 729bddd..066cf91 100644 --- a/src/config.c +++ b/src/config.c @@ -11,6 +11,27 @@ #include "infobar.h" #include "util.h" +static void +config_mouse_section(struct mbhead *mousebinds, struct conf_sec **sec) +{ + int i = 0; + struct mousebind *m; + + SLIST_INIT(mousebinds); + + for(; sec[i]; ++i) + { + m = xcalloc(1, sizeof(struct mousebind)); + + m->button = fetch_opt_first(sec[i], "1", "button").num; + m->func = uicb_name_func(fetch_opt_first(sec[i], "", "func").str); + m->cmd = fetch_opt_first(sec[i], "", "cmd").str; + m->use_area = false; + + SLIST_INSERT_HEAD(mousebinds, m, next); + } +} + static void config_theme(void) { @@ -108,7 +129,7 @@ config_tag(void) { struct screen *s; size_t i, n; - struct conf_sec *sec, **ks; + struct conf_sec *sec, **ks, **mb; char *name; int screenid; @@ -117,6 +138,13 @@ config_tag(void) ks = fetch_section(sec, "tag"); n = fetch_section_count(ks); + /* [mouse] */ + if((mb = fetch_section(sec, "mouse"))) + { + config_mouse_section(&W->tmp_head.tag, mb); + free(mb); + } + /* [tag] */ for(i = 0; i < n; ++i) { @@ -131,6 +159,23 @@ config_tag(void) free(ks); } +static void +config_client(void) +{ + struct conf_sec *sec, **mb; + + /* [client] */ + sec = fetch_section_first(NULL, "client"); + + /* [mouse] */ + /* for client frame AND titlebar */ + if((mb = fetch_section(sec, "mouse"))) + { + config_mouse_section(&W->tmp_head.client, mb); + free(mb); + } +} + #define ISTRDUP(t, s) \ do { \ if((tmp = s)) \ @@ -255,6 +300,7 @@ config_init(void) config_theme(); config_keybind(); config_tag(); + config_client(); config_bars(); config_rule(); diff --git a/src/config.h b/src/config.h index 12f2403..99acaa7 100644 --- a/src/config.h +++ b/src/config.h @@ -35,6 +35,7 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] = { "tag_client", uicb_tag_client }, { "tag_move_client_next", uicb_tag_move_client_next }, { "tag_move_client_prev", uicb_tag_move_client_prev }, + { "tag_click", uicb_tag_click }, /* Layout */ { "layout_vmirror", uicb_layout_vmirror }, diff --git a/src/event.c b/src/event.c index 8f8cb1a..fb37bfb 100644 --- a/src/event.c +++ b/src/event.c @@ -25,6 +25,8 @@ event_buttonpress(XEvent *e) SLIST_FOREACH(b, &W->h.barwin, next) if(b->win == ev->window) { + W->last_clicked_barwin = b; + SLIST_FOREACH(m, &b->mousebinds, next) if(m->button == ev->button) if(!m->use_area || (m->use_area && INAREA(ev->x, ev->y, m->area))) diff --git a/src/infobar.c b/src/infobar.c index 68f9408..51e0ebb 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -36,7 +36,6 @@ infobar_elem_tag_init(struct element *e) { struct tag *t; struct barwin *b, *prev = NULL; - struct geo g = { 0, 0, 0, 0 }; int s, j; /* Get final size before to use in placement */ @@ -66,10 +65,7 @@ infobar_elem_tag_init(struct element *e) b->ptr = (void*)t; barwin_map(b); - /* TODO: refer to tag element configuration */ - barwin_mousebind_new(b, Button1, false, g, uicb_tag_set_with_name, (Uicb)t->name); - barwin_mousebind_new(b, Button4, false, g, uicb_tag_next, NULL); - barwin_mousebind_new(b, Button5, false, g, uicb_tag_prev, NULL); + b->mousebinds = W->tmp_head.tag; SLIST_INSERT_TAIL(&e->bars, b, enext, prev); diff --git a/src/mouse.c b/src/mouse.c index 8d3c5b0..0419997 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -90,7 +90,7 @@ mouse_drag_tag(struct client *c, Window w) #define _REV_SBORDER(c) draw_reversed_rect(W->root, c, false); void -mouse_move(struct client *c, bool type) +mouse_move(struct client *c, void (*func)(struct client*, struct client*)) { struct client *c2 = NULL, *last = c; struct tag *t = NULL; @@ -134,15 +134,10 @@ mouse_move(struct client *c, bool type) if(c2) { - if(c2 != c) - { + if(last == c2) _REV_SBORDER(c2); - if(type) - client_swap2(c, c2); - else - _client_tab(c, c2); - } + func(c, c2); } else if(t && t != (struct tag*)c) tag_client(t, c); @@ -163,7 +158,7 @@ uicb_mouse_move(Uicb cmd) (void)cmd; if(W->client && mouse_check_client(W->client)) - mouse_move(W->client, true); + mouse_move(W->client, client_swap2); } void @@ -172,5 +167,5 @@ uicb_mouse_tab(Uicb cmd) (void)cmd; if(W->client && mouse_check_client(W->client)) - mouse_move(W->client, false); + mouse_move(W->client, _client_tab); } diff --git a/src/tag.c b/src/tag.c index 9f175ca..ac75ed4 100644 --- a/src/tag.c +++ b/src/tag.c @@ -200,6 +200,17 @@ uicb_tag_move_client_prev(Uicb cmd) tag_client(TAILQ_LAST(&W->screen->tags, tsub), W->client); } +void +uicb_tag_click(Uicb cmd) +{ + (void)cmd; + struct tag *t; + + if((t = (struct tag*)W->last_clicked_barwin->ptr) + && t->screen == W->screen) + tag_screen(W->screen, t); +} + static void tag_remove(struct tag *t) { diff --git a/src/tag.h b/src/tag.h index 0311ad1..1e316f5 100644 --- a/src/tag.h +++ b/src/tag.h @@ -32,6 +32,7 @@ void uicb_tag_prev(Uicb cmd); void uicb_tag_client(Uicb cmd); void uicb_tag_move_client_next(Uicb cmd); void uicb_tag_move_client_prev(Uicb cmd); +void uicb_tag_click(Uicb cmd); #endif /* TAG_H */ diff --git a/src/wmfs.h b/src/wmfs.h index f0acf73..d3f376a 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -89,7 +89,7 @@ struct barwin Drawable dr; Color fg, bg; void *ptr; /* Special cases */ - SLIST_HEAD(, mousebind) mousebinds; + SLIST_HEAD(mbhead, mousebind) mousebinds; SLIST_ENTRY(barwin) next; /* global barwin */ SLIST_ENTRY(barwin) enext; /* element barwin */ }; @@ -279,6 +279,7 @@ struct wmfs Atom *net_atom; char **argv; char confpath[MAX_PATH_LEN]; + struct barwin *last_clicked_barwin; /* FIFO stuffs */ struct @@ -298,6 +299,18 @@ struct wmfs SLIST_HEAD(, rule) rule; } h; + /* + * Temporary head of mousebind list from config + * Will be copied in barwin of clickable drawable + * later in code + */ + struct + { + struct mbhead tag; + struct mbhead client; + struct mbhead root; + } tmp_head; + /* * Selected screen, client */ diff --git a/wmfsrc b/wmfsrc index 4b7ecba..fb2e2df 100644 --- a/wmfsrc +++ b/wmfsrc @@ -79,8 +79,22 @@ [tag] screen = 0 name = "6" [/tag] [tag] screen = 0 name = "7" [/tag] + # Mousebinds associated to Tags element button + [mouse] button = "1" func = "tag_click" [/mouse] + [mouse] button = "4" func = "tag_next" [/mouse] + [mouse] button = "5" func = "tag_prev" [/mouse] + + [/tags] +[client] + + [mouse] button = "1" func = "mouse_swap" [/mouse] + [mouse] button = "2" func = "mouse_tab" [/mouse] + [mouse] button = "3" func = "mouse_resize" [/mouse] + +[/client] + [rules] [rule]