session-lock: fix pointer focus handling on map

This commit is contained in:
Isaac Freund 2023-11-17 19:48:32 +01:00
parent 68366c7331
commit 50ccd4c5b3
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
2 changed files with 27 additions and 9 deletions

View File

@ -111,7 +111,6 @@ fn handleLock(listener: *wl.Listener(*wlr.SessionLockV1), lock: *wlr.SessionLock
while (it) |node| : (it = node.next) { while (it) |node| : (it = node.next) {
const seat = &node.data; const seat = &node.data;
seat.setFocusRaw(.none); seat.setFocusRaw(.none);
seat.cursor.updateState();
// Enter locked mode // Enter locked mode
seat.prev_mode_id = seat.mode_id; seat.prev_mode_id = seat.mode_id;

View File

@ -31,6 +31,8 @@ const SceneNodeData = @import("SceneNodeData.zig");
wlr_lock_surface: *wlr.SessionLockSurfaceV1, wlr_lock_surface: *wlr.SessionLockSurfaceV1,
lock: *wlr.SessionLockV1, lock: *wlr.SessionLockV1,
idle_update_focus: ?*wl.EventSource = null,
output_mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleOutputMode), output_mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleOutputMode),
map: wl.Listener(void) = wl.Listener(void).init(handleMap), map: wl.Listener(void) = wl.Listener(void).init(handleMap),
surface_destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy), surface_destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
@ -78,6 +80,10 @@ pub fn destroy(lock_surface: *LockSurface) void {
} }
} }
if (lock_surface.idle_update_focus) |event_source| {
event_source.remove();
}
lock_surface.output_mode.link.remove(); lock_surface.output_mode.link.remove();
lock_surface.map.link.remove(); lock_surface.map.link.remove();
lock_surface.surface_destroy.link.remove(); lock_surface.surface_destroy.link.remove();
@ -105,7 +111,19 @@ fn handleMap(listener: *wl.Listener(void)) void {
output.normal_content.node.setEnabled(false); output.normal_content.node.setEnabled(false);
output.locked_content.node.setEnabled(true); output.locked_content.node.setEnabled(true);
{ // Unfortunately the surface commit handlers for the scene subsurface tree corresponding to
// this lock surface won't be called until after this function returns, which means that we cannot
// update pointer focus yet as the nodes in the scene graph representing this lock surface are still
// 0x0 in size. To work around this, use an idle callback.
const event_loop = server.wl_server.getEventLoop();
assert(lock_surface.idle_update_focus == null);
lock_surface.idle_update_focus = event_loop.addIdle(*LockSurface, updateFocus, lock_surface) catch {
std.log.err("out of memory", .{});
return;
};
}
fn updateFocus(lock_surface: *LockSurface) void {
var it = server.input_manager.seats.first; var it = server.input_manager.seats.first;
while (it) |node| : (it = node.next) { while (it) |node| : (it = node.next) {
const seat = &node.data; const seat = &node.data;
@ -114,7 +132,8 @@ fn handleMap(listener: *wl.Listener(void)) void {
} }
seat.cursor.updateState(); seat.cursor.updateState();
} }
}
lock_surface.idle_update_focus = null;
} }
fn handleDestroy(listener: *wl.Listener(void)) void { fn handleDestroy(listener: *wl.Listener(void)) void {