|
|
@ -124,42 +124,6 @@ static void seat_send_focus(struct sway_container *con,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
|
|
|
|
|
|
|
|
struct sway_container *container, enum sway_container_type type,
|
|
|
|
|
|
|
|
bool only_tiling) {
|
|
|
|
|
|
|
|
if (container->type == C_VIEW) {
|
|
|
|
|
|
|
|
return container;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct sway_container *floating =
|
|
|
|
|
|
|
|
container->type == C_WORKSPACE && !only_tiling ?
|
|
|
|
|
|
|
|
container->sway_workspace->floating : NULL;
|
|
|
|
|
|
|
|
if (container->children->length == 0 &&
|
|
|
|
|
|
|
|
(!floating || floating->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_ancestor(current->container, container)) {
|
|
|
|
|
|
|
|
if (only_tiling &&
|
|
|
|
|
|
|
|
container_is_floating_or_child(current->container)) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return current->container;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (floating && container_has_ancestor(current->container, floating)) {
|
|
|
|
|
|
|
|
return current->container;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void seat_focus_inactive_children_for_each(struct sway_seat *seat,
|
|
|
|
void seat_focus_inactive_children_for_each(struct sway_seat *seat,
|
|
|
|
struct sway_container *container,
|
|
|
|
struct sway_container *container,
|
|
|
|
void (*f)(struct sway_container *container, void *data), void *data) {
|
|
|
|
void (*f)(struct sway_container *container, void *data), void *data) {
|
|
|
@ -175,8 +139,18 @@ void seat_focus_inactive_children_for_each(struct sway_seat *seat,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
|
|
|
|
struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat,
|
|
|
|
struct sway_container *container) {
|
|
|
|
struct sway_container *ancestor) {
|
|
|
|
return seat_get_focus_by_type(seat, container, C_VIEW, false);
|
|
|
|
if (ancestor->type == C_VIEW) {
|
|
|
|
|
|
|
|
return ancestor;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct sway_seat_container *current;
|
|
|
|
|
|
|
|
wl_list_for_each(current, &seat->focus_stack, link) {
|
|
|
|
|
|
|
|
struct sway_container *con = current->container;
|
|
|
|
|
|
|
|
if (con->type == C_VIEW && container_has_ancestor(con, ancestor)) {
|
|
|
|
|
|
|
|
return con;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void handle_seat_container_destroy(struct wl_listener *listener,
|
|
|
|
static void handle_seat_container_destroy(struct wl_listener *listener,
|
|
|
@ -198,7 +172,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
|
|
|
|
if (set_focus) {
|
|
|
|
if (set_focus) {
|
|
|
|
struct sway_container *next_focus = NULL;
|
|
|
|
struct sway_container *next_focus = NULL;
|
|
|
|
while (next_focus == NULL) {
|
|
|
|
while (next_focus == NULL) {
|
|
|
|
next_focus = seat_get_focus_by_type(seat, parent, C_VIEW, false);
|
|
|
|
next_focus = seat_get_focus_inactive_view(seat, parent);
|
|
|
|
|
|
|
|
|
|
|
|
if (next_focus == NULL && parent->type == C_WORKSPACE) {
|
|
|
|
if (next_focus == NULL && parent->type == C_WORKSPACE) {
|
|
|
|
next_focus = parent;
|
|
|
|
next_focus = parent;
|
|
|
@ -653,8 +627,7 @@ void seat_set_focus_warp(struct sway_seat *seat,
|
|
|
|
// find new output's old workspace, which might have to be removed if empty
|
|
|
|
// find new output's old workspace, which might have to be removed if empty
|
|
|
|
struct sway_container *new_output_last_ws = NULL;
|
|
|
|
struct sway_container *new_output_last_ws = NULL;
|
|
|
|
if (last_output && new_output && last_output != new_output) {
|
|
|
|
if (last_output && new_output && last_output != new_output) {
|
|
|
|
new_output_last_ws =
|
|
|
|
new_output_last_ws = seat_get_active_child(seat, new_output);
|
|
|
|
seat_get_focus_by_type(seat, new_output, C_WORKSPACE, false);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (container && container->parent) {
|
|
|
|
if (container && container->parent) {
|
|
|
@ -877,22 +850,71 @@ void seat_set_exclusive_client(struct sway_seat *seat,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
|
|
|
|
struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
|
|
|
|
struct sway_container *container) {
|
|
|
|
struct sway_container *con) {
|
|
|
|
return seat_get_focus_by_type(seat, container, C_TYPES, false);
|
|
|
|
if (con->type == C_WORKSPACE && !con->children->length &&
|
|
|
|
|
|
|
|
!con->sway_workspace->floating->children->length) {
|
|
|
|
|
|
|
|
return con;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (con->type == C_VIEW) {
|
|
|
|
|
|
|
|
return con;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct sway_seat_container *current;
|
|
|
|
|
|
|
|
wl_list_for_each(current, &seat->focus_stack, link) {
|
|
|
|
|
|
|
|
if (container_has_ancestor(current->container, con)) {
|
|
|
|
|
|
|
|
return current->container;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
|
|
|
|
struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat,
|
|
|
|
struct sway_container *container) {
|
|
|
|
struct sway_container *ancestor) {
|
|
|
|
return seat_get_focus_by_type(seat, container, C_TYPES, true);
|
|
|
|
if (ancestor->type == C_WORKSPACE && !ancestor->children->length) {
|
|
|
|
|
|
|
|
return ancestor;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct sway_seat_container *current;
|
|
|
|
|
|
|
|
wl_list_for_each(current, &seat->focus_stack, link) {
|
|
|
|
|
|
|
|
struct sway_container *con = current->container;
|
|
|
|
|
|
|
|
if (con->layout != L_FLOATING && !container_is_floating_or_child(con) &&
|
|
|
|
|
|
|
|
container_has_ancestor(current->container, ancestor)) {
|
|
|
|
|
|
|
|
return con;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat,
|
|
|
|
|
|
|
|
struct sway_container *ancestor) {
|
|
|
|
|
|
|
|
if (ancestor->type == C_WORKSPACE &&
|
|
|
|
|
|
|
|
!ancestor->sway_workspace->floating->children->length) {
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct sway_seat_container *current;
|
|
|
|
|
|
|
|
wl_list_for_each(current, &seat->focus_stack, link) {
|
|
|
|
|
|
|
|
struct sway_container *con = current->container;
|
|
|
|
|
|
|
|
if (con->layout != L_FLOATING && container_is_floating_or_child(con) &&
|
|
|
|
|
|
|
|
container_has_ancestor(current->container, ancestor)) {
|
|
|
|
|
|
|
|
return con;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool impl_focus_active_child(struct sway_container *con, void *data) {
|
|
|
|
|
|
|
|
struct sway_container *parent = data;
|
|
|
|
|
|
|
|
return con->parent == parent && con->layout != L_FLOATING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct sway_container *seat_get_active_child(struct sway_seat *seat,
|
|
|
|
struct sway_container *seat_get_active_child(struct sway_seat *seat,
|
|
|
|
struct sway_container *container) {
|
|
|
|
struct sway_container *parent) {
|
|
|
|
struct sway_seat_container *current = NULL;
|
|
|
|
if (parent->type == C_VIEW) {
|
|
|
|
|
|
|
|
return parent;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
struct sway_seat_container *current;
|
|
|
|
wl_list_for_each(current, &seat->focus_stack, link) {
|
|
|
|
wl_list_for_each(current, &seat->focus_stack, link) {
|
|
|
|
if (current->container->parent == container &&
|
|
|
|
struct sway_container *con = current->container;
|
|
|
|
current->container->layout != L_FLOATING) {
|
|
|
|
if (con->parent == parent && con->layout != L_FLOATING) {
|
|
|
|
return current->container;
|
|
|
|
return con;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
@ -902,7 +924,9 @@ struct sway_container *seat_get_focus(struct sway_seat *seat) {
|
|
|
|
if (!seat->has_focus) {
|
|
|
|
if (!seat->has_focus) {
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return seat_get_focus_inactive(seat, &root_container);
|
|
|
|
struct sway_seat_container *current =
|
|
|
|
|
|
|
|
wl_container_of(seat->focus_stack.next, current, link);
|
|
|
|
|
|
|
|
return current->container;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void seat_apply_config(struct sway_seat *seat,
|
|
|
|
void seat_apply_config(struct sway_seat *seat,
|
|
|
|