@ -561,10 +561,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc,
* sx = _sx ;
* sx = _sx ;
* sy = _sy ;
* sy = _sy ;
* surface = _surface ;
* surface = _surface ;
}
return swayc ;
return swayc ;
}
return NULL ;
}
}
static struct sway_container * tiling_container_at (
struct sway_container * con , double lx , double ly ,
struct wlr_surface * * surface , double * sx , double * sy ) ;
/**
/**
* container_at for a container with layout L_TABBED .
* container_at for a container with layout L_TABBED .
*/
*/
@ -591,7 +596,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent,
// Surfaces
// Surfaces
struct sway_container * current = seat_get_active_child ( seat , parent ) ;
struct sway_container * current = seat_get_active_child ( seat , parent ) ;
return container_at( current , lx , ly , surface , sx , sy ) ;
return tiling_ container_at( current , lx , ly , surface , sx , sy ) ;
}
}
/**
/**
@ -616,7 +621,7 @@ static struct sway_container *container_at_stacked(
// Surfaces
// Surfaces
struct sway_container * current = seat_get_active_child ( seat , parent ) ;
struct sway_container * current = seat_get_active_child ( seat , parent ) ;
return container_at( current , lx , ly , surface , sx , sy ) ;
return tiling_ container_at( current , lx , ly , surface , sx , sy ) ;
}
}
/**
/**
@ -634,45 +639,13 @@ static struct sway_container *container_at_linear(struct sway_container *parent,
. height = child - > height ,
. height = child - > height ,
} ;
} ;
if ( wlr_box_contains_point ( & box , lx , ly ) ) {
if ( wlr_box_contains_point ( & box , lx , ly ) ) {
return container_at ( child , lx , ly , surface , sx , sy ) ;
return tiling_container_at ( child , lx , ly , surface , sx , sy ) ;
}
}
}
return NULL ;
}
struct sway_container * container_at ( struct sway_container * parent ,
double lx , double ly ,
struct wlr_surface * * surface , double * sx , double * sy ) {
if ( ! sway_assert ( parent - > type > = C_WORKSPACE ,
" Expected workspace or deeper " ) ) {
return NULL ;
}
if ( parent - > type = = C_VIEW ) {
return container_at_view ( parent , lx , ly , surface , sx , sy ) ;
}
if ( ! parent - > children - > length ) {
return NULL ;
}
switch ( parent - > layout ) {
case L_HORIZ :
case L_VERT :
return container_at_linear ( parent , lx , ly , surface , sx , sy ) ;
case L_TABBED :
return container_at_tabbed ( parent , lx , ly , surface , sx , sy ) ;
case L_STACKED :
return container_at_stacked ( parent , lx , ly , surface , sx , sy ) ;
case L_FLOATING :
sway_assert ( false , " Didn't expect to see floating here " ) ;
return NULL ;
case L_NONE :
return NULL ;
}
}
return NULL ;
return NULL ;
}
}
struct sway_container * floating_container_at ( double lx , double ly ,
static struct sway_container * floating_container_at ( double lx , double ly ,
struct wlr_surface * * surface , double * sx , double * sy ) {
struct wlr_surface * * surface , double * sx , double * sy ) {
for ( int i = 0 ; i < root_container . children - > length ; + + i ) {
for ( int i = 0 ; i < root_container . children - > length ; + + i ) {
struct sway_container * output = root_container . children - > items [ i ] ;
struct sway_container * output = root_container . children - > items [ i ] ;
@ -694,7 +667,8 @@ struct sway_container *floating_container_at(double lx, double ly,
. height = floater - > height ,
. height = floater - > height ,
} ;
} ;
if ( wlr_box_contains_point ( & box , lx , ly ) ) {
if ( wlr_box_contains_point ( & box , lx , ly ) ) {
return container_at ( floater , lx , ly , surface , sx , sy ) ;
return tiling_container_at ( floater , lx , ly ,
surface , sx , sy ) ;
}
}
}
}
}
}
@ -702,6 +676,90 @@ struct sway_container *floating_container_at(double lx, double ly,
return NULL ;
return NULL ;
}
}
static struct sway_container * tiling_container_at (
struct sway_container * con , double lx , double ly ,
struct wlr_surface * * surface , double * sx , double * sy ) {
if ( con - > type = = C_VIEW ) {
return container_at_view ( con , lx , ly , surface , sx , sy ) ;
}
if ( ! con - > children - > length ) {
return NULL ;
}
switch ( con - > layout ) {
case L_HORIZ :
case L_VERT :
return container_at_linear ( con , lx , ly , surface , sx , sy ) ;
case L_TABBED :
return container_at_tabbed ( con , lx , ly , surface , sx , sy ) ;
case L_STACKED :
return container_at_stacked ( con , lx , ly , surface , sx , sy ) ;
case L_FLOATING :
sway_assert ( false , " Didn't expect to see floating here " ) ;
return NULL ;
case L_NONE :
return NULL ;
}
return NULL ;
}
static bool surface_is_popup ( struct wlr_surface * surface ) {
if ( wlr_surface_is_xdg_surface ( surface ) ) {
struct wlr_xdg_surface * xdg_surface =
wlr_xdg_surface_from_wlr_surface ( surface ) ;
while ( xdg_surface ) {
if ( xdg_surface - > role = = WLR_XDG_SURFACE_ROLE_POPUP ) {
return true ;
}
xdg_surface = xdg_surface - > toplevel - > parent ;
}
return false ;
}
if ( wlr_surface_is_xdg_surface_v6 ( surface ) ) {
struct wlr_xdg_surface_v6 * xdg_surface_v6 =
wlr_xdg_surface_v6_from_wlr_surface ( surface ) ;
while ( xdg_surface_v6 ) {
if ( xdg_surface_v6 - > role = = WLR_XDG_SURFACE_V6_ROLE_POPUP ) {
return true ;
}
xdg_surface_v6 = xdg_surface_v6 - > toplevel - > parent ;
}
return false ;
}
return false ;
}
struct sway_container * container_at ( struct sway_container * workspace ,
double lx , double ly ,
struct wlr_surface * * surface , double * sx , double * sy ) {
if ( ! sway_assert ( workspace - > type = = C_WORKSPACE , " Expected a workspace " ) ) {
return NULL ;
}
struct sway_container * c ;
// Focused view's popups
struct sway_seat * seat = input_manager_current_seat ( input_manager ) ;
struct sway_container * focus =
seat_get_focus_inactive ( seat , & root_container ) ;
if ( focus & & focus - > type = = C_VIEW ) {
container_at_view ( focus , lx , ly , surface , sx , sy ) ;
if ( * surface & & surface_is_popup ( * surface ) ) {
return focus ;
}
* surface = NULL ;
}
// Floating
if ( ( c = floating_container_at ( lx , ly , surface , sx , sy ) ) ) {
return c ;
}
// Tiling
if ( ( c = tiling_container_at ( workspace , lx , ly , surface , sx , sy ) ) ) {
return c ;
}
return NULL ;
}
void container_for_each_descendant_dfs ( struct sway_container * container ,
void container_for_each_descendant_dfs ( struct sway_container * container ,
void ( * f ) ( struct sway_container * container , void * data ) ,
void ( * f ) ( struct sway_container * container , void * data ) ,
void * data ) {
void * data ) {