aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/input/seat.h4
-rw-r--r--include/sway/server.h1
-rw-r--r--sway/input/seat.c9
-rw-r--r--sway/lock.c30
4 files changed, 30 insertions, 14 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index c2041742..e3a46872 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -201,10 +201,6 @@ struct sway_workspace *seat_get_last_known_workspace(struct sway_seat *seat);
struct sway_container *seat_get_focused_container(struct sway_seat *seat);
-// Force focus to a particular surface that is not part of the workspace
-// hierarchy (used for lockscreen)
-void sway_force_focus(struct wlr_surface *surface);
-
/**
* Return the last container to be focused for the seat (or the most recently
* opened if no container has received focused) that is a child of the given
diff --git a/include/sway/server.h b/include/sway/server.h
index 055c067d..6a5a60c8 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -96,6 +96,7 @@ struct sway_server {
struct wlr_session_lock_manager_v1 *manager;
struct wlr_session_lock_v1 *lock;
+ struct wlr_surface *focused;
struct wl_listener lock_new_surface;
struct wl_listener lock_unlock;
struct wl_listener lock_destroy;
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 987e1c9f..a7408287 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -214,15 +214,6 @@ static void seat_send_focus(struct sway_node *node, struct sway_seat *seat) {
}
}
-void sway_force_focus(struct wlr_surface *surface) {
- struct sway_seat *seat;
- wl_list_for_each(seat, &server.input->seats, link) {
- seat_keyboard_notify_enter(seat, surface);
- seat_tablet_pads_notify_enter(seat, surface);
- sway_input_method_relay_set_focus(&seat->im_relay, surface);
- }
-}
-
void seat_for_each_node(struct sway_seat *seat,
void (*f)(struct sway_node *node, void *data), void *data) {
struct sway_seat_node *current = NULL;
diff --git a/sway/lock.c b/sway/lock.c
index 04f80079..3c7c06cf 100644
--- a/sway/lock.c
+++ b/sway/lock.c
@@ -17,9 +17,20 @@ struct sway_session_lock_surface {
struct wl_listener output_commit;
};
+static void set_lock_focused_surface(struct wlr_surface *focused) {
+ server.session_lock.focused = focused;
+
+ struct sway_seat *seat;
+ wl_list_for_each(seat, &server.input->seats, link) {
+ seat_set_focus_surface(seat, focused, false);
+ }
+}
+
static void handle_surface_map(struct wl_listener *listener, void *data) {
struct sway_session_lock_surface *surf = wl_container_of(listener, surf, map);
- sway_force_focus(surf->surface);
+ if (server.session_lock.focused == NULL) {
+ set_lock_focused_surface(surf->surface);
+ }
output_damage_whole(surf->output);
}
@@ -48,6 +59,21 @@ static void handle_output_commit(struct wl_listener *listener, void *data) {
static void handle_surface_destroy(struct wl_listener *listener, void *data) {
struct sway_session_lock_surface *surf = wl_container_of(listener, surf, destroy);
+
+ // Move the seat focus to another surface if one is available
+ if (server.session_lock.focused == surf->surface) {
+ struct wlr_surface *next_focus = NULL;
+
+ struct wlr_session_lock_surface_v1 *other;
+ wl_list_for_each(other, &server.session_lock.lock->surfaces, link) {
+ if (other != surf->lock_surface && other->mapped) {
+ next_focus = other->surface;
+ break;
+ }
+ }
+ set_lock_focused_surface(next_focus);
+ }
+
wl_list_remove(&surf->map.link);
wl_list_remove(&surf->destroy.link);
wl_list_remove(&surf->surface_commit.link);
@@ -88,6 +114,7 @@ static void handle_unlock(struct wl_listener *listener, void *data) {
sway_log(SWAY_DEBUG, "session unlocked");
server.session_lock.locked = false;
server.session_lock.lock = NULL;
+ server.session_lock.focused = NULL;
wl_list_remove(&server.session_lock.lock_new_surface.link);
wl_list_remove(&server.session_lock.lock_unlock.link);
@@ -115,6 +142,7 @@ static void handle_unlock(struct wl_listener *listener, void *data) {
static void handle_abandon(struct wl_listener *listener, void *data) {
sway_log(SWAY_INFO, "session lock abandoned");
server.session_lock.lock = NULL;
+ server.session_lock.focused = NULL;
wl_list_remove(&server.session_lock.lock_new_surface.link);
wl_list_remove(&server.session_lock.lock_unlock.link);