From 99e85cbfc218ffc721015f30ec5831b3594152a6 Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 4 Jan 2011 01:10:27 +0100 Subject: [PATCH 01/20] Use setitimer instead of alarm --- src/wmfs.c | 29 ++++++++++++++++++++++------- src/wmfs.h | 1 + 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/wmfs.c b/src/wmfs.c index a74ba93..25ae938 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -141,6 +141,26 @@ quit(void) return; } +/** launch status timer + */ +void +status_timer(void) +{ + struct itimerval timer = { + .it_interval = { + .tv_usec = 0, + .tv_sec = conf.status_timing, + }, + .it_value = { + .tv_usec = 1, + .tv_sec = 0, + }, + }; + + signal(SIGALRM, &signal_handle); + setitimer(ITIMER_REAL, &timer, NULL); +} + /** WMFS main loop. */ void @@ -148,10 +168,6 @@ mainloop(void) { XEvent ev; - /* launch status loop */ - if (estatus) - signal_handle(SIGALRM); - while(!exiting && !XNextEvent(dpy, &ev)) getevent(ev); @@ -400,9 +416,6 @@ signal_handle(int sig) /* exec status script (only if still not running) */ if (conf.status_pid == (pid_t)-1) conf.status_pid = spawn(conf.status_path); - /* re-set timer */ - if (conf.status_timing > 0) - alarm(conf.status_timing); break; } @@ -513,6 +526,8 @@ main(int argc, char **argv) /* Let's Go ! */ init(); scan(); + if (estatus) + status_timer(); mainloop(); quit(); diff --git a/src/wmfs.h b/src/wmfs.h index e548c49..51c8849 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include From c817b7277be9cec356d3489fed4502f27c2190fb Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 4 Jan 2011 01:24:51 +0100 Subject: [PATCH 02/20] Disable status script timer on reload (instead of ignoring signal) --- src/wmfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wmfs.c b/src/wmfs.c index 25ae938..eced565 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -269,7 +269,10 @@ void uicb_reload(uicb_t cmd) { (void)cmd; - signal(SIGALRM, SIG_IGN); + struct itimerval notimer = { { 0, 0}, { 0, 0 } }; + /* disable status timer */ + if (estatus) + setitimer(ITIMER_REAL, ¬imer, NULL); quit(); for(; argv_global[0] && argv_global[0] == ' '; ++argv_global); From 0a2c1f9d133369819d7293e0191e9a1e7538f4c6 Mon Sep 17 00:00:00 2001 From: Philippe Pepiot Date: Tue, 4 Jan 2011 03:02:29 +0100 Subject: [PATCH 03/20] Use sigaction instead of signal. SIGCHLD and SIGALRM are now exclusives (one mask other) --- src/wmfs.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/wmfs.c b/src/wmfs.c index eced565..2b62ede 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -146,6 +146,7 @@ quit(void) void status_timer(void) { + struct sigaction sa; struct itimerval timer = { .it_interval = { .tv_usec = 0, @@ -157,7 +158,11 @@ status_timer(void) }, }; - signal(SIGALRM, &signal_handle); + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = signal_handle; + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGCHLD); + sigaction(SIGALRM, &sa, NULL); setitimer(ITIMER_REAL, &timer, NULL); } @@ -405,17 +410,12 @@ signal_handle(int sig) exit(EXIT_SUCCESS); break; case SIGCHLD: - /* re-set signal handler and wait childs */ - if (signal(SIGCHLD, &signal_handle) == SIG_ERR) - warn("signal(%d)", SIGCHLD); + /* wait childs */ while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) if (pid == conf.status_pid) conf.status_pid = -1; break; case SIGALRM: - /* re-set signal handler */ - if (signal(SIGALRM, &signal_handle) == SIG_ERR) - warn("signal(%d)", SIGALRM); /* exec status script (only if still not running) */ if (conf.status_pid == (pid_t)-1) conf.status_pid = spawn(conf.status_path); @@ -437,7 +437,7 @@ main(int argc, char **argv) char *ol = "csgVS"; extern char *optarg; extern int optind; - int sigs[] = { SIGTERM, SIGQUIT, SIGCHLD }; + struct sigaction sa; argv_global = xstrdup(argv[0]); sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME")); @@ -518,17 +518,22 @@ main(int argc, char **argv) if(!(dpy = XOpenDisplay(NULL))) errx(EXIT_FAILURE, "cannot open X server."); - /* Set signal handler */ - for (i = 0; i < (int)LEN(sigs); i++) - if (signal(sigs[i], &signal_handle) == SIG_ERR) - warn("signal(%d)", sigs[i]); - /* Check if an other WM is already running; set the error handler */ XSetErrorHandler(errorhandler); /* Let's Go ! */ init(); scan(); + + /* set signal handler */ + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = signal_handle; + sigemptyset(&sa.sa_mask); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + sigaddset(&sa.sa_mask, SIGALRM); + sigaction(SIGCHLD, &sa, NULL); + if (estatus) status_timer(); mainloop(); From 18e97d3e1e4d28db9fa41edb858814117185c461 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Sat, 8 Jan 2011 15:47:19 +0100 Subject: [PATCH 04/20] Wmfs: Use pthread instead of setitimer --- configure | 2 ++ src/wmfs.c | 102 ++++++++++++++++++++++++----------------------------- 2 files changed, 48 insertions(+), 56 deletions(-) diff --git a/configure b/configure index 7a89d41..27b83e0 100755 --- a/configure +++ b/configure @@ -79,6 +79,8 @@ fi [ -n "$USE_XRANDR" ] && CFLAGS="$CFLAGS -DHAVE_XRANDR" [ -n "$USE_IMLIB2" ] && CFLAGS="$CFLAGS -DHAVE_IMLIB" +LDFLAGS="$LDFLAGS -lpthread" + cat > Makefile << EOF PREFIX=$PREFIX XDG_CONFIG_DIR=$XDG_CONFIG_DIR diff --git a/src/wmfs.c b/src/wmfs.c index 04d8a07..305fa4f 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -135,35 +135,34 @@ quit(void) XCloseDisplay(dpy); /* kill status script */ - if (conf.status_pid != -1) + if (conf.status_pid != (pid_t)-1) kill(conf.status_pid, SIGTERM); return; } -/** launch status timer - */ -void -status_timer(void) +void * +thread_process(void *arg) { - struct sigaction sa; - struct itimerval timer = { - .it_interval = { - .tv_usec = 0, - .tv_sec = conf.status_timing, - }, - .it_value = { - .tv_usec = 1, - .tv_sec = 0, - }, - }; + XEvent ev; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = signal_handle; - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGCHLD); - sigaction(SIGALRM, &sa, NULL); - setitimer(ITIMER_REAL, &timer, NULL); + /* X event loop */ + if(arg) + { + while(!exiting && !XNextEvent(dpy, &ev)) + getevent(ev); + } + /* Status checking loop with timing */ + else + { + pthread_detach(pthread_self()); + do + { + conf.status_pid = spawn(conf.status_path); + sleep(conf.status_timing); + } while (!exiting && conf.status_timing != 0); + } + pthread_exit(NULL); } /** WMFS main loop. @@ -172,9 +171,19 @@ void mainloop(void) { XEvent ev; + pthread_t evloop, evstatus; + void *ret; - while(!exiting && !XNextEvent(dpy, &ev)) - getevent(ev); + if(!estatus) + while(!exiting && !XNextEvent(dpy, &ev)) + getevent(ev); + else + { + pthread_create(&evloop, NULL, thread_process, "1"); + pthread_create(&evstatus, NULL, thread_process, NULL); + + (void)pthread_join(evloop, &ret); + } return; } @@ -274,15 +283,12 @@ void uicb_reload(uicb_t cmd) { (void)cmd; - struct itimerval notimer = { { 0, 0}, { 0, 0 } }; - /* disable status timer */ - if (estatus) - setitimer(ITIMER_REAL, ¬imer, NULL); quit(); for(; argv_global[0] && argv_global[0] == ' '; ++argv_global); - execvp(argv_global, all_argv); + /* add -C to always load the same config file */ + execlp(argv_global, argv_global, "-C", conf.confpath, NULL); return; } @@ -398,8 +404,6 @@ update_status(void) static void signal_handle(int sig) { - pid_t pid; - switch (sig) { case SIGQUIT: @@ -409,15 +413,10 @@ signal_handle(int sig) exit(EXIT_SUCCESS); break; case SIGCHLD: - /* wait childs */ - while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) - if (pid == conf.status_pid) - conf.status_pid = -1; - break; - case SIGALRM: - /* exec status script (only if still not running) */ - if (conf.status_pid == (pid_t)-1) - conf.status_pid = spawn(conf.status_path); + /* re-set signal handler and wait childs */ + if (signal(SIGCHLD, &signal_handle) == SIG_ERR) + warn("signal(%d)", SIGCHLD); + while (waitpid(-1, NULL, WNOHANG) > 0); break; } @@ -436,11 +435,9 @@ main(int argc, char **argv) char *ol = "csgVS"; extern char *optarg; extern int optind; - struct sigaction sa; + int sigs[] = { SIGTERM, SIGQUIT, SIGCHLD }; argv_global = xstrdup(argv[0]); - all_argv = argv; - sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME")); while((i = getopt(argc, argv, "hviSc:s:g:C:V:")) != -1) @@ -462,7 +459,7 @@ main(int argc, char **argv) " -V Manage WMFS with vi-like command\n" " -S Update status script\n" " -h Show this page\n" - " -i Show information\n" + " -i Show informations\n" " -v Show WMFS version\n", argv[0]); exit(EXIT_SUCCESS); break; @@ -519,24 +516,17 @@ main(int argc, char **argv) if(!(dpy = XOpenDisplay(NULL))) errx(EXIT_FAILURE, "cannot open X server."); + /* Set signal handler */ + for (i = sigs[0]; i < (int)LEN(sigs); i++) + if (signal(sigs[i], &signal_handle) == SIG_ERR) + warn("signal(%d)", sigs[i]); + /* Check if an other WM is already running; set the error handler */ XSetErrorHandler(errorhandler); /* Let's Go ! */ init(); scan(); - - /* set signal handler */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = signal_handle; - sigemptyset(&sa.sa_mask); - sigaction(SIGQUIT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - sigaddset(&sa.sa_mask, SIGALRM); - sigaction(SIGCHLD, &sa, NULL); - - if (estatus) - status_timer(); mainloop(); quit(); From 2273ccc5d5091428c5dbd77302f31c1a1d0124da Mon Sep 17 00:00:00 2001 From: Raphael Khaiat Date: Sat, 8 Jan 2011 18:20:27 +0100 Subject: [PATCH 05/20] Let wmfs reload now with the same argument that it was launched with --- src/wmfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wmfs.c b/src/wmfs.c index 305fa4f..95ab225 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -288,7 +288,7 @@ uicb_reload(uicb_t cmd) for(; argv_global[0] && argv_global[0] == ' '; ++argv_global); /* add -C to always load the same config file */ - execlp(argv_global, argv_global, "-C", conf.confpath, NULL); + execvp(argv_global, all_argv); return; } From 7bb0fdcbad83a3a6317642ab864d472f9bd6d110 Mon Sep 17 00:00:00 2001 From: Raphael Khaiat Date: Sat, 8 Jan 2011 18:23:11 +0100 Subject: [PATCH 06/20] Fix bug #67 --- src/client.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/client.c b/src/client.c index 0464872..b5653b2 100644 --- a/src/client.c +++ b/src/client.c @@ -1249,11 +1249,22 @@ client_unmanage(Client *c) /* Arrange */ for(i = 0; i < screen_count() && !b; ++i) - if(c->tag == (uint)seltag[i] || tags[i][seltag[i]].tagad & TagFlag(c->tag)) + if(c->tag == MAXTAG + 1 || c->tag == (uint)seltag[i] || tags[i][seltag[i]].tagad & TagFlag(c->tag)) b = True; if(b) - tags[c->screen][c->tag].layout.func(c->screen); + { + if(c->tag == MAXTAG + 1) + { + if(c->tag == MAXTAG+1){ + for(i = 0; i < conf.ntag[c->screen]; i++) + tags[c->screen][i].request_update = True; + tags[c->screen][seltag[c->screen]].layout.func(c->screen); + } + } + else + tags[c->screen][c->tag].layout.func(c->screen); + } else { tags[c->screen][c->tag].request_update = True; From 056cb5daf66da4e040acacf6b079ea1c3bedc3f6 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Mon, 10 Jan 2011 19:31:42 +0100 Subject: [PATCH 07/20] Util: Fix spawn --- src/util.c | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/src/util.c b/src/util.c index 961b92a..2b21e33 100644 --- a/src/util.c +++ b/src/util.c @@ -253,14 +253,15 @@ alias_to_str(char *conf_choice) * \param cmd Command * \return child pid */ -pid_t +int spawn(const char *format, ...) { char *sh = NULL; char cmd[512]; va_list ap; + pid_t pid, ret; + int p[2]; size_t len; - pid_t pid; va_start(ap, format); len = vsnprintf(cmd, sizeof(cmd), format, ap); @@ -275,18 +276,48 @@ spawn(const char *format, ...) if(!(sh = getenv("SHELL"))) sh = "/bin/sh"; + if (pipe(p) == -1) + { + warn("pipe"); + return -1; + } + if((pid = fork()) == 0) { - if(dpy) - close(ConnectionNumber(dpy)); - setsid(); - execl(sh, sh, "-c", cmd, (char*)NULL); - err(1, "execl(%s)", cmd); - } - if (pid == -1) - warn("fork()"); + close(p[0]); + if((pid = fork()) == 0) + { + if(dpy) + close(ConnectionNumber(dpy)); + setsid(); + execl(sh, sh, "-c", cmd, (char*)NULL); + exit(EXIT_FAILURE); + } - return pid; + if (sizeof(pid_t) != write(p[1], &pid, sizeof(pid_t))) + warn("write"); + + close(p[1]); + exit(EXIT_SUCCESS); + } + else if (pid != -1) + { + close(p[1]); + if (sizeof(pid_t) != read(p[0], &ret, sizeof(pid_t))) + { + warn("read"); + ret = -1; + } + close(p[0]); + waitpid(pid, NULL, 0); + } + else + { + warn("fork"); + ret = -1; + } + + return ret; } /** Swap two pointer. From c317afc79dff114be4eda71b41ad24b5993f8d00 Mon Sep 17 00:00:00 2001 From: Raphael Khaiat Date: Mon, 10 Jan 2011 20:39:14 +0100 Subject: [PATCH 08/20] Re-arrange code for fix #67 (avoid code duplication) --- src/client.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/client.c b/src/client.c index b5653b2..7405558 100644 --- a/src/client.c +++ b/src/client.c @@ -1247,31 +1247,33 @@ client_unmanage(Client *c) XUngrabServer(dpy); ewmh_get_client_list(); - /* Arrange */ - for(i = 0; i < screen_count() && !b; ++i) - if(c->tag == MAXTAG + 1 || c->tag == (uint)seltag[i] || tags[i][seltag[i]].tagad & TagFlag(c->tag)) - b = True; - if(b) + if(c->tag == MAXTAG + 1) { - if(c->tag == MAXTAG + 1) - { - if(c->tag == MAXTAG+1){ - for(i = 0; i < conf.ntag[c->screen]; i++) - tags[c->screen][i].request_update = True; - tags[c->screen][seltag[c->screen]].layout.func(c->screen); - } - } - else - tags[c->screen][c->tag].layout.func(c->screen); + for(i = 0; i < conf.ntag[c->screen]; i++) + tags[c->screen][i].request_update = True; + tags[c->screen][seltag[c->screen]].layout.func(c->screen); } else { - tags[c->screen][c->tag].request_update = True; - infobar_draw(c->screen); + /* Arrange */ + for(i = 0; i < screen_count() && !b; ++i) + if(c->tag == (uint)seltag[i] || tags[i][seltag[i]].tagad & TagFlag(c->tag)) + b = True; + + if(b) + { + tags[c->screen][c->tag].layout.func(c->screen); + } + else + { + tags[c->screen][c->tag].request_update = True; + infobar_draw(c->screen); + } } + /*XFree(c->title);*/ client_focus_next(c); From 2320e8586c5d8f4a0bf5d1c20bc8a4e01f0ed364 Mon Sep 17 00:00:00 2001 From: Raphael Khaiat Date: Mon, 10 Jan 2011 20:40:55 +0100 Subject: [PATCH 09/20] Implement fixture #63 : auto center option for free client --- src/client.c | 9 +++++++++ src/config.c | 1 + src/structs.h | 1 + wmfsrc | 1 + 4 files changed, 12 insertions(+) diff --git a/src/client.c b/src/client.c index 7405558..3bc43e4 100644 --- a/src/client.c +++ b/src/client.c @@ -706,7 +706,16 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) mx += spgeo[selscreen].x; my += spgeo[selscreen].y; } + + if(conf.client_auto_center) + { + XRectangle tmp; + tmp = screen_get_geo(selscreen); + mx = (tmp.width + mx - wa->width) / 2; + my = (tmp.height + my - wa->height) / 2; + } } + c->ogeo.x = c->geo.x = mx; c->ogeo.y = c->geo.y = my; c->ogeo.width = c->geo.width = wa->width; diff --git a/src/config.c b/src/config.c index f72d42d..7c7eb22 100644 --- a/src/config.c +++ b/src/config.c @@ -271,6 +271,7 @@ conf_client_section(void) sec = fetch_section_first(NULL, "client"); conf.client_round = fetch_opt_first(sec, "true", "client_round").bool; + conf.client_auto_center = fetch_opt_first(sec, "false", "client_auto_center").bool; if ((conf.client.borderheight = fetch_opt_first(sec, "1", "border_height").num) < 1) conf.client.borderheight = 1; diff --git a/src/structs.h b/src/structs.h index 55e7b33..004d86d 100644 --- a/src/structs.h +++ b/src/structs.h @@ -484,6 +484,7 @@ typedef struct Bool tag_round; Bool tag_auto_prev; Bool client_round; + Bool client_auto_center; Bool layout_system; /* Switch: False, Menu: True. */ Bool layout_placement; /* Right (normal): False, Left: True. */ Bool keep_layout_geo; diff --git a/wmfsrc b/wmfsrc index ad8422d..cb2cf53 100644 --- a/wmfsrc +++ b/wmfsrc @@ -157,6 +157,7 @@ [client] client_round = true + client_auto_center = false border_height = 3 border_shadow = true border_normal = "#191919" From 8ea76e11679e0fcbc020dc12ddb7806304945c32 Mon Sep 17 00:00:00 2001 From: Raphael Khaiat Date: Mon, 10 Jan 2011 21:45:11 +0100 Subject: [PATCH 10/20] Fix reload function (problem due to a bad merge), thanks to Erus --- src/wmfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wmfs.c b/src/wmfs.c index 95ab225..00f3878 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -438,6 +438,7 @@ main(int argc, char **argv) int sigs[] = { SIGTERM, SIGQUIT, SIGCHLD }; argv_global = xstrdup(argv[0]); + all_argv = argv; sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME")); while((i = getopt(argc, argv, "hviSc:s:g:C:V:")) != -1) From 27c4c260c6f5168623437c3df7a5fffb1163059d Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Wed, 12 Jan 2011 11:26:41 +0100 Subject: [PATCH 11/20] Client: Revert libvte patch by roidelapluie --- src/client.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/client.c b/src/client.c index 3bc43e4..2a75679 100644 --- a/src/client.c +++ b/src/client.c @@ -706,7 +706,7 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) mx += spgeo[selscreen].x; my += spgeo[selscreen].y; } - + if(conf.client_auto_center) { XRectangle tmp; @@ -715,7 +715,7 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) my = (tmp.height + my - wa->height) / 2; } } - + c->ogeo.x = c->geo.x = mx; c->ogeo.y = c->geo.y = my; c->ogeo.width = c->geo.width = wa->width; @@ -887,7 +887,7 @@ client_maximize(Client *c) c->geo.width = sgeo[c->screen].width - BORDH * 2; c->geo.height = sgeo[c->screen].height - BORDH; - client_moveresize(c, c->geo, True); + client_moveresize(c, c->geo, False); return; } @@ -1120,20 +1120,20 @@ client_set_rules(Client *c) } } - if(!applied_tag_rule && conf.client.default_open_tag > 0 + if(!applied_tag_rule && conf.client.default_open_tag > 0 && conf.client.default_open_tag < (uint)conf.ntag[selscreen]) { c->tag = conf.client.default_open_tag; - + client_focus_next(c); tags[c->screen][c->tag].request_update = True; } - - if(!applied_screen_rule && conf.client.default_open_screen > -1 + + if(!applied_screen_rule && conf.client.default_open_screen > -1 && conf.client.default_open_screen < screen_count()) { c->screen = conf.client.default_open_screen; - + client_focus_next(c); tags[c->screen][c->tag].request_update = True; } From 209f9a09a43f4d8f61c4e9676e5ec5f65fba1019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 12 Jan 2011 19:19:24 +0100 Subject: [PATCH 12/20] Make a bunch of functions static. --- src/config.c | 22 +++++++++---------- src/getinfo.c | 10 ++++----- src/init.c | 58 +++++++++++++++++++++++++-------------------------- src/wmfs.h | 12 ----------- 4 files changed, 45 insertions(+), 57 deletions(-) diff --git a/src/config.c b/src/config.c index 7c7eb22..5424b6f 100644 --- a/src/config.c +++ b/src/config.c @@ -128,7 +128,7 @@ name_to_uint_t mouse_button_list[] = {"5", Button5 }, }; -void +static void mouse_section(MouseBinding mb[], struct conf_sec **sec) { int n; @@ -143,7 +143,7 @@ mouse_section(MouseBinding mb[], struct conf_sec **sec) } } -void +static void conf_misc_section(void) { int pad = 12; @@ -180,7 +180,7 @@ conf_misc_section(void) return; } -void +static void conf_bar_section(void) { struct conf_sec *bar, **mouse, *selbar, *systray; @@ -238,7 +238,7 @@ conf_bar_section(void) return; } -void +static void conf_root_section(void) { struct conf_sec *root, **mouse; @@ -260,7 +260,7 @@ conf_root_section(void) return; } -void +static void conf_client_section(void) { int i, j; @@ -383,7 +383,7 @@ conf_client_section(void) return; } -void +static void conf_layout_section(void) { int i; @@ -461,7 +461,7 @@ conf_layout_section(void) return; } -void +static void conf_tag_section(void) { int i, j, k, l = 0, m, n, sc, count, bar_pos; @@ -613,7 +613,7 @@ conf_tag_section(void) return; } -void +static void conf_rule_section(void) { int i; @@ -644,7 +644,7 @@ conf_rule_section(void) return; } -void +static void conf_menu_section(void) { char *tmp2; @@ -705,7 +705,7 @@ conf_menu_section(void) return; } -void +static void conf_launcher_section(void) { int i; @@ -731,7 +731,7 @@ conf_launcher_section(void) return; } -void +static void conf_keybind_section(void) { int i; diff --git a/src/getinfo.c b/src/getinfo.c index b4e2928..a00806c 100644 --- a/src/getinfo.c +++ b/src/getinfo.c @@ -42,7 +42,7 @@ uchar *ret; /** Get information about tag (current, list, names) */ -void +static void getinfo_tag(void) { int tag = 0; @@ -82,7 +82,7 @@ getinfo_tag(void) /** Get information about screens */ -void +static void getinfo_screen(void) { int screen = 1; @@ -108,7 +108,7 @@ getinfo_screen(void) /** Get current layout name */ -void +static void getinfo_layout(void) { char *layout = NULL; @@ -129,7 +129,7 @@ getinfo_layout(void) /** Get information about current mwfact */ -void +static void getinfo_mwfact(void) { char *mwfact = NULL; @@ -150,7 +150,7 @@ getinfo_mwfact(void) /** Get information about current nmaster */ -void +static void getinfo_nmaster(void) { int nmaster = 1; diff --git a/src/init.c b/src/init.c index 21b01e0..436f1d0 100644 --- a/src/init.c +++ b/src/init.c @@ -55,32 +55,9 @@ const func_name_list_t layout_list[] = { NULL, NULL } }; -/** Init WMFS -*/ -void -init(void) -{ - /* First init */ - ewmh_init_hints(); - init_conf(); - init_gc(); - init_font(); - init_cursor(); - init_key(); - init_root(); - screen_init_geo(); - infobar_init(); - systray_acquire(); - init_status(); - ewmh_update_current_tag_prop(); - grabkeys(); - - return; -} - /** Init the font */ -void +static void init_font(void) { font = XftFontOpenName(dpy, SCREEN, conf.font); @@ -100,7 +77,7 @@ init_font(void) /** Init the graphic context */ -void +static void init_gc(void) { XGCValues gcv; @@ -127,7 +104,7 @@ init_gc(void) /** Init WMFS cursor */ -void +static void init_cursor(void) { cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); @@ -141,7 +118,7 @@ init_cursor(void) /** Init key modifier */ -void +static void init_key(void) { int i, j; @@ -160,7 +137,7 @@ init_key(void) /** Init root Window */ -void +static void init_root(void) { XSetWindowAttributes at; @@ -183,7 +160,7 @@ init_root(void) /** Init statustext shell script */ -void +static void init_status(void) { struct stat st; @@ -218,3 +195,26 @@ init_status(void) return; } +/** Init WMFS +*/ +void +init(void) +{ + /* First init */ + ewmh_init_hints(); + init_conf(); + init_gc(); + init_font(); + init_cursor(); + init_key(); + init_root(); + screen_init_geo(); + infobar_init(); + systray_acquire(); + init_status(); + ewmh_update_current_tag_prop(); + grabkeys(); + + return; +} + diff --git a/src/wmfs.h b/src/wmfs.h index 843d12e..89aa47c 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -400,20 +400,8 @@ Bool uicb_checklayout(uicb_t); /* init.c */ void init(void); -void init_root(void); -void init_font(void); -void init_gc(void); -void init_cursor(void); -void init_key(void); -void init_geometry(void); -void init_status(void); /* getinfo.c */ -void getinfo_tag(void); -void getinfo_screen(void); -void getinfo_layout(void); -void getinfo_mwfact(void); -void getinfo_nmaster(void); void getinfo(char *info); /* viwmfs.c */ From c174e69b645eca54ce1058e33a263364b5399497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 12 Jan 2011 19:21:17 +0100 Subject: [PATCH 13/20] Fix potential crash when using mouse_button_list. --- src/config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config.c b/src/config.c index 5424b6f..b329346 100644 --- a/src/config.c +++ b/src/config.c @@ -126,6 +126,7 @@ name_to_uint_t mouse_button_list[] = {"3", Button3 }, {"4", Button4 }, {"5", Button5 }, + {NULL, NoSymbol} }; static void From a5432919cade6e9fdaa24d874c70d4c8b0c5f239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 12 Jan 2011 19:22:54 +0100 Subject: [PATCH 14/20] Remove pointless if before calling free. The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- man malloc(3) --- src/draw.c | 4 ++-- src/getinfo.c | 8 ++++---- src/infobar.c | 2 +- src/launcher.c | 6 +++--- src/menu.c | 2 +- src/systray.c | 4 ++-- src/wmfs.c | 34 +++++++++++++++++----------------- src/wmfs.h | 1 - 8 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/draw.c b/src/draw.c index 4fa3b3f..8cf8a5d 100644 --- a/src/draw.c +++ b/src/draw.c @@ -100,7 +100,7 @@ draw_image_ofset_text(Drawable d, int x, int y, char* fg, char *str, int x_image if(strstr(ostr, "i[")) strncpy(str, ostr, textlen); - IFREE(ostr); + free(ostr); #endif /* HAVE_IMLIB */ return; @@ -226,7 +226,7 @@ textw(char *text) if(strstr(ostr, "i[")) strncpy(text, ostr, textlen); - IFREE(ostr); + free(ostr); #endif /* HAVE_IMLIB */ return gl.width + font->descent; diff --git a/src/getinfo.c b/src/getinfo.c index a00806c..46d3ce8 100644 --- a/src/getinfo.c +++ b/src/getinfo.c @@ -74,8 +74,8 @@ getinfo_tag(void) printf("Current tag: %d - %s\n", tag, tag_name); printf("Tag list: %s\n", tag_list); - IFREE(tag_name); - IFREE(tag_list); + free(tag_name); + free(tag_list); return; } @@ -122,7 +122,7 @@ getinfo_layout(void) printf("Current layout: %s\n", layout); - IFREE(layout); + free(layout); return; } @@ -143,7 +143,7 @@ getinfo_mwfact(void) printf("Current mwfact: %s\n", mwfact); - IFREE(mwfact); + free(mwfact); return; } diff --git a/src/infobar.c b/src/infobar.c index 390eb39..0928953 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -209,7 +209,7 @@ infobar_draw_selbar(int sc) barwin_refresh(infobar[sc].selbar); - IFREE(str); + free(str); return; } diff --git a/src/launcher.c b/src/launcher.c index 6690080..3aa32f3 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -370,7 +370,7 @@ complete_on_files(char *start, size_t hits) else warn("%s", filepath); - IFREE(filepath); + free(filepath); break; } @@ -378,8 +378,8 @@ complete_on_files(char *start, size_t hits) closedir(dir); } - IFREE(dirname); - IFREE(path); + free(dirname); + free(path); return ret; } diff --git a/src/menu.c b/src/menu.c index c90cedc..c8c8160 100644 --- a/src/menu.c +++ b/src/menu.c @@ -345,7 +345,7 @@ uicb_menu(uicb_t cmd) void menu_clear(Menu *menu) { - IFREE(menu->item); + free(menu->item); menu->nitem = 0; return; diff --git a/src/systray.c b/src/systray.c index abc8e53..832b209 100644 --- a/src/systray.c +++ b/src/systray.c @@ -118,7 +118,7 @@ systray_del(Systray *s) for(ss = &trayicons; *ss && *ss != s; ss = &(*ss)->next); *ss = s->next; - IFREE(s); + free(s); return; } @@ -162,7 +162,7 @@ systray_freeicons(void) { XUnmapWindow(dpy, i->win); XReparentWindow(dpy, i->win, ROOT, 0, 0); - IFREE(i); + free(i); } XSetSelectionOwner(dpy, net_atom[net_system_tray_s], None, CurrentTime); diff --git a/src/wmfs.c b/src/wmfs.c index 00f3878..632c7e5 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -92,8 +92,8 @@ quit(void) XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y); } - IFREE(tags); - IFREE(seltag); + free(tags); + free(seltag); systray_freeicons(); @@ -103,31 +103,31 @@ quit(void) XFreeGC(dpy, gc_stipple); infobar_destroy(); - IFREE(sgeo); - IFREE(spgeo); - IFREE(infobar); - IFREE(keys); - IFREE(net_atom); + free(sgeo); + free(spgeo); + free(infobar); + free(keys); + free(net_atom); /* Clean conf alloced thing */ - IFREE(menulayout.item); + free(menulayout.item); if(conf.menu) { len = LEN(conf.menu); for(i = 0; i < len; ++i) - IFREE(conf.menu[i].item); - IFREE(conf.menu); + free(conf.menu[i].item); + free(conf.menu); } - IFREE(conf.launcher); - IFREE(conf.rule); + free(conf.launcher); + free(conf.rule); - IFREE(conf.bars.mouse); - IFREE(conf.selbar.mouse); - IFREE(conf.titlebar.button); - IFREE(conf.client.mouse); - IFREE(conf.root.mouse); + free(conf.bars.mouse); + free(conf.selbar.mouse); + free(conf.titlebar.button); + free(conf.client.mouse); + free(conf.root.mouse); free_conf(); diff --git a/src/wmfs.h b/src/wmfs.h index 89aa47c..844935a 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -108,7 +108,6 @@ #define FRAMEH(h) ((h) + (BORDH + TBARH)) #define ROUND(x) (float)((x > 0) ? x + (float)0.5 : x - (float)0.5) #define CHECK(x) if(!(x)) return -#define IFREE(x) if(x) free(x) #define LEN(x) (sizeof(x) / sizeof((x)[0])) #define MAXCLIST (64) From b5f24e042f3ad13bb5e16a8ed6b43a2815246fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 12 Jan 2011 19:32:36 +0100 Subject: [PATCH 15/20] Remove a few check before calling free in parser. --- src/parse.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/parse.c b/src/parse.c index f649dac..cd08fd1 100644 --- a/src/parse.c +++ b/src/parse.c @@ -388,8 +388,7 @@ include(struct keyword *head) static void * free_opt(struct conf_opt *o) { - if (o) - free(o); + free(o); return NULL; } @@ -563,8 +562,7 @@ free_conf(void) while (kw) { nkw = kw->next; - if (kw->name) - free(kw->name); + free(kw->name); for (i = 0; i < nf; i++) { if (f[i] == kw->file) { From 7ac4bf32c2bf90b0ed209184e851bda454640467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 12 Jan 2011 19:40:36 +0100 Subject: [PATCH 16/20] One memset instead of two. This also fix the strange sizeof. --- src/layout.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/layout.c b/src/layout.c index fcd92ac..f9703b6 100644 --- a/src/layout.c +++ b/src/layout.c @@ -443,8 +443,7 @@ mirror(int screen, Bool horizontal) int pa, imp; Bool isp = 0; - memset(&nextg[0], 0, sizeof(nextg[0])); - memset(&nextg[1], 0, sizeof(nextg[2])); + memset(nextg, 0, sizeof(nextg)); for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n); CHECK(n); From 56b6b467ee354693f20fcf92c57ad6411ed04975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 12 Jan 2011 19:44:37 +0100 Subject: [PATCH 17/20] Avoid fd leak in parse_keywords. --- src/parse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/parse.c b/src/parse.c index cd08fd1..289fe91 100644 --- a/src/parse.c +++ b/src/parse.c @@ -307,6 +307,7 @@ parse_keywords(const char *filename) free(buf); free(bufname); + close(fd); warnx("%s read", file->name); return (error ? NULL: head); From 993b40826214fd0d92cab28a71cce88945e4b221 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Sat, 15 Jan 2011 20:55:13 +0100 Subject: [PATCH 18/20] Apply Almito's patchs for xcompmgr opacity support (#70), skype focus bug (#66) and fix for #68 & #69 --- src/client.c | 43 +++++++++++++++++++++++++++++++++---------- src/config.c | 7 +++++++ src/event.c | 6 +----- src/ewmh.c | 3 ++- src/layout.c | 1 - src/structs.h | 2 ++ src/wmfs.h | 1 + wmfsrc | 1 + 8 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/client.c b/src/client.c index 2a75679..e05ecc0 100644 --- a/src/client.c +++ b/src/client.c @@ -370,6 +370,9 @@ client_focus(Client *c) if(sel->flags & AboveFlag) sel->flags &= ~AboveFlag; + XChangeProperty(dpy,sel->frame,net_atom[net_wm_window_opacity],XA_CARDINAL, + 32,PropModeReplace,(uchar *)&conf.opacity,1); + frame_update(sel); mouse_grabbuttons(sel, !conf.focus_pclick); @@ -390,6 +393,9 @@ client_focus(Client *c) if(TBARH - BORDH && c->titlebar->stipple) c->titlebar->stipple_color = conf.titlebar.stipple.colors.focus; + + XDeleteProperty(dpy,c->frame,net_atom[net_wm_window_opacity]); + frame_update(c); mouse_grabbuttons(c, True); @@ -407,11 +413,7 @@ client_focus(Client *c) client_above(sel); if(c->flags & UrgentFlag) - { - c->flags &= ~UrgentFlag; - tags[c->screen][c->tag].urgent = False; - infobar_draw_taglist(c->screen); - } + client_urgent(c, False); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); @@ -428,6 +430,22 @@ client_focus(Client *c) return; } +/** Set urgency flag of the client + * \param c Client pointer + * \param u Bool +*/ +void +client_urgent(Client *c, Bool u) +{ + if(u) + c->flags |= UrgentFlag; + else + c->flags &= ~UrgentFlag; + + tags[c->screen][c->tag].urgent = u; + infobar_draw_taglist(c->screen); +} + /* The following functions have the same point : * find a client member with a Window {{{ */ @@ -761,7 +779,6 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) client_update_attributes(c); client_map(c); ewmh_manage_window_type(c); - client_focus(c); if(ar) arrange(c->screen, True); @@ -769,6 +786,11 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) if(!conf.client.set_new_win_master) layout_set_client_master(c); + if(c->tag == (uint)seltag[selscreen]) + { + client_focus(c); + } + return c; } @@ -1067,10 +1089,11 @@ client_set_rules(Client *c) if(c->tag != (uint)seltag[selscreen]) { tags[c->screen][c->tag].request_update = True; - client_focus(NULL); } - - tags[c->screen][c->tag].layout.func(c->screen); + else + { + tags[c->screen][c->tag].layout.func(c->screen); + } /* Deprecated but still in use */ applied_tag_rule = True; @@ -1246,7 +1269,7 @@ client_unmanage(Client *c) client_focus(NULL); if(c->flags & UrgentFlag) - tags[c->screen][c->tag].urgent = False; + client_urgent(c, False); client_detach(c); XUngrabButton(dpy, AnyButton, AnyModifier, c->win); diff --git a/src/config.c b/src/config.c index b329346..ce87837 100644 --- a/src/config.c +++ b/src/config.c @@ -148,6 +148,7 @@ static void conf_misc_section(void) { int pad = 12; + uint opacity = 255; struct conf_sec *sec; sec = fetch_section_first(NULL, "misc"); @@ -162,6 +163,12 @@ conf_misc_section(void) conf.autostart_path = fetch_opt_first(sec, "", "autostart_path").str; conf.autostart_command = fetch_opt_first(sec, "", "autostart_command").str; pad = fetch_opt_first(sec, "12", "pad").num; + opacity = fetch_opt_first(sec, "255", "opacity").num; + + if(opacity > 255) + opacity = 255; + + conf.opacity = opacity << 24; if(pad > 24 || pad < 1) { diff --git a/src/event.c b/src/event.c index c391521..29ce6f9 100644 --- a/src/event.c +++ b/src/event.c @@ -577,11 +577,7 @@ propertynotify(XPropertyEvent *ev) case XA_WM_HINTS: if((h = XGetWMHints(dpy, c->win)) && (h->flags & XUrgencyHint) && c != sel) { - c->flags |= UrgentFlag; - - tags[c->screen][c->tag].urgent = True; - infobar_draw_taglist(c->screen); - + client_urgent(c, True); XFree(h); } break; diff --git a/src/ewmh.c b/src/ewmh.c index 7fe04d8..e9f6787 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -69,6 +69,7 @@ ewmh_init_hints(void) net_atom[net_wm_icon_name] = ATOM("_NET_WM_ICON_NAME"); net_atom[net_wm_window_type] = ATOM("_NET_WM_WINDOW_TYPE"); net_atom[net_supporting_wm_check] = ATOM("_NET_SUPPORTING_WM_CHECK"); + net_atom[net_wm_window_opacity] = ATOM("_NET_WM_WINDOW_OPACITY"); net_atom[net_wm_window_type_normal] = ATOM("_NET_WM_WINDOW_TYPE_NORMAL"); net_atom[net_wm_window_type_dock] = ATOM("_NET_WM_WINDOW_TYPE_DOCK"); net_atom[net_wm_window_type_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH"); @@ -370,7 +371,7 @@ ewmh_manage_net_wm_state(long data_l[], Client *c) else if(data_l[1] == (long)net_atom[net_wm_state_demands_attention]) { if(data_l[0] == _NET_WM_STATE_ADD) - client_focus(c); + client_urgent(c, True); if(data_l[0] == _NET_WM_STATE_REMOVE) if(c == sel) client_focus(NULL); diff --git a/src/layout.c b/src/layout.c index f9703b6..debbfc5 100644 --- a/src/layout.c +++ b/src/layout.c @@ -849,7 +849,6 @@ layout_set_client_master(Client *c) client_detach(c); client_attach(c); - client_focus(c); tags[selscreen][seltag[selscreen]].layout.func(selscreen); diff --git a/src/structs.h b/src/structs.h index 004d86d..0cfebc1 100644 --- a/src/structs.h +++ b/src/structs.h @@ -115,6 +115,7 @@ enum net_wm_pid, net_showing_desktop, net_supporting_wm_check, + net_wm_window_opacity, net_wm_window_type_normal, net_wm_window_type_dock, net_wm_window_type_splash, @@ -375,6 +376,7 @@ typedef struct /* Misc option */ char *font; + uint opacity; Bool raisefocus; Bool raiseswitch; Bool focus_fmouse; diff --git a/src/wmfs.h b/src/wmfs.h index 844935a..108eacc 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -190,6 +190,7 @@ void client_unmanage(Client *c); void client_unmap(Client *c); void client_set_rules(Client *c); void client_update_attributes(Client *c); +void client_urgent(Client *c, Bool u); void uicb_client_raise(uicb_t); void uicb_client_next(uicb_t); void uicb_client_prev(uicb_t); diff --git a/wmfsrc b/wmfsrc index cb2cf53..581e494 100644 --- a/wmfsrc +++ b/wmfsrc @@ -10,6 +10,7 @@ font = "dejavu-10" raisefocus = false focus_follow_mouse = true + opacity = 255 # focus_pointer_click: click on unfocused client area: # true -- default, set focus # false -- click go to client; including dockapps From c8c210bcac68d2f902a3b066edc098c82fbe66ce Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Sat, 15 Jan 2011 20:59:19 +0100 Subject: [PATCH 19/20] Wmfs: Fix typo --- src/client.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/client.c b/src/client.c index e05ecc0..559bbaa 100644 --- a/src/client.c +++ b/src/client.c @@ -370,8 +370,8 @@ client_focus(Client *c) if(sel->flags & AboveFlag) sel->flags &= ~AboveFlag; - XChangeProperty(dpy,sel->frame,net_atom[net_wm_window_opacity],XA_CARDINAL, - 32,PropModeReplace,(uchar *)&conf.opacity,1); + XChangeProperty(dpy, sel->frame, net_atom[net_wm_window_opacity], XA_CARDINAL, + 32, PropModeReplace, (uchar *)&conf.opacity, 1); frame_update(sel); @@ -394,7 +394,7 @@ client_focus(Client *c) if(TBARH - BORDH && c->titlebar->stipple) c->titlebar->stipple_color = conf.titlebar.stipple.colors.focus; - XDeleteProperty(dpy,c->frame,net_atom[net_wm_window_opacity]); + XDeleteProperty(dpy, c->frame, net_atom[net_wm_window_opacity]); frame_update(c); mouse_grabbuttons(c, True); @@ -787,9 +787,7 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) layout_set_client_master(c); if(c->tag == (uint)seltag[selscreen]) - { client_focus(c); - } return c; } @@ -1087,13 +1085,9 @@ client_set_rules(Client *c) c->tag = j; if(c->tag != (uint)seltag[selscreen]) - { tags[c->screen][c->tag].request_update = True; - } else - { tags[c->screen][c->tag].layout.func(c->screen); - } /* Deprecated but still in use */ applied_tag_rule = True; From 7e0436ffdc444074a13b5463dcb1560372f6e23c Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Mon, 17 Jan 2011 20:19:25 +0100 Subject: [PATCH 20/20] Systray: Replace zcalloc with xcalloc (potential bug) --- src/systray.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systray.c b/src/systray.c index 832b209..ecda7bb 100644 --- a/src/systray.c +++ b/src/systray.c @@ -85,7 +85,7 @@ systray_add(Window win) if(!conf.systray.active) return; - s = zcalloc(sizeof(Systray)); + s = xcalloc(1, sizeof(Systray)); s->win = win; s->geo.height = infobar[conf.systray.screen].bar->geo.height;