#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 */
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 *);
}
if (changed & EWMH_F_ABOVE) {
- if (ws->cur_layout != &layouts[SWM_MAX_STACK]) {
- if (ABOVE(win))
- load_float_geom(win);
- else if (!MAXIMIZED(win))
- store_float_geom(win);
+ if (ABOVE(win))
+ load_float_geom(win);
+ else if (!MAXIMIZED(win))
+ store_float_geom(win);
- win->ewmh_flags &= ~EWMH_F_MAXIMIZED;
- changed &= ~EWMH_F_MAXIMIZED;
- raise_window(win);
- } else {
- /* Revert. */
- win->ewmh_flags ^= EWMH_F_ABOVE & pending;
- }
+ win->ewmh_flags &= ~EWMH_F_MAXIMIZED;
+ changed &= ~EWMH_F_MAXIMIZED;
+ raise_window(win);
}
if (changed & EWMH_F_MAXIMIZED) {
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)
{
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)
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)
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;
}
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;
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)
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)
goto out;
}
- if (r->ws->cur_layout == &layouts[SWM_MAX_STACK])
- return;
-
clear_maximized(r->ws);
source = cur_focus;
if (ICONIC(win))
continue;
- if (FLOATING(win)) {
+ if (FLOATINGFULLMAX(win)) {
update_floater(win);
continue;
}
{
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. */
if (ICONIC(w))
continue;
- if (TRANS(w)) {
+ if (TRANS(w) || ABOVE(w)) {
update_floater(w);
continue;
}
if (FULLSCREEN(win))
return;
- /* In max_stack mode, should only resize transients. */
- if (win->ws->cur_layout == &layouts[SWM_MAX_STACK] && !TRANS(win))
+ /* In max_stack mode, should only resize transients/floating. */
+ if (win->ws->cur_layout == &layouts[SWM_MAX_STACK] && !TRANS(win) && !ABOVE(win))
return;
DNPRINTF(SWM_D_EVENT, "resize: win %#x, floating: %s, "
DNPRINTF(SWM_D_EVENT, "move: win %#x, floating: %s, transient: "
"%#x\n", win->id, YESNO(ABOVE(win)), win->transient);
- /* in max_stack mode should only move transients */
- if (win->ws->cur_layout == &layouts[SWM_MAX_STACK] && !TRANS(win))
- return;
-
if (!(ABOVE(win) || TRANS(win)) || MAXIMIZED(win)) {
store_float_geom(win);
restack = true;
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) {