@ -11,50 +11,67 @@ void handle_xdg_toplevel_ack_configure(
struct wlr_xdg_surface * surface ,
struct wlr_xdg_surface_configure * configure ) {
assert ( surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
assert ( configure - > toplevel_state ! = NULL ) ;
surface - > toplevel - > last_acked = * configure - > toplevel_state ;
struct wlr_xdg_toplevel_configure * acked = configure - > toplevel_configure ;
assert ( acked ! = NULL ) ;
surface - > toplevel - > pending . maximized = acked - > maximized ;
surface - > toplevel - > pending . fullscreen = acked - > fullscreen ;
surface - > toplevel - > pending . resizing = acked - > resizing ;
surface - > toplevel - > pending . activated = acked - > activated ;
surface - > toplevel - > pending . tiled = acked - > tiled ;
surface - > toplevel - > pending . width = acked - > width ;
surface - > toplevel - > pending . height = acked - > height ;
}
bool compare_xdg_surface_toplevel_state ( struct wlr_xdg_toplevel * state ) {
// is pending state different from current state?
if ( ! state - > base - > configured ) {
bool compare_xdg_surface_toplevel_state ( struct wlr_xdg_toplevel * toplevel ) {
// Is the scheduled configure different from the last sent on e?
if ( ! toplevel - > base - > configured ) {
return false ;
}
struct wlr_xdg_toplevel_state * configured = NULL ;
if ( wl_list_empty ( & state - > base - > configure_list ) ) {
struct wlr_xdg_toplevel_configure last_acked ;
struct wlr_xdg_toplevel_configure * configure = NULL ;
if ( wl_list_empty ( & toplevel - > base - > configure_list ) ) {
// There are currently no pending configures, so check against the last
// state acked by the client.
configured = & state - > last_acked ;
last_acked . maximized = toplevel - > pending . maximized ;
last_acked . fullscreen = toplevel - > pending . fullscreen ;
last_acked . resizing = toplevel - > pending . resizing ;
last_acked . activated = toplevel - > pending . activated ;
last_acked . tiled = toplevel - > pending . tiled ;
last_acked . width = toplevel - > pending . width ;
last_acked . height = toplevel - > pending . height ;
configure = & last_acked ;
} else {
struct wlr_xdg_surface_configure * configure =
wl_container_of ( state - > base - > configure_list . prev , configure , link ) ;
configured = configure - > toplevel_state ;
struct wlr_xdg_surface_configure * surface_ configure =
wl_container_of ( toplevel - > base - > configure_list . prev , surface_ configure, link ) ;
configure = surface_configure - > toplevel_configur e;
}
if ( state - > server_pending . activated ! = configured - > activated ) {
if ( toplevel- > scheduled . activated ! = configure - > activated ) {
return false ;
}
if ( state- > server_pending . fullscreen ! = configure d - > fullscreen ) {
if ( toplevel- > scheduled . fullscreen ! = configure - > fullscreen ) {
return false ;
}
if ( state- > server_pending . maximized ! = configure d - > maximized ) {
if ( toplevel- > scheduled . maximized ! = configure - > maximized ) {
return false ;
}
if ( state- > server_pending . resizing ! = configure d - > resizing ) {
if ( toplevel- > scheduled . resizing ! = configure - > resizing ) {
return false ;
}
if ( state- > server_pending . tiled ! = configure d - > tiled ) {
if ( toplevel- > scheduled . tiled ! = configure - > tiled ) {
return false ;
}
if ( state- > server_pending . width = = configure d - > width & &
state- > server_pending . height = = configure d - > height ) {
if ( toplevel- > scheduled . width = = configure - > width & &
toplevel- > scheduled . height = = configure - > height ) {
return true ;
}
if ( state- > server_pending . width = = 0 & & state - > server_pending . height = = 0 ) {
if ( toplevel- > scheduled . width = = 0 & & toplevel - > scheduled . height = = 0 ) {
return true ;
}
@ -65,17 +82,17 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
struct wlr_xdg_surface_configure * configure ) {
assert ( surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
configure - > toplevel_ stat e = malloc ( sizeof ( * configure - > toplevel_ stat e) ) ;
if ( configure - > toplevel_ stat e = = NULL ) {
configure - > toplevel_ configur e = malloc ( sizeof ( * configure - > toplevel_ configur e) ) ;
if ( configure - > toplevel_ configur e = = NULL ) {
wlr_log ( WLR_ERROR , " Allocation failed " ) ;
wl_resource_post_no_memory ( surface - > toplevel - > resource ) ;
return ;
}
* configure - > toplevel_ state = surface - > toplevel - > server_pending ;
* configure - > toplevel_ configure = surface - > toplevel - > scheduled ;
struct wl_array states ;
wl_array_init ( & states ) ;
if ( surface - > toplevel - > s erver_pending . maximized ) {
if ( surface - > toplevel - > s cheduled . maximized ) {
uint32_t * s = wl_array_add ( & states , sizeof ( uint32_t ) ) ;
if ( ! s ) {
wlr_log ( WLR_ERROR , " Could not allocate state for maximized xdg_toplevel " ) ;
@ -83,7 +100,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
}
* s = XDG_TOPLEVEL_STATE_MAXIMIZED ;
}
if ( surface - > toplevel - > s erver_pending . fullscreen ) {
if ( surface - > toplevel - > s cheduled . fullscreen ) {
uint32_t * s = wl_array_add ( & states , sizeof ( uint32_t ) ) ;
if ( ! s ) {
wlr_log ( WLR_ERROR , " Could not allocate state for fullscreen xdg_toplevel " ) ;
@ -91,7 +108,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
}
* s = XDG_TOPLEVEL_STATE_FULLSCREEN ;
}
if ( surface - > toplevel - > s erver_pending . resizing ) {
if ( surface - > toplevel - > s cheduled . resizing ) {
uint32_t * s = wl_array_add ( & states , sizeof ( uint32_t ) ) ;
if ( ! s ) {
wlr_log ( WLR_ERROR , " Could not allocate state for resizing xdg_toplevel " ) ;
@ -99,7 +116,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
}
* s = XDG_TOPLEVEL_STATE_RESIZING ;
}
if ( surface - > toplevel - > s erver_pending . activated ) {
if ( surface - > toplevel - > s cheduled . activated ) {
uint32_t * s = wl_array_add ( & states , sizeof ( uint32_t ) ) ;
if ( ! s ) {
wlr_log ( WLR_ERROR , " Could not allocate state for activated xdg_toplevel " ) ;
@ -107,7 +124,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
}
* s = XDG_TOPLEVEL_STATE_ACTIVATED ;
}
if ( surface - > toplevel - > s erver_pending . tiled ) {
if ( surface - > toplevel - > s cheduled . tiled ) {
if ( wl_resource_get_version ( surface - > resource ) > =
XDG_TOPLEVEL_STATE_TILED_LEFT_SINCE_VERSION ) {
const struct {
@ -121,7 +138,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
} ;
for ( size_t i = 0 ; i < sizeof ( tiled ) / sizeof ( tiled [ 0 ] ) ; + + i ) {
if ( ( surface - > toplevel - > s erver_pending . tiled &
if ( ( surface - > toplevel - > s cheduled . tiled &
tiled [ i ] . edge ) = = 0 ) {
continue ;
}
@ -134,7 +151,7 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
}
* s = tiled [ i ] . state ;
}
} else if ( ! surface - > toplevel - > s erver_pending . maximized ) {
} else if ( ! surface - > toplevel - > s cheduled . maximized ) {
// This version doesn't support tiling, best we can do is make the
// toplevel maximized
uint32_t * s = wl_array_add ( & states , sizeof ( uint32_t ) ) ;
@ -147,8 +164,8 @@ void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
}
}
uint32_t width = surface - > toplevel - > s erver_pending . width ;
uint32_t height = surface - > toplevel - > s erver_pending . height ;
uint32_t width = surface - > toplevel - > s cheduled . width ;
uint32_t height = surface - > toplevel - > s cheduled . height ;
xdg_toplevel_send_configure ( surface - > toplevel - > resource , width , height ,
& states ) ;
@ -171,18 +188,7 @@ void handle_xdg_surface_toplevel_committed(struct wlr_xdg_surface *surface) {
return ;
}
// apply state from the last acked configure now that the client committed
surface - > toplevel - > current = surface - > toplevel - > last_acked ;
// update state from the client that doesn't need compositor approval
surface - > toplevel - > current . max_width =
surface - > toplevel - > client_pending . max_width ;
surface - > toplevel - > current . min_width =
surface - > toplevel - > client_pending . min_width ;
surface - > toplevel - > current . max_height =
surface - > toplevel - > client_pending . max_height ;
surface - > toplevel - > current . min_height =
surface - > toplevel - > client_pending . min_height ;
surface - > toplevel - > current = surface - > toplevel - > pending ;
}
static const struct xdg_toplevel_interface xdg_toplevel_implementation ;
@ -359,23 +365,23 @@ static void xdg_toplevel_handle_set_max_size(struct wl_client *client,
struct wl_resource * resource , int32_t width , int32_t height ) {
struct wlr_xdg_surface * surface =
wlr_xdg_surface_from_toplevel_resource ( resource ) ;
surface - > toplevel - > client_ pending. max_width = width ;
surface - > toplevel - > client_ pending. max_height = height ;
surface - > toplevel - > pending. max_width = width ;
surface - > toplevel - > pending. max_height = height ;
}
static void xdg_toplevel_handle_set_min_size ( struct wl_client * client ,
struct wl_resource * resource , int32_t width , int32_t height ) {
struct wlr_xdg_surface * surface =
wlr_xdg_surface_from_toplevel_resource ( resource ) ;
surface - > toplevel - > client_ pending. min_width = width ;
surface - > toplevel - > client_ pending. min_height = height ;
surface - > toplevel - > pending. min_width = width ;
surface - > toplevel - > pending. min_height = height ;
}
static void xdg_toplevel_handle_set_maximized ( struct wl_client * client ,
struct wl_resource * resource ) {
struct wlr_xdg_surface * surface =
wlr_xdg_surface_from_toplevel_resource ( resource ) ;
surface - > toplevel - > client_pending . maximized = true ;
surface - > toplevel - > requested . maximized = true ;
wlr_signal_emit_safe ( & surface - > toplevel - > events . request_maximize , surface ) ;
}
@ -383,31 +389,31 @@ static void xdg_toplevel_handle_unset_maximized(struct wl_client *client,
struct wl_resource * resource ) {
struct wlr_xdg_surface * surface =
wlr_xdg_surface_from_toplevel_resource ( resource ) ;
surface - > toplevel - > client_pending . maximized = false ;
surface - > toplevel - > requested . maximized = false ;
wlr_signal_emit_safe ( & surface - > toplevel - > events . request_maximize , surface ) ;
}
static void handle_fullscreen_output_destroy ( struct wl_listener * listener ,
void * data ) {
struct wlr_xdg_toplevel_ state * state =
wl_container_of ( listener , state , fullscreen_output_destroy ) ;
state - > fullscreen_output = NULL ;
wl_list_remove ( & state - > fullscreen_output_destroy . link ) ;
struct wlr_xdg_toplevel_ requested * req =
wl_container_of ( listener , req , fullscreen_output_destroy ) ;
req - > fullscreen_output = NULL ;
wl_list_remove ( & req - > fullscreen_output_destroy . link ) ;
}
static void store_fullscreen_ pending ( struct wlr_xdg_surface * surface ,
static void store_fullscreen_ requested ( struct wlr_xdg_surface * surface ,
bool fullscreen , struct wlr_output * output ) {
struct wlr_xdg_toplevel_ state * state = & surface - > toplevel - > client_pending ;
state - > fullscreen = fullscreen ;
if ( state - > fullscreen_output ) {
wl_list_remove ( & state - > fullscreen_output_destroy . link ) ;
}
state - > fullscreen_output = output ;
if ( state - > fullscreen_output ) {
state - > fullscreen_output_destroy . notify =
struct wlr_xdg_toplevel_ requested * req = & surface - > toplevel - > requested ;
req - > fullscreen = fullscreen ;
if ( req - > fullscreen_output ) {
wl_list_remove ( & req - > fullscreen_output_destroy . link ) ;
}
req - > fullscreen_output = output ;
if ( req - > fullscreen_output ) {
req - > fullscreen_output_destroy . notify =
handle_fullscreen_output_destroy ;
wl_signal_add ( & state - > fullscreen_output - > events . destroy ,
& state - > fullscreen_output_destroy ) ;
wl_signal_add ( & req - > fullscreen_output - > events . destroy ,
& req - > fullscreen_output_destroy ) ;
}
}
@ -421,7 +427,7 @@ static void xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
output = wlr_output_from_resource ( output_resource ) ;
}
store_fullscreen_ pending ( surface , true , output ) ;
store_fullscreen_ requested ( surface , true , output ) ;
struct wlr_xdg_toplevel_set_fullscreen_event event = {
. surface = surface ,
@ -437,7 +443,7 @@ static void xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
struct wlr_xdg_surface * surface =
wlr_xdg_surface_from_toplevel_resource ( resource ) ;
store_fullscreen_ pending ( surface , false , NULL ) ;
store_fullscreen_ requested ( surface , false , NULL ) ;
struct wlr_xdg_toplevel_set_fullscreen_event event = {
. surface = surface ,
@ -452,6 +458,7 @@ static void xdg_toplevel_handle_set_minimized(struct wl_client *client,
struct wl_resource * resource ) {
struct wlr_xdg_surface * surface =
wlr_xdg_surface_from_toplevel_resource ( resource ) ;
surface - > toplevel - > requested . minimized = true ;
wlr_signal_emit_safe ( & surface - > toplevel - > events . request_minimize , surface ) ;
}
@ -547,8 +554,8 @@ void destroy_xdg_toplevel(struct wlr_xdg_surface *xdg_surface) {
uint32_t wlr_xdg_toplevel_set_size ( struct wlr_xdg_surface * surface ,
uint32_t width , uint32_t height ) {
assert ( surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
surface - > toplevel - > s erver_pending . width = width ;
surface - > toplevel - > s erver_pending . height = height ;
surface - > toplevel - > s cheduled . width = width ;
surface - > toplevel - > s cheduled . height = height ;
return schedule_xdg_surface_configure ( surface ) ;
}
@ -556,7 +563,7 @@ uint32_t wlr_xdg_toplevel_set_size(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_activated ( struct wlr_xdg_surface * surface ,
bool activated ) {
assert ( surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
surface - > toplevel - > s erver_pending . activated = activated ;
surface - > toplevel - > s cheduled . activated = activated ;
return schedule_xdg_surface_configure ( surface ) ;
}
@ -564,7 +571,7 @@ uint32_t wlr_xdg_toplevel_set_activated(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_maximized ( struct wlr_xdg_surface * surface ,
bool maximized ) {
assert ( surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
surface - > toplevel - > s erver_pending . maximized = maximized ;
surface - > toplevel - > s cheduled . maximized = maximized ;
return schedule_xdg_surface_configure ( surface ) ;
}
@ -572,7 +579,7 @@ uint32_t wlr_xdg_toplevel_set_maximized(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_fullscreen ( struct wlr_xdg_surface * surface ,
bool fullscreen ) {
assert ( surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
surface - > toplevel - > s erver_pending . fullscreen = fullscreen ;
surface - > toplevel - > s cheduled . fullscreen = fullscreen ;
return schedule_xdg_surface_configure ( surface ) ;
}
@ -580,7 +587,7 @@ uint32_t wlr_xdg_toplevel_set_fullscreen(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_resizing ( struct wlr_xdg_surface * surface ,
bool resizing ) {
assert ( surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
surface - > toplevel - > s erver_pending . resizing = resizing ;
surface - > toplevel - > s cheduled . resizing = resizing ;
return schedule_xdg_surface_configure ( surface ) ;
}
@ -588,7 +595,7 @@ uint32_t wlr_xdg_toplevel_set_resizing(struct wlr_xdg_surface *surface,
uint32_t wlr_xdg_toplevel_set_tiled ( struct wlr_xdg_surface * surface ,
uint32_t tiled ) {
assert ( surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
surface - > toplevel - > s erver_pending . tiled = tiled ;
surface - > toplevel - > s cheduled . tiled = tiled ;
return schedule_xdg_surface_configure ( surface ) ;
}