|
|
@ -59,6 +59,13 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client,
|
|
|
|
struct wlr_seat_handle *seat_handle =
|
|
|
|
struct wlr_seat_handle *seat_handle =
|
|
|
|
wl_resource_get_user_data(seat_resource);
|
|
|
|
wl_resource_get_user_data(seat_resource);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!surface->configured) {
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->toplevel_state->resource,
|
|
|
|
|
|
|
|
ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
|
|
|
|
|
|
|
|
"surface has not been configured yet");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_xdg_toplevel_v6_show_window_menu_event *event =
|
|
|
|
struct wlr_xdg_toplevel_v6_show_window_menu_event *event =
|
|
|
|
calloc(1, sizeof(struct wlr_xdg_toplevel_v6_show_window_menu_event));
|
|
|
|
calloc(1, sizeof(struct wlr_xdg_toplevel_v6_show_window_menu_event));
|
|
|
|
if (event == NULL) {
|
|
|
|
if (event == NULL) {
|
|
|
@ -85,6 +92,13 @@ static void xdg_toplevel_protocol_move(struct wl_client *client,
|
|
|
|
struct wlr_seat_handle *seat_handle =
|
|
|
|
struct wlr_seat_handle *seat_handle =
|
|
|
|
wl_resource_get_user_data(seat_resource);
|
|
|
|
wl_resource_get_user_data(seat_resource);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!surface->configured) {
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->toplevel_state->resource,
|
|
|
|
|
|
|
|
ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
|
|
|
|
|
|
|
|
"surface has not been configured yet");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_xdg_toplevel_v6_move_event *event =
|
|
|
|
struct wlr_xdg_toplevel_v6_move_event *event =
|
|
|
|
calloc(1, sizeof(struct wlr_xdg_toplevel_v6_move_event));
|
|
|
|
calloc(1, sizeof(struct wlr_xdg_toplevel_v6_move_event));
|
|
|
|
if (event == NULL) {
|
|
|
|
if (event == NULL) {
|
|
|
@ -109,6 +123,13 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client,
|
|
|
|
struct wlr_seat_handle *seat_handle =
|
|
|
|
struct wlr_seat_handle *seat_handle =
|
|
|
|
wl_resource_get_user_data(seat_resource);
|
|
|
|
wl_resource_get_user_data(seat_resource);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!surface->configured) {
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->toplevel_state->resource,
|
|
|
|
|
|
|
|
ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
|
|
|
|
|
|
|
|
"surface has not been configured yet");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_xdg_toplevel_v6_resize_event *event =
|
|
|
|
struct wlr_xdg_toplevel_v6_resize_event *event =
|
|
|
|
calloc(1, sizeof(struct wlr_xdg_toplevel_v6_resize_event));
|
|
|
|
calloc(1, sizeof(struct wlr_xdg_toplevel_v6_resize_event));
|
|
|
|
if (event == NULL) {
|
|
|
|
if (event == NULL) {
|
|
|
@ -243,6 +264,7 @@ static void copy_toplevel_state(struct wlr_xdg_toplevel_v6_state *src,
|
|
|
|
struct wlr_xdg_toplevel_v6_state *dest) {
|
|
|
|
struct wlr_xdg_toplevel_v6_state *dest) {
|
|
|
|
dest->width = src->width;
|
|
|
|
dest->width = src->width;
|
|
|
|
dest->height = src->height;
|
|
|
|
dest->height = src->height;
|
|
|
|
|
|
|
|
|
|
|
|
dest->max_width = src->max_width;
|
|
|
|
dest->max_width = src->max_width;
|
|
|
|
dest->max_height = src->max_height;
|
|
|
|
dest->max_height = src->max_height;
|
|
|
|
dest->min_width = src->min_width;
|
|
|
|
dest->min_width = src->min_width;
|
|
|
@ -265,8 +287,10 @@ static void xdg_surface_ack_configure(struct wl_client *client,
|
|
|
|
struct wl_resource *resource, uint32_t serial) {
|
|
|
|
struct wl_resource *resource, uint32_t serial) {
|
|
|
|
struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource);
|
|
|
|
struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource);
|
|
|
|
|
|
|
|
|
|
|
|
// TODO handle popups
|
|
|
|
if (surface->role == WLR_XDG_SURFACE_V6_ROLE_NONE) {
|
|
|
|
if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) {
|
|
|
|
wl_resource_post_error(surface->resource,
|
|
|
|
|
|
|
|
ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
|
|
|
|
|
|
|
|
"xdg_surface must have a role");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -285,7 +309,9 @@ static void xdg_surface_ack_configure(struct wl_client *client,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
if (!found) {
|
|
|
|
// TODO post error on the client resource
|
|
|
|
wl_resource_post_error(surface->client->resource,
|
|
|
|
|
|
|
|
ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
|
|
|
|
|
|
|
|
"wrong configure serial: %u", serial);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -308,6 +334,14 @@ static void xdg_surface_set_window_geometry(struct wl_client *client,
|
|
|
|
struct wl_resource *resource, int32_t x, int32_t y, int32_t width,
|
|
|
|
struct wl_resource *resource, int32_t x, int32_t y, int32_t width,
|
|
|
|
int32_t height) {
|
|
|
|
int32_t height) {
|
|
|
|
struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource);
|
|
|
|
struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (surface->role == WLR_XDG_SURFACE_V6_ROLE_NONE) {
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->resource,
|
|
|
|
|
|
|
|
ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
|
|
|
|
|
|
|
|
"xdg_surface must have a role");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
surface->has_next_geometry = true;
|
|
|
|
surface->has_next_geometry = true;
|
|
|
|
surface->next_geometry->height = height;
|
|
|
|
surface->next_geometry->height = height;
|
|
|
|
surface->next_geometry->width = width;
|
|
|
|
surface->next_geometry->width = width;
|
|
|
@ -400,9 +434,13 @@ static void wlr_xdg_surface_send_configure(void *user_data) {
|
|
|
|
|
|
|
|
|
|
|
|
surface->configure_idle = NULL;
|
|
|
|
surface->configure_idle = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
// TODO handle no memory
|
|
|
|
|
|
|
|
struct wlr_xdg_surface_v6_configure *configure =
|
|
|
|
struct wlr_xdg_surface_v6_configure *configure =
|
|
|
|
calloc(1, sizeof(struct wlr_xdg_surface_v6_configure));
|
|
|
|
calloc(1, sizeof(struct wlr_xdg_surface_v6_configure));
|
|
|
|
|
|
|
|
if (configure == NULL) {
|
|
|
|
|
|
|
|
wl_client_post_no_memory(surface->client->client);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_insert(surface->configure_list.prev, &configure->link);
|
|
|
|
wl_list_insert(surface->configure_list.prev, &configure->link);
|
|
|
|
configure->serial = wl_display_next_serial(display);
|
|
|
|
configure->serial = wl_display_next_serial(display);
|
|
|
|
|
|
|
|
|
|
|
@ -454,7 +492,7 @@ static void handle_wlr_surface_destroyed(struct wl_listener *listener,
|
|
|
|
|
|
|
|
|
|
|
|
static void wlr_xdg_surface_v6_toplevel_committed(
|
|
|
|
static void wlr_xdg_surface_v6_toplevel_committed(
|
|
|
|
struct wlr_xdg_surface_v6 *surface) {
|
|
|
|
struct wlr_xdg_surface_v6 *surface) {
|
|
|
|
if (!surface->toplevel_state->added) {
|
|
|
|
if (!surface->surface->current.buffer && !surface->toplevel_state->added) {
|
|
|
|
// on the first commit, send a configure request to tell the client it
|
|
|
|
// on the first commit, send a configure request to tell the client it
|
|
|
|
// is added
|
|
|
|
// is added
|
|
|
|
wlr_xdg_surface_v6_schedule_configure(surface, true);
|
|
|
|
wlr_xdg_surface_v6_schedule_configure(surface, true);
|
|
|
@ -462,6 +500,12 @@ static void wlr_xdg_surface_v6_toplevel_committed(
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!surface->surface->current.buffer) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: error if they try to resize a maximized or fullscreen window
|
|
|
|
|
|
|
|
|
|
|
|
copy_toplevel_state(&surface->toplevel_state->next,
|
|
|
|
copy_toplevel_state(&surface->toplevel_state->next,
|
|
|
|
&surface->toplevel_state->current);
|
|
|
|
&surface->toplevel_state->current);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -471,6 +515,13 @@ static void handle_wlr_surface_committed(struct wl_listener *listener,
|
|
|
|
struct wlr_xdg_surface_v6 *surface =
|
|
|
|
struct wlr_xdg_surface_v6 *surface =
|
|
|
|
wl_container_of(listener, surface, surface_commit_listener);
|
|
|
|
wl_container_of(listener, surface, surface_commit_listener);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (surface->surface->current.buffer && !surface->configured) {
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->resource,
|
|
|
|
|
|
|
|
ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER,
|
|
|
|
|
|
|
|
"xdg_surface has never been configured");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (surface->has_next_geometry) {
|
|
|
|
if (surface->has_next_geometry) {
|
|
|
|
surface->has_next_geometry = false;
|
|
|
|
surface->has_next_geometry = false;
|
|
|
|
surface->geometry->x = surface->next_geometry->x;
|
|
|
|
surface->geometry->x = surface->next_geometry->x;
|
|
|
@ -479,8 +530,18 @@ static void handle_wlr_surface_committed(struct wl_listener *listener,
|
|
|
|
surface->geometry->height = surface->next_geometry->height;
|
|
|
|
surface->geometry->height = surface->next_geometry->height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) {
|
|
|
|
switch (surface->role) {
|
|
|
|
|
|
|
|
case WLR_XDG_SURFACE_V6_ROLE_NONE:
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->resource,
|
|
|
|
|
|
|
|
ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
|
|
|
|
|
|
|
|
"xdg_surface must have a role");
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL:
|
|
|
|
wlr_xdg_surface_v6_toplevel_committed(surface);
|
|
|
|
wlr_xdg_surface_v6_toplevel_committed(surface);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WLR_XDG_SURFACE_V6_ROLE_POPUP:
|
|
|
|
|
|
|
|
wlr_log(L_DEBUG, "TODO: popup surface committed");
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
wl_signal_emit(&surface->events.commit, surface);
|
|
|
|
wl_signal_emit(&surface->events.commit, surface);
|
|
|
@ -491,6 +552,7 @@ static void xdg_shell_get_xdg_surface(struct wl_client *wl_client,
|
|
|
|
struct wl_resource *surface_resource) {
|
|
|
|
struct wl_resource *surface_resource) {
|
|
|
|
struct wlr_xdg_client_v6 *client =
|
|
|
|
struct wlr_xdg_client_v6 *client =
|
|
|
|
wl_resource_get_user_data(client_resource);
|
|
|
|
wl_resource_get_user_data(client_resource);
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_xdg_surface_v6 *surface;
|
|
|
|
struct wlr_xdg_surface_v6 *surface;
|
|
|
|
if (!(surface = calloc(1, sizeof(struct wlr_xdg_surface_v6)))) {
|
|
|
|
if (!(surface = calloc(1, sizeof(struct wlr_xdg_surface_v6)))) {
|
|
|
|
wl_client_post_no_memory(wl_client);
|
|
|
|
wl_client_post_no_memory(wl_client);
|
|
|
@ -517,6 +579,13 @@ static void xdg_shell_get_xdg_surface(struct wl_client *wl_client,
|
|
|
|
&zxdg_surface_v6_interface, wl_resource_get_version(client_resource),
|
|
|
|
&zxdg_surface_v6_interface, wl_resource_get_version(client_resource),
|
|
|
|
id);
|
|
|
|
id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (surface->surface->current.buffer != NULL) {
|
|
|
|
|
|
|
|
wl_resource_post_error(surface->resource,
|
|
|
|
|
|
|
|
ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER,
|
|
|
|
|
|
|
|
"xdg_surface must not have a buffer at creation");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_init(&surface->configure_list);
|
|
|
|
wl_list_init(&surface->configure_list);
|
|
|
|
|
|
|
|
|
|
|
|
wl_signal_init(&surface->events.request_minimize);
|
|
|
|
wl_signal_init(&surface->events.request_minimize);
|
|
|
|