commits
tags
diff --git a/src/defs.h b/src/defs.h
index ac8f74f..a18731f 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -96,6 +96,7 @@ typedef struct {
int resize_window_amt;
Bool new_win_focus;
Bool warp_cursor;
+ Bool focus_follows_mouse;
Bool floating_on_top;
Bool new_win_master;
Binding binds[MAX_ITEMS];
diff --git a/src/parser.c b/src/parser.c
index e50db00..ed09899 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -372,6 +372,8 @@ int parser(Config *cfg)
}
else if (!strcmp(key, "floating_on_top"))
cfg->floating_on_top = !strcmp(rest, "true");
+ else if (!strcmp(key, "focus_follows_mouse"))
+ cfg->focus_follows_mouse = !strcmp(rest, "true");
else if (!strcmp(key, "focused_border_colour"))
cfg->border_foc_col = parse_col(rest);
else if (!strcmp(key, "gaps"))
diff --git a/src/sxwm.c b/src/sxwm.c
index c30db92..6f2f934 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -64,6 +64,7 @@ void hdl_config_ntf(XEvent *xev);
void hdl_config_req(XEvent *xev);
void hdl_dummy(XEvent *xev);
void hdl_destroy_ntf(XEvent *xev);
+void hdl_enter_ntf(XEvent *xev);
void hdl_keypress(XEvent *xev);
void hdl_mapping_ntf(XEvent *xev);
void hdl_map_req(XEvent *xev);
@@ -1174,6 +1175,31 @@ void hdl_destroy_ntf(XEvent *xev)
}
}
+void hdl_enter_ntf(XEvent *xev)
+{
+ XCrossingEvent *crossing_ev = &xev->xcrossing;
+
+ if (!user_config.focus_follows_mouse)
+ return;
+
+ /* Same filter dwm uses (manage()'s XSelectInput + enternotify()):
+ * mode != NotifyNormal skips crossings synthesized by an active
+ * pointer grab (drag/resize), detail == NotifyInferior skips crossing
+ * into a child of a window we're already in -- both would otherwise
+ * flicker focus or fight an active drag. add_client()'s window_masks
+ * already requests EnterWindowMask per client (same as dwm's
+ * manage()), so crossing_ev->window here is directly the client
+ * being entered -- no need for ->subwindow. */
+ if (crossing_ev->mode != NotifyNormal || crossing_ev->detail == NotifyInferior)
+ return;
+
+ Client *c = find_client(find_toplevel(crossing_ev->window));
+ if (!c || c == focused || c->ws != current_ws)
+ return;
+
+ set_input_focus(c, False, False);
+}
+
void hdl_keypress(XEvent *xev)
{
KeyCode code = xev->xkey.keycode;
@@ -1627,6 +1653,7 @@ void init_defaults(void)
user_config.n_binds = 0;
user_config.new_win_focus = True;
user_config.warp_cursor = True;
+ user_config.focus_follows_mouse = False;
user_config.new_win_master = False;
user_config.floating_on_top = True;
}
@@ -2301,6 +2328,7 @@ void setup(void)
evtable[ConfigureNotify] = hdl_config_ntf;
evtable[ConfigureRequest] = hdl_config_req;
evtable[DestroyNotify] = hdl_destroy_ntf;
+ evtable[EnterNotify] = hdl_enter_ntf;
evtable[KeyPress] = hdl_keypress;
evtable[MappingNotify] = hdl_mapping_ntf;
evtable[MapRequest] = hdl_map_req;