allow unmanaged clients (like dzen or dmenu) to have keyboard focus
This commit is contained in:
parent
9e912cf790
commit
332ceb7136
2 changed files with 31 additions and 9 deletions
11
client.h
11
client.h
|
@ -275,6 +275,17 @@ client_surface_at(Client *c, double cx, double cy, double *sx, double *sy)
|
||||||
return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy);
|
return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_wants_focus(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
return client_is_unmanaged(c)
|
||||||
|
&& wlr_xwayland_or_surface_wants_focus(c->surface.xwayland)
|
||||||
|
&& wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
client_wants_fullscreen(Client *c)
|
client_wants_fullscreen(Client *c)
|
||||||
{
|
{
|
||||||
|
|
29
dwl.c
29
dwl.c
|
@ -659,8 +659,7 @@ buttonpress(struct wl_listener *listener, void *data)
|
||||||
case WLR_BUTTON_PRESSED:
|
case WLR_BUTTON_PRESSED:
|
||||||
/* Change focus if the button was _pressed_ over a client */
|
/* Change focus if the button was _pressed_ over a client */
|
||||||
xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL);
|
xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL);
|
||||||
/* Don't focus unmanaged clients */
|
if (c && (!client_is_unmanaged(c) || client_wants_focus(c)))
|
||||||
if (c && !client_is_unmanaged(c))
|
|
||||||
focusclient(c, 1);
|
focusclient(c, 1);
|
||||||
|
|
||||||
keyboard = wlr_seat_get_keyboard(seat);
|
keyboard = wlr_seat_get_keyboard(seat);
|
||||||
|
@ -1173,7 +1172,7 @@ focusclient(Client *c, int lift)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Put the new client atop the focus stack and select its monitor */
|
/* Put the new client atop the focus stack and select its monitor */
|
||||||
if (c) {
|
if (c && !client_is_unmanaged(c)) {
|
||||||
wl_list_remove(&c->flink);
|
wl_list_remove(&c->flink);
|
||||||
wl_list_insert(&fstack, &c->flink);
|
wl_list_insert(&fstack, &c->flink);
|
||||||
selmon = c->mon;
|
selmon = c->mon;
|
||||||
|
@ -1192,6 +1191,7 @@ focusclient(Client *c, int lift)
|
||||||
/* If an overlay is focused, don't focus or activate the client,
|
/* If an overlay is focused, don't focus or activate the client,
|
||||||
* but only update its position in fstack to render its border with focuscolor
|
* but only update its position in fstack to render its border with focuscolor
|
||||||
* and focus it after the overlay is closed. */
|
* and focus it after the overlay is closed. */
|
||||||
|
Client *w = client_from_wlr_surface(old);
|
||||||
if (wlr_surface_is_layer_surface(old)) {
|
if (wlr_surface_is_layer_surface(old)) {
|
||||||
struct wlr_layer_surface_v1 *wlr_layer_surface =
|
struct wlr_layer_surface_v1 *wlr_layer_surface =
|
||||||
wlr_layer_surface_v1_from_wlr_surface(old);
|
wlr_layer_surface_v1_from_wlr_surface(old);
|
||||||
|
@ -1200,11 +1200,13 @@ focusclient(Client *c, int lift)
|
||||||
&& (wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
&& (wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
||||||
|| wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY))
|
|| wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY))
|
||||||
return;
|
return;
|
||||||
} else {
|
} else if (w && w == exclusive_focus && client_wants_focus(w)) {
|
||||||
Client *w;
|
return;
|
||||||
if ((w = client_from_wlr_surface(old)))
|
/* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg
|
||||||
for (i = 0; i < 4; i++)
|
* and probably other clients */
|
||||||
wlr_scene_rect_set_color(w->border[i], bordercolor);
|
} else if (w && !client_is_unmanaged(w) && (!c || !client_wants_focus(c))) {
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
wlr_scene_rect_set_color(w->border[i], bordercolor);
|
||||||
|
|
||||||
client_activate_surface(old, 0);
|
client_activate_surface(old, 0);
|
||||||
}
|
}
|
||||||
|
@ -1444,6 +1446,10 @@ mapnotify(struct wl_listener *listener, void *data)
|
||||||
wlr_scene_node_reparent(c->scene, layers[LyrFloat]);
|
wlr_scene_node_reparent(c->scene, layers[LyrFloat]);
|
||||||
wlr_scene_node_set_position(c->scene, c->geom.x + borderpx,
|
wlr_scene_node_set_position(c->scene, c->geom.x + borderpx,
|
||||||
c->geom.y + borderpx);
|
c->geom.y + borderpx);
|
||||||
|
if (client_wants_focus(c)) {
|
||||||
|
focusclient(c, 1);
|
||||||
|
exclusive_focus = c;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2399,7 +2405,12 @@ unmapnotify(struct wl_listener *listener, void *data)
|
||||||
if (c->mon)
|
if (c->mon)
|
||||||
c->mon->un_map = 1;
|
c->mon->un_map = 1;
|
||||||
|
|
||||||
if (!client_is_unmanaged(c)) {
|
if (client_is_unmanaged(c)) {
|
||||||
|
if (c == exclusive_focus)
|
||||||
|
exclusive_focus = NULL;
|
||||||
|
if (client_surface(c) == seat->keyboard_state.focused_surface)
|
||||||
|
focusclient(selclient(), 1);
|
||||||
|
} else {
|
||||||
wl_list_remove(&c->link);
|
wl_list_remove(&c->link);
|
||||||
setmon(c, NULL, 0);
|
setmon(c, NULL, 0);
|
||||||
wl_list_remove(&c->flink);
|
wl_list_remove(&c->flink);
|
||||||
|
|
Loading…
Reference in a new issue