JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Fix segfault when X keyboard map does not include Num_Lock.
[spectrwm.git] / spectrwm.c
index 41bd6d4..00972db 100644 (file)
@@ -373,6 +373,7 @@ int          bar_justify = SWM_BAR_JUSTIFY_LEFT;
 char            *bar_format = NULL;
 int             stack_enabled = 1;
 int             clock_enabled = 1;
+int             iconic_enabled = 0;
 int             urgent_enabled = 0;
 char           *clock_format = NULL;
 int             window_class_enabled = 0;
@@ -2077,6 +2078,8 @@ bar_workspace_name(char *s, size_t sz, struct swm_region *r)
 void
 bar_fmt(const char *fmtexp, char *fmtnew, struct swm_region *r, size_t sz)
 {
+       struct ws_win           *w;
+
        /* if format provided, just copy the buffers */
        if (bar_format != NULL) {
                strlcpy(fmtnew, fmtexp, sz);
@@ -2094,6 +2097,15 @@ bar_fmt(const char *fmtexp, char *fmtnew, struct swm_region *r, size_t sz)
        /* only show the workspace name if there's actually one */
        if (r != NULL && r->ws != NULL && r->ws->name != NULL)
                strlcat(fmtnew, "<+D>", sz);
+
+       /* If enabled, only show the iconic count if there are iconic wins. */
+       if (iconic_enabled && r != NULL && r->ws != NULL)
+               TAILQ_FOREACH(w, &r->ws->winlist, entry)
+                       if (w->iconic) {
+                               strlcat(fmtnew, "{+M}", sz);
+                               break;
+                       }
+
        strlcat(fmtnew, "+3<", sz);
 
        if (clock_enabled) {
@@ -2143,9 +2155,10 @@ char *
 bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep,
     size_t sz)
 {
+       struct ws_win           *w;
        char                    *ptr;
        char                    tmp[SWM_BAR_MAX];
-       int                     limit, size;
+       int                     limit, size, count;
        size_t                  len;
 
        /* reset strlcat(3) buffer */
@@ -2183,6 +2196,14 @@ bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep,
        case 'I':
                snprintf(tmp, sizeof tmp, "%d", r->ws->idx + 1);
                break;
+       case 'M':
+               count = 0;
+               TAILQ_FOREACH(w, &r->ws->winlist, entry)
+                       if (w->iconic)
+                               ++count;
+
+               snprintf(tmp, sizeof tmp, "%d", count);
+               break;
        case 'N':
                snprintf(tmp, sizeof tmp, "%d", r->s->idx + 1);
                break;
@@ -6797,9 +6818,11 @@ updatenumlockmask(void)
                                    + j];
                                keycode = xcb_key_symbols_get_keycode(syms,
                                                XK_Num_Lock);
-                               if (kc == *keycode)
-                                       numlockmask = (1 << i);
-                               free(keycode);
+                               if (keycode) {
+                                       if (kc == *keycode)
+                                               numlockmask = (1 << i);
+                                       free(keycode);
+                               }
                        }
                }
                free(modmap_r);
@@ -7138,19 +7161,19 @@ setconfquirk(const char *selector, const char *value, int flags)
 void
 setup_quirks(void)
 {
-       setquirk("MPlayer",             "xv",           "",     SWM_Q_FLOAT | SWM_Q_FULLSCREEN | SWM_Q_FOCUSPREV);
-       setquirk("OpenOffice.org 3.2",  "VCLSalFrame",  "",     SWM_Q_FLOAT);
-       setquirk("Firefox-bin",         "firefox-bin",  "",     SWM_Q_TRANSSZ);
-       setquirk("Firefox",             "Dialog",       "",     SWM_Q_FLOAT);
-       setquirk("Gimp",                "gimp",         "",     SWM_Q_FLOAT | SWM_Q_ANYWHERE);
-       setquirk("XTerm",               "xterm",        "",     SWM_Q_XTERM_FONTADJ);
-       setquirk("xine",                "Xine Window",  "",     SWM_Q_FLOAT | SWM_Q_ANYWHERE);
-       setquirk("Xitk",                "Xitk Combo",   "",     SWM_Q_FLOAT | SWM_Q_ANYWHERE);
-       setquirk("xine",                "xine Panel",   "",     SWM_Q_FLOAT | SWM_Q_ANYWHERE);
-       setquirk("Xitk",                "Xine Window",  "",     SWM_Q_FLOAT | SWM_Q_ANYWHERE);
-       setquirk("xine",                "xine Video Fullscreen Window", "",     SWM_Q_FULLSCREEN | SWM_Q_FLOAT);
-       setquirk("pcb",                 "pcb",          "",     SWM_Q_FLOAT);
-       setquirk("SDL_App",             "SDL_App",      "",     SWM_Q_FLOAT | SWM_Q_FULLSCREEN);
+       setquirk("MPlayer",             "xv",           ".*",   SWM_Q_FLOAT | SWM_Q_FULLSCREEN | SWM_Q_FOCUSPREV);
+       setquirk("OpenOffice.org 3.2",  "VCLSalFrame",  ".*",   SWM_Q_FLOAT);
+       setquirk("Firefox-bin",         "firefox-bin",  ".*",   SWM_Q_TRANSSZ);
+       setquirk("Firefox",             "Dialog",       ".*",   SWM_Q_FLOAT);
+       setquirk("Gimp",                "gimp",         ".*",   SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+       setquirk("XTerm",               "xterm",        ".*",   SWM_Q_XTERM_FONTADJ);
+       setquirk("xine",                "Xine Window",  ".*",   SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+       setquirk("Xitk",                "Xitk Combo",   ".*",   SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+       setquirk("xine",                "xine Panel",   ".*",   SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+       setquirk("Xitk",                "Xine Window",  ".*",   SWM_Q_FLOAT | SWM_Q_ANYWHERE);
+       setquirk("xine",                "xine Video Fullscreen Window", ".*",   SWM_Q_FULLSCREEN | SWM_Q_FLOAT);
+       setquirk("pcb",                 "pcb",          ".*",   SWM_Q_FLOAT);
+       setquirk("SDL_App",             "SDL_App",      ".*",   SWM_Q_FLOAT | SWM_Q_FULLSCREEN);
 }
 
 /* conf file stuff */
@@ -7179,6 +7202,7 @@ enum {
        SWM_S_FOCUS_CLOSE_WRAP,
        SWM_S_FOCUS_DEFAULT,
        SWM_S_FOCUS_MODE,
+       SWM_S_ICONIC_ENABLED,
        SWM_S_REGION_PADDING,
        SWM_S_SPAWN_ORDER,
        SWM_S_SPAWN_TERM,
@@ -7346,6 +7370,9 @@ setconfvalue(const char *selector, const char *value, int flags)
                else
                        errx(1, "focus_mode");
                break;
+       case SWM_S_ICONIC_ENABLED:
+               iconic_enabled = atoi(value);
+               break;
        case SWM_S_REGION_PADDING:
                region_padding = atoi(value);
                if (region_padding < 0)
@@ -7649,6 +7676,7 @@ struct config_option configopt[] = {
        { "focus_close_wrap",           setconfvalue,   SWM_S_FOCUS_CLOSE_WRAP },
        { "focus_default",              setconfvalue,   SWM_S_FOCUS_DEFAULT },
        { "focus_mode",                 setconfvalue,   SWM_S_FOCUS_MODE },
+       { "iconic_enabled",             setconfvalue,   SWM_S_ICONIC_ENABLED },
        { "keyboard_mapping",           setkeymapping,  0 },
        { "layout",                     setlayout,      0 },
        { "modkey",                     setconfmodkey,  0 },
@@ -8745,10 +8773,22 @@ mapnotify(xcb_map_notify_event_t *e)
 void
 mappingnotify(xcb_mapping_notify_event_t *e)
 {
+       struct ws_win   *w;
+       int     i, j, num_screens;
+
        xcb_refresh_keyboard_mapping(syms, e);
 
-       if (e->request == XCB_MAPPING_KEYBOARD)
+       if (e->request == XCB_MAPPING_KEYBOARD) {
                grabkeys();
+
+               /* Regrab buttons on all managed windows. */
+               num_screens = get_screen_count();
+               for (i = 0; i < num_screens; i++)
+                       for (j = 0; j < workspace_limit; j++)
+                               TAILQ_FOREACH(w, &screens[i].ws[j].winlist,
+                                   entry)
+                                       grabbuttons(w);
+       }
 }
 
 void
@@ -8934,6 +8974,10 @@ propertynotify(xcb_property_notify_event_t *e)
                                focus_flush();
                        }
                } else if (e->state == XCB_PROPERTY_DELETE) {
+                       /* Reload floating geometry in case region changed. */
+                       if (win->floating)
+                               load_float_geom(win);
+
                        /* The window is no longer iconic, restack ws. */
                        if (focus_mode != SWM_FOCUS_FOLLOW)
                                ws->focus_pending = get_focus_magic(win);