summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/input/seat.h15
-rw-r--r--sway/commands/split.c1
-rw-r--r--sway/criteria.c2
-rw-r--r--sway/input/seat.c74
-rw-r--r--sway/ipc-json.c10
-rw-r--r--sway/tree/layout.c5
6 files changed, 81 insertions, 26 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index c7be58b5..308f5c6d 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -87,8 +87,19 @@ struct sway_container *seat_get_focus(struct sway_seat *seat);
87struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, 87struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
88 struct sway_container *container); 88 struct sway_container *container);
89 89
90struct sway_container *seat_get_focus_by_type(struct sway_seat *seat, 90/**
91 struct sway_container *container, enum sway_container_type type); 91 * Descend into the focus stack to find the focus-inactive view. Useful for
92 * container placement when they change position in the tree.
93 */
94struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
95 struct sway_container *container);
96
97/**
98 * Iterate over the focus-inactive children of the container calling the function on each.
99 */
100void seat_focus_inactive_children_for_each(struct sway_seat *seat,
101 struct sway_container *container,
102 void (*f)(struct sway_container *container, void *data), void *data);
92 103
93void seat_apply_config(struct sway_seat *seat, struct seat_config *seat_config); 104void seat_apply_config(struct sway_seat *seat, struct seat_config *seat_config);
94 105
diff --git a/sway/commands/split.c b/sway/commands/split.c
index ab8565a9..130ed31f 100644
--- a/sway/commands/split.c
+++ b/sway/commands/split.c
@@ -11,6 +11,7 @@
11static struct cmd_results *do_split(int layout) { 11static struct cmd_results *do_split(int layout) {
12 struct sway_container *con = config->handler_context.current_container; 12 struct sway_container *con = config->handler_context.current_container;
13 struct sway_container *parent = container_split(con, layout); 13 struct sway_container *parent = container_split(con, layout);
14 container_create_notify(parent);
14 arrange_windows(parent, -1, -1); 15 arrange_windows(parent, -1, -1);
15 16
16 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 17 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/criteria.c b/sway/criteria.c
index 5fee1888..53461c74 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -273,7 +273,7 @@ static int regex_cmp(const char *item, const pcre *regex) {
273 273
274// test a single view if it matches list of criteria tokens (all of them). 274// test a single view if it matches list of criteria tokens (all of them).
275static bool criteria_test(struct sway_container *cont, list_t *tokens) { 275static bool criteria_test(struct sway_container *cont, list_t *tokens) {
276 if (cont->type != C_VIEW) { 276 if (cont->type < C_CONTAINER) {
277 return false; 277 return false;
278 } 278 }
279 int matches = 0; 279 int matches = 0;
diff --git a/sway/input/seat.c b/sway/input/seat.c
index c34da5e5..fccb739b 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -86,6 +86,45 @@ static void seat_send_focus(struct sway_seat *seat,
86 } 86 }
87} 87}
88 88
89static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
90 struct sway_container *container, enum sway_container_type type) {
91 if (container->type == C_VIEW || container->children->length == 0) {
92 return container;
93 }
94
95 struct sway_seat_container *current = NULL;
96 wl_list_for_each(current, &seat->focus_stack, link) {
97 if (current->container->type != type && type != C_TYPES) {
98 continue;
99 }
100
101 if (container_has_child(container, current->container)) {
102 return current->container;
103 }
104 }
105
106 return NULL;
107}
108
109void seat_focus_inactive_children_for_each(struct sway_seat *seat,
110 struct sway_container *container,
111 void (*f)(struct sway_container *container, void *data), void *data) {
112 struct sway_seat_container *current = NULL;
113 wl_list_for_each(current, &seat->focus_stack, link) {
114 if (current->container->parent == NULL) {
115 continue;
116 }
117 if (current->container->parent == container) {
118 f(current->container, data);
119 }
120 }
121}
122
123struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
124 struct sway_container *container) {
125 return seat_get_focus_by_type(seat, container, C_VIEW);
126}
127
89static void handle_seat_container_destroy(struct wl_listener *listener, 128static void handle_seat_container_destroy(struct wl_listener *listener,
90 void *data) { 129 void *data) {
91 struct sway_seat_container *seat_con = 130 struct sway_seat_container *seat_con =
@@ -382,10 +421,23 @@ void seat_set_focus_warp(struct sway_seat *seat,
382 if (container) { 421 if (container) {
383 struct sway_seat_container *seat_con = 422 struct sway_seat_container *seat_con =
384 seat_container_from_container(seat, container); 423 seat_container_from_container(seat, container);
385 if (!seat_con) { 424 if (seat_con == NULL) {
386 return; 425 return;
387 } 426 }
388 427
428 // put all the anscestors of this container on top of the focus stack
429 struct sway_seat_container *parent =
430 seat_container_from_container(seat,
431 seat_con->container->parent);
432 while (parent) {
433 wl_list_remove(&parent->link);
434 wl_list_insert(&seat->focus_stack, &parent->link);
435
436 parent =
437 seat_container_from_container(seat,
438 parent->container->parent);
439 }
440
389 wl_list_remove(&seat_con->link); 441 wl_list_remove(&seat_con->link);
390 wl_list_insert(&seat->focus_stack, &seat_con->link); 442 wl_list_insert(&seat->focus_stack, &seat_con->link);
391 443
@@ -557,26 +609,6 @@ struct sway_container *sway_seat_get_focus(struct sway_seat *seat) {
557 return seat_get_focus_inactive(seat, &root_container); 609 return seat_get_focus_inactive(seat, &root_container);
558} 610}
559 611
560struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
561 struct sway_container *container, enum sway_container_type type) {
562 if (container->type == C_VIEW || container->children->length == 0) {
563 return container;
564 }
565
566 struct sway_seat_container *current = NULL;
567 wl_list_for_each(current, &seat->focus_stack, link) {
568 if (current->container->type != type && type != C_TYPES) {
569 continue;
570 }
571
572 if (container_has_child(container, current->container)) {
573 return current->container;
574 }
575 }
576
577 return NULL;
578}
579
580struct sway_container *seat_get_focus(struct sway_seat *seat) { 612struct sway_container *seat_get_focus(struct sway_seat *seat) {
581 if (!seat->has_focus) { 613 if (!seat->has_focus) {
582 return NULL; 614 return NULL;
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index f9c6c90b..6158fc29 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -166,6 +166,11 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
166 } 166 }
167} 167}
168 168
169static void focus_inactive_children_iterator(struct sway_container *c, void *data) {
170 json_object *focus = data;
171 json_object_array_add(focus, json_object_new_int(c->id));
172}
173
169json_object *ipc_json_describe_container(struct sway_container *c) { 174json_object *ipc_json_describe_container(struct sway_container *c) {
170 if (!(sway_assert(c, "Container must not be null."))) { 175 if (!(sway_assert(c, "Container must not be null."))) {
171 return NULL; 176 return NULL;
@@ -183,6 +188,11 @@ json_object *ipc_json_describe_container(struct sway_container *c) {
183 json_object_object_add(object, "focused", 188 json_object_object_add(object, "focused",
184 json_object_new_boolean(focused)); 189 json_object_new_boolean(focused));
185 190
191 json_object *focus = json_object_new_array();
192 seat_focus_inactive_children_for_each(seat, c,
193 focus_inactive_children_iterator, focus);
194 json_object_object_add(object, "focus", focus);
195
186 switch (c->type) { 196 switch (c->type) {
187 case C_ROOT: 197 case C_ROOT:
188 ipc_json_describe_root(c, object); 198 ipc_json_describe_root(c, object);
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index e81facc6..ae76ca26 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -251,6 +251,7 @@ static void workspace_rejigger(struct sway_container *ws,
251 container_flatten(ws); 251 container_flatten(ws);
252 container_reap_empty_recursive(original_parent); 252 container_reap_empty_recursive(original_parent);
253 wl_signal_emit(&child->events.reparent, original_parent); 253 wl_signal_emit(&child->events.reparent, original_parent);
254 container_create_notify(new_parent);
254 arrange_windows(ws, -1, -1); 255 arrange_windows(ws, -1, -1);
255} 256}
256 257
@@ -872,7 +873,7 @@ struct sway_container *container_get_in_direction(
872 } 873 }
873 if (next->children && next->children->length) { 874 if (next->children && next->children->length) {
874 // TODO consider floating children as well 875 // TODO consider floating children as well
875 return seat_get_focus_by_type(seat, next, C_VIEW); 876 return seat_get_focus_inactive_view(seat, next);
876 } else { 877 } else {
877 return next; 878 return next;
878 } 879 }
@@ -910,7 +911,7 @@ struct sway_container *container_get_in_direction(
910 wlr_log(L_DEBUG, 911 wlr_log(L_DEBUG,
911 "cont %d-%p dir %i sibling %d: %p", idx, 912 "cont %d-%p dir %i sibling %d: %p", idx,
912 container, dir, desired, desired_con); 913 container, dir, desired, desired_con);
913 struct sway_container *next = seat_get_focus_by_type(seat, desired_con, C_VIEW); 914 struct sway_container *next = seat_get_focus_inactive_view(seat, desired_con);
914 return next; 915 return next;
915 } 916 }
916 } 917 }