]> code.delx.au - spectrwm/blobdiff - spectrwm.c
WIP: Treat maximized/fullscreen differently to floating
[spectrwm] / spectrwm.c
index 5a278d11d6562cb679180574b9d9771276dcce71..fc09084101146679f0fa2888c7ee2bc6f8469013 100644 (file)
@@ -248,7 +248,8 @@ uint32_t            swm_debug = 0
 #define MAXIMIZED(w)           (MAXIMIZED_VERT(w) || MAXIMIZED_HORZ(w))
 #define MANUAL(w)              ((w)->ewmh_flags & SWM_F_MANUAL)
 #define TRANS(w)               ((w)->transient != XCB_WINDOW_NONE)
-#define FLOATING(w)            (ABOVE(w) || TRANS(w) || FULLSCREEN(w) ||      \
+#define FLOATING(w)            (ABOVE(w) || TRANS(w))
+#define FLOATINGFULLMAX(w)     (ABOVE(w) || TRANS(w) || FULLSCREEN(w) ||      \
     MAXIMIZED(w))
 
 /* Constrain Window flags */
@@ -999,10 +1000,12 @@ void      bar_toggle(struct binding *, struct swm_region *, union arg *);
 void    bar_urgent(char *, size_t);
 void    bar_window_class(char *, size_t, struct swm_region *);
 void    bar_window_class_instance(char *, size_t, struct swm_region *);
+void    bar_window_index_count(char *, size_t, struct swm_region *);
 void    bar_window_instance(char *, size_t, struct swm_region *);
 void    bar_window_name(char *, size_t, struct swm_region *);
 void    bar_window_state(char *, size_t, struct swm_region *);
 void    bar_workspace_name(char *, size_t, struct swm_region *);
+void    bar_workspace_state(char *, size_t, struct swm_region *);
 int     binding_cmp(struct binding *, struct binding *);
 void    binding_insert(uint16_t, enum binding_type, uint32_t, enum actionid,
             uint32_t, const char *);
@@ -2430,6 +2433,30 @@ bar_window_class_instance(char *s, size_t sz, struct swm_region *r)
        bar_window_instance(s, sz, r);
 }
 
+void
+bar_window_index_count(char *s, size_t sz, struct swm_region *r)
+{
+       struct ws_win           *w;
+       int                     count, index;
+
+       if (r == NULL || r->ws == NULL || r->ws->focus == NULL) {
+               strlcat(s, "0/0", sz);
+               return;
+       }
+
+       count = 0;
+       index = 0;
+
+       TAILQ_FOREACH(w, &r->ws->winlist, entry) {
+               ++count;
+               if (w->id == r->ws->focus->id) {
+                       index = count;
+               }
+       }
+
+       snprintf(s, sz, "%d/%d", index, count);
+}
+
 void
 bar_window_state(char *s, size_t sz, struct swm_region *r)
 {
@@ -2509,6 +2536,44 @@ bar_workspace_name(char *s, size_t sz, struct swm_region *r)
                strlcat(s, r->ws->name, sz);
 }
 
+void
+bar_workspace_state(char *s, size_t sz, struct swm_region *r)
+{
+       struct ws_win           *win;
+       int                     i, j, num_screens;
+       bool                    used_workspaces[SWM_WS_MAX];
+       char                    tmp[8];
+       int                     first = 1;
+       char                    *fmt;
+
+       if (r == NULL || r->ws == NULL)
+               return;
+
+       for (i = 0; i < SWM_WS_MAX; ++i)
+               used_workspaces[i] = false;
+
+       num_screens = get_screen_count();
+       for (i = 0; i < num_screens; i++)
+               for (j = 0; j < workspace_limit; j++)
+                       TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry)
+                               ++used_workspaces[win->ws->idx];
+
+       for (i = 0; i < SWM_WS_MAX; ++i) {
+               fmt = NULL;
+               if (i == r->ws->idx) {
+                       fmt = " [%d]";
+               } else if (used_workspaces[i]) {
+                       fmt = " %d";
+               }
+               if (fmt) {
+                       fmt = fmt + first;
+                       first = 0;
+                       snprintf(tmp, sizeof tmp, fmt, i + 1);
+                       strlcat(s, tmp, sz);
+               }
+       }
+}
+
 /* build the default bar format according to the defined enabled options */
 void
 bar_fmt(const char *fmtexp, char *fmtnew, struct swm_region *r, size_t sz)
@@ -2631,6 +2696,9 @@ 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 'i':
+               bar_workspace_state(tmp, sizeof tmp, r);
+               break;
        case 'M':
                count = 0;
                TAILQ_FOREACH(w, &r->ws->winlist, entry)
@@ -2642,6 +2710,9 @@ bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep,
        case 'N':
                snprintf(tmp, sizeof tmp, "%d", r->s->idx + 1);
                break;
+       case 'p':
+               bar_window_index_count(tmp, sizeof tmp, r);
+               break;
        case 'P':
                bar_window_class_instance(tmp, sizeof tmp, r);
                break;
@@ -3287,13 +3358,13 @@ config_win(struct ws_win *win, xcb_configure_request_event_t *ev)
 }
 
 int
-count_win(struct workspace *ws, bool count_transient)
+count_win(struct workspace *ws, bool count_floating)
 {
        struct ws_win           *win;
        int                     count = 0;
 
        TAILQ_FOREACH(win, &ws->winlist, entry) {
-               if (!count_transient && FLOATING(win))
+               if (!count_floating && FLOATING(win))
                        continue;
                if (ICONIC(win))
                        continue;
@@ -3438,11 +3509,11 @@ raise_window(struct ws_win *win)
 void
 update_win_stacking(struct ws_win *win)
 {
-       struct ws_win           *sibling;
 #ifdef SWM_DEBUG
        struct ws_win           *w;
 #endif
        struct swm_region       *r;
+       uint16_t                configure_mask;
        uint32_t                val[2];
 
        if (win == NULL || (r = win->ws->r) == NULL)
@@ -3454,25 +3525,25 @@ update_win_stacking(struct ws_win *win)
                return;
        }
 
-       sibling = TAILQ_NEXT(win, stack_entry);
-       if (sibling != NULL && (FLOATING(win) == FLOATING(sibling) ||
-           (win->ws->always_raise && win->ws->focus == win))) {
-               val[0] = sibling->frame;
-               val[1] = XCB_STACK_MODE_ABOVE;
-       } else if (FLOATING(win) || (win->ws->always_raise &&
+        if (FLOATINGFULLMAX(win) || (win->ws->always_raise &&
            win->ws->focus == win)) {
-               val[0] = r->bar->id;
-               val[1] = XCB_STACK_MODE_ABOVE;
+               configure_mask = XCB_CONFIG_WINDOW_STACK_MODE;
+               val[0] = XCB_STACK_MODE_ABOVE;
+               val[1] = 0;
+
+               DNPRINTF(SWM_D_EVENT, "update_win_stacking: to very top "
+                   "win %#x (%#x), ", win->frame, win->id);
        } else {
+               configure_mask = XCB_CONFIG_WINDOW_STACK_MODE |
+                       XCB_CONFIG_WINDOW_SIBLING;
                val[0] = r->bar->id;
                val[1] = XCB_STACK_MODE_BELOW;
-       }
 
-       DNPRINTF(SWM_D_EVENT, "update_win_stacking: win %#x (%#x), "
-           "sibling %#x mode %#x\n", win->frame, win->id, val[0], val[1]);
+               DNPRINTF(SWM_D_EVENT, "update_win_stacking: to tile top "
+                   "win %#x (%#x), ", win->frame, win->id);
+       }
 
-       xcb_configure_window(conn, win->frame, XCB_CONFIG_WINDOW_SIBLING |
-           XCB_CONFIG_WINDOW_STACK_MODE, val);
+       xcb_configure_window(conn, win->frame, configure_mask, val);
 
 #ifdef SWM_DEBUG
        TAILQ_FOREACH(w, &win->ws->winlist, entry)
@@ -5292,7 +5363,7 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, bool flip)
                if (ICONIC(win))
                        continue;
 
-               if (FLOATING(win)) {
+               if (FLOATINGFULLMAX(win)) {
                        update_floater(win);
                        continue;
                }
@@ -5530,15 +5601,13 @@ max_stack(struct workspace *ws, struct swm_geometry *g)
 {
        struct swm_geometry     gg = *g;
        struct ws_win           *w, *win = NULL, *parent = NULL, *tmpw;
-       int                     winno;
 
        DNPRINTF(SWM_D_STACK, "max_stack: workspace: %d\n", ws->idx);
 
        if (ws == NULL)
                return;
 
-       winno = count_win(ws, false);
-       if (winno == 0 && count_win(ws, true) == 0)
+       if (count_win(ws, true) == 0)
                return;
 
        /* Figure out which top level window should be visible. */
@@ -9681,6 +9750,10 @@ conf_load(const char *filename, int keymapping)
                            configopt[optidx].optname);
                        continue;
                }
+               /* trim trailing spaces */
+               ce = optval + strlen(optval) - 1;
+               while (ce > optval && isspace(*ce)) --ce;
+               *(ce + 1) = '\0';
                /* call function to deal with it all */
                if (configopt[optidx].func(optsub, optval,
                    configopt[optidx].funcflags) != 0) {