@ -43,7 +43,7 @@ struct tinywl_server {
struct wlr_xdg_shell * xdg_shell ;
struct wlr_xdg_shell * xdg_shell ;
struct wl_listener new_xdg_surface ;
struct wl_listener new_xdg_surface ;
struct wl_list view s;
struct wl_list toplevel s;
struct wlr_cursor * cursor ;
struct wlr_cursor * cursor ;
struct wlr_xcursor_manager * cursor_mgr ;
struct wlr_xcursor_manager * cursor_mgr ;
@ -59,7 +59,7 @@ struct tinywl_server {
struct wl_listener request_set_selection ;
struct wl_listener request_set_selection ;
struct wl_list keyboards ;
struct wl_list keyboards ;
enum tinywl_cursor_mode cursor_mode ;
enum tinywl_cursor_mode cursor_mode ;
struct tinywl_ view * grabbed_view ;
struct tinywl_ toplevel * grabbed_toplevel ;
double grab_x , grab_y ;
double grab_x , grab_y ;
struct wlr_box grab_geobox ;
struct wlr_box grab_geobox ;
uint32_t resize_edges ;
uint32_t resize_edges ;
@ -78,7 +78,7 @@ struct tinywl_output {
struct wl_listener destroy ;
struct wl_listener destroy ;
} ;
} ;
struct tinywl_ view {
struct tinywl_ toplevel {
struct wl_list link ;
struct wl_list link ;
struct tinywl_server * server ;
struct tinywl_server * server ;
struct wlr_xdg_toplevel * xdg_toplevel ;
struct wlr_xdg_toplevel * xdg_toplevel ;
@ -102,12 +102,12 @@ struct tinywl_keyboard {
struct wl_listener destroy ;
struct wl_listener destroy ;
} ;
} ;
static void focus_ view( struct tinywl_view * view , struct wlr_surface * surface ) {
static void focus_ toplevel( struct tinywl_toplevel * toplevel , struct wlr_surface * surface ) {
/* Note: this function only deals with keyboard focus. */
/* Note: this function only deals with keyboard focus. */
if ( view = = NULL ) {
if ( toplevel = = NULL ) {
return ;
return ;
}
}
struct tinywl_server * server = view - > server ;
struct tinywl_server * server = toplevel - > server ;
struct wlr_seat * seat = server - > seat ;
struct wlr_seat * seat = server - > seat ;
struct wlr_surface * prev_surface = seat - > keyboard_state . focused_surface ;
struct wlr_surface * prev_surface = seat - > keyboard_state . focused_surface ;
if ( prev_surface = = surface ) {
if ( prev_surface = = surface ) {
@ -127,19 +127,19 @@ static void focus_view(struct tinywl_view *view, struct wlr_surface *surface) {
}
}
}
}
struct wlr_keyboard * keyboard = wlr_seat_get_keyboard ( seat ) ;
struct wlr_keyboard * keyboard = wlr_seat_get_keyboard ( seat ) ;
/* Move the view to the front */
/* Move the toplevel to the front */
wlr_scene_node_raise_to_top ( & view - > scene_tree - > node ) ;
wlr_scene_node_raise_to_top ( & toplevel - > scene_tree - > node ) ;
wl_list_remove ( & view - > link ) ;
wl_list_remove ( & toplevel - > link ) ;
wl_list_insert ( & server - > views, & view - > link ) ;
wl_list_insert ( & server - > toplevels, & toplevel - > link ) ;
/* Activate the new surface */
/* Activate the new surface */
wlr_xdg_toplevel_set_activated ( view - > xdg_toplevel , true ) ;
wlr_xdg_toplevel_set_activated ( toplevel - > xdg_toplevel , true ) ;
/*
/*
* Tell the seat to have the keyboard enter this surface . wlroots will keep
* Tell the seat to have the keyboard enter this surface . wlroots will keep
* track of this and automatically send key events to the appropriate
* track of this and automatically send key events to the appropriate
* clients without additional work on your part .
* clients without additional work on your part .
*/
*/
if ( keyboard ! = NULL ) {
if ( keyboard ! = NULL ) {
wlr_seat_keyboard_notify_enter ( seat , view - > xdg_toplevel - > base - > surface ,
wlr_seat_keyboard_notify_enter ( seat , toplevel - > xdg_toplevel - > base - > surface ,
keyboard - > keycodes , keyboard - > num_keycodes , & keyboard - > modifiers ) ;
keyboard - > keycodes , keyboard - > num_keycodes , & keyboard - > modifiers ) ;
}
}
}
}
@ -175,13 +175,13 @@ static bool handle_keybinding(struct tinywl_server *server, xkb_keysym_t sym) {
wl_display_terminate ( server - > wl_display ) ;
wl_display_terminate ( server - > wl_display ) ;
break ;
break ;
case XKB_KEY_F1 :
case XKB_KEY_F1 :
/* Cycle to the next view */
/* Cycle to the next toplevel */
if ( wl_list_length ( & server - > view s) < 2 ) {
if ( wl_list_length ( & server - > toplevel s) < 2 ) {
break ;
break ;
}
}
struct tinywl_ view * next_view = wl_container_of (
struct tinywl_ toplevel * next_toplevel =
server - > views . prev , next_view , link ) ;
wl_container_of ( server - > toplevels . prev , next_toplevel , link ) ;
focus_ view( next_view , next_view - > xdg_toplevel - > base - > surface ) ;
focus_ toplevel( next_toplevel , next_toplevel - > xdg_toplevel - > base - > surface ) ;
break ;
break ;
default :
default :
return false ;
return false ;
@ -336,12 +336,12 @@ static void seat_request_set_selection(struct wl_listener *listener, void *data)
wlr_seat_set_selection ( server - > seat , event - > source , event - > serial ) ;
wlr_seat_set_selection ( server - > seat , event - > source , event - > serial ) ;
}
}
static struct tinywl_ view * desktop_view _at(
static struct tinywl_ toplevel * desktop_toplevel _at(
struct tinywl_server * server , double lx , double ly ,
struct tinywl_server * server , double lx , double ly ,
struct wlr_surface * * surface , double * sx , double * sy ) {
struct wlr_surface * * surface , double * sx , double * sy ) {
/* This returns the topmost node in the scene at the given layout coords.
/* This returns the topmost node in the scene at the given layout coords.
* w e only care about surface nodes as we are specifically looking for a
* W e only care about surface nodes as we are specifically looking for a
* surface in the surface tree of a tinywl_ view . */
* surface in the surface tree of a tinywl_ toplevel . */
struct wlr_scene_node * node = wlr_scene_node_at (
struct wlr_scene_node * node = wlr_scene_node_at (
& server - > scene - > tree . node , lx , ly , sx , sy ) ;
& server - > scene - > tree . node , lx , ly , sx , sy ) ;
if ( node = = NULL | | node - > type ! = WLR_SCENE_NODE_BUFFER ) {
if ( node = = NULL | | node - > type ! = WLR_SCENE_NODE_BUFFER ) {
@ -355,7 +355,7 @@ static struct tinywl_view *desktop_view_at(
}
}
* surface = scene_surface - > surface ;
* surface = scene_surface - > surface ;
/* Find the node corresponding to the tinywl_ view at the root of this
/* Find the node corresponding to the tinywl_ toplevel at the root of this
* surface tree , it is the only one for which we set the data field . */
* surface tree , it is the only one for which we set the data field . */
struct wlr_scene_tree * tree = node - > parent ;
struct wlr_scene_tree * tree = node - > parent ;
while ( tree ! = NULL & & tree - > node . data = = NULL ) {
while ( tree ! = NULL & & tree - > node . data = = NULL ) {
@ -367,29 +367,29 @@ static struct tinywl_view *desktop_view_at(
static void reset_cursor_mode ( struct tinywl_server * server ) {
static void reset_cursor_mode ( struct tinywl_server * server ) {
/* Reset the cursor mode to passthrough. */
/* Reset the cursor mode to passthrough. */
server - > cursor_mode = TINYWL_CURSOR_PASSTHROUGH ;
server - > cursor_mode = TINYWL_CURSOR_PASSTHROUGH ;
server - > grabbed_ view = NULL ;
server - > grabbed_ toplevel = NULL ;
}
}
static void process_cursor_move ( struct tinywl_server * server , uint32_t time ) {
static void process_cursor_move ( struct tinywl_server * server , uint32_t time ) {
/* Move the grabbed view to the new position. */
/* Move the grabbed toplevel to the new position. */
struct tinywl_ view * view = server - > grabbed_view ;
struct tinywl_ toplevel * toplevel = server - > grabbed_toplevel ;
wlr_scene_node_set_position ( & view - > scene_tree - > node ,
wlr_scene_node_set_position ( & toplevel - > scene_tree - > node ,
server - > cursor - > x - server - > grab_x ,
server - > cursor - > x - server - > grab_x ,
server - > cursor - > y - server - > grab_y ) ;
server - > cursor - > y - server - > grab_y ) ;
}
}
static void process_cursor_resize ( struct tinywl_server * server , uint32_t time ) {
static void process_cursor_resize ( struct tinywl_server * server , uint32_t time ) {
/*
/*
* Resizing the grabbed view can be a little bit complicated , because we
* Resizing the grabbed toplevel can be a little bit complicated , because we
* could be resizing from any corner or edge . This not only resizes the view
* could be resizing from any corner or edge . This not only resizes the
* on one or two axes , but can also move the view if you resize from the top
* toplevel on one or two axes , but can also move the toplevel if you resize
* or left edges ( or top - left corner ) .
* from the top or left edges ( or top - left corner ) .
*
*
* Note that I took some shortcuts here . In a more fleshed - out compositor ,
* Note that I took some shortcuts here . In a more fleshed - out compositor ,
* you ' d wait for the client to prepare a buffer at the new size , then
* you ' d wait for the client to prepare a buffer at the new size , then
* commit any movement that was prepared .
* commit any movement that was prepared .
*/
*/
struct tinywl_ view * view = server - > grabbed_view ;
struct tinywl_ toplevel * toplevel = server - > grabbed_toplevel ;
double border_x = server - > cursor - > x - server - > grab_x ;
double border_x = server - > cursor - > x - server - > grab_x ;
double border_y = server - > cursor - > y - server - > grab_y ;
double border_y = server - > cursor - > y - server - > grab_y ;
int new_left = server - > grab_geobox . x ;
int new_left = server - > grab_geobox . x ;
@ -421,13 +421,13 @@ static void process_cursor_resize(struct tinywl_server *server, uint32_t time) {
}
}
struct wlr_box geo_box ;
struct wlr_box geo_box ;
wlr_xdg_surface_get_geometry ( view - > xdg_toplevel - > base , & geo_box ) ;
wlr_xdg_surface_get_geometry ( toplevel - > xdg_toplevel - > base , & geo_box ) ;
wlr_scene_node_set_position ( & view - > scene_tree - > node ,
wlr_scene_node_set_position ( & toplevel - > scene_tree - > node ,
new_left - geo_box . x , new_top - geo_box . y ) ;
new_left - geo_box . x , new_top - geo_box . y ) ;
int new_width = new_right - new_left ;
int new_width = new_right - new_left ;
int new_height = new_bottom - new_top ;
int new_height = new_bottom - new_top ;
wlr_xdg_toplevel_set_size ( view - > xdg_toplevel , new_width , new_height ) ;
wlr_xdg_toplevel_set_size ( toplevel - > xdg_toplevel , new_width , new_height ) ;
}
}
static void process_cursor_motion ( struct tinywl_server * server , uint32_t time ) {
static void process_cursor_motion ( struct tinywl_server * server , uint32_t time ) {
@ -440,16 +440,16 @@ static void process_cursor_motion(struct tinywl_server *server, uint32_t time) {
return ;
return ;
}
}
/* Otherwise, find the view under the pointer and send the event along. */
/* Otherwise, find the toplevel under the pointer and send the event along. */
double sx , sy ;
double sx , sy ;
struct wlr_seat * seat = server - > seat ;
struct wlr_seat * seat = server - > seat ;
struct wlr_surface * surface = NULL ;
struct wlr_surface * surface = NULL ;
struct tinywl_ view * view = desktop_view _at( server ,
struct tinywl_ toplevel * toplevel = desktop_toplevel _at( server ,
server - > cursor - > x , server - > cursor - > y , & surface , & sx , & sy ) ;
server - > cursor - > x , server - > cursor - > y , & surface , & sx , & sy ) ;
if ( ! view ) {
if ( ! toplevel ) {
/* If there's no view under the cursor, set the cursor image to a
/* If there's no toplevel under the cursor, set the cursor image to a
* default . This is what makes the cursor image appear when you move it
* default . This is what makes the cursor image appear when you move it
* around the screen , not over any view s. */
* around the screen , not over any toplevel s. */
wlr_cursor_set_xcursor ( server - > cursor , server - > cursor_mgr , " default " ) ;
wlr_cursor_set_xcursor ( server - > cursor , server - > cursor_mgr , " default " ) ;
}
}
if ( surface ) {
if ( surface ) {
@ -516,14 +516,14 @@ static void server_cursor_button(struct wl_listener *listener, void *data) {
event - > time_msec , event - > button , event - > state ) ;
event - > time_msec , event - > button , event - > state ) ;
double sx , sy ;
double sx , sy ;
struct wlr_surface * surface = NULL ;
struct wlr_surface * surface = NULL ;
struct tinywl_ view * view = desktop_view _at( server ,
struct tinywl_ toplevel * toplevel = desktop_toplevel _at( server ,
server - > cursor - > x , server - > cursor - > y , & surface , & sx , & sy ) ;
server - > cursor - > x , server - > cursor - > y , & surface , & sx , & sy ) ;
if ( event - > state = = WLR_BUTTON_RELEASED ) {
if ( event - > state = = WLR_BUTTON_RELEASED ) {
/* If you released any buttons, we exit interactive move/resize mode. */
/* If you released any buttons, we exit interactive move/resize mode. */
reset_cursor_mode ( server ) ;
reset_cursor_mode ( server ) ;
} else {
} else {
/* Focus that client if the button was _pressed_ */
/* Focus that client if the button was _pressed_ */
focus_ view( view , surface ) ;
focus_ toplevel( toplevel , surface ) ;
}
}
}
}
@ -652,73 +652,73 @@ static void server_new_output(struct wl_listener *listener, void *data) {
static void xdg_toplevel_map ( struct wl_listener * listener , void * data ) {
static void xdg_toplevel_map ( struct wl_listener * listener , void * data ) {
/* Called when the surface is mapped, or ready to display on-screen. */
/* Called when the surface is mapped, or ready to display on-screen. */
struct tinywl_ view * view = wl_container_of ( listener , view , map ) ;
struct tinywl_ toplevel * toplevel = wl_container_of ( listener , toplevel , map ) ;
wl_list_insert ( & view- > server - > views , & view - > link ) ;
wl_list_insert ( & toplevel- > server - > toplevels , & toplevel - > link ) ;
focus_ view( view , view - > xdg_toplevel - > base - > surface ) ;
focus_ toplevel( toplevel , toplevel - > xdg_toplevel - > base - > surface ) ;
}
}
static void xdg_toplevel_unmap ( struct wl_listener * listener , void * data ) {
static void xdg_toplevel_unmap ( struct wl_listener * listener , void * data ) {
/* Called when the surface is unmapped, and should no longer be shown. */
/* Called when the surface is unmapped, and should no longer be shown. */
struct tinywl_ view * view = wl_container_of ( listener , view , unmap ) ;
struct tinywl_ toplevel * toplevel = wl_container_of ( listener , toplevel , unmap ) ;
/* Reset the cursor mode if the grabbed view was unmapped. */
/* Reset the cursor mode if the grabbed toplevel was unmapped. */
if ( view = = view - > server - > grabbed_view ) {
if ( toplevel = = toplevel - > server - > grabbed_toplevel ) {
reset_cursor_mode ( view - > server ) ;
reset_cursor_mode ( toplevel - > server ) ;
}
}
wl_list_remove ( & view - > link ) ;
wl_list_remove ( & toplevel - > link ) ;
}
}
static void xdg_toplevel_destroy ( struct wl_listener * listener , void * data ) {
static void xdg_toplevel_destroy ( struct wl_listener * listener , void * data ) {
/* Called when the surface is destroyed and should never be shown again. */
/* Called when the surface is destroyed and should never be shown again. */
struct tinywl_ view * view = wl_container_of ( listener , view , destroy ) ;
struct tinywl_ toplevel * toplevel = wl_container_of ( listener , toplevel , destroy ) ;
wl_list_remove ( & view - > map . link ) ;
wl_list_remove ( & toplevel - > map . link ) ;
wl_list_remove ( & view - > unmap . link ) ;
wl_list_remove ( & toplevel - > unmap . link ) ;
wl_list_remove ( & view - > destroy . link ) ;
wl_list_remove ( & toplevel - > destroy . link ) ;
wl_list_remove ( & view - > request_move . link ) ;
wl_list_remove ( & toplevel - > request_move . link ) ;
wl_list_remove ( & view - > request_resize . link ) ;
wl_list_remove ( & toplevel - > request_resize . link ) ;
wl_list_remove ( & view - > request_maximize . link ) ;
wl_list_remove ( & toplevel - > request_maximize . link ) ;
wl_list_remove ( & view - > request_fullscreen . link ) ;
wl_list_remove ( & toplevel - > request_fullscreen . link ) ;
free ( view ) ;
free ( toplevel ) ;
}
}
static void begin_interactive ( struct tinywl_ view * view ,
static void begin_interactive ( struct tinywl_ toplevel * toplevel ,
enum tinywl_cursor_mode mode , uint32_t edges ) {
enum tinywl_cursor_mode mode , uint32_t edges ) {
/* This function sets up an interactive move or resize operation, where the
/* This function sets up an interactive move or resize operation, where the
* compositor stops propegating pointer events to clients and instead
* compositor stops propegating pointer events to clients and instead
* consumes them itself , to move or resize windows . */
* consumes them itself , to move or resize windows . */
struct tinywl_server * server = view - > server ;
struct tinywl_server * server = toplevel - > server ;
struct wlr_surface * focused_surface =
struct wlr_surface * focused_surface =
server - > seat - > pointer_state . focused_surface ;
server - > seat - > pointer_state . focused_surface ;
if ( view - > xdg_toplevel - > base - > surface ! =
if ( toplevel - > xdg_toplevel - > base - > surface ! =
wlr_surface_get_root_surface ( focused_surface ) ) {
wlr_surface_get_root_surface ( focused_surface ) ) {
/* Deny move/resize requests from unfocused clients. */
/* Deny move/resize requests from unfocused clients. */
return ;
return ;
}
}
server - > grabbed_ view = view ;
server - > grabbed_ toplevel = toplevel ;
server - > cursor_mode = mode ;
server - > cursor_mode = mode ;
if ( mode = = TINYWL_CURSOR_MOVE ) {
if ( mode = = TINYWL_CURSOR_MOVE ) {
server - > grab_x = server - > cursor - > x - view - > scene_tree - > node . x ;
server - > grab_x = server - > cursor - > x - toplevel - > scene_tree - > node . x ;
server - > grab_y = server - > cursor - > y - view - > scene_tree - > node . y ;
server - > grab_y = server - > cursor - > y - toplevel - > scene_tree - > node . y ;
} else {
} else {
struct wlr_box geo_box ;
struct wlr_box geo_box ;
wlr_xdg_surface_get_geometry ( view - > xdg_toplevel - > base , & geo_box ) ;
wlr_xdg_surface_get_geometry ( toplevel - > xdg_toplevel - > base , & geo_box ) ;
double border_x = ( view - > scene_tree - > node . x + geo_box . x ) +
double border_x = ( toplevel - > scene_tree - > node . x + geo_box . x ) +
( ( edges & WLR_EDGE_RIGHT ) ? geo_box . width : 0 ) ;
( ( edges & WLR_EDGE_RIGHT ) ? geo_box . width : 0 ) ;
double border_y = ( view - > scene_tree - > node . y + geo_box . y ) +
double border_y = ( toplevel - > scene_tree - > node . y + geo_box . y ) +
( ( edges & WLR_EDGE_BOTTOM ) ? geo_box . height : 0 ) ;
( ( edges & WLR_EDGE_BOTTOM ) ? geo_box . height : 0 ) ;
server - > grab_x = server - > cursor - > x - border_x ;
server - > grab_x = server - > cursor - > x - border_x ;
server - > grab_y = server - > cursor - > y - border_y ;
server - > grab_y = server - > cursor - > y - border_y ;
server - > grab_geobox = geo_box ;
server - > grab_geobox = geo_box ;
server - > grab_geobox . x + = view - > scene_tree - > node . x ;
server - > grab_geobox . x + = toplevel - > scene_tree - > node . x ;
server - > grab_geobox . y + = view - > scene_tree - > node . y ;
server - > grab_geobox . y + = toplevel - > scene_tree - > node . y ;
server - > resize_edges = edges ;
server - > resize_edges = edges ;
}
}
@ -731,8 +731,8 @@ static void xdg_toplevel_request_move(
* decorations . Note that a more sophisticated compositor should check the
* decorations . Note that a more sophisticated compositor should check the
* provided serial against a list of button press serials sent to this
* provided serial against a list of button press serials sent to this
* client , to prevent the client from requesting this whenever they want . */
* client , to prevent the client from requesting this whenever they want . */
struct tinywl_ view * view = wl_container_of ( listener , view , request_move ) ;
struct tinywl_ toplevel * toplevel = wl_container_of ( listener , toplevel , request_move ) ;
begin_interactive ( view , TINYWL_CURSOR_MOVE , 0 ) ;
begin_interactive ( toplevel , TINYWL_CURSOR_MOVE , 0 ) ;
}
}
static void xdg_toplevel_request_resize (
static void xdg_toplevel_request_resize (
@ -743,8 +743,8 @@ static void xdg_toplevel_request_resize(
* provided serial against a list of button press serials sent to this
* provided serial against a list of button press serials sent to this
* client , to prevent the client from requesting this whenever they want . */
* client , to prevent the client from requesting this whenever they want . */
struct wlr_xdg_toplevel_resize_event * event = data ;
struct wlr_xdg_toplevel_resize_event * event = data ;
struct tinywl_ view * view = wl_container_of ( listener , view , request_resize ) ;
struct tinywl_ toplevel * toplevel = wl_container_of ( listener , toplevel , request_resize ) ;
begin_interactive ( view , TINYWL_CURSOR_RESIZE , event - > edges ) ;
begin_interactive ( toplevel , TINYWL_CURSOR_RESIZE , event - > edges ) ;
}
}
static void xdg_toplevel_request_maximize (
static void xdg_toplevel_request_maximize (
@ -754,17 +754,17 @@ static void xdg_toplevel_request_maximize(
* client - side decorations . tinywl doesn ' t support maximization , but
* client - side decorations . tinywl doesn ' t support maximization , but
* to conform to xdg - shell protocol we still must send a configure .
* to conform to xdg - shell protocol we still must send a configure .
* wlr_xdg_surface_schedule_configure ( ) is used to send an empty reply . */
* wlr_xdg_surface_schedule_configure ( ) is used to send an empty reply . */
struct tinywl_ view * view =
struct tinywl_ toplevel * toplevel =
wl_container_of ( listener , view , request_maximize ) ;
wl_container_of ( listener , toplevel , request_maximize ) ;
wlr_xdg_surface_schedule_configure ( view - > xdg_toplevel - > base ) ;
wlr_xdg_surface_schedule_configure ( toplevel - > xdg_toplevel - > base ) ;
}
}
static void xdg_toplevel_request_fullscreen (
static void xdg_toplevel_request_fullscreen (
struct wl_listener * listener , void * data ) {
struct wl_listener * listener , void * data ) {
/* Just as with request_maximize, we must send a configure here. */
/* Just as with request_maximize, we must send a configure here. */
struct tinywl_ view * view =
struct tinywl_ toplevel * toplevel =
wl_container_of ( listener , view , request_fullscreen ) ;
wl_container_of ( listener , toplevel , request_fullscreen ) ;
wlr_xdg_surface_schedule_configure ( view - > xdg_toplevel - > base ) ;
wlr_xdg_surface_schedule_configure ( toplevel - > xdg_toplevel - > base ) ;
}
}
static void server_new_xdg_surface ( struct wl_listener * listener , void * data ) {
static void server_new_xdg_surface ( struct wl_listener * listener , void * data ) {
@ -790,35 +790,35 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
}
}
assert ( xdg_surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
assert ( xdg_surface - > role = = WLR_XDG_SURFACE_ROLE_TOPLEVEL ) ;
/* Allocate a tinywl_ view for this surface */
/* Allocate a tinywl_ toplevel for this surface */
struct tinywl_ view * view = calloc ( 1 , sizeof ( * view ) ) ;
struct tinywl_ toplevel * toplevel = calloc ( 1 , sizeof ( * toplevel ) ) ;
view - > server = server ;
toplevel - > server = server ;
view - > xdg_toplevel = xdg_surface - > toplevel ;
toplevel - > xdg_toplevel = xdg_surface - > toplevel ;
view - > scene_tree = wlr_scene_xdg_surface_create (
toplevel - > scene_tree = wlr_scene_xdg_surface_create (
& view - > server - > scene - > tree , view - > xdg_toplevel - > base ) ;
& toplevel - > server - > scene - > tree , toplevel - > xdg_toplevel - > base ) ;
view - > scene_tree - > node . data = view ;
toplevel - > scene_tree - > node . data = toplevel ;
xdg_surface - > data = view - > scene_tree ;
xdg_surface - > data = toplevel - > scene_tree ;
/* Listen to the various events it can emit */
/* Listen to the various events it can emit */
view - > map . notify = xdg_toplevel_map ;
toplevel - > map . notify = xdg_toplevel_map ;
wl_signal_add ( & xdg_surface - > surface - > events . map , & view - > map ) ;
wl_signal_add ( & xdg_surface - > surface - > events . map , & toplevel - > map ) ;
view - > unmap . notify = xdg_toplevel_unmap ;
toplevel - > unmap . notify = xdg_toplevel_unmap ;
wl_signal_add ( & xdg_surface - > surface - > events . unmap , & view - > unmap ) ;
wl_signal_add ( & xdg_surface - > surface - > events . unmap , & toplevel - > unmap ) ;
view - > destroy . notify = xdg_toplevel_destroy ;
toplevel - > destroy . notify = xdg_toplevel_destroy ;
wl_signal_add ( & xdg_surface - > events . destroy , & view - > destroy ) ;
wl_signal_add ( & xdg_surface - > events . destroy , & toplevel - > destroy ) ;
/* cotd */
/* cotd */
struct wlr_xdg_toplevel * toplevel = xdg_surface - > toplevel ;
struct wlr_xdg_toplevel * xdg_ toplevel = xdg_surface - > toplevel ;
view - > request_move . notify = xdg_toplevel_request_move ;
toplevel - > request_move . notify = xdg_toplevel_request_move ;
wl_signal_add ( & toplevel- > events . request_move , & view - > request_move ) ;
wl_signal_add ( & xdg_ toplevel- > events . request_move , & toplevel - > request_move ) ;
view - > request_resize . notify = xdg_toplevel_request_resize ;
toplevel - > request_resize . notify = xdg_toplevel_request_resize ;
wl_signal_add ( & toplevel- > events . request_resize , & view - > request_resize ) ;
wl_signal_add ( & xdg_ toplevel- > events . request_resize , & toplevel - > request_resize ) ;
view - > request_maximize . notify = xdg_toplevel_request_maximize ;
toplevel - > request_maximize . notify = xdg_toplevel_request_maximize ;
wl_signal_add ( & toplevel- > events . request_maximize ,
wl_signal_add ( & xdg_ toplevel- > events . request_maximize ,
& view - > request_maximize ) ;
& toplevel - > request_maximize ) ;
view - > request_fullscreen . notify = xdg_toplevel_request_fullscreen ;
toplevel - > request_fullscreen . notify = xdg_toplevel_request_fullscreen ;
wl_signal_add ( & toplevel- > events . request_fullscreen ,
wl_signal_add ( & xdg_ toplevel- > events . request_fullscreen ,
& view - > request_fullscreen ) ;
& toplevel - > request_fullscreen ) ;
}
}
int main ( int argc , char * argv [ ] ) {
int main ( int argc , char * argv [ ] ) {
@ -914,7 +914,7 @@ int main(int argc, char *argv[]) {
*
*
* https : //drewdevault.com/2018/07/29/Wayland-shells.html
* https : //drewdevault.com/2018/07/29/Wayland-shells.html
*/
*/
wl_list_init ( & server . view s) ;
wl_list_init ( & server . toplevel s) ;
server . xdg_shell = wlr_xdg_shell_create ( server . wl_display , 3 ) ;
server . xdg_shell = wlr_xdg_shell_create ( server . wl_display , 3 ) ;
server . new_xdg_surface . notify = server_new_xdg_surface ;
server . new_xdg_surface . notify = server_new_xdg_surface ;
wl_signal_add ( & server . xdg_shell - > events . new_surface ,
wl_signal_add ( & server . xdg_shell - > events . new_surface ,