@ -104,6 +104,9 @@ struct shell_surface {
struct desktop_shell * shell ;
struct wl_list children_list ;
struct wl_list children_link ;
int32_t saved_x , saved_y ;
bool saved_position_valid ;
bool saved_rotation_valid ;
@ -2416,6 +2419,13 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface,
wl_list_init ( & shsurf - > workspace_transform . link ) ;
/*
* initialize list as well as link . The latter allows to use
* wl_list_remove ( ) even when this surface is not in another list .
*/
wl_list_init ( & shsurf - > children_list ) ;
wl_list_init ( & shsurf - > children_link ) ;
weston_desktop_surface_set_user_data ( desktop_surface , shsurf ) ;
weston_desktop_surface_set_activated ( desktop_surface ,
shsurf - > focus_count > 0 ) ;
@ -2427,12 +2437,19 @@ desktop_surface_removed(struct weston_desktop_surface *desktop_surface,
{
struct shell_surface * shsurf =
weston_desktop_surface_get_user_data ( desktop_surface ) ;
struct shell_surface * shsurf_child , * tmp ;
struct weston_surface * surface =
weston_desktop_surface_get_surface ( desktop_surface ) ;
if ( ! shsurf )
return ;
wl_list_for_each_safe ( shsurf_child , tmp , & shsurf - > children_list , children_link ) {
wl_list_remove ( & shsurf_child - > children_link ) ;
wl_list_init ( & shsurf_child - > children_link ) ;
}
wl_list_remove ( & shsurf - > children_link ) ;
wl_signal_emit ( & shsurf - > destroy_signal , shsurf ) ;
if ( shsurf - > fullscreen . black_view )
@ -2747,6 +2764,20 @@ desktop_surface_resize(struct weston_desktop_surface *desktop_surface,
wl_resource_post_no_memory ( resource ) ;
}
static void
desktop_surface_set_parent ( struct weston_desktop_surface * desktop_surface ,
struct weston_desktop_surface * parent ,
void * shell )
{
struct shell_surface * shsurf =
weston_desktop_surface_get_user_data ( desktop_surface ) ;
struct shell_surface * shsurf_parent =
weston_desktop_surface_get_user_data ( parent ) ;
wl_list_insert ( shsurf_parent - > children_list . prev ,
& shsurf - > children_link ) ;
}
static void
desktop_surface_fullscreen_requested ( struct weston_desktop_surface * desktop_surface ,
bool fullscreen ,
@ -2929,6 +2960,7 @@ static const struct weston_desktop_api shell_desktop_api = {
. committed = desktop_surface_committed ,
. move = desktop_surface_move ,
. resize = desktop_surface_resize ,
. set_parent = desktop_surface_set_parent ,
. fullscreen_requested = desktop_surface_fullscreen_requested ,
. maximized_requested = desktop_surface_maximized_requested ,
. minimized_requested = desktop_surface_minimized_requested ,
@ -3777,6 +3809,18 @@ lower_fullscreen_layer(struct desktop_shell *shell,
}
}
static struct shell_surface * get_last_child ( struct shell_surface * shsurf )
{
struct shell_surface * shsurf_child ;
wl_list_for_each_reverse ( shsurf_child , & shsurf - > children_list , children_link ) {
if ( weston_view_is_mapped ( shsurf_child - > view ) )
return shsurf_child ;
}
return NULL ;
}
void
activate ( struct desktop_shell * shell , struct weston_view * view ,
struct weston_seat * seat , uint32_t flags )
@ -3786,12 +3830,19 @@ activate(struct desktop_shell *shell, struct weston_view *view,
struct focus_state * state ;
struct workspace * ws ;
struct weston_surface * old_es ;
struct shell_surface * shsurf ;
struct shell_surface * shsurf , * shsurf_child ;
main_surface = weston_surface_get_main_surface ( es ) ;
shsurf = get_shell_surface ( main_surface ) ;
assert ( shsurf ) ;
shsurf_child = get_last_child ( shsurf ) ;
if ( shsurf_child ) {
/* Activate last xdg child instead of parent. */
activate ( shell , shsurf_child - > view , seat , flags ) ;
return ;
}
/* Only demote fullscreen surfaces on the output of activated shsurf.
* Leave fullscreen surfaces on unrelated outputs alone . */
if ( shsurf - > output )