aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/input/seat.h16
-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, 82 insertions, 26 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index c7be58b5..ff76841e 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -87,8 +87,20 @@ struct sway_container *seat_get_focus(struct sway_seat *seat);
struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
struct sway_container *container);
-struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
- struct sway_container *container, enum sway_container_type type);
+/**
+ * Descend into the focus stack to find the focus-inactive view. Useful for
+ * container placement when they change position in the tree.
+ */
+struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
+ struct sway_container *container);
+
+/**
+ * Iterate over the focus-inactive children of the container calling the
+ * function on each.
+ */
+void seat_focus_inactive_children_for_each(struct sway_seat *seat,
+ struct sway_container *container,
+ void (*f)(struct sway_container *container, void *data), void *data);
void seat_apply_config(struct sway_seat *seat, struct seat_config *seat_config);
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 @@
static struct cmd_results *do_split(int layout) {
struct sway_container *con = config->handler_context.current_container;
struct sway_container *parent = container_split(con, layout);
+ container_create_notify(parent);
arrange_windows(parent, -1, -1);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/criteria.c b/sway/criteria.c
index 5fee1888..22e9a49b 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -273,7 +273,7 @@ static int regex_cmp(const char *item, const pcre *regex) {
// test a single view if it matches list of criteria tokens (all of them).
static bool criteria_test(struct sway_container *cont, list_t *tokens) {
- if (cont->type != C_VIEW) {
+ if (cont->type != C_CONTAINER && cont->type != C_VIEW) {
return false;
}
int matches = 0;
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 7b01fe88..467e5087 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -87,6 +87,45 @@ static void seat_send_focus(struct sway_seat *seat,
}
}
+static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
+ struct sway_container *container, enum sway_container_type type) {
+ if (container->type == C_VIEW || container->children->length == 0) {
+ return container;
+ }
+
+ struct sway_seat_container *current = NULL;
+ wl_list_for_each(current, &seat->focus_stack, link) {
+ if (current->container->type != type && type != C_TYPES) {
+ continue;
+ }
+
+ if (container_has_child(container, current->container)) {
+ return current->container;
+ }
+ }
+
+ return NULL;
+}
+
+void seat_focus_inactive_children_for_each(struct sway_seat *seat,
+ struct sway_container *container,
+ void (*f)(struct sway_container *container, void *data), void *data) {
+ struct sway_seat_container *current = NULL;
+ wl_list_for_each(current, &seat->focus_stack, link) {
+ if (current->container->parent == NULL) {
+ continue;
+ }
+ if (current->container->parent == container) {
+ f(current->container, data);
+ }
+ }
+}
+
+struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
+ struct sway_container *container) {
+ return seat_get_focus_by_type(seat, container, C_VIEW);
+}
+
static void handle_seat_container_destroy(struct wl_listener *listener,
void *data) {
struct sway_seat_container *seat_con =
@@ -412,10 +451,23 @@ void seat_set_focus_warp(struct sway_seat *seat,
if (container) {
struct sway_seat_container *seat_con =
seat_container_from_container(seat, container);
- if (!seat_con) {
+ if (seat_con == NULL) {
return;
}
+ // put all the anscestors of this container on top of the focus stack
+ struct sway_seat_container *parent =
+ seat_container_from_container(seat,
+ seat_con->container->parent);
+ while (parent) {
+ wl_list_remove(&parent->link);
+ wl_list_insert(&seat->focus_stack, &parent->link);
+
+ parent =
+ seat_container_from_container(seat,
+ parent->container->parent);
+ }
+
wl_list_remove(&seat_con->link);
wl_list_insert(&seat->focus_stack, &seat_con->link);
@@ -590,26 +642,6 @@ struct sway_container *sway_seat_get_focus(struct sway_seat *seat) {
return seat_get_focus_inactive(seat, &root_container);
}
-struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
- struct sway_container *container, enum sway_container_type type) {
- if (container->type == C_VIEW || container->children->length == 0) {
- return container;
- }
-
- struct sway_seat_container *current = NULL;
- wl_list_for_each(current, &seat->focus_stack, link) {
- if (current->container->type != type && type != C_TYPES) {
- continue;
- }
-
- if (container_has_child(container, current->container)) {
- return current->container;
- }
- }
-
- return NULL;
-}
-
struct sway_container *seat_get_focus(struct sway_seat *seat) {
if (!seat->has_focus) {
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
}
}
+static void focus_inactive_children_iterator(struct sway_container *c, void *data) {
+ json_object *focus = data;
+ json_object_array_add(focus, json_object_new_int(c->id));
+}
+
json_object *ipc_json_describe_container(struct sway_container *c) {
if (!(sway_assert(c, "Container must not be null."))) {
return NULL;
@@ -183,6 +188,11 @@ json_object *ipc_json_describe_container(struct sway_container *c) {
json_object_object_add(object, "focused",
json_object_new_boolean(focused));
+ json_object *focus = json_object_new_array();
+ seat_focus_inactive_children_for_each(seat, c,
+ focus_inactive_children_iterator, focus);
+ json_object_object_add(object, "focus", focus);
+
switch (c->type) {
case C_ROOT:
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,
container_flatten(ws);
container_reap_empty_recursive(original_parent);
wl_signal_emit(&child->events.reparent, original_parent);
+ container_create_notify(new_parent);
arrange_windows(ws, -1, -1);
}
@@ -872,7 +873,7 @@ struct sway_container *container_get_in_direction(
}
if (next->children && next->children->length) {
// TODO consider floating children as well
- return seat_get_focus_by_type(seat, next, C_VIEW);
+ return seat_get_focus_inactive_view(seat, next);
} else {
return next;
}
@@ -910,7 +911,7 @@ struct sway_container *container_get_in_direction(
wlr_log(L_DEBUG,
"cont %d-%p dir %i sibling %d: %p", idx,
container, dir, desired, desired_con);
- struct sway_container *next = seat_get_focus_by_type(seat, desired_con, C_VIEW);
+ struct sway_container *next = seat_get_focus_inactive_view(seat, desired_con);
return next;
}
}