mirror of
https://github.com/swaywm/sway.git
synced 2026-06-13 14:33:19 -04:00
Set lock focus per-seat
This commit is contained in:
parent
bafbcdd139
commit
c2ae62e21c
4 changed files with 43 additions and 33 deletions
|
|
@ -99,6 +99,7 @@ struct sway_seat {
|
||||||
char *prev_workspace_name; // for workspace back_and_forth
|
char *prev_workspace_name; // for workspace back_and_forth
|
||||||
|
|
||||||
struct wlr_layer_surface_v1 *focused_layer;
|
struct wlr_layer_surface_v1 *focused_layer;
|
||||||
|
struct wlr_surface *focused_lock;
|
||||||
// If the exclusive layer is set, views cannot receive keyboard focus
|
// If the exclusive layer is set, views cannot receive keyboard focus
|
||||||
bool has_exclusive_layer;
|
bool has_exclusive_layer;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ struct sway_transaction;
|
||||||
|
|
||||||
struct sway_session_lock {
|
struct sway_session_lock {
|
||||||
struct wlr_session_lock_v1 *lock;
|
struct wlr_session_lock_v1 *lock;
|
||||||
struct wlr_surface *focused;
|
|
||||||
bool abandoned;
|
bool abandoned;
|
||||||
|
|
||||||
struct wl_list outputs; // struct sway_session_lock_output
|
struct wl_list outputs; // struct sway_session_lock_output
|
||||||
|
|
@ -182,7 +181,7 @@ void sway_session_lock_add_output(struct sway_session_lock *lock,
|
||||||
bool sway_session_lock_has_surface(struct sway_session_lock *lock,
|
bool sway_session_lock_has_surface(struct sway_session_lock *lock,
|
||||||
struct wlr_surface *surface);
|
struct wlr_surface *surface);
|
||||||
void sway_session_lock_focus_output(struct sway_session_lock *lock,
|
void sway_session_lock_focus_output(struct sway_session_lock *lock,
|
||||||
struct sway_output *output);
|
struct sway_seat* seat, struct sway_output *output);
|
||||||
void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data);
|
void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data);
|
||||||
#if WLR_HAS_XWAYLAND
|
#if WLR_HAS_XWAYLAND
|
||||||
void handle_xwayland_surface(struct wl_listener *listener, void *data);
|
void handle_xwayland_surface(struct wl_listener *listener, void *data);
|
||||||
|
|
|
||||||
|
|
@ -1269,11 +1269,11 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
|
||||||
// Try focusing the current sway_output's lock-surface
|
// Try focusing the current sway_output's lock-surface
|
||||||
struct sway_output *output = node ? node_get_output(node) : NULL;
|
struct sway_output *output = node ? node_get_output(node) : NULL;
|
||||||
if (output) {
|
if (output) {
|
||||||
sway_session_lock_focus_output(server.session_lock.lock, output);
|
sway_session_lock_focus_output(server.session_lock.lock, seat, output);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Fallback to the previously focused lock surface
|
// Fallback to the previously focused lock surface
|
||||||
seat_set_focus_surface(seat, server.session_lock.lock->focused, false);
|
seat_set_focus_surface(seat, seat->focused_lock, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
68
sway/lock.c
68
sway/lock.c
|
|
@ -30,38 +30,39 @@ struct sway_session_lock_output {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void focus_surface(struct sway_session_lock *lock,
|
static void focus_surface(struct sway_session_lock *lock,
|
||||||
struct wlr_surface *focused) {
|
struct sway_seat *seat, struct wlr_surface *focused) {
|
||||||
lock->focused = focused;
|
if (seat) {
|
||||||
|
seat->focused_lock = focused;
|
||||||
struct sway_seat *seat;
|
|
||||||
wl_list_for_each(seat, &server.input->seats, link) {
|
|
||||||
seat_set_focus_surface(seat, focused, false);
|
seat_set_focus_surface(seat, focused, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void refocus_output(struct sway_session_lock_output *output) {
|
static void refocus_output(struct sway_session_lock_output *output) {
|
||||||
// Move the seat focus to another surface if one is available
|
// Move the seat focus to another surface if one is available
|
||||||
if (output->lock->focused == output->surface->surface) {
|
struct wlr_surface *next_focus = NULL;
|
||||||
struct wlr_surface *next_focus = NULL;
|
|
||||||
|
|
||||||
struct sway_session_lock_output *candidate;
|
struct sway_session_lock_output *candidate;
|
||||||
wl_list_for_each(candidate, &output->lock->outputs, link) {
|
wl_list_for_each(candidate, &output->lock->outputs, link) {
|
||||||
if (candidate == output || !candidate->surface) {
|
if (candidate == output || !candidate->surface) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (candidate->surface->surface->mapped) {
|
|
||||||
next_focus = candidate->surface->surface;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
focus_surface(output->lock, next_focus);
|
if (candidate->surface->surface->mapped) {
|
||||||
|
next_focus = candidate->surface->surface;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_seat *seat;
|
||||||
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
|
if (seat->focused_lock == output->surface->surface) {
|
||||||
|
focus_surface(output->lock, seat, next_focus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sway_session_lock_focus_output(struct sway_session_lock *lock,
|
void sway_session_lock_focus_output(struct sway_session_lock *lock,
|
||||||
struct sway_output *output) {
|
struct sway_seat* seat, struct sway_output *output) {
|
||||||
// Try focusing the lock surface on the provided output
|
// Try focusing the lock surface on the provided output
|
||||||
struct sway_session_lock_output *candidate;
|
struct sway_session_lock_output *candidate;
|
||||||
wl_list_for_each(candidate, &lock->outputs, link) {
|
wl_list_for_each(candidate, &lock->outputs, link) {
|
||||||
|
|
@ -70,8 +71,7 @@ void sway_session_lock_focus_output(struct sway_session_lock *lock,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (candidate->surface->surface->mapped) {
|
if (candidate->surface->surface->mapped) {
|
||||||
// Set the focus for all seats
|
focus_surface(lock, seat, candidate->surface->surface);
|
||||||
focus_surface(lock, candidate->surface->surface);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,15 +80,18 @@ void sway_session_lock_focus_output(struct sway_session_lock *lock,
|
||||||
static void handle_surface_map(struct wl_listener *listener, void *data) {
|
static void handle_surface_map(struct wl_listener *listener, void *data) {
|
||||||
struct sway_session_lock_output *surf = wl_container_of(listener, surf, surface_map);
|
struct sway_session_lock_output *surf = wl_container_of(listener, surf, surface_map);
|
||||||
|
|
||||||
struct sway_seat *seat = input_manager_current_seat();
|
struct sway_seat *seat;
|
||||||
struct sway_workspace *focused_ws = seat_get_focused_workspace(seat);
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
struct sway_output *focused_output = focused_ws ? focused_ws->output : NULL;
|
struct sway_workspace *focused_ws = seat_get_focused_workspace(seat);
|
||||||
|
struct sway_output *focused_output = focused_ws ? focused_ws->output : NULL;
|
||||||
|
|
||||||
// Only set the initial focus surface when it's on the focused output.
|
// Only set the initial focus lock-surface when the surface is on the
|
||||||
// Fallback to the first mapped surface if no focused output can be found.
|
// focused output. Fallback to the first mapped surface if no focused
|
||||||
if (focused_output == surf->output
|
// output can be found.
|
||||||
|| (!focused_output && surf->lock->focused == NULL)) {
|
if (focused_output == surf->output
|
||||||
focus_surface(surf->lock, surf->surface->surface);
|
|| (!focused_output && seat->focused_lock == NULL)) {
|
||||||
|
focus_surface(surf->lock, seat, surf->surface->surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cursor_rebase_all();
|
cursor_rebase_all();
|
||||||
}
|
}
|
||||||
|
|
@ -224,6 +227,11 @@ static void sway_session_lock_destroy(struct sway_session_lock* lock) {
|
||||||
wlr_scene_node_destroy(&lock_output->tree->node);
|
wlr_scene_node_destroy(&lock_output->tree->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sway_seat *seat;
|
||||||
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
|
seat->focused_lock = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (server.session_lock.lock == lock) {
|
if (server.session_lock.lock == lock) {
|
||||||
server.session_lock.lock = NULL;
|
server.session_lock.lock = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -245,6 +253,8 @@ static void handle_unlock(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
struct sway_seat *seat;
|
struct sway_seat *seat;
|
||||||
wl_list_for_each(seat, &server.input->seats, link) {
|
wl_list_for_each(seat, &server.input->seats, link) {
|
||||||
|
seat->focused_lock = NULL;
|
||||||
|
|
||||||
// copied from seat_set_focus_layer -- deduplicate?
|
// copied from seat_set_focus_layer -- deduplicate?
|
||||||
struct sway_node *previous = seat_get_focus_inactive(seat, &root->node);
|
struct sway_node *previous = seat_get_focus_inactive(seat, &root->node);
|
||||||
if (previous) {
|
if (previous) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue