Skip to content

Commit 9d16b4b

Browse files
committed
Focus client by name
1 parent bb91a00 commit 9d16b4b

File tree

5 files changed

+139
-14
lines changed

5 files changed

+139
-14
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ maximums, or for setting the width for 80 column terminals).
5555

5656
* **Win+Tab** Cycle to previous clients in any stack
5757
* **Menu** Quickly focus previous client in any stack
58+
* **Win+f** Focus client by name
5859
* **Win+Down** Select client / raise selected client
5960
* **Win+Up** Select client / raise selected client
6061
* **Win+q** Delete client

client.c

+34
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <err.h>
2525
#include <stdlib.h>
2626
#include <string.h>
27+
#include <ctype.h>
2728

2829
static struct client *_head;
2930
static struct client *_focus;
@@ -347,6 +348,39 @@ remove_client(struct client *client)
347348
draw_menu();
348349
}
349350

351+
struct client *
352+
match_client(const char *s)
353+
{
354+
struct client *np;
355+
struct client *best_match;
356+
int best_pts, pts;
357+
const char *p, *q;
358+
359+
best_match = NULL;
360+
best_pts = 0;
361+
for (np = _head; np != NULL; np = np->next)
362+
if (np->name != NULL) {
363+
q = s;
364+
pts = 0;
365+
p = np->renamed_name;
366+
if (p == NULL)
367+
p = np->name;
368+
if (p == NULL)
369+
p = "no name";
370+
for (; *p != '\0' && *q != '\0'; p++)
371+
if (tolower(*p) == tolower(*q++))
372+
pts++;
373+
else
374+
break;
375+
if (pts > best_pts) {
376+
best_pts = pts;
377+
best_match = np;
378+
}
379+
}
380+
381+
return best_match;
382+
}
383+
350384
struct client *
351385
find_top_client(struct stack *stack)
352386
{

keyboard.c

+4
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ static const struct binding binding[] = {
156156
XK_space, Mod4Mask,
157157
NULL, prompt_rename
158158
},
159+
{
160+
XK_f, Mod4Mask,
161+
NULL, prompt_find
162+
},
159163
{
160164
XK_l, Mod4Mask,
161165
NULL, restart

mxswm.h

+2
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ void set_client_name(struct client *, const char *);
191191
void rename_client_name(struct client *, const char *);
192192
void delete_client(void);
193193
void destroy_client(void);
194+
struct client *match_client(const char *);
194195

195196
unsigned short display_height(void);
196197
unsigned short display_width(void);
@@ -248,6 +249,7 @@ Time current_event_timestamp(void);
248249

249250
void prompt_command(void);
250251
void prompt_rename(void);
252+
void prompt_find(void);
251253

252254
#ifdef TRACE
253255
struct client *event_client();

prompt.c

+98-14
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,24 @@ static Window create_prompt(void);
3232
static void draw_prompt(void);
3333
static void close_prompt();
3434
static int keycode(XKeyEvent *);
35-
static void open_prompt(const char *, PromptCallback, void *);
35+
static void open_prompt(const char *, PromptCallback, PromptCallback,
36+
void *, int);
3637

3738
static void command_callback(const char *, void *);
3839
static void rename_callback(const char *, void *);
40+
static void find_callback(const char *, void *);
41+
static void find_step_callback(const char *, void *);
3942

4043
static Window window;
4144
static wchar_t prompt[4096];
4245
static size_t nprompt;
46+
static size_t pos;
47+
static int _want_centered;
4348

4449
static XIC ic;
4550

4651
static PromptCallback callback;
52+
static PromptCallback step_callback;
4753
static void *callback_udata;
4854

4955
static void
@@ -69,46 +75,95 @@ rename_callback(const char *s, void *udata)
6975
rename_client_name(client, s);
7076
}
7177

78+
static void
79+
find_callback(const char *s, void *udata)
80+
{
81+
struct client *client;
82+
83+
client = match_client(s);
84+
if (client != NULL)
85+
focus_client(client, client->stack);
86+
}
87+
88+
static void
89+
find_step_callback(const char *s, void *udata)
90+
{
91+
struct client *client;
92+
char *q;
93+
94+
client = match_client(s);
95+
if (client != NULL) {
96+
q = client->renamed_name;
97+
if (q == NULL)
98+
q = client->name;
99+
nprompt = mbstowcs(prompt, q, sizeof(prompt));
100+
prompt[nprompt] = '\0';
101+
} else if (s == NULL || s[0] == '\0') {
102+
nprompt = 0;
103+
prompt[nprompt] = '\0';
104+
}
105+
}
106+
107+
void
108+
prompt_find()
109+
{
110+
close_menu();
111+
open_prompt("", find_callback, find_step_callback, NULL, 1);
112+
}
113+
72114
void
73115
prompt_command()
74116
{
75117
close_menu();
76-
open_prompt("", command_callback, NULL);
118+
open_prompt("", command_callback, NULL, NULL, 0);
77119
}
78120

79121
void
80122
prompt_rename()
81123
{
82124
if (is_menu_visible())
83125
select_menu_item();
84-
open_prompt(client_name(current_client()), rename_callback,
85-
current_client());
126+
open_prompt(client_name(current_client()), rename_callback, NULL,
127+
current_client(), 0);
86128
}
87129

88130
static void
89-
open_prompt(const char *initial, PromptCallback _callback, void *udata)
131+
open_prompt(const char *initial, PromptCallback _callback,
132+
PromptCallback _step_callback, void *udata, int center)
90133
{
91134
XEvent e;
92135
XIM xim;
93136

94137
callback = _callback;
95138
callback_udata = udata;
96139

140+
step_callback = _step_callback;
141+
142+
_want_centered = center;
143+
97144
if (initial != NULL) {
98145
nprompt = mbstowcs(prompt, initial, sizeof(prompt));
99146
prompt[nprompt] = '\0';
147+
pos = nprompt;
100148
} else {
101149
nprompt = 0;
150+
pos = 0;
102151
prompt[nprompt] = '\0';
103152
}
104153

105154
if (window == 0)
106155
window = create_prompt();
107156

108157
set_font(FONT_TITLE);
109-
XMoveResizeWindow(display(), window, STACK_X(current_stack()),
110-
STACK_Y(current_stack()), STACK_WIDTH(current_stack()),
111-
get_font_height());
158+
159+
if (_want_centered)
160+
XMoveResizeWindow(display(), window, display_width() / 4,
161+
display_height() / 2, display_width() / 2,
162+
get_font_height());
163+
else
164+
XMoveResizeWindow(display(), window, STACK_X(current_stack()),
165+
STACK_Y(current_stack()), STACK_WIDTH(current_stack()),
166+
get_font_height());
112167
XRaiseWindow(display(), window);
113168
XMapWindow(display(), window);
114169
draw_prompt();
@@ -174,8 +229,14 @@ keycode(XKeyEvent *e)
174229
return 0;
175230
case XK_BackSpace:
176231
case XK_Delete:
177-
if (nprompt > 0)
178-
prompt[--nprompt] = '\0';
232+
if (nprompt > 0 && pos > 0) {
233+
prompt[--pos] = '\0';
234+
nprompt--;
235+
}
236+
if (step_callback != NULL) {
237+
wcstombs(s, prompt, sizeof(s));
238+
step_callback(s, callback_udata);
239+
}
179240
return 1;
180241
}
181242

@@ -184,15 +245,22 @@ keycode(XKeyEvent *e)
184245
n = 0;
185246
return 1;
186247
} else {
187-
if ((ret = mbtowc(&prompt[nprompt], ch, n)) <= 0) {
248+
if ((ret = mbtowc(&prompt[pos], ch, n)) <= 0) {
188249
TRACE_LOG("trouble converting...");
189-
} else
250+
} else {
190251
nprompt++;
252+
pos++;
253+
}
191254

192255
TRACE_LOG("mbtowc returns %d %zu\n", ret, MB_CUR_MAX);
193256
prompt[nprompt] = '\0';
194257
}
195258

259+
if (step_callback != NULL) {
260+
wcstombs(s, prompt, sizeof(s));
261+
step_callback(s, callback_udata);
262+
}
263+
196264
return 1;
197265
}
198266

@@ -225,16 +293,32 @@ static void
225293
draw_prompt()
226294
{
227295
char s[4096];
296+
char s_until_pos[4096];
297+
wchar_t prompt_until_pos[4096];
298+
char ch[4 + 1];
299+
wchar_t prompt_cursor[2];
228300
XGlyphInfo extents;
229301

230302
XClearWindow(display(), window);
231303

304+
memcpy(prompt_until_pos, prompt, sizeof(prompt_until_pos));
305+
prompt_until_pos[pos] = '\0';
306+
wcstombs(s_until_pos, prompt_until_pos, sizeof(s_until_pos));
232307
wcstombs(s, prompt, sizeof(s));
233308

234309
TRACE_LOG("s is: %s", s);
235310

236-
font_extents(s, strlen(s), &extents);
311+
if (pos < nprompt && nprompt > 0) {
312+
font_extents(s, strlen(s_until_pos), &extents);
313+
314+
prompt_cursor[0] = prompt[pos];
315+
prompt_cursor[1] = '\0';
316+
wcstombs(ch, prompt_cursor, sizeof(ch));
317+
draw_font(window, extents.xOff, 0, COLOR_CURSOR, ch);
318+
} else {
319+
font_extents(s, strlen(s), &extents);
320+
draw_font(window, extents.xOff, 0, COLOR_CURSOR, " ");
321+
}
237322

238323
draw_font(window, 0, 0, -1, s);
239-
draw_font(window, extents.xOff, 0, COLOR_CURSOR, " ");
240324
}

0 commit comments

Comments
 (0)