@ -38,6 +38,8 @@
# include "../shared/config-parser.h"
# include "log.h"
# define DEFAULT_NUM_WORKSPACES 1
enum animation_type {
ANIMATION_NONE ,
@ -45,6 +47,10 @@ enum animation_type {
ANIMATION_FADE
} ;
struct workspace {
struct weston_layer layer ;
} ;
struct desktop_shell {
struct weston_compositor * compositor ;
@ -54,7 +60,6 @@ struct desktop_shell {
struct weston_layer fullscreen_layer ;
struct weston_layer panel_layer ;
struct weston_layer toplevel_layer ;
struct weston_layer background_layer ;
struct weston_layer lock_layer ;
@ -79,6 +84,12 @@ struct desktop_shell {
struct wl_list backgrounds ;
struct wl_list panels ;
struct {
struct wl_array array ;
unsigned int current ;
unsigned int num ;
} workspaces ;
struct {
char * path ;
int duration ;
@ -276,12 +287,15 @@ shell_configuration(struct desktop_shell *shell)
char * config_file ;
char * path = NULL ;
int duration = 60 ;
unsigned int num_workspaces = DEFAULT_NUM_WORKSPACES ;
char * modifier = NULL ;
char * win_animation = NULL ;
struct config_key shell_keys [ ] = {
{ " binding-modifier " , CONFIG_KEY_STRING , & modifier } ,
{ " animation " , CONFIG_KEY_STRING , & win_animation } ,
{ " num-workspaces " ,
CONFIG_KEY_UNSIGNED_INTEGER , & num_workspaces } ,
} ;
struct config_key saver_keys [ ] = {
@ -302,6 +316,79 @@ shell_configuration(struct desktop_shell *shell)
shell - > screensaver . duration = duration ;
shell - > binding_modifier = get_modifier ( modifier ) ;
shell - > win_animation_type = get_animation_type ( win_animation ) ;
shell - > workspaces . num = num_workspaces > 0 ? num_workspaces : 1 ;
}
static void
workspace_destroy ( struct workspace * ws )
{
free ( ws ) ;
}
static struct workspace *
workspace_create ( void )
{
struct workspace * ws = malloc ( sizeof * ws ) ;
if ( ws = = NULL )
return NULL ;
weston_layer_init ( & ws - > layer , NULL ) ;
return ws ;
}
static struct workspace *
get_workspace ( struct desktop_shell * shell , unsigned int index )
{
struct workspace * * pws = shell - > workspaces . array . data ;
pws + = index ;
return * pws ;
}
static 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 ) ;
wl_list_insert ( & shell - > panel_layer . link , & ws - > layer . link ) ;
shell - > workspaces . current = index ;
}
static void
change_workspace ( struct desktop_shell * shell , unsigned int index )
{
struct workspace * from ;
struct workspace * to ;
struct weston_seat * seat ;
if ( index = = shell - > workspaces . current )
return ;
/* Don't change workspace when there is any fullscreen surfaces. */
if ( ! wl_list_empty ( & shell - > fullscreen_layer . surface_list ) )
return ;
/* Clear keyboard focus so that no hidden surfaces will keep it. */
wl_list_for_each ( seat , & shell - > compositor - > seat_list , link )
if ( seat - > seat . keyboard )
wl_keyboard_set_focus ( seat - > seat . keyboard , NULL ) ;
from = get_current_workspace ( shell ) ;
to = get_workspace ( shell , index ) ;
shell - > workspaces . current = index ;
wl_list_insert ( & from - > layer . link , & to - > layer . link ) ;
wl_list_remove ( & from - > layer . link ) ;
weston_compositor_damage_all ( shell - > compositor ) ;
}
static void
@ -1540,7 +1627,6 @@ resume_desktop(struct desktop_shell *shell)
& shell - > fullscreen_layer . link ) ;
wl_list_insert ( & shell - > fullscreen_layer . link ,
& shell - > panel_layer . link ) ;
wl_list_insert ( & shell - > panel_layer . link , & shell - > toplevel_layer . link ) ;
shell - > locked = false ;
shell - > compositor - > idle_time = shell - > compositor - > option_idle_time ;
@ -1935,6 +2021,8 @@ activate(struct desktop_shell *shell, struct weston_surface *es,
struct weston_seat * seat )
{
struct weston_surface * surf , * prev ;
struct workspace * ws ;
struct weston_layer * ws_layer ;
weston_surface_activate ( es , seat ) ;
@ -1956,18 +2044,21 @@ activate(struct desktop_shell *shell, struct weston_surface *es,
shell_configure_fullscreen ( get_shell_surface ( es ) ) ;
break ;
default :
ws = get_current_workspace ( shell ) ;
ws_layer = & ws - > layer ;
/* move the fullscreen surfaces down into the toplevel layer */
if ( ! wl_list_empty ( & shell - > fullscreen_layer . surface_list ) ) {
wl_list_for_each_reverse_safe ( surf ,
prev ,
& shell - > fullscreen_layer . surface_list ,
layer_link )
layer_link ) {
weston_surface_restack ( surf ,
& shell - > toplevel_layer . surface_list ) ;
& ws_layer - > surface_list ) ;
}
}
weston_surface_restack ( es ,
& shell - > toplevel_layer . surface_list ) ;
weston_surface_restack ( es , & ws_layer - > surface_list ) ;
break ;
}
}
@ -2033,7 +2124,6 @@ lock(struct wl_listener *listener, void *data)
* input events while we are locked . */
wl_list_remove ( & shell - > panel_layer . link ) ;
wl_list_remove ( & shell - > toplevel_layer . link ) ;
wl_list_remove ( & shell - > fullscreen_layer . link ) ;
wl_list_insert ( & shell - > compositor - > cursor_layer . link ,
& shell - > lock_layer . link ) ;
@ -2101,16 +2191,13 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
int32_t width , int32_t height , int32_t sx , int32_t sy )
{
struct weston_compositor * compositor = shell - > compositor ;
struct shell_surface * shsurf ;
enum shell_surface_type surface_type = SHELL_SURFACE_NONE ;
struct shell_surface * shsurf = get_shell_surface ( surface ) ;
enum shell_surface_type surface_type = shsurf - > type ;
struct weston_surface * parent ;
struct weston_seat * seat ;
struct workspace * ws ;
int panel_height = 0 ;
shsurf = get_shell_surface ( surface ) ;
if ( shsurf )
surface_type = shsurf - > type ;
surface - > geometry . width = width ;
surface - > geometry . height = height ;
surface - > geometry . dirty = 1 ;
@ -2184,8 +2271,8 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
case SHELL_SURFACE_NONE :
break ;
default :
wl_list_insert ( & shell - > toplevel_layer . surface_list ,
& surface - > layer_link ) ;
ws = get_current_workspace ( shell ) ;
wl_list_insert ( & ws - > layer . surface_list , & surface - > layer_link ) ;
break ;
}
@ -2661,11 +2748,53 @@ force_kill_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
kill ( pid , SIGKILL ) ;
}
static void
workspace_up_binding ( struct wl_seat * seat , uint32_t time ,
uint32_t key , void * data )
{
struct desktop_shell * shell = data ;
unsigned int new_index = shell - > workspaces . current ;
if ( new_index ! = 0 )
new_index - - ;
change_workspace ( shell , new_index ) ;
}
static void
workspace_down_binding ( struct wl_seat * seat , uint32_t time ,
uint32_t key , void * data )
{
struct desktop_shell * shell = data ;
unsigned int new_index = shell - > workspaces . current ;
if ( new_index < shell - > workspaces . num - 1 )
new_index + + ;
change_workspace ( shell , new_index ) ;
}
static void
workspace_f_binding ( struct wl_seat * seat , uint32_t time ,
uint32_t key , void * data )
{
struct desktop_shell * shell = data ;
unsigned int new_index ;
new_index = key - KEY_F1 ;
if ( new_index > = shell - > workspaces . num )
new_index = shell - > workspaces . num - 1 ;
change_workspace ( shell , new_index ) ;
}
static void
shell_destroy ( struct wl_listener * listener , void * data )
{
struct desktop_shell * shell =
container_of ( listener , struct desktop_shell , destroy_listener ) ;
struct workspace * * ws ;
if ( shell - > child . client )
wl_client_destroy ( shell - > child . client ) ;
@ -2673,6 +2802,10 @@ shell_destroy(struct wl_listener *listener, void *data)
wl_list_remove ( & shell - > lock_listener . link ) ;
wl_list_remove ( & shell - > unlock_listener . link ) ;
wl_array_for_each ( ws , & shell - > workspaces . array )
workspace_destroy ( * ws ) ;
wl_array_release ( & shell - > workspaces . array ) ;
free ( shell - > screensaver . path ) ;
free ( shell ) ;
}
@ -2681,6 +2814,7 @@ static void
shell_add_bindings ( struct weston_compositor * ec , struct desktop_shell * shell )
{
uint32_t mod ;
int i , num_workspace_bindings ;
/* fixed bindings */
weston_compositor_add_key_binding ( ec , KEY_BACKSPACE ,
@ -2722,6 +2856,21 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
debug_repaint_binding , shell ) ;
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 ) ;
/* 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 ) ;
}
}
int
@ -2731,6 +2880,8 @@ WL_EXPORT int
shell_init ( struct weston_compositor * ec )
{
struct desktop_shell * shell ;
struct workspace * * pws ;
unsigned int i ;
shell = malloc ( sizeof * shell ) ;
if ( shell = = NULL )
@ -2758,13 +2909,24 @@ shell_init(struct weston_compositor *ec)
weston_layer_init ( & shell - > fullscreen_layer , & ec - > cursor_layer . link ) ;
weston_layer_init ( & shell - > panel_layer , & shell - > fullscreen_layer . link ) ;
weston_layer_init ( & shell - > toplevel _layer, & shell - > panel_layer . link ) ;
weston_layer_init ( & shell - > background_layer ,
& shell - > toplevel_layer . link ) ;
wl_list _init ( & shell - > lock_layer . surface_list ) ;
weston_layer_init ( & shell - > background _layer, & shell - > panel_layer . link ) ;
weston_layer_init ( & shell - > lock_layer , NULL ) ;
wl_array _init ( & shell - > workspaces . array ) ;
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 ( ) ;
if ( * pws = = NULL )
return - 1 ;
}
activate_workspace ( shell , 0 ) ;
if ( wl_display_add_global ( ec - > wl_display , & wl_shell_interface ,
shell , bind_shell ) = = NULL )
return - 1 ;