shell: Properly track the focus state surface
We have to move the surface destroy listener around as we track the currently focused surface. Introduce a helper function, focus_state_set_focus() for this and use throughout. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=73768
This commit is contained in:
+19
-8
@@ -667,6 +667,21 @@ ensure_focus_state(struct desktop_shell *shell, struct weston_seat *seat)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
focus_state_set_focus(struct focus_state *state,
|
||||||
|
struct weston_surface *surface)
|
||||||
|
{
|
||||||
|
if (state->keyboard_focus) {
|
||||||
|
wl_list_remove(&state->surface_destroy_listener.link);
|
||||||
|
wl_list_init(&state->surface_destroy_listener.link);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->keyboard_focus = surface;
|
||||||
|
if (surface)
|
||||||
|
wl_signal_add(&surface->destroy_signal,
|
||||||
|
&state->surface_destroy_listener);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
|
restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
|
||||||
{
|
{
|
||||||
@@ -688,12 +703,10 @@ replace_focus_state(struct desktop_shell *shell, struct workspace *ws,
|
|||||||
struct weston_seat *seat)
|
struct weston_seat *seat)
|
||||||
{
|
{
|
||||||
struct focus_state *state;
|
struct focus_state *state;
|
||||||
struct weston_surface *surface;
|
|
||||||
|
|
||||||
wl_list_for_each(state, &ws->focus_list, link) {
|
wl_list_for_each(state, &ws->focus_list, link) {
|
||||||
if (state->seat == seat) {
|
if (state->seat == seat) {
|
||||||
surface = seat->keyboard->focus;
|
focus_state_set_focus(state, seat->keyboard->focus);
|
||||||
state->keyboard_focus = surface;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -707,7 +720,7 @@ drop_focus_state(struct desktop_shell *shell, struct workspace *ws,
|
|||||||
|
|
||||||
wl_list_for_each(state, &ws->focus_list, link)
|
wl_list_for_each(state, &ws->focus_list, link)
|
||||||
if (state->keyboard_focus == surface)
|
if (state->keyboard_focus == surface)
|
||||||
state->keyboard_focus = NULL;
|
focus_state_set_focus(state, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1258,7 +1271,7 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
|
|||||||
|
|
||||||
state = ensure_focus_state(shell, seat);
|
state = ensure_focus_state(shell, seat);
|
||||||
if (state != NULL)
|
if (state != NULL)
|
||||||
state->keyboard_focus = surface;
|
focus_state_set_focus(state, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4225,9 +4238,7 @@ activate(struct desktop_shell *shell, struct weston_surface *es,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
old_es = state->keyboard_focus;
|
old_es = state->keyboard_focus;
|
||||||
state->keyboard_focus = es;
|
focus_state_set_focus(state, es);
|
||||||
wl_list_remove(&state->surface_destroy_listener.link);
|
|
||||||
wl_signal_add(&es->destroy_signal, &state->surface_destroy_listener);
|
|
||||||
|
|
||||||
shsurf = get_shell_surface(main_surface);
|
shsurf = get_shell_surface(main_surface);
|
||||||
assert(shsurf);
|
assert(shsurf);
|
||||||
|
|||||||
Reference in New Issue
Block a user