diff --git a/examples/compositor.c b/examples/compositor.c index 9d96b053..841407bf 100644 --- a/examples/compositor.c +++ b/examples/compositor.c @@ -56,6 +56,8 @@ struct sample_state { struct wl_listener cursor_motion_absolute; struct wl_listener cursor_button; struct wl_listener cursor_axis; + + struct wl_listener new_xdg_surface_v6; }; /* @@ -85,6 +87,15 @@ static void output_frame_handle_surface(struct sample_state *sample, } } } + +static void handle_new_xdg_surface_v6(struct wl_listener *listener, + void *data) { + struct wlr_xdg_surface_v6 *surface = data; + wlr_log(L_DEBUG, "new xdg surface: title=%s, app_id=%s", + surface->title, surface->app_id); + // configure the surface and add it to data structures here +} + static void handle_output_frame(struct output_state *output, struct timespec *ts) { struct compositor_state *state = output->compositor; @@ -309,6 +320,12 @@ int main(int argc, char *argv[]) { state.wl_shell = wlr_wl_shell_create(compositor.display); state.xdg_shell = wlr_xdg_shell_v6_create(compositor.display); + // shell events + wl_signal_add(&state.xdg_shell->events.new_surface, + &state.new_xdg_surface_v6); + state.new_xdg_surface_v6.notify = handle_new_xdg_surface_v6; + + state.data_device_manager = wlr_data_device_manager_create(compositor.display); @@ -341,6 +358,8 @@ int main(int argc, char *argv[]) { wl_display_run(compositor.display); + wl_list_remove(&state.new_xdg_surface_v6.link); + wlr_xwayland_destroy(state.xwayland); close(state.keymap_fd); wlr_seat_destroy(state.wl_seat); diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index a4afaf3b..7c912370 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -8,6 +8,10 @@ struct wlr_xdg_shell_v6 { struct wl_list wl_resources; struct wl_list surfaces; + struct { + struct wl_signal new_surface; + } events; + void *data; }; @@ -53,10 +57,12 @@ struct wlr_xdg_surface_v6 { struct wl_client *client; struct wl_resource *resource; struct wlr_surface *surface; + struct wlr_xdg_shell_v6 *shell; struct wl_list link; enum wlr_xdg_surface_v6_role role; struct wlr_xdg_toplevel_v6 *toplevel_state; + bool configured; struct wl_event_source *configure_idle; struct wl_list configure_list; @@ -74,6 +80,7 @@ struct wlr_xdg_surface_v6 { struct wl_signal request_minimize; struct wl_signal commit; struct wl_signal destroy; + struct wl_signal ack_configure; } events; void *data; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 11b44d6d..d32990db 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -205,7 +205,6 @@ static void wlr_xdg_toplevel_v6_ack_configure( static void xdg_surface_ack_configure(struct wl_client *client, struct wl_resource *resource, uint32_t serial) { - wlr_log(L_DEBUG, "TODO xdg surface ack configure"); struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); // TODO handle popups @@ -237,7 +236,13 @@ static void xdg_surface_ack_configure(struct wl_client *client, wlr_xdg_toplevel_v6_ack_configure(surface, configure); } - // TODO send ack_configure event? + if (!surface->configured) { + surface->configured = true; + wl_signal_emit(&surface->shell->events.new_surface, surface); + } + + wl_signal_emit(&surface->events.ack_configure, surface); + free(configure); } @@ -444,6 +449,7 @@ static void xdg_shell_get_xdg_surface(struct wl_client *client, } surface->client = client; + surface->shell = xdg_shell; surface->role = WLR_XDG_SURFACE_V6_ROLE_NONE; surface->surface = wl_resource_get_user_data(_surface); surface->resource = wl_resource_create(client, @@ -454,6 +460,7 @@ static void xdg_shell_get_xdg_surface(struct wl_client *client, wl_signal_init(&surface->events.request_minimize); wl_signal_init(&surface->events.commit); wl_signal_init(&surface->events.destroy); + wl_signal_init(&surface->events.ack_configure); wl_signal_add(&surface->surface->signals.destroy, &surface->surface_destroy_listener); @@ -514,8 +521,12 @@ struct wlr_xdg_shell_v6 *wlr_xdg_shell_v6_create(struct wl_display *display) { return NULL; } xdg_shell->wl_global = wl_global; + + wl_signal_init(&xdg_shell->events.new_surface); + wl_list_init(&xdg_shell->wl_resources); wl_list_init(&xdg_shell->surfaces); + return xdg_shell; }