aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/desktop/transaction.h7
-rw-r--r--include/sway/tree/view.h3
-rw-r--r--include/swaylock/seat.h6
-rw-r--r--include/swaylock/swaylock.h2
-rw-r--r--sway/commands/focus.c1
-rw-r--r--sway/desktop/transaction.c40
-rw-r--r--sway/desktop/xdg_shell.c9
-rw-r--r--sway/desktop/xdg_shell_v6.c9
-rw-r--r--sway/desktop/xwayland.c14
-rw-r--r--sway/input/cursor.c22
-rw-r--r--sway/input/seat.c7
-rw-r--r--sway/ipc-json.c23
-rw-r--r--sway/tree/view.c7
-rw-r--r--swaybar/bar.c10
-rw-r--r--swaylock/main.c5
-rw-r--r--swaylock/seat.c22
16 files changed, 149 insertions, 38 deletions
diff --git a/include/sway/desktop/transaction.h b/include/sway/desktop/transaction.h
index 66e8c9a2..f38f033c 100644
--- a/include/sway/desktop/transaction.h
+++ b/include/sway/desktop/transaction.h
@@ -29,6 +29,13 @@ struct sway_view;
29void transaction_commit_dirty(void); 29void transaction_commit_dirty(void);
30 30
31/** 31/**
32 * Same as above, but runs the specific callback when the transaction is
33 * applied.
34 */
35void transaction_commit_dirty_with_callback(
36 void (*callback)(void *data), void *data);
37
38/**
32 * Notify the transaction system that a view is ready for the new layout. 39 * Notify the transaction system that a view is ready for the new layout.
33 * 40 *
34 * When all views in the transaction are ready, the layout will be applied. 41 * When all views in the transaction are ready, the layout will be applied.
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index a0b4dd46..0240f294 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -30,6 +30,7 @@ enum sway_view_prop {
30 VIEW_PROP_WINDOW_ROLE, 30 VIEW_PROP_WINDOW_ROLE,
31#ifdef HAVE_XWAYLAND 31#ifdef HAVE_XWAYLAND
32 VIEW_PROP_X11_WINDOW_ID, 32 VIEW_PROP_X11_WINDOW_ID,
33 VIEW_PROP_X11_PARENT_ID,
33#endif 34#endif
34}; 35};
35 36
@@ -256,6 +257,8 @@ const char *view_get_instance(struct sway_view *view);
256 257
257uint32_t view_get_x11_window_id(struct sway_view *view); 258uint32_t view_get_x11_window_id(struct sway_view *view);
258 259
260uint32_t view_get_x11_parent_id(struct sway_view *view);
261
259const char *view_get_window_role(struct sway_view *view); 262const char *view_get_window_role(struct sway_view *view);
260 263
261uint32_t view_get_window_type(struct sway_view *view); 264uint32_t view_get_window_type(struct sway_view *view);
diff --git a/include/swaylock/seat.h b/include/swaylock/seat.h
index 4bcf40c0..c79afcd0 100644
--- a/include/swaylock/seat.h
+++ b/include/swaylock/seat.h
@@ -10,6 +10,12 @@ struct swaylock_xkb {
10 struct xkb_keymap *keymap; 10 struct xkb_keymap *keymap;
11}; 11};
12 12
13struct swaylock_seat {
14 struct swaylock_state *state;
15 struct wl_pointer *pointer;
16 struct wl_keyboard *keyboard;
17};
18
13extern const struct wl_seat_listener seat_listener; 19extern const struct wl_seat_listener seat_listener;
14 20
15#endif 21#endif
diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h
index 25b41a71..18af7ab4 100644
--- a/include/swaylock/swaylock.h
+++ b/include/swaylock/swaylock.h
@@ -62,8 +62,6 @@ struct swaylock_state {
62 struct wl_compositor *compositor; 62 struct wl_compositor *compositor;
63 struct zwlr_layer_shell_v1 *layer_shell; 63 struct zwlr_layer_shell_v1 *layer_shell;
64 struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager; 64 struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager;
65 struct wl_pointer *pointer;
66 struct wl_keyboard *keyboard;
67 struct wl_shm *shm; 65 struct wl_shm *shm;
68 struct wl_list surfaces; 66 struct wl_list surfaces;
69 struct wl_list images; 67 struct wl_list images;
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index 7dfa8814..81af8e0f 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -294,6 +294,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
294 if (next_focus) { 294 if (next_focus) {
295 seat_set_focus(seat, next_focus); 295 seat_set_focus(seat, next_focus);
296 seat_consider_warp_to_focus(seat); 296 seat_consider_warp_to_focus(seat);
297 cursor_rebase(seat->cursor);
297 } 298 }
298 299
299 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 300 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 5dec279d..b2f7f922 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -25,6 +25,8 @@ struct sway_transaction {
25 size_t num_waiting; 25 size_t num_waiting;
26 size_t num_configures; 26 size_t num_configures;
27 struct timespec commit_time; 27 struct timespec commit_time;
28 void (*callback)(void *data);
29 void *callback_data;
28}; 30};
29 31
30struct sway_transaction_instruction { 32struct sway_transaction_instruction {
@@ -295,6 +297,10 @@ static void transaction_apply(struct sway_transaction *transaction) {
295 297
296 node->instruction = NULL; 298 node->instruction = NULL;
297 } 299 }
300
301 if (transaction->callback) {
302 transaction->callback(transaction->callback_data);
303 }
298} 304}
299 305
300static void transaction_commit(struct sway_transaction *transaction); 306static void transaction_commit(struct sway_transaction *transaction);
@@ -499,14 +505,7 @@ void transaction_notify_view_ready_by_size(struct sway_view *view,
499 } 505 }
500} 506}
501 507
502void transaction_commit_dirty(void) { 508static void do_commit_dirty(struct sway_transaction *transaction) {
503 if (!server.dirty_nodes->length) {
504 return;
505 }
506 struct sway_transaction *transaction = transaction_create();
507 if (!transaction) {
508 return;
509 }
510 for (int i = 0; i < server.dirty_nodes->length; ++i) { 509 for (int i = 0; i < server.dirty_nodes->length; ++i) {
511 struct sway_node *node = server.dirty_nodes->items[i]; 510 struct sway_node *node = server.dirty_nodes->items[i];
512 transaction_add_node(transaction, node); 511 transaction_add_node(transaction, node);
@@ -525,3 +524,28 @@ void transaction_commit_dirty(void) {
525 transaction_progress_queue(); 524 transaction_progress_queue();
526 } 525 }
527} 526}
527
528void transaction_commit_dirty(void) {
529 if (!server.dirty_nodes->length) {
530 return;
531 }
532 struct sway_transaction *transaction = transaction_create();
533 if (!transaction) {
534 return;
535 }
536 do_commit_dirty(transaction);
537}
538
539void transaction_commit_dirty_with_callback(
540 void (*callback)(void *data), void *data) {
541 if (!server.dirty_nodes->length) {
542 return;
543 }
544 struct sway_transaction *transaction = transaction_create();
545 if (!transaction) {
546 return;
547 }
548 transaction->callback = callback;
549 transaction->callback_data = data;
550 do_commit_dirty(transaction);
551}
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index fda1bdef..064e2707 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -9,6 +9,7 @@
9#include "sway/decoration.h" 9#include "sway/decoration.h"
10#include "sway/desktop.h" 10#include "sway/desktop.h"
11#include "sway/desktop/transaction.h" 11#include "sway/desktop/transaction.h"
12#include "sway/input/cursor.h"
12#include "sway/input/input-manager.h" 13#include "sway/input/input-manager.h"
13#include "sway/input/seat.h" 14#include "sway/input/seat.h"
14#include "sway/output.h" 15#include "sway/output.h"
@@ -396,6 +397,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
396 wl_list_remove(&xdg_shell_view->set_app_id.link); 397 wl_list_remove(&xdg_shell_view->set_app_id.link);
397} 398}
398 399
400static void do_rebase(void *data) {
401 struct sway_cursor *cursor = data;
402 cursor_rebase(cursor);
403}
404
399static void handle_map(struct wl_listener *listener, void *data) { 405static void handle_map(struct wl_listener *listener, void *data) {
400 struct sway_xdg_shell_view *xdg_shell_view = 406 struct sway_xdg_shell_view *xdg_shell_view =
401 wl_container_of(listener, xdg_shell_view, map); 407 wl_container_of(listener, xdg_shell_view, map);
@@ -422,7 +428,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
422 view_map(view, view->wlr_xdg_surface->surface, 428 view_map(view, view->wlr_xdg_surface->surface,
423 xdg_surface->toplevel->client_pending.fullscreen, csd); 429 xdg_surface->toplevel->client_pending.fullscreen, csd);
424 430
425 transaction_commit_dirty(); 431 struct sway_seat *seat = input_manager_current_seat();
432 transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
426 433
427 xdg_shell_view->commit.notify = handle_commit; 434 xdg_shell_view->commit.notify = handle_commit;
428 wl_signal_add(&xdg_surface->surface->events.commit, 435 wl_signal_add(&xdg_surface->surface->events.commit,
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index 7159f1ed..90bf55b2 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -8,6 +8,7 @@
8#include "sway/decoration.h" 8#include "sway/decoration.h"
9#include "sway/desktop.h" 9#include "sway/desktop.h"
10#include "sway/desktop/transaction.h" 10#include "sway/desktop/transaction.h"
11#include "sway/input/cursor.h"
11#include "sway/input/input-manager.h" 12#include "sway/input/input-manager.h"
12#include "sway/input/seat.h" 13#include "sway/input/seat.h"
13#include "sway/output.h" 14#include "sway/output.h"
@@ -393,6 +394,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
393 wl_list_remove(&xdg_shell_v6_view->set_app_id.link); 394 wl_list_remove(&xdg_shell_v6_view->set_app_id.link);
394} 395}
395 396
397static void do_rebase(void *data) {
398 struct sway_cursor *cursor = data;
399 cursor_rebase(cursor);
400}
401
396static void handle_map(struct wl_listener *listener, void *data) { 402static void handle_map(struct wl_listener *listener, void *data) {
397 struct sway_xdg_shell_v6_view *xdg_shell_v6_view = 403 struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
398 wl_container_of(listener, xdg_shell_v6_view, map); 404 wl_container_of(listener, xdg_shell_v6_view, map);
@@ -413,7 +419,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
413 view_map(view, view->wlr_xdg_surface_v6->surface, 419 view_map(view, view->wlr_xdg_surface_v6->surface,
414 xdg_surface->toplevel->client_pending.fullscreen, csd); 420 xdg_surface->toplevel->client_pending.fullscreen, csd);
415 421
416 transaction_commit_dirty(); 422 struct sway_seat *seat = input_manager_current_seat();
423 transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
417 424
418 xdg_shell_v6_view->commit.notify = handle_commit; 425 xdg_shell_v6_view->commit.notify = handle_commit;
419 wl_signal_add(&xdg_surface->surface->events.commit, 426 wl_signal_add(&xdg_surface->surface->events.commit,
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 5305ce12..95275937 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -8,6 +8,7 @@
8#include "log.h" 8#include "log.h"
9#include "sway/desktop.h" 9#include "sway/desktop.h"
10#include "sway/desktop/transaction.h" 10#include "sway/desktop/transaction.h"
11#include "sway/input/cursor.h"
11#include "sway/input/input-manager.h" 12#include "sway/input/input-manager.h"
12#include "sway/input/seat.h" 13#include "sway/input/seat.h"
13#include "sway/output.h" 14#include "sway/output.h"
@@ -171,6 +172,11 @@ static uint32_t get_int_prop(struct sway_view *view, enum sway_view_prop prop) {
171 switch (prop) { 172 switch (prop) {
172 case VIEW_PROP_X11_WINDOW_ID: 173 case VIEW_PROP_X11_WINDOW_ID:
173 return view->wlr_xwayland_surface->window_id; 174 return view->wlr_xwayland_surface->window_id;
175 case VIEW_PROP_X11_PARENT_ID:
176 if (view->wlr_xwayland_surface->parent) {
177 return view->wlr_xwayland_surface->parent->window_id;
178 }
179 return 0;
174 case VIEW_PROP_WINDOW_TYPE: 180 case VIEW_PROP_WINDOW_TYPE:
175 return *view->wlr_xwayland_surface->window_type; 181 return *view->wlr_xwayland_surface->window_type;
176 default: 182 default:
@@ -385,6 +391,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
385 wl_list_remove(&xwayland_view->commit.link); 391 wl_list_remove(&xwayland_view->commit.link);
386} 392}
387 393
394static void do_rebase(void *data) {
395 struct sway_cursor *cursor = data;
396 cursor_rebase(cursor);
397}
398
388static void handle_map(struct wl_listener *listener, void *data) { 399static void handle_map(struct wl_listener *listener, void *data) {
389 struct sway_xwayland_view *xwayland_view = 400 struct sway_xwayland_view *xwayland_view =
390 wl_container_of(listener, xwayland_view, map); 401 wl_container_of(listener, xwayland_view, map);
@@ -411,7 +422,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
411 // Put it back into the tree 422 // Put it back into the tree
412 view_map(view, xsurface->surface, xsurface->fullscreen, false); 423 view_map(view, xsurface->surface, xsurface->fullscreen, false);
413 424
414 transaction_commit_dirty(); 425 struct sway_seat *seat = input_manager_current_seat();
426 transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
415} 427}
416 428
417static void handle_request_configure(struct wl_listener *listener, void *data) { 429static void handle_request_configure(struct wl_listener *listener, void *data) {
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index a07bc53b..3942b64f 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -996,8 +996,9 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor,
996 if (on_titlebar) { 996 if (on_titlebar) {
997 enum sway_container_layout layout = container_parent_layout(cont); 997 enum sway_container_layout layout = container_parent_layout(cont);
998 if (layout == L_TABBED || layout == L_STACKED) { 998 if (layout == L_TABBED || layout == L_STACKED) {
999 struct sway_node *tabcontainer = node_get_parent(node);
999 struct sway_node *active = 1000 struct sway_node *active =
1000 seat_get_active_tiling_child(seat, node_get_parent(node)); 1001 seat_get_active_tiling_child(seat, tabcontainer);
1001 list_t *siblings = container_get_siblings(cont); 1002 list_t *siblings = container_get_siblings(cont);
1002 int desired = list_find(siblings, active->sway_container) + 1003 int desired = list_find(siblings, active->sway_container) +
1003 event->delta_discrete; 1004 event->delta_discrete;
@@ -1006,9 +1007,19 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor,
1006 } else if (desired >= siblings->length) { 1007 } else if (desired >= siblings->length) {
1007 desired = siblings->length - 1; 1008 desired = siblings->length - 1;
1008 } 1009 }
1009 struct sway_container *new_focus = siblings->items[desired]; 1010 struct sway_node *old_focus = seat_get_focus(seat);
1010 node = seat_get_focus_inactive(seat, &new_focus->node); 1011 struct sway_container *new_sibling_con = siblings->items[desired];
1011 seat_set_focus(seat, node); 1012 struct sway_node *new_sibling = &new_sibling_con->node;
1013 struct sway_node *new_focus =
1014 seat_get_focus_inactive(seat, new_sibling);
1015 if (node_has_ancestor(old_focus, tabcontainer)) {
1016 seat_set_focus(seat, new_focus);
1017 } else {
1018 // Scrolling when focus is not in the tabbed container at all
1019 seat_set_raw_focus(seat, new_sibling);
1020 seat_set_raw_focus(seat, new_focus);
1021 seat_set_raw_focus(seat, old_focus);
1022 }
1012 return; 1023 return;
1013 } 1024 }
1014 } 1025 }
@@ -1220,6 +1231,9 @@ static void handle_request_set_cursor(struct wl_listener *listener,
1220 1231
1221void cursor_set_image(struct sway_cursor *cursor, const char *image, 1232void cursor_set_image(struct sway_cursor *cursor, const char *image,
1222 struct wl_client *client) { 1233 struct wl_client *client) {
1234 if (!(cursor->seat->wlr_seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) {
1235 return;
1236 }
1223 if (!image) { 1237 if (!image) {
1224 wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); 1238 wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
1225 } else if (!cursor->image || strcmp(cursor->image, image) != 0) { 1239 } else if (!cursor->image || strcmp(cursor->image, image) != 0) {
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 16acc8a5..89d841bb 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -389,12 +389,15 @@ static void seat_update_capabilities(struct sway_seat *seat) {
389 break; 389 break;
390 } 390 }
391 } 391 }
392 wlr_seat_set_capabilities(seat->wlr_seat, caps);
393 392
394 // Hide cursor if seat doesn't have pointer capability 393 // Hide cursor if seat doesn't have pointer capability.
394 // We must call cursor_set_image while the wlr_seat has the capabilities
395 // otherwise it's a no op.
395 if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) { 396 if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) {
396 cursor_set_image(seat->cursor, NULL, NULL); 397 cursor_set_image(seat->cursor, NULL, NULL);
398 wlr_seat_set_capabilities(seat->wlr_seat, caps);
397 } else { 399 } else {
400 wlr_seat_set_capabilities(seat->wlr_seat, caps);
398 cursor_set_image(seat->cursor, "left_ptr", NULL); 401 cursor_set_image(seat->cursor, "left_ptr", NULL);
399 } 402 }
400} 403}
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index a29647ed..2cd0cb2d 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -266,6 +266,29 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
266 if (c->view->type == SWAY_VIEW_XWAYLAND) { 266 if (c->view->type == SWAY_VIEW_XWAYLAND) {
267 json_object_object_add(object, "window", 267 json_object_object_add(object, "window",
268 json_object_new_int(view_get_x11_window_id(c->view))); 268 json_object_new_int(view_get_x11_window_id(c->view)));
269
270 json_object *window_props = json_object_new_object();
271
272 json_object_object_add(window_props, "class",
273 class ? json_object_new_string(class) : NULL);
274 const char *instance = view_get_instance(c->view);
275 json_object_object_add(window_props, "instance",
276 instance ? json_object_new_string(instance) : NULL);
277 json_object_object_add(window_props, "title",
278 c->title ? json_object_new_string(c->title) : NULL);
279
280 // the transient_for key is always present in i3's output
281 uint32_t parent_id = view_get_x11_parent_id(c->view);
282 json_object_object_add(window_props, "transient_for",
283 parent_id ? json_object_new_int(parent_id) : NULL);
284
285 const char *role = view_get_window_role(c->view);
286 if (role) {
287 json_object_object_add(window_props, "window_role",
288 json_object_new_string(role));
289 }
290
291 json_object_object_add(object, "window_properties", window_props);
269 } 292 }
270#endif 293#endif
271} 294}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index a8486dd7..20babf7b 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -116,6 +116,13 @@ uint32_t view_get_x11_window_id(struct sway_view *view) {
116 } 116 }
117 return 0; 117 return 0;
118} 118}
119
120uint32_t view_get_x11_parent_id(struct sway_view *view) {
121 if (view->impl->get_int_prop) {
122 return view->impl->get_int_prop(view, VIEW_PROP_X11_PARENT_ID);
123 }
124 return 0;
125}
119#endif 126#endif
120const char *view_get_window_role(struct sway_view *view) { 127const char *view_get_window_role(struct sway_view *view) {
121 if (view->impl->get_string_prop) { 128 if (view->impl->get_string_prop) {
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 3661c637..08c386a7 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -26,11 +26,6 @@
26#include "wlr-layer-shell-unstable-v1-client-protocol.h" 26#include "wlr-layer-shell-unstable-v1-client-protocol.h"
27#include "xdg-output-unstable-v1-client-protocol.h" 27#include "xdg-output-unstable-v1-client-protocol.h"
28 28
29static void bar_init(struct swaybar *bar) {
30 bar->config = init_config();
31 wl_list_init(&bar->outputs);
32}
33
34void free_workspaces(struct wl_list *list) { 29void free_workspaces(struct wl_list *list) {
35 struct swaybar_workspace *ws, *tmp; 30 struct swaybar_workspace *ws, *tmp;
36 wl_list_for_each_safe(ws, tmp, list, link) { 31 wl_list_for_each_safe(ws, tmp, list, link) {
@@ -327,7 +322,9 @@ static const struct wl_registry_listener registry_listener = {
327}; 322};
328 323
329bool bar_setup(struct swaybar *bar, const char *socket_path) { 324bool bar_setup(struct swaybar *bar, const char *socket_path) {
330 bar_init(bar); 325 bar->visible = true;
326 bar->config = init_config();
327 wl_list_init(&bar->outputs);
331 bar->eventloop = loop_create(); 328 bar->eventloop = loop_create();
332 329
333 bar->ipc_socketfd = ipc_open_socket(socket_path); 330 bar->ipc_socketfd = ipc_open_socket(socket_path);
@@ -376,7 +373,6 @@ bool bar_setup(struct swaybar *bar, const char *socket_path) {
376 pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); 373 pointer->cursor_surface = wl_compositor_create_surface(bar->compositor);
377 assert(pointer->cursor_surface); 374 assert(pointer->cursor_surface);
378 375
379 bar->visible = true;
380 if (bar->config->workspace_buttons) { 376 if (bar->config->workspace_buttons) {
381 ipc_get_workspaces(bar); 377 ipc_get_workspaces(bar);
382 } 378 }
diff --git a/swaylock/main.c b/swaylock/main.c
index ebc2b263..9b74b671 100644
--- a/swaylock/main.c
+++ b/swaylock/main.c
@@ -280,7 +280,10 @@ static void handle_global(void *data, struct wl_registry *registry,
280 } else if (strcmp(interface, wl_seat_interface.name) == 0) { 280 } else if (strcmp(interface, wl_seat_interface.name) == 0) {
281 struct wl_seat *seat = wl_registry_bind( 281 struct wl_seat *seat = wl_registry_bind(
282 registry, name, &wl_seat_interface, 3); 282 registry, name, &wl_seat_interface, 3);
283 wl_seat_add_listener(seat, &seat_listener, state); 283 struct swaylock_seat *swaylock_seat =
284 calloc(1, sizeof(struct swaylock_seat));
285 swaylock_seat->state = state;
286 wl_seat_add_listener(seat, &seat_listener, swaylock_seat);
284 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { 287 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
285 state->layer_shell = wl_registry_bind( 288 state->layer_shell = wl_registry_bind(
286 registry, name, &zwlr_layer_shell_v1_interface, 1); 289 registry, name, &zwlr_layer_shell_v1_interface, 1);
diff --git a/swaylock/seat.c b/swaylock/seat.c
index 22dd9360..7b72114f 100644
--- a/swaylock/seat.c
+++ b/swaylock/seat.c
@@ -144,22 +144,22 @@ static const struct wl_pointer_listener pointer_listener = {
144 144
145static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, 145static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
146 enum wl_seat_capability caps) { 146 enum wl_seat_capability caps) {
147 struct swaylock_state *state = data; 147 struct swaylock_seat *seat = data;
148 if (state->pointer) { 148 if (seat->pointer) {
149 wl_pointer_release(state->pointer); 149 wl_pointer_release(seat->pointer);
150 state->pointer = NULL; 150 seat->pointer = NULL;
151 } 151 }
152 if (state->keyboard) { 152 if (seat->keyboard) {
153 wl_keyboard_release(state->keyboard); 153 wl_keyboard_release(seat->keyboard);
154 state->keyboard = NULL; 154 seat->keyboard = NULL;
155 } 155 }
156 if ((caps & WL_SEAT_CAPABILITY_POINTER)) { 156 if ((caps & WL_SEAT_CAPABILITY_POINTER)) {
157 state->pointer = wl_seat_get_pointer(wl_seat); 157 seat->pointer = wl_seat_get_pointer(wl_seat);
158 wl_pointer_add_listener(state->pointer, &pointer_listener, NULL); 158 wl_pointer_add_listener(seat->pointer, &pointer_listener, NULL);
159 } 159 }
160 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { 160 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
161 state->keyboard = wl_seat_get_keyboard(wl_seat); 161 seat->keyboard = wl_seat_get_keyboard(wl_seat);
162 wl_keyboard_add_listener(state->keyboard, &keyboard_listener, state); 162 wl_keyboard_add_listener(seat->keyboard, &keyboard_listener, seat->state);
163 } 163 }
164} 164}
165 165