JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Change bar_action handling to eliminate the need for bar_delay.
authorReginald Kennedy <rk@rejii.com>
Sun, 23 Sep 2012 10:33:23 +0000 (18:33 +0800)
committerReginald Kennedy <rk@rejii.com>
Sun, 23 Sep 2012 10:37:28 +0000 (18:37 +0800)
Old code called alarm() regularly and checked for input only at certain
times.  Now, the file descriptor for reading the text is added to the
select() in the main loop, and so updates are caught immediately and
efficiently.

Patch submitted by Jason Woofenden <jason@jasonwoof.com>

(Note: Minor modifications were made to formatting and a dummy version
of the bar_delay option was added to avoid breaking old conf files.)

spectrwm.1
spectrwm.c
spectrwm.conf
spectrwm_es.1
spectrwm_it.1
spectrwm_pt.1
spectrwm_ru.1

index 59a5acb..f27d837 100644 (file)
@@ -101,10 +101,6 @@ Set status bar border thickness in pixels.
 Disable border by setting to 0.
 .It Ic bar_color Ns Bq Ar x
 Color of the status bar window in screen
-.Ar x .
-.It Ic bar_delay
-Update frequency, in seconds, of external script that populates the status
-bar.
 .It Ic bar_enabled
 Set default
 .Ar bar_toggle
index 639969f..0020f39 100644 (file)
@@ -351,8 +351,6 @@ int          bar_pipe[2];
 char            bar_ext[SWM_BAR_MAX];
 char            bar_vertext[SWM_BAR_MAX];
 int             bar_version = 0;
-sig_atomic_t    bar_alarm = 0;
-int             bar_delay = 30;
 int             bar_enabled = 1;
 int             bar_border_width = 1;
 int             bar_at_bottom = 0;
@@ -834,7 +832,6 @@ void         bar_replace_pad(char *, int *, size_t);
 char *  bar_replace_seq(char *, char *, struct swm_region *, size_t *,
             size_t);
 void    bar_setup(struct swm_region *);
-void    bar_signal(int);
 void    bar_title_name(char *, size_t, struct swm_region *);
 void    bar_toggle(struct swm_region *, union arg *);
 void    bar_update(void);
@@ -2203,10 +2200,8 @@ bar_update(void)
        size_t                  len;
        char                    *b;
 
-       if (!bar_enabled)
-               return;
-       if (bar_extra && bar_extra_running) {
-               /* ignore short reads; it'll correct itself */
+       if (bar_enabled && bar_extra && bar_extra_running) {
+               /* Ignore short reads; it'll correct itself. */
                while ((b = fgetln(stdin, &len)) != NULL)
                        if (b && b[len - 1] == '\n') {
                                b[len - 1] = '\0';
@@ -2216,20 +2211,20 @@ bar_update(void)
                        warn("bar_update: bar_extra failed");
                        bar_extra_stop();
                }
-       } else
-               strlcpy(bar_ext, "", sizeof bar_ext);
+       } else {
+               /*
+                * Attempt to drain stdin, so it doesn't cause the main loop to
+                * call us as fast as it can.
+                */
+               fgetln(stdin, &len);
 
-       bar_fmt_print();
-       alarm(bar_delay);
-}
+               if (!bar_enabled)
+                       return;
 
-void
-bar_signal(int sig)
-{
-       /* suppress unused warning since var is needed */
-       (void)sig;
+               bar_ext[0] = '\0';
+       }
 
-       bar_alarm = 1;
+       bar_fmt_print();
 }
 
 void
@@ -2291,10 +2286,15 @@ bar_refresh(void)
                        err(1, "pipe error");
                socket_setnonblock(bar_pipe[0]);
                socket_setnonblock(bar_pipe[1]); /* XXX hmmm, really? */
+
+               /* Set stdin to read from the pipe. */
                if (dup2(bar_pipe[0], 0) == -1)
                        err(1, "dup2");
+
+               /* Set stdout to write to the pipe. */
                if (dup2(bar_pipe[1], 1) == -1)
                        err(1, "dup2");
+
                if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
                        err(1, "could not disable SIGPIPE");
                switch (bar_pid = fork()) {
@@ -2322,7 +2322,9 @@ bar_refresh(void)
                        xcb_change_window_attributes(conn, r->bar->id,
                            XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa);
                }
+
        bar_update();
+       xcb_flush(conn);
 }
 
 int
@@ -2488,8 +2490,6 @@ bar_setup(struct swm_region *r)
            "%d x %d\n", WINID(r->bar), X(r->bar), Y(r->bar), WIDTH(r->bar),
            HEIGHT(r->bar));
 
-       if (signal(SIGALRM, bar_signal) == SIG_ERR)
-               err(1, "could not install bar_signal");
        bar_refresh();
 }
 
@@ -6489,7 +6489,7 @@ setconfvalue(char *selector, char *value, int flags)
                        bar_border_width = 0;
                break;
        case SWM_S_BAR_DELAY:
-               bar_delay = atoi(value);
+               /* No longer needed; leave to not break old conf files. */
                break;
        case SWM_S_BAR_ENABLED:
                bar_enabled = atoi(value);
@@ -8838,6 +8838,9 @@ main(int argc, char *argv[])
        xcb_generic_event_t     *evt;
        struct timeval          tv;
        fd_set                  rd;
+       int                     rd_max;
+       int                     do_bar_update = 0;
+       int                     num_readable;
 
        /* suppress unused warning since var is needed */
        (void)argc;
@@ -8968,6 +8971,8 @@ noconfig:
        xcb_ungrab_server(conn);
        xcb_flush(conn);
 
+       rd_max = xfd > STDIN_FILENO ? xfd : STDIN_FILENO;
+
        while (running) {
                while ((evt = xcb_poll_for_event(conn))) {
                        if (!running)
@@ -8992,21 +8997,27 @@ noconfig:
                }
 
                FD_ZERO(&rd);
+               FD_SET(STDIN_FILENO, &rd);
                FD_SET(xfd, &rd);
                tv.tv_sec = 1;
                tv.tv_usec = 0;
-               if (select(xfd + 1, &rd, NULL, NULL, &tv) == -1)
-                       if (errno != EINTR) {
-                               DNPRINTF(SWM_D_MISC, "select failed");
-                       }
+               num_readable = select(rd_max + 1, &rd, NULL, NULL, &tv);
+               if (num_readable == -1 && errno != EINTR)
+                       DNPRINTF(SWM_D_MISC, "select failed");
+               else if (num_readable > 0 && FD_ISSET(STDIN_FILENO, &rd))
+                       do_bar_update = 1;
+
                if (restart_wm)
                        restart(NULL, NULL);
+
                if (search_resp)
                        search_do_resp();
+
                if (!running)
                        goto done;
-               if (bar_alarm) {
-                       bar_alarm = 0;
+
+               if (do_bar_update) {
+                       do_bar_update = 0;
                        bar_update();
                }
        }
index f56559a..576e374 100644 (file)
@@ -25,7 +25,6 @@
 # bar_font_color[1]    = rgb:a0/a0/a0
 # bar_font             = -*-terminus-medium-*-*-*-*-*-*-*-*-*-*-*
 # bar_action           = baraction.sh
-# bar_delay            = 1
 # bar_justify          = left
 # bar_format           = +N:+I +S <+D>+4<%a %b %d %R %Z %Y+8<+A+4<+V
 # bar_at_bottom                = 1
index 0645e60..90010a6 100644 (file)
@@ -105,9 +105,6 @@ Fuente de la barra de estado.
 .It Cm bar_action
 Scripts externos con populares agregados de información para la barra
 de estado, como la vida de la bateria.
-.It Cm bar_delay
-Frecuencia de actualización, en segundos, de los scripts de la barra de
-estado.
 .It Cm bar_at_bottom
 Puedes posicionar la statusbar en la parte inferior de la pantalla.
 .It Cm stack_enabled
index 09d7356..ef85d43 100644 (file)
@@ -105,9 +105,6 @@ Font della barra di stato.
 .It Cm bar_action
 Script esterno che aggiunge informazioni come la carica della batteria alla
 barra di stato.
-.It Cm bar_delay
-Frequenza di aggiornamento, in secondi, dello script esterno che aggiunge
-informazioni alla barra di stato.
 .It Cm bar_at_bottom
 Posiziona la barra di stato sul fondo dello schermo anzich? in cima.
 .It Cm stack_enabled
index 3249901..b2835ef 100644 (file)
@@ -98,9 +98,6 @@ Fonte da barra de status.
 .It Cm bar_action
 Script externo que preenche a barra de status com informa\(,c\(~oes adicionais,
 como tempo de vida da bateria.
-.It Cm bar_delay
-Freq\(:u\(^encia da atualiza\(,c\(~ao, em segundos, do script externo que preenche
-a barra de status.
 .It Cm bar_at_bottom
 Coloca a barra de status na parte inferior de cada regi\(~ao, ao inv\('es da parte superior.
 .It Cm stack_enabled
index c65a21b..4c3c5d9 100644 (file)
@@ -96,8 +96,6 @@ Shift
 .It Cm bar_action
 Внешний файл скрипта для статусной строки, выводящий туда информацию,
 например, уровень заряда батарей.
-.It Cm bar_delay
-Частота выполнения внешнего скрипта статусной строки, секунды.
 .It Cm stack_enabled
 Включить отображение способа укладки окон в статусной строке.
 .It Cm clock_enabled