From c9ca43ac665ec0473a0671e15f55837befa21078 Mon Sep 17 00:00:00 2001 From: Lawrence Teo Date: Mon, 9 Jan 2012 20:30:00 -0500 Subject: [PATCH] Fix a crash when mvws_n is used in an empty workspace. mvws_n invokes send_to_ws(), which in turn calls focus() to focus on the previous window before sending the current window to the desired workspace. The TAILQ_PREV() call in focus() will fail if there are no windows in the current workspace. This commit adds a safeguard to focus() by ensuring that the list of windows in the current workspace is not empty and that there is at least one uniconified window to focus on before proceeding. This commit also modifies send_to_ws() to set r->ws->focus to NULL if there are no more windows in the workspace after sending the current window to another workspace. This fixes an odd behavior where you can "summon" a window that you have previously moved to another workspace, even though you are in an empty workspace. Closes FS#191 ok marco --- scrotwm.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/scrotwm.c b/scrotwm.c index c2aece7..37cdf48 100644 --- a/scrotwm.c +++ b/scrotwm.c @@ -2446,6 +2446,7 @@ focus(struct swm_region *r, union arg *args) struct ws_win *cur_focus = NULL; struct ws_win_list *wl = NULL; struct workspace *ws = NULL; + int all_iconics; if (!(r && r->ws)) return; @@ -2471,6 +2472,17 @@ focus(struct swm_region *r, union arg *args) return; ws = r->ws; wl = &ws->winlist; + if (TAILQ_EMPTY(wl)) + return; + /* make sure there is at least one uniconified window */ + all_iconics = 1; + TAILQ_FOREACH(winfocus, wl, entry) + if (winfocus->iconic == 0) { + all_iconics = 0; + break; + } + if (all_iconics) + return; winlostfocus = cur_focus; @@ -3118,7 +3130,7 @@ send_to_ws(struct swm_region *r, union arg *args) unsigned char ws_idx_str[SWM_PROPLEN]; union arg a; - if (r && r->ws) + if (r && r->ws && r->ws->focus) win = r->ws->focus; else return; @@ -3146,6 +3158,8 @@ send_to_ws(struct swm_region *r, union arg *args) unmap_window(win); TAILQ_REMOVE(&ws->winlist, win, entry); TAILQ_INSERT_TAIL(&nws->winlist, win, entry); + if (TAILQ_EMPTY(&ws->winlist)) + r->ws->focus = NULL; win->ws = nws; /* Try to update the window's workspace property */ -- 1.7.10.4