@ -6,36 +6,58 @@ struct wlr_scene_output_layout {
struct wlr_output_layout * layout ;
struct wlr_scene * scene ;
struct wl_list outputs ; // wlr_scene_output_layout_output.link
struct wl_listener layout_add ;
struct wl_listener layout_change ;
struct wl_listener layout_destroy ;
struct wl_listener scene_destroy ;
} ;
static void scene_output_layout_destroy ( struct wlr_scene_output_layout * sol ) {
wl_list_remove ( & sol - > layout_destroy . link ) ;
wl_list_remove ( & sol - > layout_add . link ) ;
wl_list_remove ( & sol - > layout_change . link ) ;
wl_list_remove ( & sol - > scene_destroy . link ) ;
free ( sol ) ;
struct wlr_scene_output_layout_output {
struct wlr_output_layout_output * layout_output ;
struct wlr_scene_output * scene_output ;
struct wl_list link ; // wlr_scene_output_layout.outputs
struct wl_listener layout_output_destroy ;
struct wl_listener scene_output_destroy ;
} ;
static void scene_output_layout_output_destroy (
struct wlr_scene_output_layout_output * solo ) {
wlr_scene_output_destroy ( solo - > scene_output ) ;
wl_list_remove ( & solo - > layout_output_destroy . link ) ;
wl_list_remove ( & solo - > scene_output_destroy . link ) ;
wl_list_remove ( & solo - > link ) ;
free ( solo ) ;
}
static void scene_output_layout_handle_layout_destroy (
static void scene_output_layout_ output_ handle_layout_outp ut_destroy(
struct wl_listener * listener , void * data ) {
struct wlr_scene_output_layout * sol =
wl_container_of ( listener , sol , layout_destroy ) ;
struct wlr_scene_output_layout_output * solo =
wl_container_of ( listener , solo , layout_output_destroy ) ;
scene_output_layout_output_destroy ( solo ) ;
}
// Remove all outputs managed by the output layout
struct wlr_scene_output * scene_output , * tmp ;
wl_list_for_each_safe ( scene_output , tmp , & sol - > scene - > outputs , link ) {
struct wlr_output_layout_output * lo =
wlr_output_layout_get ( sol - > layout , scene_output - > output ) ;
if ( lo ! = NULL ) {
wlr_scene_output_destroy ( scene_output ) ;
}
}
static void scene_output_layout_output_handle_scene_output_destroy (
struct wl_listener * listener , void * data ) {
struct wlr_scene_output_layout_output * solo =
wl_container_of ( listener , solo , scene_output_destroy ) ;
solo - > scene_output = NULL ;
scene_output_layout_output_destroy ( solo ) ;
}
scene_output_layout_destroy ( sol ) ;
static void scene_output_layout_destroy ( struct wlr_scene_output_layout * sol ) {
struct wlr_scene_output_layout_output * solo , * tmp ;
wl_list_for_each_safe ( solo , tmp , & sol - > outputs , link ) {
scene_output_layout_output_destroy ( solo ) ;
}
wl_list_remove ( & sol - > layout_add . link ) ;
wl_list_remove ( & sol - > layout_change . link ) ;
wl_list_remove ( & sol - > layout_destroy . link ) ;
wl_list_remove ( & sol - > scene_destroy . link ) ;
free ( sol ) ;
}
static void scene_output_layout_handle_layout_change (
@ -43,17 +65,10 @@ static void scene_output_layout_handle_layout_change(
struct wlr_scene_output_layout * sol =
wl_container_of ( listener , sol , layout_change ) ;
struct wlr_scene_output * scene_output , * tmp ;
wl_list_for_each_safe ( scene_output , tmp , & sol - > scene - > outputs , link ) {
struct wlr_output_layout_output * lo =
wlr_output_layout_get ( sol - > layout , scene_output - > output ) ;
if ( lo = = NULL ) {
// Output has been removed from the layout
wlr_scene_output_destroy ( scene_output ) ;
continue ;
}
wlr_scene_output_set_position ( scene_output , lo - > x , lo - > y ) ;
struct wlr_scene_output_layout_output * solo ;
wl_list_for_each ( solo , & sol - > outputs , link ) {
wlr_scene_output_set_position ( solo - > scene_output ,
solo - > layout_output - > x , solo - > layout_output - > y ) ;
}
}
@ -63,13 +78,38 @@ static void scene_output_layout_handle_layout_add(
wl_container_of ( listener , sol , layout_add ) ;
struct wlr_output_layout_output * lo = data ;
struct wlr_scene_output * scene_output =
wlr_scene_output_create ( sol - > scene , lo - > output ) ;
if ( scene_output = = NULL ) {
struct wlr_scene_output_layout_output * solo = calloc ( 1 , sizeof ( * solo ) ) ;
if ( solo = = NULL ) {
return ;
}
wlr_scene_output_set_position ( scene_output , lo - > x , lo - > y ) ;
solo - > scene_output = wlr_scene_output_create ( sol - > scene , lo - > output ) ;
if ( solo - > scene_output = = NULL ) {
free ( solo ) ;
return ;
}
solo - > layout_output = lo ;
solo - > layout_output_destroy . notify =
scene_output_layout_output_handle_layout_output_destroy ;
wl_signal_add ( & lo - > events . destroy , & solo - > layout_output_destroy ) ;
solo - > scene_output_destroy . notify =
scene_output_layout_output_handle_scene_output_destroy ;
wl_signal_add ( & solo - > scene_output - > events . destroy ,
& solo - > scene_output_destroy ) ;
wl_list_insert ( & sol - > outputs , & solo - > link ) ;
wlr_scene_output_set_position ( solo - > scene_output , lo - > x , lo - > y ) ;
}
static void scene_output_layout_handle_layout_destroy (
struct wl_listener * listener , void * data ) {
struct wlr_scene_output_layout * sol =
wl_container_of ( listener , sol , layout_destroy ) ;
scene_output_layout_destroy ( sol ) ;
}
static void scene_output_layout_handle_scene_destroy (
@ -89,6 +129,8 @@ bool wlr_scene_attach_output_layout(struct wlr_scene *scene,
sol - > scene = scene ;
sol - > layout = output_layout ;
wl_list_init ( & sol - > outputs ) ;
sol - > layout_destroy . notify = scene_output_layout_handle_layout_destroy ;
wl_signal_add ( & output_layout - > events . destroy , & sol - > layout_destroy ) ;