@ -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 ,
struct sway_container * container ,
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 * container ) {
return seat_get_focus_by_type ( seat , container , C_VIEW , false ) ;
struct sway_container * ancestor ) {
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 ,
@ -198,7 +172,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
if ( set_focus ) {
struct sway_container * 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 ) {
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
struct sway_container * new_output_last_ws = NULL ;
if ( last_output & & new_output & & last_output ! = new_output ) {
new_output_last_ws =
seat_get_focus_by_type ( seat , new_output , C_WORKSPACE , false ) ;
new_output_last_ws = seat_get_active_child ( seat , new_output ) ;
}
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 * container ) {
return seat_get_focus_by_type ( seat , container , C_TYPES , false ) ;
struct sway_container * con ) {
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 * container ) {
return seat_get_focus_by_type ( seat , container , C_TYPES , true ) ;
struct sway_container * ancestor ) {
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 * container ) {
struct sway_seat_container * current = NULL ;
struct sway_container * parent ) {
if ( parent - > type = = C_VIEW ) {
return parent ;
}
struct sway_seat_container * current ;
wl_list_for_each ( current , & seat - > focus_stack , link ) {
if ( current - > container - > parent = = container & &
current - > container - > layout ! = L_FLOATING ) {
return current - > container ;
struct sway_container * con = current - > container ;
if ( con - > parent = = parent & & con - > layout ! = L_FLOATING ) {
return c on;
}
}
return NULL ;
@ -902,7 +924,9 @@ struct sway_container *seat_get_focus(struct sway_seat *seat) {
if ( ! seat - > has_focus ) {
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 ,