JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Search windows in the current workspace.
authorLawrence Teo <lteo@devio.us>
Tue, 29 Nov 2011 04:41:37 +0000 (23:41 -0500)
committerLawrence Teo <lteo@devio.us>
Tue, 29 Nov 2011 04:49:53 +0000 (23:49 -0500)
Pressing M-s will show a little numbered box on the top-left of each
window. You can switch focus to the desired window by typing its number
and pressing Enter. This lets you focus on a window instantly without
needing to cycle through other windows.

ok marco

scrotwm.1
scrotwm.c
scrotwm_cz.conf
scrotwm_es.conf
scrotwm_fr.conf
scrotwm_us.conf

index 09b4f88..7991701 100644 (file)
--- a/scrotwm.1
+++ b/scrotwm.1
@@ -13,7 +13,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: November 11 2011 $
+.Dd $Mdocdate: November 28 2011 $
 .Dt SCROTWM 1
 .Os
 .Sh NAME
@@ -451,6 +451,8 @@ move_down
 name_workspace
 .It Cm M-/
 search_workspace
+.It Cm M-s
+search_win
 .El
 .Pp
 The action names and descriptions are listed below:
@@ -584,6 +586,8 @@ Move a floating window a step downwards.
 Name the current workspace.
 .It Cm search_workspace
 Search for a workspace.
+.It Cm search_win
+Search the windows in the current workspace.
 .El
 .Pp
 Custom bindings in the configuration file are specified as follows:
index 1575a43..718c5d5 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
@@ -207,12 +207,23 @@ pid_t                     searchpid;
 volatile sig_atomic_t  search_resp;
 int                    search_resp_action;
 
+struct search_window {
+       TAILQ_ENTRY(search_window)      entry;
+       int                                     idx;
+       struct ws_win           *win;
+       Window                          indicator;
+};
+TAILQ_HEAD(search_winlist, search_window);
+
+struct search_winlist search_wl;
+
 /* search actions */
 enum {
        SWM_SEARCH_NONE,
        SWM_SEARCH_UNICONIFY,
        SWM_SEARCH_NAME_WORKSPACE,
-       SWM_SEARCH_SEARCH_WORKSPACE
+       SWM_SEARCH_SEARCH_WORKSPACE,
+       SWM_SEARCH_SEARCH_WINDOW
 };
 
 /* dialog windows */
@@ -3309,6 +3320,86 @@ search_workspace(struct swm_region *r, union arg *args)
 }
 
 void
+search_win_cleanup(void)
+{
+       struct search_window    *sw = NULL;
+
+       while ((sw = TAILQ_FIRST(&search_wl)) != NULL) {
+               XDestroyWindow(display, sw->indicator);
+               TAILQ_REMOVE(&search_wl, sw, entry);
+               free(sw);
+       }
+}
+
+void
+search_win(struct swm_region *r, union arg *args)
+{
+       struct ws_win           *win = NULL;
+       struct search_window    *sw = NULL;
+       Window                  w;
+       GC                      gc;
+       XGCValues               gcv;
+       int                     i;
+       char                    s[8];
+       FILE                    *lfile;
+       size_t                  len;
+       int                     textwidth;
+
+       DNPRINTF(SWM_D_MISC, "search_win\n");
+
+       search_r = r;
+       search_resp_action = SWM_SEARCH_SEARCH_WINDOW;
+
+       spawn_select(r, args, "search", &searchpid);
+
+       if ((lfile = fdopen(select_list_pipe[1], "w")) == NULL)
+               return;
+
+       TAILQ_INIT(&search_wl);
+
+       i = 1;
+       TAILQ_FOREACH(win, &r->ws->winlist, entry) {
+               if (win->iconic == 1)
+                       continue;
+
+               sw = calloc(1, sizeof(struct search_window));
+               if (sw == NULL) {
+                       fprintf(stderr, "search_win: calloc: %s", strerror(errno));
+                       fclose(lfile);
+                       search_win_cleanup();
+                       return;
+               }
+               sw->idx = i;
+               sw->win = win;
+
+               snprintf(s, sizeof s, "%d", i);
+               len = strlen(s);
+               textwidth = XTextWidth(bar_fs, s, len);
+
+               w = XCreateSimpleWindow(display,
+                   win->id, 0, 0, textwidth + 12,
+                   bar_fs->ascent + bar_fs->descent + 4, 1,
+                   r->s->c[SWM_S_COLOR_UNFOCUS].color,
+                   r->s->c[SWM_S_COLOR_FOCUS].color);
+
+               sw->indicator = w;
+               TAILQ_INSERT_TAIL(&search_wl, sw, entry);
+
+               gc = XCreateGC(display, w, 0, &gcv);
+               XSetFont(display, gc, bar_fs->fid);
+               XMapRaised(display, w);
+               XSetForeground(display, gc, r->s->c[SWM_S_COLOR_BAR].color);
+
+               XDrawString(display, w, gc, 6, bar_fs->ascent + 2, s, len);
+
+               fprintf(lfile, "%d\n", i);
+               i++;
+       }
+
+       fclose(lfile);
+}
+
+void
 search_resp_uniconify(char *resp, unsigned long len)
 {
        unsigned char           *name;
@@ -3397,6 +3488,39 @@ search_resp_search_workspace(char *resp, unsigned long len)
        switchws(search_r, &a);
 }
 
+void
+search_resp_search_window(char *resp, unsigned long len)
+{
+       char                    *s;
+       int                     idx;
+       const char              *errstr;
+       struct search_window    *sw;
+
+       DNPRINTF(SWM_D_MISC, "search_resp_search_window: resp %s\n", resp);
+
+       s = strdup(resp);
+       if (!s) {
+               DNPRINTF(SWM_D_MISC, "search_resp_search_window: strdup: %s",
+                   strerror(errno));
+               return;
+       }
+       s[len - 1] = '\0';
+       idx = strtonum(s, 1, INT_MAX, &errstr);
+       if (errstr) {
+               DNPRINTF(SWM_D_MISC, "window idx is %s: %s",
+                   errstr, s);
+               free(s);
+               return;
+       }
+       free(s);
+
+       TAILQ_FOREACH(sw, &search_wl, entry)
+               if (idx == sw->idx) {
+                       focus_win(sw->win);
+                       break;
+               }
+}
+
 #define MAX_RESP_LEN   1024
 
 void
@@ -3434,9 +3558,15 @@ search_do_resp(void)
        case SWM_SEARCH_SEARCH_WORKSPACE:
                search_resp_search_workspace(resp, len);
                break;
+       case SWM_SEARCH_SEARCH_WINDOW:
+               search_resp_search_window(resp, len);
+               break;
        }
 
 done:
+       if (search_resp_action == SWM_SEARCH_SEARCH_WINDOW)
+               search_win_cleanup();
+
        search_resp_action = SWM_SEARCH_NONE;
        close(select_resp_pipe[0]);
        free(resp);
@@ -3893,6 +4023,7 @@ enum keyfuncid {
        kf_move_down,
        kf_name_workspace,
        kf_search_workspace,
+       kf_search_win,
        kf_dumpwins, /* MUST BE LAST */
        kf_invalid
 };
@@ -3983,6 +4114,7 @@ struct keyfunc {
        { "move_down",          move_step,      {.id = SWM_ARG_ID_MOVEDOWN} },
        { "name_workspace",     name_workspace, {0} },
        { "search_workspace",   search_workspace,       {0} },
+       { "search_win",         search_win,     {0} },
        { "dumpwins",           dumpwins,       {0} }, /* MUST BE LAST */
        { "invalid key func",   NULL,           {0} },
 };
@@ -4595,6 +4727,7 @@ setup_keys(void)
        setkeybinding(MODKEY|ShiftMask, XK_bracketright,kf_move_down,   NULL);
        setkeybinding(MODKEY|ShiftMask, XK_slash,       kf_name_workspace,NULL);
        setkeybinding(MODKEY,           XK_slash,       kf_search_workspace,NULL);
+       setkeybinding(MODKEY,           XK_s,           kf_search_win,  NULL);
 #ifdef SWM_DEBUG
        setkeybinding(MODKEY|ShiftMask, XK_d,           kf_dumpwins,    NULL);
 #endif
index 598bab4..ea4e5fe 100644 (file)
@@ -69,3 +69,4 @@ bind[move_up]         = MOD+Shift+uacute
 bind[move_down]                = MOD+Shift+parenright
 bind[name_workspace]   = MOD+Shift+slash
 bind[search_workspace] = MOD+slash
+bind[search_win]       = MOD+s
index 5b2668e..f7afbb6 100644 (file)
@@ -69,3 +69,4 @@ bind[move_up]         = MOD+Shift+dead_grave
 bind[move_down]                = MOD+Shift+plus
 bind[name_workspace]   = MOD+Shift+slash
 bind[search_workspace] = MOD+slash
+bind[search_win]       = MOD+s
index e38db31..639193b 100644 (file)
@@ -69,3 +69,4 @@ bind[move_up]         = MOD+Shift+ugrave
 bind[move_down]                = MOD+Shift+asterisk
 bind[name_workspace]   = MOD+Shift+slash
 bind[search_workspace] = MOD+slash
+bind[search_win]       = MOD+s
index 0781eed..5f7efc2 100644 (file)
@@ -69,3 +69,4 @@ bind[move_up]         = MOD+Shift+bracketleft
 bind[move_down]                = MOD+Shift+bracketright
 bind[name_workspace]   = MOD+Shift+slash
 bind[search_workspace] = MOD+slash
+bind[search_win]       = MOD+s