@ -126,8 +126,6 @@ struct shell_surface {
struct weston_curtain * black_view ;
} fullscreen ;
struct weston_transform workspace_transform ;
struct weston_output * fullscreen_output ;
struct weston_output * output ;
struct wl_listener output_destroy_listener ;
@ -516,9 +514,6 @@ shell_configuration(struct desktop_shell *shell)
weston_config_section_get_string ( section , " focus-animation " , & s , " none " ) ;
shell - > focus_animation_type = get_animation_type ( s ) ;
free ( s ) ;
weston_config_section_get_uint ( section , " num-workspaces " ,
& shell - > workspaces . num ,
DEFAULT_NUM_WORKSPACES ) ;
}
static int
@ -534,15 +529,6 @@ focus_surface_committed(struct weston_surface *es, int32_t sx, int32_t sy)
{
}
static struct focus_surface *
get_focus_surface ( struct weston_surface * surface )
{
if ( surface - > committed = = focus_surface_committed )
return surface - > committed_private ;
else
return NULL ;
}
static bool
is_focus_view ( struct weston_view * view )
{
@ -574,8 +560,6 @@ create_focus_surface(struct weston_compositor *ec,
weston_view_set_output ( fsurf - > curtain - > view , output ) ;
fsurf - > curtain - > view - > is_mapped = true ;
wl_list_init ( & fsurf - > workspace_transform . link ) ;
return fsurf ;
}
@ -768,21 +752,6 @@ restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
}
}
static void
replace_focus_state ( struct desktop_shell * shell , struct workspace * ws ,
struct weston_seat * seat )
{
struct weston_keyboard * keyboard = weston_seat_get_keyboard ( seat ) ;
struct focus_state * state ;
wl_list_for_each ( state , & ws - > focus_list , link ) {
if ( state - > seat = = seat ) {
focus_state_set_focus ( state , keyboard - > focus ) ;
return ;
}
}
}
static void
drop_focus_state ( struct desktop_shell * shell , struct workspace * ws ,
struct weston_surface * surface )
@ -876,7 +845,6 @@ workspace_destroy(struct workspace *ws)
focus_surface_destroy ( ws - > fsurf_back ) ;
desktop_shell_destroy_layer ( & ws - > layer ) ;
free ( ws ) ;
}
static void
@ -893,14 +861,13 @@ seat_destroyed(struct wl_listener *listener, void *data)
wl_list_remove ( & state - > link ) ;
}
static struct workspace *
static void
workspace_create ( struct desktop_shell * shell )
{
struct workspace * ws = malloc ( sizeof * ws ) ;
if ( ws = = NULL )
return NULL ;
struct workspace * ws = & shell - > workspace ;
weston_layer_init ( & ws - > layer , shell - > compositor ) ;
weston_layer_set_position ( & ws - > layer , WESTON_LAYER_POSITION_NORMAL ) ;
wl_list_init ( & ws - > focus_list ) ;
wl_list_init ( & ws - > seat_destroyed_listener . link ) ;
@ -908,343 +875,12 @@ workspace_create(struct desktop_shell *shell)
ws - > fsurf_front = NULL ;
ws - > fsurf_back = NULL ;
ws - > focus_animation = NULL ;
return ws ;
}
static int
workspace_is_empty ( struct workspace * ws )
{
return wl_list_empty ( & ws - > layer . view_list . link ) ;
}
static struct workspace *
get_workspace ( struct desktop_shell * shell , unsigned int index )
{
struct workspace * * pws = shell - > workspaces . array . data ;
assert ( index < shell - > workspaces . num ) ;
pws + = index ;
return * pws ;
}
struct workspace *
get_current_workspace ( struct desktop_shell * shell )
{
return get_workspace ( shell , shell - > workspaces . current ) ;
}
static void
activate_workspace ( struct desktop_shell * shell , unsigned int index )
{
struct workspace * ws ;
ws = get_workspace ( shell , index ) ;
weston_layer_set_position ( & ws - > layer , WESTON_LAYER_POSITION_NORMAL ) ;
shell - > workspaces . current = index ;
}
static unsigned int
get_output_height ( struct weston_output * output )
{
return abs ( output - > region . extents . y1 - output - > region . extents . y2 ) ;
}
static struct weston_transform *
view_get_transform ( struct weston_view * view )
{
struct focus_surface * fsurf = NULL ;
struct shell_surface * shsurf = NULL ;
if ( is_focus_view ( view ) ) {
fsurf = get_focus_surface ( view - > surface ) ;
return & fsurf - > workspace_transform ;
}
shsurf = get_shell_surface ( view - > surface ) ;
if ( shsurf )
return & shsurf - > workspace_transform ;
return NULL ;
}
static void
view_translate ( struct workspace * ws , struct weston_view * view , double d )
{
struct weston_transform * transform = view_get_transform ( view ) ;
if ( ! transform )
return ;
if ( wl_list_empty ( & transform - > link ) )
wl_list_insert ( view - > geometry . transformation_list . prev ,
& transform - > link ) ;
weston_matrix_init ( & transform - > matrix ) ;
weston_matrix_translate ( & transform - > matrix ,
0.0 , d , 0.0 ) ;
weston_view_geometry_dirty ( view ) ;
}
static void
workspace_translate_out ( struct workspace * ws , double fraction )
{
struct weston_view * view ;
unsigned int height ;
double d ;
wl_list_for_each ( view , & ws - > layer . view_list . link , layer_link . link ) {
height = get_output_height ( view - > surface - > output ) ;
d = height * fraction ;
view_translate ( ws , view , d ) ;
}
}
static void
workspace_translate_in ( struct workspace * ws , double fraction )
{
struct weston_view * view ;
unsigned int height ;
double d ;
wl_list_for_each ( view , & ws - > layer . view_list . link , layer_link . link ) {
height = get_output_height ( view - > surface - > output ) ;
if ( fraction > 0 )
d = - ( height - height * fraction ) ;
else
d = height + height * fraction ;
view_translate ( ws , view , d ) ;
}
}
static void
reverse_workspace_change_animation ( struct desktop_shell * shell ,
unsigned int index ,
struct workspace * from ,
struct workspace * to )
{
shell - > workspaces . current = index ;
shell - > workspaces . anim_to = to ;
shell - > workspaces . anim_from = from ;
shell - > workspaces . anim_dir = - 1 * shell - > workspaces . anim_dir ;
shell - > workspaces . anim_timestamp = ( struct timespec ) { 0 } ;
weston_layer_set_position ( & to - > layer , WESTON_LAYER_POSITION_NORMAL ) ;
weston_layer_set_position ( & from - > layer , WESTON_LAYER_POSITION_NORMAL - 1 ) ;
weston_compositor_schedule_repaint ( shell - > compositor ) ;
}
static void
workspace_deactivate_transforms ( struct workspace * ws )
{
struct weston_view * view ;
struct weston_transform * transform ;
wl_list_for_each ( view , & ws - > layer . view_list . link , layer_link . link ) {
transform = view_get_transform ( view ) ;
if ( ! transform )
continue ;
if ( ! wl_list_empty ( & transform - > link ) ) {
wl_list_remove ( & transform - > link ) ;
wl_list_init ( & transform - > link ) ;
}
weston_view_geometry_dirty ( view ) ;
}
}
static void
finish_workspace_change_animation ( struct desktop_shell * shell ,
struct workspace * from ,
struct workspace * to )
{
struct weston_view * view ;
weston_compositor_schedule_repaint ( shell - > compositor ) ;
/* Views that extend past the bottom of the output are still
* visible after the workspace animation ends but before its layer
* is hidden . In that case , we need to damage below those views so
* that the screen is properly repainted . */
wl_list_for_each ( view , & from - > layer . view_list . link , layer_link . link )
weston_view_damage_below ( view ) ;
wl_list_remove ( & shell - > workspaces . animation . link ) ;
workspace_deactivate_transforms ( from ) ;
workspace_deactivate_transforms ( to ) ;
shell - > workspaces . anim_to = NULL ;
weston_layer_unset_position ( & shell - > workspaces . anim_from - > layer ) ;
}
static void
animate_workspace_change_frame ( struct weston_animation * animation ,
struct weston_output * output ,
const struct timespec * time )
{
struct desktop_shell * shell =
container_of ( animation , struct desktop_shell ,
workspaces . animation ) ;
struct workspace * from = shell - > workspaces . anim_from ;
struct workspace * to = shell - > workspaces . anim_to ;
int64_t t ;
double x , y ;
if ( workspace_is_empty ( from ) & & workspace_is_empty ( to ) ) {
finish_workspace_change_animation ( shell , from , to ) ;
return ;
}
if ( timespec_is_zero ( & shell - > workspaces . anim_timestamp ) ) {
if ( shell - > workspaces . anim_current = = 0.0 )
shell - > workspaces . anim_timestamp = * time ;
else
timespec_add_msec ( & shell - > workspaces . anim_timestamp ,
time ,
/* Inverse of movement function 'y' below. */
- ( asin ( 1.0 - shell - > workspaces . anim_current ) *
DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH *
M_2_PI ) ) ;
}
t = timespec_sub_to_msec ( time , & shell - > workspaces . anim_timestamp ) ;
/*
* x = [ 0 , π / 2 ]
* y ( x ) = sin ( x )
*/
x = t * ( 1.0 / DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH ) * M_PI_2 ;
y = sin ( x ) ;
if ( t < DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH ) {
weston_compositor_schedule_repaint ( shell - > compositor ) ;
workspace_translate_out ( from , shell - > workspaces . anim_dir * y ) ;
workspace_translate_in ( to , shell - > workspaces . anim_dir * y ) ;
shell - > workspaces . anim_current = y ;
weston_compositor_schedule_repaint ( shell - > compositor ) ;
}
else
finish_workspace_change_animation ( shell , from , to ) ;
}
static void
animate_workspace_change ( struct desktop_shell * shell ,
unsigned int index ,
struct workspace * from ,
struct workspace * to )
{
struct weston_output * output ;
int dir ;
if ( index > shell - > workspaces . current )
dir = - 1 ;
else
dir = 1 ;
shell - > workspaces . current = index ;
shell - > workspaces . anim_dir = dir ;
shell - > workspaces . anim_from = from ;
shell - > workspaces . anim_to = to ;
shell - > workspaces . anim_current = 0.0 ;
shell - > workspaces . anim_timestamp = ( struct timespec ) { 0 } ;
output = container_of ( shell - > compositor - > output_list . next ,
struct weston_output , link ) ;
wl_list_insert ( & output - > animation_list ,
& shell - > workspaces . animation . link ) ;
weston_layer_set_position ( & to - > layer , WESTON_LAYER_POSITION_NORMAL ) ;
weston_layer_set_position ( & from - > layer , WESTON_LAYER_POSITION_NORMAL - 1 ) ;
workspace_translate_in ( to , 0 ) ;
restore_focus_state ( shell , to ) ;
weston_compositor_schedule_repaint ( shell - > compositor ) ;
}
static void
update_workspace ( struct desktop_shell * shell , unsigned int index ,
struct workspace * from , struct workspace * to )
{
shell - > workspaces . current = index ;
weston_layer_set_position ( & to - > layer , WESTON_LAYER_POSITION_NORMAL ) ;
weston_layer_unset_position ( & from - > layer ) ;
}
static void
change_workspace ( struct desktop_shell * shell , unsigned int index )
{
struct workspace * from ;
struct workspace * to ;
struct focus_state * state ;
if ( index = = shell - > workspaces . current )
return ;
/* Don't change workspace when there is any fullscreen surfaces. */
if ( ! wl_list_empty ( & shell - > fullscreen_layer . view_list . link ) )
return ;
from = get_current_workspace ( shell ) ;
to = get_workspace ( shell , index ) ;
if ( shell - > workspaces . anim_from = = to & &
shell - > workspaces . anim_to = = from ) {
restore_focus_state ( shell , to ) ;
reverse_workspace_change_animation ( shell , index , from , to ) ;
return ;
}
if ( shell - > workspaces . anim_to ! = NULL )
finish_workspace_change_animation ( shell ,
shell - > workspaces . anim_from ,
shell - > workspaces . anim_to ) ;
restore_focus_state ( shell , to ) ;
if ( shell - > focus_animation_type ! = ANIMATION_NONE ) {
wl_list_for_each ( state , & from - > focus_list , link )
if ( state - > keyboard_focus )
animate_focus_change ( shell , from ,
get_default_view ( state - > keyboard_focus ) , NULL ) ;
wl_list_for_each ( state , & to - > focus_list , link )
if ( state - > keyboard_focus )
animate_focus_change ( shell , to ,
NULL , get_default_view ( state - > keyboard_focus ) ) ;
}
if ( workspace_is_empty ( to ) & & workspace_is_empty ( from ) )
update_workspace ( shell , index , from , to ) ;
else
animate_workspace_change ( shell , index , from , to ) ;
}
static bool
workspace_has_only ( struct workspace * ws , struct weston_surface * surface )
{
struct wl_list * list = & ws - > layer . view_list . link ;
struct wl_list * e ;
if ( wl_list_empty ( list ) )
return false ;
e = list - > next ;
if ( e - > next ! = list )
return false ;
return container_of ( e , struct weston_view , layer_link . link ) - > surface = = surface ;
return & shell - > workspace ;
}
static void
@ -1267,68 +903,6 @@ surface_keyboard_focus_lost(struct weston_surface *surface)
}
}
static void
take_surface_to_workspace_by_seat ( struct desktop_shell * shell ,
struct weston_seat * seat ,
unsigned int index )
{
struct weston_keyboard * keyboard = weston_seat_get_keyboard ( seat ) ;
struct weston_surface * surface ;
struct weston_view * view ;
struct shell_surface * shsurf ;
struct workspace * from ;
struct workspace * to ;
struct focus_state * state ;
surface = weston_surface_get_main_surface ( keyboard - > focus ) ;
view = get_default_view ( surface ) ;
if ( view = = NULL | |
index = = shell - > workspaces . current | |
is_focus_view ( view ) )
return ;
from = get_current_workspace ( shell ) ;
to = get_workspace ( shell , index ) ;
weston_layer_entry_remove ( & view - > layer_link ) ;
weston_layer_entry_insert ( & to - > layer . view_list , & view - > layer_link ) ;
shsurf = get_shell_surface ( surface ) ;
if ( shsurf ! = NULL )
shell_surface_update_child_surface_layers ( shsurf ) ;
replace_focus_state ( shell , to , seat ) ;
drop_focus_state ( shell , from , surface ) ;
if ( shell - > workspaces . anim_from = = to & &
shell - > workspaces . anim_to = = from ) {
reverse_workspace_change_animation ( shell , index , from , to ) ;
return ;
}
if ( shell - > workspaces . anim_to ! = NULL )
finish_workspace_change_animation ( shell ,
shell - > workspaces . anim_from ,
shell - > workspaces . anim_to ) ;
if ( workspace_is_empty ( from ) & &
workspace_has_only ( to , surface ) )
update_workspace ( shell , index , from , to ) ;
else {
if ( shsurf ! = NULL & &
wl_list_empty ( & shsurf - > workspace_transform . link ) )
wl_list_insert ( & shell - > workspaces . anim_sticky_list ,
& shsurf - > workspace_transform . link ) ;
animate_workspace_change ( shell , index , from , to ) ;
}
state = ensure_focus_state ( shell , seat ) ;
if ( state ! = NULL )
focus_state_set_focus ( state , surface ) ;
}
static void
touch_move_grab_down ( struct weston_touch_grab * grab ,
const struct timespec * time ,
@ -2306,8 +1880,6 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface,
wl_list_init ( & shsurf - > rotation . transform . link ) ;
weston_matrix_init ( & shsurf - > rotation . rotation ) ;
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 .
@ -4570,86 +4142,6 @@ force_kill_binding(struct weston_keyboard *keyboard,
kill ( pid , SIGKILL ) ;
}
static void
workspace_up_binding ( struct weston_keyboard * keyboard ,
const struct timespec * time , uint32_t key , void * data )
{
struct desktop_shell * shell = data ;
unsigned int new_index = shell - > workspaces . current ;
if ( shell - > locked )
return ;
if ( new_index ! = 0 )
new_index - - ;
change_workspace ( shell , new_index ) ;
}
static void
workspace_down_binding ( struct weston_keyboard * keyboard ,
const struct timespec * time , uint32_t key , void * data )
{
struct desktop_shell * shell = data ;
unsigned int new_index = shell - > workspaces . current ;
if ( shell - > locked )
return ;
if ( new_index < shell - > workspaces . num - 1 )
new_index + + ;
change_workspace ( shell , new_index ) ;
}
static void
workspace_f_binding ( struct weston_keyboard * keyboard ,
const struct timespec * time , uint32_t key , void * data )
{
struct desktop_shell * shell = data ;
unsigned int new_index ;
if ( shell - > locked )
return ;
new_index = key - KEY_F1 ;
if ( new_index > = shell - > workspaces . num )
new_index = shell - > workspaces . num - 1 ;
change_workspace ( shell , new_index ) ;
}
static void
workspace_move_surface_up_binding ( struct weston_keyboard * keyboard ,
const struct timespec * time , uint32_t key ,
void * data )
{
struct desktop_shell * shell = data ;
unsigned int new_index = shell - > workspaces . current ;
if ( shell - > locked )
return ;
if ( new_index ! = 0 )
new_index - - ;
take_surface_to_workspace_by_seat ( shell , keyboard - > seat , new_index ) ;
}
static void
workspace_move_surface_down_binding ( struct weston_keyboard * keyboard ,
const struct timespec * time , uint32_t key ,
void * data )
{
struct desktop_shell * shell = data ;
unsigned int new_index = shell - > workspaces . current ;
if ( shell - > locked )
return ;
if ( new_index < shell - > workspaces . num - 1 )
new_index + + ;
take_surface_to_workspace_by_seat ( shell , keyboard - > seat , new_index ) ;
}
static void
shell_reposition_view_on_output_change ( struct weston_view * view )
{
@ -4703,16 +4195,12 @@ void
shell_for_each_layer ( struct desktop_shell * shell ,
shell_for_each_layer_func_t func , void * data )
{
struct workspace * * ws ;
func ( shell , & shell - > fullscreen_layer , data ) ;
func ( shell , & shell - > panel_layer , data ) ;
func ( shell , & shell - > background_layer , data ) ;
func ( shell , & shell - > lock_layer , data ) ;
func ( shell , & shell - > input_panel_layer , data ) ;
wl_array_for_each ( ws , & shell - > workspaces . array )
func ( shell , & ( * ws ) - > layer , data ) ;
func ( shell , & shell - > workspace . layer , data ) ;
}
static void
@ -4917,7 +4405,6 @@ shell_destroy(struct wl_listener *listener, void *data)
{
struct desktop_shell * shell =
container_of ( listener , struct desktop_shell , destroy_listener ) ;
struct workspace * * ws ;
struct shell_output * shell_output , * tmp ;
struct shell_seat * shseat , * shseat_next ;
@ -4950,9 +4437,7 @@ shell_destroy(struct wl_listener *listener, void *data)
weston_desktop_destroy ( shell - > desktop ) ;
wl_array_for_each ( ws , & shell - > workspaces . array )
workspace_destroy ( * ws ) ;
wl_array_release ( & shell - > workspaces . array ) ;
workspace_destroy ( & shell - > workspace ) ;
desktop_shell_destroy_layer ( & shell - > panel_layer ) ;
desktop_shell_destroy_layer ( & shell - > background_layer ) ;
@ -4969,7 +4454,6 @@ static void
shell_add_bindings ( struct weston_compositor * ec , struct desktop_shell * shell )
{
uint32_t mod ;
int i , num_workspace_bindings ;
if ( shell - > allow_zap )
weston_compositor_add_key_binding ( ec , KEY_BACKSPACE ,
@ -5026,27 +4510,6 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
ec ) ;
weston_compositor_add_key_binding ( ec , KEY_K , mod ,
force_kill_binding , shell ) ;
weston_compositor_add_key_binding ( ec , KEY_UP , mod ,
workspace_up_binding , shell ) ;
weston_compositor_add_key_binding ( ec , KEY_DOWN , mod ,
workspace_down_binding , shell ) ;
weston_compositor_add_key_binding ( ec , KEY_UP , mod | MODIFIER_SHIFT ,
workspace_move_surface_up_binding ,
shell ) ;
weston_compositor_add_key_binding ( ec , KEY_DOWN , mod | MODIFIER_SHIFT ,
workspace_move_surface_down_binding ,
shell ) ;
/* Add bindings for mod+F[1-6] for workspace 1 to 6. */
if ( shell - > workspaces . num > 1 ) {
num_workspace_bindings = shell - > workspaces . num ;
if ( num_workspace_bindings > 6 )
num_workspace_bindings = 6 ;
for ( i = 0 ; i < num_workspace_bindings ; i + + )
weston_compositor_add_key_binding ( ec , KEY_F1 + i , mod ,
workspace_f_binding ,
shell ) ;
}
weston_install_debug_key_binding ( ec , mod ) ;
}
@ -5067,8 +4530,6 @@ wet_shell_init(struct weston_compositor *ec,
{
struct weston_seat * seat ;
struct desktop_shell * shell ;
struct workspace * * pws ;
unsigned int i ;
struct wl_event_loop * loop ;
shell = zalloc ( sizeof * shell ) ;
@ -5104,8 +4565,6 @@ wet_shell_init(struct weston_compositor *ec,
weston_layer_set_position ( & shell - > background_layer ,
WESTON_LAYER_POSITION_BACKGROUND ) ;
wl_array_init ( & shell - > workspaces . array ) ;
wl_list_init ( & shell - > workspaces . client_list ) ;
wl_list_init ( & shell - > seat_list ) ;
if ( input_panel_setup ( shell ) < 0 )
@ -5117,23 +4576,10 @@ wet_shell_init(struct weston_compositor *ec,
shell_configuration ( shell ) ;
for ( i = 0 ; i < shell - > workspaces . num ; i + + ) {
pws = wl_array_add ( & shell - > workspaces . array , sizeof * pws ) ;
if ( pws = = NULL )
return - 1 ;
* pws = workspace_create ( shell ) ;
if ( * pws = = NULL )
return - 1 ;
}
activate_workspace ( shell , 0 ) ;
workspace_create ( shell ) ;
weston_layer_init ( & shell - > minimized_layer , ec ) ;
wl_list_init ( & shell - > workspaces . anim_sticky_list ) ;
wl_list_init ( & shell - > workspaces . animation . link ) ;
shell - > workspaces . animation . frame = animate_workspace_change_frame ;
shell - > desktop = weston_desktop_create ( ec , & shell_desktop_api , shell ) ;
if ( ! shell - > desktop )
return - 1 ;