aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-02-10 18:10:29 -0500
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-02-10 18:19:53 -0500
commitce3a1b3922850124c562e56ea9a783b090e969b9 (patch)
tree8517cf2c3ddb3641122d22f83e8458055fa3e4ac /sway/input/seat.c
parentuse bfs iterator to collect focus stack (diff)
downloadsway-ce3a1b3922850124c562e56ea9a783b090e969b9.tar.gz
sway-ce3a1b3922850124c562e56ea9a783b090e969b9.tar.zst
sway-ce3a1b3922850124c562e56ea9a783b090e969b9.zip
properly pick next focus
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c47
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
44static struct sway_seat_container *seat_container_from_container( 61static 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
269static 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
277void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) { 292void 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
321swayc_t *sway_seat_get_focus_inactive(struct sway_seat *seat, swayc_t *container) { 333swayc_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) {