mirror of
https://codeberg.org/dwl/dwl.git
synced 2026-09-19 13:52:48 +00:00
add support for layer-shell on-demand keyboard interactivity
Supersedes https://codeberg.org/dwl/dwl/pulls/674 Co-authored-by: Leonardo Hernández Hernández <leohdz172@proton.me> Co-authored-by: MayOrMayNotBeACat <maybeacat804@gmail.com>
This commit is contained in:
co-authored by
Leonardo Hernández Hernández
MayOrMayNotBeACat
parent
4c54bd8113
commit
0a6dc6d548
@@ -309,7 +309,7 @@ static void moveresize(const Arg *arg);
|
|||||||
static void outputmgrapply(struct wl_listener *listener, void *data);
|
static void outputmgrapply(struct wl_listener *listener, void *data);
|
||||||
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
|
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
|
||||||
static void outputmgrtest(struct wl_listener *listener, void *data);
|
static void outputmgrtest(struct wl_listener *listener, void *data);
|
||||||
static void pointerfocus(Client *c, struct wlr_surface *surface,
|
static void pointerfocus(Client *c, LayerSurface* l, struct wlr_surface *surface,
|
||||||
double sx, double sy, uint32_t time);
|
double sx, double sy, uint32_t time);
|
||||||
static void printstatus(void);
|
static void printstatus(void);
|
||||||
static void powermgrsetmode(struct wl_listener *listener, void *data);
|
static void powermgrsetmode(struct wl_listener *listener, void *data);
|
||||||
@@ -593,10 +593,13 @@ arrangelayers(Monitor *m)
|
|||||||
for (i = 3; i >= 0; i--)
|
for (i = 3; i >= 0; i--)
|
||||||
arrangelayer(m, &m->layers[i], &usable_area, 0);
|
arrangelayer(m, &m->layers[i], &usable_area, 0);
|
||||||
|
|
||||||
/* Find topmost keyboard interactive layer, if such a layer exists */
|
/* Find topmost keyboard interactive layer that has indicated it wants
|
||||||
|
* exclusive access to the keyboard, if such a layer exists */
|
||||||
for (i = 0; i < (int)LENGTH(layers_above_shell); i++) {
|
for (i = 0; i < (int)LENGTH(layers_above_shell); i++) {
|
||||||
wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) {
|
wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) {
|
||||||
if (locked || !l->layer_surface->current.keyboard_interactive || !l->mapped)
|
if (locked ||
|
||||||
|
l->layer_surface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE ||
|
||||||
|
!l->mapped)
|
||||||
continue;
|
continue;
|
||||||
/* Deactivate the focused client. */
|
/* Deactivate the focused client. */
|
||||||
focusclient(NULL, 0);
|
focusclient(NULL, 0);
|
||||||
@@ -629,6 +632,7 @@ buttonpress(struct wl_listener *listener, void *data)
|
|||||||
struct wlr_keyboard *keyboard;
|
struct wlr_keyboard *keyboard;
|
||||||
uint32_t mods;
|
uint32_t mods;
|
||||||
Client *c;
|
Client *c;
|
||||||
|
LayerSurface *l;
|
||||||
const Button *b;
|
const Button *b;
|
||||||
|
|
||||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||||
@@ -640,10 +644,15 @@ buttonpress(struct wl_listener *listener, void *data)
|
|||||||
if (locked)
|
if (locked)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* 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);
|
or a layer surface with on-demand keyboard interactivity */
|
||||||
if (c && (!client_is_unmanaged(c) || client_wants_focus(c)))
|
xytonode(cursor->x, cursor->y, NULL, &c, &l, NULL, NULL);
|
||||||
|
if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) {
|
||||||
focusclient(c, 1);
|
focusclient(c, 1);
|
||||||
|
} else if (l && l->layer_surface->current.keyboard_interactive) {
|
||||||
|
focusclient(NULL, 0);
|
||||||
|
client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat));
|
||||||
|
}
|
||||||
|
|
||||||
keyboard = wlr_seat_get_keyboard(seat);
|
keyboard = wlr_seat_get_keyboard(seat);
|
||||||
mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
||||||
@@ -843,6 +852,11 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (layer_surface == exclusive_focus
|
||||||
|
&& layer_surface->current.keyboard_interactive !=
|
||||||
|
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
|
||||||
|
exclusive_focus = NULL;
|
||||||
|
|
||||||
if (layer_surface->current.committed == 0 && l->mapped == layer_surface->surface->mapped)
|
if (layer_surface->current.committed == 0 && l->mapped == layer_surface->surface->mapped)
|
||||||
return;
|
return;
|
||||||
l->mapped = layer_surface->surface->mapped;
|
l->mapped = layer_surface->surface->mapped;
|
||||||
@@ -1454,7 +1468,8 @@ focusclient(Client *c, int lift)
|
|||||||
* and focus it after the overlay is closed. */
|
* and focus it after the overlay is closed. */
|
||||||
if (old_client_type == LayerShell && wlr_scene_node_coords(
|
if (old_client_type == LayerShell && wlr_scene_node_coords(
|
||||||
&old_l->scene->node, &unused_lx, &unused_ly)
|
&old_l->scene->node, &unused_lx, &unused_ly)
|
||||||
&& old_l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
|
&& old_l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
||||||
|
&& old_l->layer_surface->current.keyboard_interactive == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
|
||||||
return;
|
return;
|
||||||
} else if (old_c && old_c == exclusive_focus && client_wants_focus(old_c)) {
|
} else if (old_c && old_c == exclusive_focus && client_wants_focus(old_c)) {
|
||||||
return;
|
return;
|
||||||
@@ -1894,20 +1909,20 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
|
|||||||
{
|
{
|
||||||
double sx = 0, sy = 0, sx_confined, sy_confined;
|
double sx = 0, sy = 0, sx_confined, sy_confined;
|
||||||
Client *c = NULL, *w = NULL;
|
Client *c = NULL, *w = NULL;
|
||||||
LayerSurface *l = NULL;
|
LayerSurface *l = NULL, *focusedl = NULL;
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
struct wlr_pointer_constraint_v1 *constraint;
|
struct wlr_pointer_constraint_v1 *constraint;
|
||||||
|
|
||||||
/* Find the client under the pointer and send the event along. */
|
/* Find the client under the pointer and send the event along. */
|
||||||
xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);
|
xytonode(cursor->x, cursor->y, &surface, &c, &l, &sx, &sy);
|
||||||
|
|
||||||
if (cursor_mode == CurPressed && !seat->drag
|
if (cursor_mode == CurPressed && !seat->drag
|
||||||
&& surface != seat->pointer_state.focused_surface
|
&& surface != seat->pointer_state.focused_surface
|
||||||
&& toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) {
|
&& toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &focusedl) >= 0) {
|
||||||
c = w;
|
c = w;
|
||||||
surface = seat->pointer_state.focused_surface;
|
surface = seat->pointer_state.focused_surface;
|
||||||
sx = cursor->x - (l ? l->scene->node.x : w->geom.x);
|
sx = cursor->x - (focusedl ? focusedl->scene->node.x : w->geom.x);
|
||||||
sy = cursor->y - (l ? l->scene->node.y : w->geom.y);
|
sy = cursor->y - (focusedl ? focusedl->scene->node.y : w->geom.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* time is 0 in internal calls meant to restore pointer focus. */
|
/* time is 0 in internal calls meant to restore pointer focus. */
|
||||||
@@ -1964,7 +1979,7 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
|
|||||||
if (!surface && !seat->drag)
|
if (!surface && !seat->drag)
|
||||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
|
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
|
||||||
|
|
||||||
pointerfocus(c, surface, sx, sy, time);
|
pointerfocus(c, l, surface, sx, sy, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2088,14 +2103,19 @@ outputmgrtest(struct wl_listener *listener, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
|
pointerfocus(Client *c, LayerSurface *l, struct wlr_surface *surface, double sx, double sy,
|
||||||
uint32_t time)
|
uint32_t time)
|
||||||
{
|
{
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
|
|
||||||
if (surface != seat->pointer_state.focused_surface &&
|
if (surface != seat->pointer_state.focused_surface && sloppyfocus && time) {
|
||||||
sloppyfocus && time && c && !client_is_unmanaged(c))
|
if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) {
|
||||||
focusclient(c, 0);
|
focusclient(c, 0);
|
||||||
|
} else if (l && l->layer_surface->current.keyboard_interactive) {
|
||||||
|
focusclient(NULL, 0);
|
||||||
|
client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If surface is NULL, clear pointer focus */
|
/* If surface is NULL, clear pointer focus */
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
@@ -2583,7 +2603,7 @@ setup(void)
|
|||||||
wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel);
|
wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel);
|
||||||
wl_signal_add(&xdg_shell->events.new_popup, &new_xdg_popup);
|
wl_signal_add(&xdg_shell->events.new_popup, &new_xdg_popup);
|
||||||
|
|
||||||
layer_shell = wlr_layer_shell_v1_create(dpy, 3);
|
layer_shell = wlr_layer_shell_v1_create(dpy, 4);
|
||||||
wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface);
|
wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface);
|
||||||
|
|
||||||
idle_notifier = wlr_idle_notifier_v1_create(dpy);
|
idle_notifier = wlr_idle_notifier_v1_create(dpy);
|
||||||
|
|||||||
Reference in New Issue
Block a user