SWM_S_COLOR_BAR_BORDER_UNFOCUS,
SWM_S_COLOR_BAR_FONT,
SWM_S_COLOR_FOCUS,
+ SWM_S_COLOR_FOCUS_MAXIMIZED,
SWM_S_COLOR_UNFOCUS,
+ SWM_S_COLOR_UNFOCUS_MAXIMIZED,
SWM_S_COLOR_MAX
};
struct {
uint32_t pixel;
char *name;
+ int manual;
} c[SWM_S_COLOR_MAX];
xcb_gcontext_t bar_gc;
#define SWM_ARG_ID_MOVEDOWN (101)
#define SWM_ARG_ID_MOVELEFT (102)
#define SWM_ARG_ID_MOVERIGHT (103)
+#define SWM_ARG_ID_RAISE (105)
+#define SWM_ARG_ID_LOWER (106)
#define SWM_ARG_ID_BAR_TOGGLE (110)
#define SWM_ARG_ID_BAR_TOGGLE_WS (111)
char **argv;
void update_modkey(unsigned int);
void update_win_stacking(struct ws_win *);
void update_window(struct ws_win *);
+void update_window_color(struct ws_win *);
void update_wm_state(struct ws_win *win);
void validate_spawns(void);
int validate_win(struct ws_win *);
ws->focus_pending = win;
}
}
+
+ update_window_color(win);
raise_window(win);
}
continue;
if (ws->cur_layout == &layouts[SWM_MAX_STACK])
break;
+ if (TRANS(win) && (win->transient == target->transient ||
+ win->transient == target->id))
+ break;
if (FULLSCREEN(win))
break;
if (FULLSCREEN(target))
update_win_stacking(win);
}
+#ifdef SWM_DEBUG
+ if (swm_debug & SWM_D_STACK) {
+ DPRINTF("=== stacking order (top down) === \n");
+ TAILQ_FOREACH(target, &r->ws->stack, stack_entry) {
+ DPRINTF("win %#x, fs: %s, maximized: %s, above: %s, "
+ "iconic: %s\n", target->id, YESNO(FULLSCREEN(target)),
+ YESNO(MAXIMIZED(target)), YESNO(ABOVE(target)),
+ YESNO(ICONIC(target)));
+ }
+ }
+#endif
DNPRINTF(SWM_D_EVENT, "raise_window: done\n");
}
win->ws->focus_prev = NULL;
}
- xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL,
- &win->s->c[SWM_S_COLOR_UNFOCUS].pixel);
+ update_window_color(win);
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, &none);
DNPRINTF(SWM_D_FOCUS, "focus_win: win %#x\n", WINID(win));
- if (win == NULL)
- goto out;
-
- if (win->ws == NULL)
- goto out;
-
- if (!win->mapped)
+ if (win == NULL || win->ws == NULL || !win->mapped)
goto out;
ws = win->ws;
/* Change border to unfocused color. */
xcb_change_window_attributes(conn, cfw->id,
XCB_CW_BORDER_PIXEL,
- &cfw->s->c[SWM_S_COLOR_UNFOCUS].pixel);
+ &cfw->s->c[(MAXIMIZED(cfw) ?
+ SWM_S_COLOR_UNFOCUS_MAXIMIZED :
+ SWM_S_COLOR_UNFOCUS)].pixel);
} else {
unfocus_win(cfw);
}
client_msg(win, a_takefocus, last_event_time);
}
- xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL,
- &win->s->c[SWM_S_COLOR_FOCUS].pixel);
-
if (ws->cur_layout->flags & SWM_L_MAPONFOCUS ||
ws->always_raise) {
/* If a parent exists, map it first. */
set_region(ws->r);
+ update_window_color(win);
+
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1,
&win->id);
return;
if ((win = old_ws->focus) != NULL) {
- xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL,
- &win->s->c[SWM_S_COLOR_UNFOCUS].pixel);
+ update_window_color(win);
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1,
union arg a;
struct swm_screen *s = r->s;
int cycle_all = 0;
- int move = 0;
+ int mv = 0;
DNPRINTF(SWM_D_WS, "cyclews: id: %d, screen[%d]:%dx%d+%d+%d, ws: %d\n",
args->id, r->s->idx, WIDTH(r), HEIGHT(r), X(r), Y(r), r->ws->idx);
do {
switch (args->id) {
case SWM_ARG_ID_CYCLEWS_MOVE_UP:
- move = 1;
+ mv = 1;
/* FALLTHROUGH */
case SWM_ARG_ID_CYCLEWS_UP_ALL:
cycle_all = 1;
a.id = (a.id < workspace_limit - 1) ? a.id + 1 : 0;
break;
case SWM_ARG_ID_CYCLEWS_MOVE_DOWN:
- move = 1;
+ mv = 1;
/* FALLTHROUGH */
case SWM_ARG_ID_CYCLEWS_DOWN_ALL:
cycle_all = 1;
if (!cycle_visible && s->ws[a.id].r != NULL)
continue;
- if (move)
+ if (mv)
send_to_ws(r, &a);
switchws(r, &a);
args->id, r->s->idx, WIDTH(r), HEIGHT(r), X(r), Y(r), r->ws->idx);
cur_focus = r->ws->focus;
- if (cur_focus == NULL || ABOVE(cur_focus) || FULLSCREEN(cur_focus))
+ if (cur_focus == NULL || FULLSCREEN(cur_focus))
return;
+ /* Adjust stacking in floating layer. */
+ if (ABOVE(cur_focus)) {
+ switch (args->id) {
+ case SWM_ARG_ID_SWAPPREV:
+ target = TAILQ_PREV(cur_focus, ws_win_stack,
+ stack_entry);
+ if (target != NULL && FLOATING(target)) {
+ TAILQ_REMOVE(&cur_focus->ws->stack, cur_focus,
+ stack_entry);
+ TAILQ_INSERT_BEFORE(target, cur_focus,
+ stack_entry);
+ update_win_stacking(cur_focus);
+ focus_flush();
+ }
+ break;
+ case SWM_ARG_ID_SWAPNEXT:
+ target = TAILQ_NEXT(cur_focus, stack_entry);
+ if (target != NULL && FLOATING(target)) {
+ TAILQ_REMOVE(&cur_focus->ws->stack, cur_focus,
+ stack_entry);
+ TAILQ_INSERT_AFTER(&cur_focus->ws->stack,
+ target, cur_focus, stack_entry);
+ update_win_stacking(cur_focus);
+ focus_flush();
+ }
+ break;
+ }
+ goto out;
+ }
+
if (r->ws->cur_layout == &layouts[SWM_MAX_STACK])
return;
}
sort_windows(wl);
-
ewmh_update_client_list();
stack();
-
focus_flush();
+out:
+ DNPRINTF(SWM_D_MOVE, "swapwin: done\n");
}
struct ws_win *
++len;
}
- if((name_list = calloc(sizeof(char *), len)) == NULL)
+ if((name_list = calloc(len, sizeof(char))) == NULL)
err(1, "update_desktop_names: calloc: failed to "
"allocate memory.");
if (count == 0)
continue;
- wins = calloc(sizeof(xcb_window_t), count);
+ wins = calloc(count, sizeof(xcb_window_t));
if (wins == NULL)
err(1, "ewmh_update_client_list: calloc: failed to "
"allocate memory.");
int num_screens, i, j;
uint32_t *vals;
- vals = calloc(sizeof(uint32_t), workspace_limit * 2);
+ vals = calloc(workspace_limit * 2, sizeof(uint32_t));
if (vals == NULL)
err(1, "ewmh_update_desktops: calloc: failed to allocate "
"memory.");
}
void
+update_window_color(struct ws_win *win)
+{
+ uint32_t *pixel;
+
+ if (WS_FOCUSED(win->ws) && win->ws->focus == win)
+ pixel = MAXIMIZED(win) ?
+ &win->s->c[SWM_S_COLOR_FOCUS_MAXIMIZED].pixel :
+ &win->s->c[SWM_S_COLOR_FOCUS].pixel;
+ else
+ pixel = MAXIMIZED(win) ?
+ &win->s->c[SWM_S_COLOR_UNFOCUS_MAXIMIZED].pixel :
+ &win->s->c[SWM_S_COLOR_UNFOCUS].pixel;
+
+ xcb_change_window_attributes(conn, win->id,
+ XCB_CW_BORDER_PIXEL, pixel);
+}
+
+void
update_window(struct ws_win *win)
{
uint16_t mask;
xcb_flush(conn);
}
break;
+ case XCB_KEY_PRESS:
+ /* Ignore. */
+ xcb_allow_events(conn, XCB_ALLOW_ASYNC_KEYBOARD,
+ ((xcb_key_press_event_t *)evt)->time);
+ xcb_flush(conn);
+ break;
default:
event_handle(evt);
xcb_flush(conn);
}
break;
+ case XCB_KEY_PRESS:
+ /* Ignore. */
+ xcb_allow_events(conn, XCB_ALLOW_ASYNC_KEYBOARD,
+ ((xcb_key_press_event_t *)evt)->time);
+ xcb_flush(conn);
+ break;
default:
event_handle(evt);
strdup(r->s->c[SWM_S_COLOR_FOCUS].name))
== NULL)
err(1, "spawn_custom color focus");
+ } else if (strcasecmp(ap, "$color_focus_maximized") == 0) {
+ if ((real_args[c] =
+ strdup(r->s->c[SWM_S_COLOR_FOCUS_MAXIMIZED].name))
+ == NULL)
+ err(1, "spawn_custom color focus maximized");
} else if (strcasecmp(ap, "$color_unfocus") == 0) {
if ((real_args[c] =
strdup(r->s->c[SWM_S_COLOR_UNFOCUS].name))
== NULL)
err(1, "spawn_custom color unfocus");
+ } else if (strcasecmp(ap, "$color_unfocus_maximized") == 0) {
+ if ((real_args[c] =
+ strdup(r->s->c[SWM_S_COLOR_UNFOCUS_MAXIMIZED].name))
+ == NULL)
+ err(1, "spawn_custom color unfocus maximized");
} else if (strcasecmp(ap, "$region_index") == 0) {
if (asprintf(&real_args[c], "%d",
get_region_index(r) + 1) < 1)
spawn_insert(const char *name, const char *args, int flags)
{
struct spawn_prog *sp;
- char *arg, *dup, *ptr;
+ char *arg, *cp, *ptr;
DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s[%s]\n", name, args);
err(1, "spawn_insert: strdup");
/* Convert the arguments to an argument list. */
- if ((ptr = dup = strdup(args)) == NULL)
+ if ((ptr = cp = strdup(args)) == NULL)
err(1, "spawn_insert: strdup");
while ((arg = argsep(&ptr)) != NULL) {
/* Null argument; skip it. */
if ((sp->argv[sp->argc - 1] = strdup(arg)) == NULL)
err(1, "spawn_insert: strdup");
}
- free(dup);
+ free(cp);
sp->flags = flags;
int
setconfcolor(const char *selector, const char *value, int flags)
{
- setscreencolor(value,
- (selector == NULL || strlen(selector) == 0) ? -1 : atoi(selector),
- flags);
+ int sid, i, num_screens;
+
+ sid = (selector == NULL || strlen(selector) == 0) ? -1 : atoi(selector);
+
+ /*
+ * When setting focus/unfocus colors, we need to also
+ * set maximize colors to match if they haven't been customized.
+ */
+ i = sid < 0 ? 0 : sid;
+ if (flags == SWM_S_COLOR_FOCUS &&
+ !screens[i].c[SWM_S_COLOR_FOCUS_MAXIMIZED].manual)
+ setscreencolor(value, sid, SWM_S_COLOR_FOCUS_MAXIMIZED);
+ else if (flags == SWM_S_COLOR_UNFOCUS &&
+ !screens[i].c[SWM_S_COLOR_UNFOCUS_MAXIMIZED].manual)
+ setscreencolor(value, sid, SWM_S_COLOR_UNFOCUS_MAXIMIZED);
+
+ setscreencolor(value, sid, flags);
+
+ /* Track override of color. */
+ num_screens = get_screen_count();
+ if (sid > 0 && sid <= num_screens) {
+ screens[i].c[flags].manual = 1;
+ } else if (sid == -1) {
+ for (i = 0; i < num_screens; ++i)
+ screens[i].c[flags].manual = 1;
+ } else {
+ errx(1, "invalid screen index: %d out of bounds (maximum %d)",
+ sid, num_screens);
+ }
+
return (0);
}
{ "clock_enabled", setconfvalue, SWM_S_CLOCK_ENABLED },
{ "clock_format", setconfvalue, SWM_S_CLOCK_FORMAT },
{ "color_focus", setconfcolor, SWM_S_COLOR_FOCUS },
+ { "color_focus_maximized", setconfcolor, SWM_S_COLOR_FOCUS_MAXIMIZED },
{ "color_unfocus", setconfcolor, SWM_S_COLOR_UNFOCUS },
+ { "color_unfocus_maximized", setconfcolor, SWM_S_COLOR_UNFOCUS_MAXIMIZED },
{ "cycle_empty", setconfvalue, SWM_S_CYCLE_EMPTY },
{ "cycle_visible", setconfvalue, SWM_S_CYCLE_VISIBLE },
{ "dialog_ratio", setconfvalue, SWM_S_DIALOG_RATIO },
win->g_floatvalid = 1;
- if (ABOVE(win) && r && !MAXIMIZED(win) && (TRANS(win) ||
- win->ws->cur_layout != &layouts[SWM_MAX_STACK])) {
+ if (!MAXIMIZED(win) && !FULLSCREEN(win) &&
+ (TRANS(win) || (ABOVE(win) &&
+ win->ws->cur_layout != &layouts[SWM_MAX_STACK]))) {
WIDTH(win) = win->g_float.w;
HEIGHT(win) = win->g_float.h;
- if (r) {
+ if (r != NULL) {
update_floater(win);
focus_flush();
+ } else {
+ config_win(win, e);
+ xcb_flush(conn);
}
} else {
config_win(win, e);
SWM_S_COLOR_BAR_BORDER_UNFOCUS);
setscreencolor("black", i + 1, SWM_S_COLOR_BAR);
setscreencolor("rgb:a0/a0/a0", i + 1, SWM_S_COLOR_BAR_FONT);
+ setscreencolor("red", i + 1, SWM_S_COLOR_FOCUS_MAXIMIZED);
+ setscreencolor("rgb:88/88/88", i + 1, SWM_S_COLOR_UNFOCUS_MAXIMIZED);
/* create graphics context on screen */
screens[i].bar_gc = xcb_generate_id(conn);