Skip to content

Commit 45908da

Browse files
committed
Added sloppy-focus/click-to-focus toggle
As requested by @pyratebeard 2bwm now has the ability to switch between a sloppy-focus mode and a click-to-focus mode by pressing mod4+s, additional behavior can be added in the configuration (config.h) via the sloppy_switch_cmd which will be triggered on the change.
1 parent 50a9ca3 commit 45908da

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

2bwm.c

+70-2
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,12 @@
3636
static xcb_generic_event_t *ev = NULL;
3737
static void (*events[XCB_NO_OPERATION])(xcb_generic_event_t *e);
3838
static unsigned int numlockmask = 0;
39-
int sigcode = 0; // Signal code. Non-zero if we've been interruped by a signal.
39+
static bool is_sloppy = true; // by default use sloppy focus
40+
int sigcode = 0; // Signal code. Non-zero if we've been interruped by a signal.
4041
xcb_connection_t *conn = NULL; // Connection to X server.
4142
xcb_ewmh_connection_t *ewmh = NULL; // Ewmh Connection.
4243
xcb_screen_t *screen = NULL; // Our current screen.
43-
int randrbase = 0; // Beginning of RANDR extension events.
44+
int randrbase = 0; // Beginning of RANDR extension events.
4445
static uint8_t curws = 0; // Current workspace.
4546
struct client *focuswin = NULL; // Current focus window.
4647
static xcb_drawable_t top_win=0; // Window always on top.
@@ -844,6 +845,7 @@ newwin(xcb_generic_event_t *ev)
844845
XCB_NONE
845846
};
846847

848+
847849
/* The window is trying to map itself on the current workspace,
848850
* but since it's unmapped it probably belongs on another workspace.*/
849851
if (NULL != findclient(&e->window))
@@ -887,6 +889,8 @@ newwin(xcb_generic_event_t *ev)
887889

888890
if (!client->maxed)
889891
setborders(client,true);
892+
// always focus new window
893+
setfocus(client);
890894
}
891895

892896
/* Set border colour, width and event mask for window. */
@@ -2798,8 +2802,26 @@ void
27982802
buttonpress(xcb_generic_event_t *ev)
27992803
{
28002804
xcb_button_press_event_t *e = (xcb_button_press_event_t *)ev;
2805+
struct client *client;
28012806
unsigned int i;
28022807

2808+
2809+
if (!is_sloppy && e->detail == XCB_BUTTON_INDEX_1
2810+
&& CLEANMASK(e->state) == 0) {
2811+
// skip if already focused
2812+
if (NULL != focuswin && e->event == focuswin->id) {
2813+
return;
2814+
}
2815+
client = findclient(&e->event);
2816+
if (NULL != client) {
2817+
setfocus(client);
2818+
raisewindow(client->id);
2819+
centerpointer(client->id,client);
2820+
setborders(client,true);
2821+
}
2822+
return;
2823+
}
2824+
28032825
for (i=0; i<LENGTH(buttons); i++)
28042826
if (buttons[i].func && buttons[i].button == e->detail
28052827
&& CLEANMASK(buttons[i].mask)
@@ -2895,6 +2917,13 @@ enternotify(xcb_generic_event_t *ev)
28952917
{
28962918
xcb_enter_notify_event_t *e = (xcb_enter_notify_event_t *)ev;
28972919
struct client *client;
2920+
unsigned int modifiers[] = {
2921+
0,
2922+
XCB_MOD_MASK_LOCK,
2923+
numlockmask,
2924+
numlockmask | XCB_MOD_MASK_LOCK
2925+
};
2926+
28982927

28992928
/*
29002929
* If this isn't a normal enter notify, don't bother. We also need
@@ -2907,6 +2936,7 @@ enternotify(xcb_generic_event_t *ev)
29072936
* to change focus in those cases.
29082937
*/
29092938

2939+
29102940
if (e->mode == XCB_NOTIFY_MODE_NORMAL
29112941
|| e->mode == XCB_NOTIFY_MODE_UNGRAB) {
29122942
/* If we're entering the same window we focus now,
@@ -2915,6 +2945,7 @@ enternotify(xcb_generic_event_t *ev)
29152945
if (NULL != focuswin && e->event == focuswin->id)
29162946
return;
29172947

2948+
29182949
/* Otherwise, set focus to the window we just entered if we
29192950
* can find it among the windows we know about.
29202951
* If not, just keep focus in the old window. */
@@ -2923,6 +2954,30 @@ enternotify(xcb_generic_event_t *ev)
29232954
if (NULL == client)
29242955
return;
29252956

2957+
/* skip this if not is_sloppy
2958+
* we'll focus on click instead (see buttonpress function)
2959+
* thus we have to grab left click button on that window
2960+
* the grab is removed at the end of the setfocus function,
2961+
* in the grabbuttons when not in sloppy mode
2962+
*/
2963+
if (!is_sloppy) {
2964+
for (unsigned int m=0; m<LENGTH(modifiers); m++) {
2965+
xcb_grab_button(conn,
2966+
0, // owner_events => 0 means
2967+
// the grab_window won't
2968+
// receive this event
2969+
client->id,
2970+
XCB_EVENT_MASK_BUTTON_PRESS,
2971+
XCB_GRAB_MODE_ASYNC,
2972+
XCB_GRAB_MODE_ASYNC,
2973+
screen->root, XCB_NONE,
2974+
XCB_BUTTON_INDEX_1,
2975+
modifiers[m]
2976+
);
2977+
}
2978+
return;
2979+
}
2980+
29262981
setfocus(client);
29272982
setborders(client,true);
29282983
}
@@ -3063,6 +3118,19 @@ grabbuttons(struct client *c)
30633118
buttons[b].mask|modifiers[m]
30643119
);
30653120
}
3121+
3122+
/* ungrab the left click, otherwise we can't use it
3123+
* we've previously grabbed the left click in the enternotify function
3124+
* when not in sloppy mode
3125+
* though the name is counter-intuitive to the method
3126+
*/
3127+
for (unsigned int m=0; m<LENGTH(modifiers); m++) {
3128+
xcb_ungrab_button(conn,
3129+
XCB_BUTTON_INDEX_1,
3130+
c->id,
3131+
modifiers[m]
3132+
);
3133+
}
30663134
}
30673135

30683136
void

config.h

+16
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ static void halfandcentered(const Arg *arg)
4949
Arg arg3 = {.i=TWOBWM_TELEPORT_CENTER};
5050
teleport(&arg3);
5151
}
52+
///---Sloppy focus behavior---///
53+
/*
54+
* Command to execute when switching from sloppy focus to click to focus
55+
* The strings "Sloppy" and "Click" will be passed as the last argument
56+
* If NULL this is ignored
57+
*/
58+
static const char *sloppy_switch_cmd[] = {};
59+
//static const char *sloppy_switch_cmd[] = { "notify-send", "toggle sloppy", NULL };
60+
static void toggle_sloppy(const Arg *arg)
61+
{
62+
is_sloppy = !is_sloppy;
63+
if (arg->com != NULL && LENGTH(arg->com) > 0) {
64+
start(arg);
65+
}
66+
}
5267
///---Shortcuts---///
5368
/* Check /usr/include/X11/keysymdef.h for the list of all keys
5469
* 0x000000 is for no modkey
@@ -183,6 +198,7 @@ static key keys[] = {
183198
{ MOD |CONTROL, XK_q, twobwm_exit, {.i=0}},
184199
{ MOD |CONTROL, XK_r, twobwm_restart, {.i=0}},
185200
{ MOD , XK_space, halfandcentered, {.i=0}},
201+
{ MOD , XK_s, toggle_sloppy, {.com = sloppy_switch_cmd}},
186202
// Change current workspace
187203
DESKTOPCHANGE( XK_1, 0)
188204
DESKTOPCHANGE( XK_2, 1)

0 commit comments

Comments
 (0)