Add new options to change focus behavior on window open and close.

ok marco
This commit is contained in:
Reginald Kennedy 2012-05-23 18:31:11 +08:00
parent b7d49e02ee
commit a658878aea
3 changed files with 155 additions and 19 deletions

View file

@ -134,6 +134,29 @@ This ratio is the screen size to what they will be resized.
For example, 0.6 is 60% of the physical screen size. For example, 0.6 is 60% of the physical screen size.
.It Ic disable_border .It Ic disable_border
Remove border when bar is disabled and there is only one window on the screen. Remove border when bar is disabled and there is only one window on the screen.
.It Ic focus_close
Window to put focus when the focused window is closed.
Possible values are
.Pa first ,
.Pa next ,
.Pa previous
(default) and
.Pa last .
.Pa next
and
.Pa previous
are relative to the window that is closed.
.It Ic focus_close_wrap
Whether to allow the focus to jump to the last window when the first window is
closed or vice versa.
Disable by setting to 0.
.It Ic focus_default
Window to put focus when no window has been focused.
Possible values are
.Pa first
and
.Pa last
(default).
.It Ic focus_mode .It Ic focus_mode
Using a value of Using a value of
.Pa follow_cursor .Pa follow_cursor
@ -201,6 +224,19 @@ e.g.\& screen[1]:800x1200+0+0.
To make a screen span multiple monitors, create a region big enough to cover To make a screen span multiple monitors, create a region big enough to cover
them all, e.g. screen[1]:2048x768+0+0 makes the screen span two monitors with them all, e.g. screen[1]:2048x768+0+0 makes the screen span two monitors with
1024x768 resolution sitting one next to the other. 1024x768 resolution sitting one next to the other.
.It Ic spawn_position
Position in stack to place newly spawned windows.
Possible values are
.Pa first ,
.Pa next ,
.Pa previous
and
.Pa last
(default).
.Pa next
and
.Pa previous
are relative to the focused window.
.It Ic stack_enabled .It Ic stack_enabled
Enable or disable displaying the current stacking algorithm in the status bar. Enable or disable displaying the current stacking algorithm in the status bar.
.It Ic term_width .It Ic term_width

View file

@ -253,6 +253,11 @@ enum {
SWM_SEARCH_SEARCH_WINDOW SWM_SEARCH_SEARCH_WINDOW
}; };
#define SWM_STACK_TOP (0)
#define SWM_STACK_BOTTOM (1)
#define SWM_STACK_ABOVE (2)
#define SWM_STACK_BELOW (3)
/* dialog windows */ /* dialog windows */
double dialog_ratio = 0.6; double dialog_ratio = 0.6;
/* status bar */ /* status bar */
@ -296,6 +301,10 @@ int title_name_enabled = 0;
int title_class_enabled = 0; int title_class_enabled = 0;
int window_name_enabled = 0; int window_name_enabled = 0;
int focus_mode = SWM_FOCUS_DEFAULT; int focus_mode = SWM_FOCUS_DEFAULT;
int focus_close = SWM_STACK_BELOW;
int focus_close_wrap = 1;
int focus_default = SWM_STACK_TOP;
int spawn_position = SWM_STACK_TOP;
int disable_border = 0; int disable_border = 0;
int border_width = 1; int border_width = 1;
int verbose_layout = 0; int verbose_layout = 0;
@ -2511,8 +2520,6 @@ focus_prev(struct ws_win *win)
struct ws_win_list *wl = NULL; struct ws_win_list *wl = NULL;
struct workspace *ws = NULL; struct workspace *ws = NULL;
DNPRINTF(SWM_D_FOCUS, "focus_prev: window: 0x%lx\n", WINID(win));
if (!(win && win->ws)) if (!(win && win->ws))
return; return;
@ -2520,14 +2527,15 @@ focus_prev(struct ws_win *win)
wl = &ws->winlist; wl = &ws->winlist;
cur_focus = ws->focus; cur_focus = ws->focus;
DNPRINTF(SWM_D_FOCUS, "focus_prev: window: 0x%lx, cur_focus: 0x%lx\n",
WINID(win), WINID(cur_focus));
/* pickle, just focus on whatever */ /* pickle, just focus on whatever */
if (cur_focus == NULL) { if (cur_focus == NULL) {
/* use prev_focus if valid */ /* use prev_focus if valid */
if (ws->focus_prev && ws->focus_prev != cur_focus && if (ws->focus_prev && ws->focus_prev != cur_focus &&
find_window(WINID(ws->focus_prev))) find_window(WINID(ws->focus_prev)))
winfocus = ws->focus_prev; winfocus = ws->focus_prev;
if (winfocus == NULL)
winfocus = TAILQ_FIRST(wl);
goto done; goto done;
} }
@ -2548,14 +2556,44 @@ focus_prev(struct ws_win *win)
goto done; goto done;
} }
if (cur_focus == win) DNPRINTF(SWM_D_FOCUS, "focus_prev: focus_close: %d\n", focus_close);
winfocus = TAILQ_PREV(win, ws_win_list, entry);
if (winfocus == NULL)
winfocus = TAILQ_LAST(wl, ws_win_list);
if (winfocus == NULL || winfocus == win)
winfocus = TAILQ_NEXT(cur_focus, entry);
if (winfocus == NULL || winfocus == win) {
switch (focus_close) {
case SWM_STACK_BOTTOM:
winfocus = TAILQ_FIRST(wl);
break;
case SWM_STACK_TOP:
winfocus = TAILQ_LAST(wl, ws_win_list);
break;
case SWM_STACK_ABOVE:
if ((winfocus = TAILQ_NEXT(cur_focus, entry)) == NULL) {
if (focus_close_wrap)
winfocus = TAILQ_FIRST(wl);
else
winfocus = TAILQ_PREV(cur_focus,
ws_win_list, entry);
}
break;
case SWM_STACK_BELOW:
if ((winfocus = TAILQ_PREV(cur_focus, ws_win_list,
entry)) == NULL) {
if (focus_close_wrap)
winfocus = TAILQ_LAST(wl, ws_win_list);
else
winfocus = TAILQ_NEXT(cur_focus, entry);
}
break;
}
}
done: done:
if (winfocus == NULL) {
if (focus_default == SWM_STACK_TOP)
winfocus = TAILQ_LAST(wl, ws_win_list);
else
winfocus = TAILQ_FIRST(wl);
}
focus_magic(winfocus); focus_magic(winfocus);
} }
@ -5281,11 +5319,12 @@ enum { SWM_S_BAR_DELAY, SWM_S_BAR_ENABLED, SWM_S_BAR_BORDER_WIDTH,
SWM_S_STACK_ENABLED, SWM_S_CLOCK_ENABLED, SWM_S_CLOCK_FORMAT, SWM_S_STACK_ENABLED, SWM_S_CLOCK_ENABLED, SWM_S_CLOCK_FORMAT,
SWM_S_CYCLE_EMPTY, SWM_S_CYCLE_VISIBLE, SWM_S_WORKSPACE_LIMIT, SWM_S_CYCLE_EMPTY, SWM_S_CYCLE_VISIBLE, SWM_S_WORKSPACE_LIMIT,
SWM_S_SS_ENABLED, SWM_S_TERM_WIDTH, SWM_S_TITLE_CLASS_ENABLED, SWM_S_SS_ENABLED, SWM_S_TERM_WIDTH, SWM_S_TITLE_CLASS_ENABLED,
SWM_S_TITLE_NAME_ENABLED, SWM_S_WINDOW_NAME_ENABLED, SWM_S_URGENT_ENABLED, SWM_S_TITLE_NAME_ENABLED, SWM_S_WINDOW_NAME_ENABLED,
SWM_S_FOCUS_MODE, SWM_S_DISABLE_BORDER, SWM_S_BORDER_WIDTH, SWM_S_URGENT_ENABLED, SWM_S_FOCUS_MODE, SWM_S_FOCUS_CLOSE,
SWM_S_BAR_FONT, SWM_S_BAR_ACTION, SWM_S_SPAWN_TERM, SWM_S_FOCUS_CLOSE_WRAP, SWM_S_FOCUS_DEFAULT, SWM_S_SPAWN_ORDER,
SWM_S_SS_APP, SWM_S_DIALOG_RATIO, SWM_S_BAR_AT_BOTTOM, SWM_S_DISABLE_BORDER, SWM_S_BORDER_WIDTH, SWM_S_BAR_FONT,
SWM_S_VERBOSE_LAYOUT, SWM_S_BAR_JUSTIFY SWM_S_BAR_ACTION, SWM_S_SPAWN_TERM, SWM_S_SS_APP, SWM_S_DIALOG_RATIO,
SWM_S_BAR_AT_BOTTOM, SWM_S_VERBOSE_LAYOUT, SWM_S_BAR_JUSTIFY
}; };
int int
@ -5371,6 +5410,41 @@ setconfvalue(char *selector, char *value, int flags)
else else
errx(1, "focus_mode"); errx(1, "focus_mode");
break; break;
case SWM_S_FOCUS_CLOSE:
if (!strcmp(value, "first"))
focus_close = SWM_STACK_BOTTOM;
else if (!strcmp(value, "last"))
focus_close = SWM_STACK_TOP;
else if (!strcmp(value, "next"))
focus_close = SWM_STACK_ABOVE;
else if (!strcmp(value, "previous"))
focus_close = SWM_STACK_BELOW;
else
errx(1, "focus_close");
break;
case SWM_S_FOCUS_CLOSE_WRAP:
focus_close_wrap = atoi(value);
break;
case SWM_S_FOCUS_DEFAULT:
if (!strcmp(value, "last"))
focus_default = SWM_STACK_TOP;
else if (!strcmp(value, "first"))
focus_default = SWM_STACK_BOTTOM;
else
errx(1, "focus_default");
break;
case SWM_S_SPAWN_ORDER:
if (!strcmp(value, "first"))
spawn_position = SWM_STACK_BOTTOM;
else if (!strcmp(value, "last"))
spawn_position = SWM_STACK_TOP;
else if (!strcmp(value, "next"))
spawn_position = SWM_STACK_ABOVE;
else if (!strcmp(value, "previous"))
spawn_position = SWM_STACK_BELOW;
else
errx(1, "spawn_position");
break;
case SWM_S_DISABLE_BORDER: case SWM_S_DISABLE_BORDER:
disable_border = atoi(value); disable_border = atoi(value);
break; break;
@ -5620,6 +5694,10 @@ struct config_option configopt[] = {
{ "title_class_enabled", setconfvalue, SWM_S_TITLE_CLASS_ENABLED }, { "title_class_enabled", setconfvalue, SWM_S_TITLE_CLASS_ENABLED },
{ "title_name_enabled", setconfvalue, SWM_S_TITLE_NAME_ENABLED }, { "title_name_enabled", setconfvalue, SWM_S_TITLE_NAME_ENABLED },
{ "focus_mode", setconfvalue, SWM_S_FOCUS_MODE }, { "focus_mode", setconfvalue, SWM_S_FOCUS_MODE },
{ "focus_close", setconfvalue, SWM_S_FOCUS_CLOSE },
{ "focus_close_wrap", setconfvalue, SWM_S_FOCUS_CLOSE_WRAP },
{ "focus_default", setconfvalue, SWM_S_FOCUS_DEFAULT },
{ "spawn_position", setconfvalue, SWM_S_SPAWN_ORDER },
{ "disable_border", setconfvalue, SWM_S_DISABLE_BORDER }, { "disable_border", setconfvalue, SWM_S_DISABLE_BORDER },
{ "border_width", setconfvalue, SWM_S_BORDER_WIDTH }, { "border_width", setconfvalue, SWM_S_BORDER_WIDTH },
{ "autorun", setautorun, 0 }, { "autorun", setautorun, 0 },
@ -5859,12 +5937,27 @@ manage_window(Window id)
DNPRINTF(SWM_D_MISC, "manage_window: previously unmanaged " DNPRINTF(SWM_D_MISC, "manage_window: previously unmanaged "
"window: 0x%lx\n", win->id); "window: 0x%lx\n", win->id);
TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry); TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry);
if (win->transient) { if (win->transient)
set_child_transient(win, &trans); set_child_transient(win, &trans);
} if (trans && (ww = find_window(trans)))
if (trans && (ww = find_window(trans)))
TAILQ_INSERT_AFTER(&win->ws->winlist, ww, win, entry); TAILQ_INSERT_AFTER(&win->ws->winlist, ww, win, entry);
else else if ((ww = win->ws->focus) &&
spawn_position == SWM_STACK_ABOVE)
TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry);
else if (ww && spawn_position == SWM_STACK_BELOW)
TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry);
else switch (spawn_position) {
default:
case SWM_STACK_TOP:
case SWM_STACK_ABOVE:
TAILQ_INSERT_TAIL(&win->ws->winlist, win, entry); TAILQ_INSERT_TAIL(&win->ws->winlist, win, entry);
break;
case SWM_STACK_BOTTOM:
case SWM_STACK_BELOW:
TAILQ_INSERT_HEAD(&win->ws->winlist, win, entry);
}
ewmh_update_actions(win); ewmh_update_actions(win);
return (win); return (win);
} }
@ -5951,6 +6044,8 @@ manage_window(Window id)
win->s = r->s; /* this never changes */ win->s = r->s; /* this never changes */
if (trans && (ww = find_window(trans))) if (trans && (ww = find_window(trans)))
TAILQ_INSERT_AFTER(&ws->winlist, ww, win, entry); TAILQ_INSERT_AFTER(&ws->winlist, ww, win, entry);
else if (spawn_position == SWM_STACK_ABOVE && win->ws->focus)
TAILQ_INSERT_AFTER(&win->ws->winlist, win->ws->focus, win, entry);
else else
TAILQ_INSERT_TAIL(&ws->winlist, win, entry); TAILQ_INSERT_TAIL(&ws->winlist, win, entry);

View file

@ -4,6 +4,10 @@
# workspace_limit = 22 # workspace_limit = 22
# focus_mode = default # focus_mode = default
# focus_close = previous
# focus_close_wrap = 1
# focus_default = last
# spawn_position = next
# window decoration # window decoration
# border_width = 1 # border_width = 1
@ -33,7 +37,8 @@
# verbose_layout = 1 # verbose_layout = 1
# urgent_enabled = 1 # urgent_enabled = 1
# spawn app # Spawn Applications
# spawn_position = last
# program[term] = xterm # program[term] = xterm
# program[screenshot_all] = screenshot.sh full # program[screenshot_all] = screenshot.sh full
# program[screenshot_wind] = screenshot.sh window # program[screenshot_wind] = screenshot.sh window