diff options
author | Tony Crisci <tony@dubstepdish.com> | 2018-02-10 18:10:29 -0500 |
---|---|---|
committer | Tony Crisci <tony@dubstepdish.com> | 2018-02-10 18:19:53 -0500 |
commit | ce3a1b3922850124c562e56ea9a783b090e969b9 (patch) | |
tree | 8517cf2c3ddb3641122d22f83e8458055fa3e4ac | |
parent | use bfs iterator to collect focus stack (diff) | |
download | sway-ce3a1b3922850124c562e56ea9a783b090e969b9.tar.gz sway-ce3a1b3922850124c562e56ea9a783b090e969b9.tar.zst sway-ce3a1b3922850124c562e56ea9a783b090e969b9.zip |
properly pick next focus
-rw-r--r-- | sway/input/seat.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index ab751b54..2abe8a1f 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -36,13 +36,35 @@ static void handle_seat_container_destroy(struct wl_listener *listener, | |||
36 | void *data) { | 36 | void *data) { |
37 | struct sway_seat_container *seat_con = | 37 | struct sway_seat_container *seat_con = |
38 | wl_container_of(listener, seat_con, destroy); | 38 | wl_container_of(listener, seat_con, destroy); |
39 | struct sway_seat *seat = seat_con->seat; | ||
40 | swayc_t *con = seat_con->container; | ||
41 | |||
42 | bool is_focus = (sway_seat_get_focus(seat) == con); | ||
43 | |||
39 | wl_list_remove(&seat_con->link); | 44 | wl_list_remove(&seat_con->link); |
45 | |||
46 | if (is_focus) { | ||
47 | // pick next focus | ||
48 | sway_seat_set_focus(seat, NULL); | ||
49 | swayc_t *next = sway_seat_get_focus_inactive(seat, con->parent); | ||
50 | if (next == NULL) { | ||
51 | next = con->parent; | ||
52 | } | ||
53 | sway_seat_set_focus(seat, next); | ||
54 | } | ||
55 | |||
40 | wl_list_remove(&seat_con->destroy.link); | 56 | wl_list_remove(&seat_con->destroy.link); |
57 | |||
41 | free(seat_con); | 58 | free(seat_con); |
42 | } | 59 | } |
43 | 60 | ||
44 | static struct sway_seat_container *seat_container_from_container( | 61 | static struct sway_seat_container *seat_container_from_container( |
45 | struct sway_seat *seat, swayc_t *con) { | 62 | struct sway_seat *seat, swayc_t *con) { |
63 | if (con->type < C_WORKSPACE) { | ||
64 | // these don't get seat containers ever | ||
65 | return NULL; | ||
66 | } | ||
67 | |||
46 | struct sway_seat_container *seat_con = NULL; | 68 | struct sway_seat_container *seat_con = NULL; |
47 | wl_list_for_each(seat_con, &seat->focus_stack, link) { | 69 | wl_list_for_each(seat_con, &seat->focus_stack, link) { |
48 | if (seat_con->container == con) { | 70 | if (seat_con->container == con) { |
@@ -57,6 +79,7 @@ static struct sway_seat_container *seat_container_from_container( | |||
57 | } | 79 | } |
58 | 80 | ||
59 | seat_con->container = con; | 81 | seat_con->container = con; |
82 | seat_con->seat = seat; | ||
60 | wl_list_insert(seat->focus_stack.prev, &seat_con->link); | 83 | wl_list_insert(seat->focus_stack.prev, &seat_con->link); |
61 | wl_signal_add(&con->events.destroy, &seat_con->destroy); | 84 | wl_signal_add(&con->events.destroy, &seat_con->destroy); |
62 | seat_con->destroy.notify = handle_seat_container_destroy; | 85 | seat_con->destroy.notify = handle_seat_container_destroy; |
@@ -266,14 +289,6 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) { | |||
266 | seat->cursor->cursor->y); | 289 | seat->cursor->cursor->y); |
267 | } | 290 | } |
268 | 291 | ||
269 | static void handle_focus_destroy(struct wl_listener *listener, void *data) { | ||
270 | struct sway_seat *seat = wl_container_of(listener, seat, focus_destroy); | ||
271 | swayc_t *container = data; | ||
272 | // TODO dont set focus to the parent, set focus to the next focus inactive | ||
273 | // of the parent | ||
274 | sway_seat_set_focus(seat, container->parent); | ||
275 | } | ||
276 | |||
277 | void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { | 292 | void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { |
278 | swayc_t *last_focus = sway_seat_get_focus(seat); | 293 | swayc_t *last_focus = sway_seat_get_focus(seat); |
279 | 294 | ||
@@ -281,17 +296,12 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { | |||
281 | return; | 296 | return; |
282 | } | 297 | } |
283 | 298 | ||
284 | if (last_focus) { | ||
285 | wl_list_remove(&seat->focus_destroy.link); | ||
286 | seat->has_focus = false; | ||
287 | } | ||
288 | |||
289 | if (container) { | 299 | if (container) { |
290 | struct sway_seat_container *seat_con = | 300 | struct sway_seat_container *seat_con = |
291 | seat_container_from_container(seat, container); | 301 | seat_container_from_container(seat, container); |
292 | wl_signal_add(&container->events.destroy, &seat->focus_destroy); | 302 | if (!seat_con) { |
293 | seat->focus_destroy.notify = handle_focus_destroy; | 303 | return; |
294 | seat->has_focus = true; | 304 | } |
295 | 305 | ||
296 | wl_list_remove(&seat_con->link); | 306 | wl_list_remove(&seat_con->link); |
297 | wl_list_insert(&seat->focus_stack, &seat_con->link); | 307 | wl_list_insert(&seat->focus_stack, &seat_con->link); |
@@ -316,15 +326,14 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { | |||
316 | struct sway_view *view = last_focus->sway_view; | 326 | struct sway_view *view = last_focus->sway_view; |
317 | view_set_activated(view, false); | 327 | view_set_activated(view, false); |
318 | } | 328 | } |
329 | |||
330 | seat->has_focus = (container != NULL); | ||
319 | } | 331 | } |
320 | 332 | ||
321 | swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container) { | 333 | swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container) { |
322 | struct sway_seat_container *current = NULL; | 334 | struct sway_seat_container *current = NULL; |
323 | swayc_t *parent = NULL; | 335 | swayc_t *parent = NULL; |
324 | wl_list_for_each(current, &seat->focus_stack, link) { | 336 | wl_list_for_each(current, &seat->focus_stack, link) { |
325 | if (current->container->type < C_WORKSPACE) { | ||
326 | continue; | ||
327 | } | ||
328 | parent = current->container->parent; | 337 | parent = current->container->parent; |
329 | 338 | ||
330 | if (current->container == container) { | 339 | if (current->container == container) { |