surface: replace wlr_surface_set_role_committed with wlr_surface_role

This commit is contained in:
emersion 2018-07-07 22:45:16 +01:00
parent be54278207
commit 33db4263a0
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
24 changed files with 256 additions and 167 deletions

View File

@ -13,6 +13,8 @@ struct wlr_client_data_source {
struct wl_resource *resource; struct wl_resource *resource;
}; };
extern const struct wlr_surface_role drag_icon_surface_role;
struct wlr_data_offer *data_offer_create(struct wl_client *client, struct wlr_data_offer *data_offer_create(struct wl_client *client,
struct wlr_data_source *source, uint32_t version); struct wlr_data_source *source, uint32_t version);
void data_offer_update_action(struct wlr_data_offer *offer); void data_offer_update_action(struct wlr_data_offer *offer);

View File

@ -10,8 +10,8 @@ struct wlr_xdg_positioner_resource {
struct wlr_xdg_positioner attrs; struct wlr_xdg_positioner attrs;
}; };
#define XDG_TOPLEVEL_ROLE "xdg_toplevel" extern const struct wlr_surface_role xdg_toplevel_surface_role;
#define XDG_POPUP_ROLE "xdg_popup" extern const struct wlr_surface_role xdg_popup_surface_role;
uint32_t schedule_xdg_surface_configure(struct wlr_xdg_surface *surface); uint32_t schedule_xdg_surface_configure(struct wlr_xdg_surface *surface);
struct wlr_xdg_surface *create_xdg_surface( struct wlr_xdg_surface *create_xdg_surface(
@ -19,6 +19,7 @@ struct wlr_xdg_surface *create_xdg_surface(
uint32_t id); uint32_t id);
void unmap_xdg_surface(struct wlr_xdg_surface *surface); void unmap_xdg_surface(struct wlr_xdg_surface *surface);
void destroy_xdg_surface(struct wlr_xdg_surface *surface); void destroy_xdg_surface(struct wlr_xdg_surface *surface);
void handle_xdg_surface_committed(struct wlr_surface *wlr_surface);
void create_xdg_positioner(struct wlr_xdg_client *client, uint32_t id); void create_xdg_positioner(struct wlr_xdg_client *client, uint32_t id);
struct wlr_xdg_positioner_resource *get_xdg_positioner_from_resource( struct wlr_xdg_positioner_resource *get_xdg_positioner_from_resource(

View File

@ -10,8 +10,8 @@ struct wlr_xdg_positioner_v6_resource {
struct wlr_xdg_positioner_v6 attrs; struct wlr_xdg_positioner_v6 attrs;
}; };
#define XDG_TOPLEVEL_V6_ROLE "xdg_toplevel_v6" extern const struct wlr_surface_role xdg_toplevel_v6_surface_role;
#define XDG_POPUP_V6_ROLE "xdg_popup_v6" extern const struct wlr_surface_role xdg_popup_v6_surface_role;
uint32_t schedule_xdg_surface_v6_configure(struct wlr_xdg_surface_v6 *surface); uint32_t schedule_xdg_surface_v6_configure(struct wlr_xdg_surface_v6 *surface);
struct wlr_xdg_surface_v6 *create_xdg_surface_v6( struct wlr_xdg_surface_v6 *create_xdg_surface_v6(
@ -19,6 +19,7 @@ struct wlr_xdg_surface_v6 *create_xdg_surface_v6(
uint32_t id); uint32_t id);
void unmap_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface); void unmap_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface);
void destroy_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface); void destroy_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface);
void handle_xdg_surface_v6_committed(struct wlr_surface *wlr_surface);
void create_xdg_positioner_v6(struct wlr_xdg_client_v6 *client, uint32_t id); void create_xdg_positioner_v6(struct wlr_xdg_client_v6 *client, uint32_t id);
struct wlr_xdg_positioner_v6_resource *get_xdg_positioner_v6_from_resource( struct wlr_xdg_positioner_v6_resource *get_xdg_positioner_v6_from_resource(

View File

@ -76,7 +76,7 @@ struct wlr_layer_surface {
struct wlr_layer_surface_state server_pending; struct wlr_layer_surface_state server_pending;
struct wlr_layer_surface_state current; struct wlr_layer_surface_state current;
struct wl_listener surface_destroy_listener; struct wl_listener surface_destroy;
struct { struct {
struct wl_signal destroy; struct wl_signal destroy;

View File

@ -540,4 +540,6 @@ bool wlr_seat_validate_grab_serial(struct wlr_seat *seat, uint32_t serial);
struct wlr_seat_client *wlr_seat_client_from_resource( struct wlr_seat_client *wlr_seat_client_from_resource(
struct wl_resource *resource); struct wl_resource *resource);
bool wlr_surface_is_pointer_cursor(struct wlr_surface *surface);
#endif #endif

View File

@ -36,6 +36,11 @@ struct wlr_surface_state {
struct wl_listener buffer_destroy; struct wl_listener buffer_destroy;
}; };
struct wlr_surface_role {
const char *name;
void (*commit)(struct wlr_surface *surface);
};
struct wlr_surface { struct wlr_surface {
struct wl_resource *resource; struct wl_resource *resource;
struct wlr_renderer *renderer; struct wlr_renderer *renderer;
@ -68,7 +73,9 @@ struct wlr_surface {
* the previous commit. * the previous commit.
*/ */
struct wlr_surface_state current, pending, previous; struct wlr_surface_state current, pending, previous;
const char *role; // the lifetime-bound role or null
const struct wlr_surface_role *role; // the lifetime-bound role or NULL
void *role_data; // role-specific data
struct { struct {
struct wl_signal commit; struct wl_signal commit;
@ -76,10 +83,6 @@ struct wlr_surface {
struct wl_signal destroy; struct wl_signal destroy;
} events; } events;
// surface commit callback for the role that runs before all others
void (*role_committed)(struct wlr_surface *surface, void *role_data);
void *role_data;
struct wl_list subsurfaces; // wlr_subsurface::parent_link struct wl_list subsurfaces; // wlr_subsurface::parent_link
// wlr_subsurface::parent_pending_link // wlr_subsurface::parent_pending_link
@ -137,7 +140,8 @@ struct wlr_surface *wlr_surface_create(struct wl_client *client,
* Set the lifetime role for this surface. Returns 0 on success or -1 if the * Set the lifetime role for this surface. Returns 0 on success or -1 if the
* role cannot be set. * role cannot be set.
*/ */
int wlr_surface_set_role(struct wlr_surface *surface, const char *role, bool wlr_surface_set_role(struct wlr_surface *surface,
const struct wlr_surface_role *role, void *role_data,
struct wl_resource *error_resource, uint32_t error_code); struct wl_resource *error_resource, uint32_t error_code);
/** /**
@ -200,14 +204,6 @@ struct wlr_box;
*/ */
void wlr_surface_get_extends(struct wlr_surface *surface, struct wlr_box *box); void wlr_surface_get_extends(struct wlr_surface *surface, struct wlr_box *box);
/**
* Set a callback for surface commit that runs before all the other callbacks.
* This is intended for use by the surface role.
*/
void wlr_surface_set_role_committed(struct wlr_surface *surface,
void (*role_committed)(struct wlr_surface *surface, void *role_data),
void *role_data);
struct wlr_surface *wlr_surface_from_resource(struct wl_resource *resource); struct wlr_surface *wlr_surface_from_resource(struct wl_resource *resource);
/** /**

View File

@ -69,7 +69,7 @@ struct wlr_wl_shell_surface {
char *title; char *title;
char *class; char *class;
struct wl_listener surface_destroy_listener; struct wl_listener surface_destroy;
struct wlr_wl_shell_surface *parent; struct wlr_wl_shell_surface *parent;
struct wl_list popup_link; struct wl_list popup_link;
@ -152,7 +152,7 @@ struct wlr_surface *wlr_wl_shell_surface_surface_at(
bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface); bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface);
struct wlr_wl_surface *wlr_wl_shell_surface_from_wlr_surface( struct wlr_wl_shell_surface *wlr_wl_shell_surface_from_wlr_surface(
struct wlr_surface *surface); struct wlr_surface *surface);
/** /**

View File

@ -163,7 +163,8 @@ struct wlr_xdg_surface {
struct wlr_box next_geometry; struct wlr_box next_geometry;
struct wlr_box geometry; struct wlr_box geometry;
struct wl_listener surface_destroy_listener; struct wl_listener surface_destroy;
struct wl_listener surface_commit;
struct { struct {
struct wl_signal destroy; struct wl_signal destroy;

View File

@ -161,7 +161,8 @@ struct wlr_xdg_surface_v6 {
struct wlr_box next_geometry; struct wlr_box next_geometry;
struct wlr_box geometry; struct wlr_box geometry;
struct wl_listener surface_destroy_listener; struct wl_listener surface_destroy;
struct wl_listener surface_commit;
struct { struct {
struct wl_signal destroy; struct wl_signal destroy;

View File

@ -56,10 +56,8 @@ static void data_device_start_drag(struct wl_client *client,
if (icon_resource) { if (icon_resource) {
icon = wlr_surface_from_resource(icon_resource); icon = wlr_surface_from_resource(icon_resource);
} if (!wlr_surface_set_role(icon, &drag_icon_surface_role, NULL,
if (icon) { icon_resource, WL_DATA_DEVICE_ERROR_ROLE)) {
if (wlr_surface_set_role(icon, "wl_data_device-icon",
icon_resource, WL_DATA_DEVICE_ERROR_ROLE) < 0) {
return; return;
} }
} }

View File

@ -324,7 +324,7 @@ static void drag_icon_destroy(struct wlr_drag_icon *icon) {
} }
drag_icon_set_mapped(icon, false); drag_icon_set_mapped(icon, false);
wlr_signal_emit_safe(&icon->events.destroy, icon); wlr_signal_emit_safe(&icon->events.destroy, icon);
wlr_surface_set_role_committed(icon->surface, NULL, NULL); icon->surface->role_data = NULL;
wl_list_remove(&icon->surface_destroy.link); wl_list_remove(&icon->surface_destroy.link);
wl_list_remove(&icon->seat_client_destroy.link); wl_list_remove(&icon->seat_client_destroy.link);
wl_list_remove(&icon->link); wl_list_remove(&icon->link);
@ -338,15 +338,24 @@ static void drag_icon_handle_surface_destroy(struct wl_listener *listener,
drag_icon_destroy(icon); drag_icon_destroy(icon);
} }
static void drag_icon_handle_surface_commit(struct wlr_surface *surface, static void drag_icon_surface_role_commit(struct wlr_surface *surface) {
void *role_data) { assert(surface->role == &drag_icon_surface_role);
struct wlr_drag_icon *icon = role_data; struct wlr_drag_icon *icon = surface->role_data;
if (icon == NULL) {
return;
}
icon->sx += icon->surface->current.dx; icon->sx += icon->surface->current.dx;
icon->sy += icon->surface->current.dy; icon->sy += icon->surface->current.dy;
drag_icon_set_mapped(icon, wlr_surface_has_buffer(surface)); drag_icon_set_mapped(icon, wlr_surface_has_buffer(surface));
} }
const struct wlr_surface_role drag_icon_surface_role = {
.name = "wl_data_device-icon",
.commit = drag_icon_surface_role_commit,
};
static void drag_icon_handle_seat_client_destroy(struct wl_listener *listener, static void drag_icon_handle_seat_client_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_drag_icon *icon = struct wlr_drag_icon *icon =
@ -375,12 +384,11 @@ static struct wlr_drag_icon *drag_icon_create(
wl_signal_add(&icon->surface->events.destroy, &icon->surface_destroy); wl_signal_add(&icon->surface->events.destroy, &icon->surface_destroy);
icon->surface_destroy.notify = drag_icon_handle_surface_destroy; icon->surface_destroy.notify = drag_icon_handle_surface_destroy;
wlr_surface_set_role_committed(icon->surface,
drag_icon_handle_surface_commit, icon);
wl_signal_add(&client->events.destroy, &icon->seat_client_destroy); wl_signal_add(&client->events.destroy, &icon->seat_client_destroy);
icon->seat_client_destroy.notify = drag_icon_handle_seat_client_destroy; icon->seat_client_destroy.notify = drag_icon_handle_seat_client_destroy;
icon->surface->role_data = icon;
wl_list_insert(&client->seat->drag_icons, &icon->link); wl_list_insert(&client->seat->drag_icons, &icon->link);
wlr_signal_emit_safe(&client->seat->events.new_drag_icon, icon); wlr_signal_emit_safe(&client->seat->events.new_drag_icon, icon);

View File

@ -60,6 +60,10 @@ static struct wlr_seat_client *seat_client_from_pointer_resource(
return wl_resource_get_user_data(resource); return wl_resource_get_user_data(resource);
} }
static const struct wlr_surface_role pointer_cursor_surface_role = {
.name = "wl_pointer-cursor",
};
static void pointer_set_cursor(struct wl_client *client, static void pointer_set_cursor(struct wl_client *client,
struct wl_resource *pointer_resource, uint32_t serial, struct wl_resource *pointer_resource, uint32_t serial,
struct wl_resource *surface_resource, struct wl_resource *surface_resource,
@ -73,8 +77,8 @@ static void pointer_set_cursor(struct wl_client *client,
struct wlr_surface *surface = NULL; struct wlr_surface *surface = NULL;
if (surface_resource != NULL) { if (surface_resource != NULL) {
surface = wlr_surface_from_resource(surface_resource); surface = wlr_surface_from_resource(surface_resource);
if (wlr_surface_set_role(surface, "wl_pointer-cursor", surface_resource, if (!wlr_surface_set_role(surface, &pointer_cursor_surface_role, NULL,
WL_POINTER_ERROR_ROLE) < 0) { surface_resource, WL_POINTER_ERROR_ROLE)) {
return; return;
} }
} }
@ -351,3 +355,7 @@ void seat_client_destroy_pointer(struct wl_resource *resource) {
} }
wl_resource_set_user_data(resource, NULL); wl_resource_set_user_data(resource, NULL);
} }
bool wlr_surface_is_pointer_cursor(struct wlr_surface *surface) {
return surface->role == &pointer_cursor_surface_role;
}

View File

@ -10,11 +10,10 @@
#define COMPOSITOR_VERSION 4 #define COMPOSITOR_VERSION 4
#define SUBCOMPOSITOR_VERSION 1 #define SUBCOMPOSITOR_VERSION 1
static const char *subsurface_role = "wl_subsurface"; extern const struct wlr_surface_role subsurface_role;
bool wlr_surface_is_subsurface(struct wlr_surface *surface) { bool wlr_surface_is_subsurface(struct wlr_surface *surface) {
return surface->role != NULL && return surface->role == &subsurface_role;
strcmp(surface->role, subsurface_role) == 0;
} }
struct wlr_subsurface *wlr_subsurface_from_wlr_surface( struct wlr_subsurface *wlr_subsurface_from_wlr_surface(
@ -73,8 +72,8 @@ static void subcompositor_handle_get_subsurface(struct wl_client *client,
return; return;
} }
if (wlr_surface_set_role(surface, subsurface_role, resource, if (!wlr_surface_set_role(surface, &subsurface_role, NULL,
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0) { resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE)) {
return; return;
} }

View File

@ -11,8 +11,6 @@
#include "util/signal.h" #include "util/signal.h"
#include "wlr-layer-shell-unstable-v1-protocol.h" #include "wlr-layer-shell-unstable-v1-protocol.h"
static const char *zwlr_layer_surface_role = "zwlr_layer_surface";
static void resource_handle_destroy(struct wl_client *client, static void resource_handle_destroy(struct wl_client *client,
struct wl_resource *resource) { struct wl_resource *resource) {
wl_resource_destroy(resource); wl_resource_destroy(resource);
@ -35,8 +33,10 @@ static struct wlr_layer_surface *layer_surface_from_resource(
return wl_resource_get_user_data(resource); return wl_resource_get_user_data(resource);
} }
static const struct wlr_surface_role layer_surface_role;
bool wlr_surface_is_layer_surface(struct wlr_surface *surface) { bool wlr_surface_is_layer_surface(struct wlr_surface *surface) {
return strcmp(surface->role, zwlr_layer_surface_role) == 0; return surface->role == &layer_surface_role;
} }
struct wlr_layer_surface *wlr_layer_surface_from_wlr_surface( struct wlr_layer_surface *wlr_layer_surface_from_wlr_surface(
@ -181,9 +181,8 @@ static void layer_surface_destroy(struct wlr_layer_surface *surface) {
} }
wlr_signal_emit_safe(&surface->events.destroy, surface); wlr_signal_emit_safe(&surface->events.destroy, surface);
wl_resource_set_user_data(surface->resource, NULL); wl_resource_set_user_data(surface->resource, NULL);
wl_list_remove(&surface->surface_destroy_listener.link); surface->surface->role_data = NULL;
wl_list_init(&surface->surface_destroy_listener.link); wl_list_remove(&surface->surface_destroy.link);
wlr_surface_set_role_committed(surface->surface, NULL, NULL);
wl_list_remove(&surface->link); wl_list_remove(&surface->link);
free(surface->namespace); free(surface->namespace);
free(surface); free(surface);
@ -251,9 +250,12 @@ void wlr_layer_surface_close(struct wlr_layer_surface *surface) {
zwlr_layer_surface_v1_send_closed(surface->resource); zwlr_layer_surface_v1_send_closed(surface->resource);
} }
static void handle_surface_committed(struct wlr_surface *wlr_surface, static void layer_surface_role_commit(struct wlr_surface *wlr_surface) {
void *role_data) { struct wlr_layer_surface *surface =
struct wlr_layer_surface *surface = role_data; wlr_layer_surface_from_wlr_surface(wlr_surface);
if (surface == NULL) {
return;
}
if (surface->closed) { if (surface->closed) {
// Ignore commits after the compositor has closed it // Ignore commits after the compositor has closed it
@ -305,10 +307,15 @@ static void handle_surface_committed(struct wlr_surface *wlr_surface,
} }
} }
static const struct wlr_surface_role layer_surface_role = {
.name = "zwlr_layer_surface_v1",
.commit = layer_surface_role_commit,
};
static void handle_surface_destroyed(struct wl_listener *listener, static void handle_surface_destroyed(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_layer_surface *layer_surface = struct wlr_layer_surface *layer_surface =
wl_container_of(listener, layer_surface, surface_destroy_listener); wl_container_of(listener, layer_surface, surface_destroy);
layer_surface_destroy(layer_surface); layer_surface_destroy(layer_surface);
} }
@ -322,11 +329,6 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client,
struct wlr_surface *wlr_surface = struct wlr_surface *wlr_surface =
wlr_surface_from_resource(surface_resource); wlr_surface_from_resource(surface_resource);
if (wlr_surface_set_role(wlr_surface, zwlr_layer_surface_role,
client_resource, ZWLR_LAYER_SHELL_V1_ERROR_ROLE)) {
return;
}
struct wlr_layer_surface *surface = struct wlr_layer_surface *surface =
calloc(1, sizeof(struct wlr_layer_surface)); calloc(1, sizeof(struct wlr_layer_surface));
if (surface == NULL) { if (surface == NULL) {
@ -334,6 +336,12 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client,
return; return;
} }
if (!wlr_surface_set_role(wlr_surface, &layer_surface_role, surface,
client_resource, ZWLR_LAYER_SHELL_V1_ERROR_ROLE)) {
free(surface);
return;
}
surface->shell = shell; surface->shell = shell;
surface->surface = wlr_surface; surface->surface = wlr_surface;
if (output_resource) { if (output_resource) {
@ -368,15 +376,13 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client,
wl_list_init(&surface->popups); wl_list_init(&surface->popups);
wl_signal_init(&surface->events.destroy); wl_signal_init(&surface->events.destroy);
wl_signal_add(&surface->surface->events.destroy,
&surface->surface_destroy_listener);
surface->surface_destroy_listener.notify = handle_surface_destroyed;
wl_signal_init(&surface->events.map); wl_signal_init(&surface->events.map);
wl_signal_init(&surface->events.unmap); wl_signal_init(&surface->events.unmap);
wl_signal_init(&surface->events.new_popup); wl_signal_init(&surface->events.new_popup);
wlr_surface_set_role_committed(surface->surface, wl_signal_add(&surface->surface->events.destroy,
handle_surface_committed, surface); &surface->surface_destroy);
surface->surface_destroy.notify = handle_surface_destroyed;
wlr_log(L_DEBUG, "new layer_surface %p (res %p)", wlr_log(L_DEBUG, "new layer_surface %p (res %p)",
surface, surface->resource); surface, surface->resource);

View File

@ -10,6 +10,7 @@
#include <wlr/types/wlr_box.h> #include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_matrix.h> #include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_surface.h> #include <wlr/types/wlr_surface.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include <wlr/util/region.h> #include <wlr/util/region.h>
@ -811,7 +812,8 @@ static void output_cursor_handle_destroy(struct wl_listener *listener,
void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor,
struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y) { struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y) {
if (surface && strcmp(surface->role, "wl_pointer-cursor") != 0) { if (surface && !wlr_surface_is_pointer_cursor(surface)) {
wlr_log(L_ERROR, "Tried to set a cursor surface with invalid role");
return; return;
} }

View File

@ -370,8 +370,8 @@ static void surface_commit_pending(struct wlr_surface *surface) {
} }
} }
if (surface->role_committed) { if (surface->role && surface->role->commit) {
surface->role_committed(surface, surface->role_data); surface->role->commit(surface);
} }
wlr_signal_emit_safe(&surface->events.commit, surface); wlr_signal_emit_safe(&surface->events.commit, surface);
@ -632,25 +632,25 @@ bool wlr_surface_has_buffer(struct wlr_surface *surface) {
return wlr_surface_get_texture(surface) != NULL; return wlr_surface_get_texture(surface) != NULL;
} }
int wlr_surface_set_role(struct wlr_surface *surface, const char *role, bool wlr_surface_set_role(struct wlr_surface *surface,
const struct wlr_surface_role *role, void *role_data,
struct wl_resource *error_resource, uint32_t error_code) { struct wl_resource *error_resource, uint32_t error_code) {
assert(role); assert(role != NULL);
if (surface->role == NULL || if (surface->role != NULL && surface->role != role) {
surface->role == role || if (error_resource != NULL) {
strcmp(surface->role, role) == 0) { wl_resource_post_error(error_resource, error_code,
surface->role = role; "Cannot assign role %s to wl_surface@%d, already has role %s\n",
role->name, wl_resource_get_id(surface->resource),
return 0; surface->role->name);
}
return false;
} }
wl_resource_post_error(error_resource, error_code, assert(surface->role_data == NULL);
"Cannot assign role %s to wl_surface@%d, already has role %s\n", surface->role = role;
role, surface->role_data = role_data;
wl_resource_get_id(surface->resource), return true;
surface->role);
return -1;
} }
static const struct wl_subsurface_interface subsurface_implementation; static const struct wl_subsurface_interface subsurface_implementation;
@ -788,8 +788,12 @@ static const struct wl_subsurface_interface subsurface_implementation = {
.set_desync = subsurface_handle_set_desync, .set_desync = subsurface_handle_set_desync,
}; };
static void subsurface_role_committed(struct wlr_surface *surface, void *data) { static void subsurface_role_commit(struct wlr_surface *surface) {
struct wlr_subsurface *subsurface = data; struct wlr_subsurface *subsurface =
wlr_subsurface_from_wlr_surface(surface);
if (subsurface == NULL) {
return;
}
if (subsurface->current.x != subsurface->pending.x || if (subsurface->current.x != subsurface->pending.x ||
subsurface->current.y != subsurface->pending.y) { subsurface->current.y != subsurface->pending.y) {
@ -816,6 +820,11 @@ static void subsurface_role_committed(struct wlr_surface *surface, void *data) {
} }
} }
const struct wlr_surface_role subsurface_role = {
.name = "wl_subsurface",
.commit = subsurface_role_commit,
};
static void subsurface_handle_parent_destroy(struct wl_listener *listener, static void subsurface_handle_parent_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_subsurface *subsurface = struct wlr_subsurface *subsurface =
@ -874,8 +883,7 @@ struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface,
wl_list_insert(parent->subsurface_pending_list.prev, wl_list_insert(parent->subsurface_pending_list.prev,
&subsurface->parent_pending_link); &subsurface->parent_pending_link);
wlr_surface_set_role_committed(surface, subsurface_role_committed, surface->role_data = subsurface;
subsurface);
struct wl_list *resource_link = wl_resource_get_link(subsurface->resource); struct wl_list *resource_link = wl_resource_get_link(subsurface->resource);
if (resource_list != NULL) { if (resource_list != NULL) {
@ -964,13 +972,6 @@ void wlr_surface_send_frame_done(struct wlr_surface *surface,
} }
} }
void wlr_surface_set_role_committed(struct wlr_surface *surface,
void (*role_committed)(struct wlr_surface *surface, void *role_data),
void *role_data) {
surface->role_committed = role_committed;
surface->role_data = role_data;
}
static void surface_for_each_surface(struct wlr_surface *surface, int x, int y, static void surface_for_each_surface(struct wlr_surface *surface, int x, int y,
wlr_surface_iterator_func_t iterator, void *user_data) { wlr_surface_iterator_func_t iterator, void *user_data) {
iterator(surface, x, y, user_data); iterator(surface, x, y, user_data);

View File

@ -10,17 +10,16 @@
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "util/signal.h" #include "util/signal.h"
static const char *wlr_wl_shell_surface_role = "wl-shell-surface"; static const struct wlr_surface_role shell_surface_role;
bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface) { bool wlr_surface_is_wl_shell_surface(struct wlr_surface *surface) {
return surface->role != NULL && return surface->role == &shell_surface_role;
strcmp(surface->role, wlr_wl_shell_surface_role) == 0;
} }
struct wlr_wl_surface *wlr_wl_shell_surface_from_wlr_surface( struct wlr_wl_shell_surface *wlr_wl_shell_surface_from_wlr_surface(
struct wlr_surface *surface) { struct wlr_surface *surface) {
assert(wlr_surface_is_wl_shell_surface(surface)); assert(wlr_surface_is_wl_shell_surface(surface));
return (struct wlr_wl_surface *)surface->role_data; return (struct wlr_wl_shell_surface *)surface->role_data;
} }
static void shell_pointer_grab_end(struct wlr_seat_pointer_grab *grab) { static void shell_pointer_grab_end(struct wlr_seat_pointer_grab *grab) {
@ -446,9 +445,9 @@ static void shell_surface_destroy(struct wlr_wl_shell_surface *surface) {
} }
wl_list_remove(&surface->popup_link); wl_list_remove(&surface->popup_link);
surface->surface->role_data = NULL;
wl_list_remove(&surface->link); wl_list_remove(&surface->link);
wl_list_remove(&surface->surface_destroy_listener.link); wl_list_remove(&surface->surface_destroy.link);
wlr_surface_set_role_committed(surface->surface, NULL, NULL);
wl_event_source_remove(surface->ping_timer); wl_event_source_remove(surface->ping_timer);
free(surface->transient_state); free(surface->transient_state);
free(surface->title); free(surface->title);
@ -466,12 +465,17 @@ static void shell_surface_resource_destroy(struct wl_resource *resource) {
static void shell_surface_handle_surface_destroy(struct wl_listener *listener, static void shell_surface_handle_surface_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_wl_shell_surface *surface = struct wlr_wl_shell_surface *surface =
wl_container_of(listener, surface, surface_destroy_listener); wl_container_of(listener, surface, surface_destroy);
shell_surface_destroy(surface); shell_surface_destroy(surface);
} }
static void handle_surface_committed(struct wlr_surface *wlr_surface,
void *role_data) { static void shell_surface_role_commit(struct wlr_surface *wlr_surface) {
struct wlr_wl_shell_surface *surface = role_data; struct wlr_wl_shell_surface *surface =
wlr_wl_shell_surface_from_wlr_surface(wlr_surface);
if (surface == NULL) {
return;
}
if (!surface->configured && if (!surface->configured &&
wlr_surface_has_buffer(surface->surface) && wlr_surface_has_buffer(surface->surface) &&
surface->state != WLR_WL_SHELL_SURFACE_STATE_NONE) { surface->state != WLR_WL_SHELL_SURFACE_STATE_NONE) {
@ -490,6 +494,11 @@ static void handle_surface_committed(struct wlr_surface *wlr_surface,
} }
} }
static const struct wlr_surface_role shell_surface_role = {
.name = "wl_shell_surface",
.commit = shell_surface_role_commit,
};
static int shell_surface_ping_timeout(void *user_data) { static int shell_surface_ping_timeout(void *user_data) {
struct wlr_wl_shell_surface *surface = user_data; struct wlr_wl_shell_surface *surface = user_data;
wlr_signal_emit_safe(&surface->events.ping_timeout, surface); wlr_signal_emit_safe(&surface->events.ping_timeout, surface);
@ -510,10 +519,6 @@ static void shell_protocol_get_shell_surface(struct wl_client *client,
struct wl_resource *shell_resource, uint32_t id, struct wl_resource *shell_resource, uint32_t id,
struct wl_resource *surface_resource) { struct wl_resource *surface_resource) {
struct wlr_surface *surface = wlr_surface_from_resource(surface_resource); struct wlr_surface *surface = wlr_surface_from_resource(surface_resource);
if (wlr_surface_set_role(surface, wlr_wl_shell_surface_role,
shell_resource, WL_SHELL_ERROR_ROLE)) {
return;
}
struct wlr_wl_shell *wl_shell = shell_from_resource(shell_resource); struct wlr_wl_shell *wl_shell = shell_from_resource(shell_resource);
struct wlr_wl_shell_surface *wl_surface = struct wlr_wl_shell_surface *wl_surface =
@ -522,6 +527,13 @@ static void shell_protocol_get_shell_surface(struct wl_client *client,
wl_resource_post_no_memory(shell_resource); wl_resource_post_no_memory(shell_resource);
return; return;
} }
if (!wlr_surface_set_role(surface, &shell_surface_role, wl_surface,
shell_resource, WL_SHELL_ERROR_ROLE)) {
free(wl_surface);
return;
}
wl_list_init(&wl_surface->grab_link); wl_list_init(&wl_surface->grab_link);
wl_list_init(&wl_surface->popup_link); wl_list_init(&wl_surface->popup_link);
wl_list_init(&wl_surface->popups); wl_list_init(&wl_surface->popups);
@ -557,12 +569,8 @@ static void shell_protocol_get_shell_surface(struct wl_client *client,
wl_signal_init(&wl_surface->events.set_class); wl_signal_init(&wl_surface->events.set_class);
wl_signal_add(&wl_surface->surface->events.destroy, wl_signal_add(&wl_surface->surface->events.destroy,
&wl_surface->surface_destroy_listener); &wl_surface->surface_destroy);
wl_surface->surface_destroy_listener.notify = wl_surface->surface_destroy.notify = shell_surface_handle_surface_destroy;
shell_surface_handle_surface_destroy;
wlr_surface_set_role_committed(surface, handle_surface_committed,
wl_surface);
struct wl_display *display = wl_client_get_display(client); struct wl_display *display = wl_client_get_display(client);
struct wl_event_loop *loop = wl_display_get_event_loop(display); struct wl_event_loop *loop = wl_display_get_event_loop(display);

View File

@ -212,6 +212,11 @@ static void xdg_popup_handle_resource_destroy(struct wl_resource *resource) {
} }
} }
const struct wlr_surface_role xdg_popup_surface_role = {
.name = "xdg_popup",
.commit = handle_xdg_surface_committed,
};
void create_xdg_popup(struct wlr_xdg_surface *xdg_surface, void create_xdg_popup(struct wlr_xdg_surface *xdg_surface,
struct wlr_xdg_surface *parent, struct wlr_xdg_surface *parent,
struct wlr_xdg_positioner_resource *positioner, int32_t id) { struct wlr_xdg_positioner_resource *positioner, int32_t id) {
@ -223,8 +228,8 @@ void create_xdg_popup(struct wlr_xdg_surface *xdg_surface,
return; return;
} }
if (wlr_surface_set_role(xdg_surface->surface, XDG_POPUP_ROLE, if (!wlr_surface_set_role(xdg_surface->surface, &xdg_popup_surface_role,
xdg_surface->resource, XDG_WM_BASE_ERROR_ROLE)) { xdg_surface, xdg_surface->resource, XDG_WM_BASE_ERROR_ROLE)) {
return; return;
} }

View File

@ -6,9 +6,8 @@
#include "util/signal.h" #include "util/signal.h"
bool wlr_surface_is_xdg_surface(struct wlr_surface *surface) { bool wlr_surface_is_xdg_surface(struct wlr_surface *surface) {
return surface->role != NULL && return surface->role == &xdg_toplevel_surface_role ||
(strcmp(surface->role, XDG_TOPLEVEL_ROLE) == 0 || surface->role == &xdg_popup_surface_role;
strcmp(surface->role, XDG_POPUP_ROLE) == 0);
} }
struct wlr_xdg_surface *wlr_xdg_surface_from_wlr_surface( struct wlr_xdg_surface *wlr_xdg_surface_from_wlr_surface(
@ -294,9 +293,10 @@ static void xdg_surface_handle_resource_destroy(struct wl_resource *resource) {
} }
} }
static void handle_surface_committed(struct wlr_surface *wlr_surface, static void xdg_surface_handle_surface_commit(struct wl_listener *listener,
void *role_data) { void *data) {
struct wlr_xdg_surface *surface = role_data; struct wlr_xdg_surface *surface =
wl_container_of(listener, surface, surface_commit);
if (wlr_surface_has_buffer(surface->surface) && !surface->configured) { if (wlr_surface_has_buffer(surface->surface) && !surface->configured) {
wl_resource_post_error(surface->resource, wl_resource_post_error(surface->resource,
@ -305,6 +305,21 @@ static void handle_surface_committed(struct wlr_surface *wlr_surface,
return; return;
} }
if (surface->role == WLR_XDG_SURFACE_ROLE_NONE) {
wl_resource_post_error(surface->resource,
XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
"xdg_surface must have a role");
return;
}
}
void handle_xdg_surface_committed(struct wlr_surface *wlr_surface) {
struct wlr_xdg_surface *surface =
wlr_xdg_surface_from_wlr_surface(wlr_surface);
if (surface == NULL) {
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;
@ -315,10 +330,7 @@ static void handle_surface_committed(struct wlr_surface *wlr_surface,
switch (surface->role) { switch (surface->role) {
case WLR_XDG_SURFACE_ROLE_NONE: case WLR_XDG_SURFACE_ROLE_NONE:
wl_resource_post_error(surface->resource, assert(false);
XDG_SURFACE_ERROR_NOT_CONSTRUCTED,
"xdg_surface must have a role");
break;
case WLR_XDG_SURFACE_ROLE_TOPLEVEL: case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
handle_xdg_surface_toplevel_committed(surface); handle_xdg_surface_toplevel_committed(surface);
break; break;
@ -346,7 +358,7 @@ static void handle_surface_committed(struct wlr_surface *wlr_surface,
static void xdg_surface_handle_surface_destroy(struct wl_listener *listener, static void xdg_surface_handle_surface_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_xdg_surface *xdg_surface = struct wlr_xdg_surface *xdg_surface =
wl_container_of(listener, xdg_surface, surface_destroy_listener); wl_container_of(listener, xdg_surface, surface_destroy);
destroy_xdg_surface(xdg_surface); destroy_xdg_surface(xdg_surface);
} }
@ -391,12 +403,12 @@ struct wlr_xdg_surface *create_xdg_surface(
wl_signal_init(&xdg_surface->events.unmap); wl_signal_init(&xdg_surface->events.unmap);
wl_signal_add(&xdg_surface->surface->events.destroy, wl_signal_add(&xdg_surface->surface->events.destroy,
&xdg_surface->surface_destroy_listener); &xdg_surface->surface_destroy);
xdg_surface->surface_destroy_listener.notify = xdg_surface->surface_destroy.notify = xdg_surface_handle_surface_destroy;
xdg_surface_handle_surface_destroy;
wlr_surface_set_role_committed(xdg_surface->surface, wl_signal_add(&xdg_surface->surface->events.commit,
handle_surface_committed, xdg_surface); &xdg_surface->surface_commit);
xdg_surface->surface_commit.notify = xdg_surface_handle_surface_commit;
wlr_log(L_DEBUG, "new xdg_surface %p (res %p)", xdg_surface, wlr_log(L_DEBUG, "new xdg_surface %p (res %p)", xdg_surface,
xdg_surface->resource); xdg_surface->resource);
@ -434,9 +446,10 @@ void destroy_xdg_surface(struct wlr_xdg_surface *surface) {
} }
wl_resource_set_user_data(surface->resource, NULL); wl_resource_set_user_data(surface->resource, NULL);
surface->surface->role_data = NULL;
wl_list_remove(&surface->link); wl_list_remove(&surface->link);
wl_list_remove(&surface->surface_destroy_listener.link); wl_list_remove(&surface->surface_destroy.link);
wlr_surface_set_role_committed(surface->surface, NULL, NULL); wl_list_remove(&surface->surface_commit.link);
free(surface); free(surface);
} }

View File

@ -447,10 +447,15 @@ static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource) {
} }
} }
const struct wlr_surface_role xdg_toplevel_surface_role = {
.name = "xdg_toplevel",
.commit = handle_xdg_surface_committed,
};
void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface, void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface,
uint32_t id) { uint32_t id) {
if (wlr_surface_set_role(xdg_surface->surface, XDG_TOPLEVEL_ROLE, if (!wlr_surface_set_role(xdg_surface->surface, &xdg_toplevel_surface_role,
xdg_surface->resource, XDG_WM_BASE_ERROR_ROLE)) { xdg_surface, xdg_surface->resource, XDG_WM_BASE_ERROR_ROLE)) {
return; return;
} }

View File

@ -249,6 +249,11 @@ void handle_xdg_surface_v6_popup_committed(struct wlr_xdg_surface_v6 *surface) {
} }
} }
const struct wlr_surface_role xdg_popup_v6_surface_role = {
.name = "xdg_popup_v6",
.commit = handle_xdg_surface_v6_committed,
};
void create_xdg_popup_v6(struct wlr_xdg_surface_v6 *xdg_surface, void create_xdg_popup_v6(struct wlr_xdg_surface_v6 *xdg_surface,
struct wlr_xdg_surface_v6 *parent, struct wlr_xdg_surface_v6 *parent,
struct wlr_xdg_positioner_v6_resource *positioner, int32_t id) { struct wlr_xdg_positioner_v6_resource *positioner, int32_t id) {
@ -260,8 +265,8 @@ void create_xdg_popup_v6(struct wlr_xdg_surface_v6 *xdg_surface,
return; return;
} }
if (wlr_surface_set_role(xdg_surface->surface, XDG_POPUP_V6_ROLE, if (!wlr_surface_set_role(xdg_surface->surface, &xdg_popup_v6_surface_role,
xdg_surface->resource, ZXDG_SHELL_V6_ERROR_ROLE)) { xdg_surface, xdg_surface->resource, ZXDG_SHELL_V6_ERROR_ROLE)) {
return; return;
} }

View File

@ -6,9 +6,8 @@
#include "util/signal.h" #include "util/signal.h"
bool wlr_surface_is_xdg_surface_v6(struct wlr_surface *surface) { bool wlr_surface_is_xdg_surface_v6(struct wlr_surface *surface) {
return surface->role != NULL && return surface->role == &xdg_toplevel_v6_surface_role ||
(strcmp(surface->role, XDG_TOPLEVEL_V6_ROLE) == 0 || surface->role == &xdg_popup_v6_surface_role;
strcmp(surface->role, XDG_POPUP_V6_ROLE) == 0);
} }
struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_from_wlr_surface( struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_from_wlr_surface(
@ -119,9 +118,10 @@ void destroy_xdg_surface_v6(struct wlr_xdg_surface_v6 *surface) {
} }
wl_resource_set_user_data(surface->resource, NULL); wl_resource_set_user_data(surface->resource, NULL);
surface->surface->role_data = NULL;
wl_list_remove(&surface->link); wl_list_remove(&surface->link);
wl_list_remove(&surface->surface_destroy_listener.link); wl_list_remove(&surface->surface_destroy.link);
wlr_surface_set_role_committed(surface->surface, NULL, NULL); wl_list_remove(&surface->surface_commit.link);
free(surface); free(surface);
} }
@ -347,13 +347,14 @@ void wlr_xdg_surface_v6_send_close(struct wlr_xdg_surface_v6 *surface) {
static void xdg_surface_handle_surface_destroy(struct wl_listener *listener, static void xdg_surface_handle_surface_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_xdg_surface_v6 *xdg_surface = struct wlr_xdg_surface_v6 *xdg_surface =
wl_container_of(listener, xdg_surface, surface_destroy_listener); wl_container_of(listener, xdg_surface, surface_destroy);
destroy_xdg_surface_v6(xdg_surface); destroy_xdg_surface_v6(xdg_surface);
} }
static void handle_surface_committed(struct wlr_surface *wlr_surface, static void xdg_surface_handle_surface_commit(struct wl_listener *listener,
void *role_data) { void *data) {
struct wlr_xdg_surface_v6 *surface = role_data; struct wlr_xdg_surface_v6 *surface =
wl_container_of(listener, surface, surface_commit);
if (wlr_surface_has_buffer(surface->surface) && !surface->configured) { if (wlr_surface_has_buffer(surface->surface) && !surface->configured) {
wl_resource_post_error(surface->resource, wl_resource_post_error(surface->resource,
@ -362,6 +363,21 @@ static void handle_surface_committed(struct wlr_surface *wlr_surface,
return; return;
} }
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;
}
}
void handle_xdg_surface_v6_committed(struct wlr_surface *wlr_surface) {
struct wlr_xdg_surface_v6 *surface =
wlr_xdg_surface_v6_from_wlr_surface(wlr_surface);
if (surface == NULL) {
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;
@ -372,10 +388,7 @@ static void handle_surface_committed(struct wlr_surface *wlr_surface,
switch (surface->role) { switch (surface->role) {
case WLR_XDG_SURFACE_V6_ROLE_NONE: case WLR_XDG_SURFACE_V6_ROLE_NONE:
wl_resource_post_error(surface->resource, assert(false);
ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
"xdg_surface must have a role");
break;
case WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL: case WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL:
handle_xdg_surface_v6_toplevel_committed(surface); handle_xdg_surface_v6_toplevel_committed(surface);
break; break;
@ -449,12 +462,12 @@ struct wlr_xdg_surface_v6 *create_xdg_surface_v6(
wl_signal_init(&xdg_surface->events.unmap); wl_signal_init(&xdg_surface->events.unmap);
wl_signal_add(&xdg_surface->surface->events.destroy, wl_signal_add(&xdg_surface->surface->events.destroy,
&xdg_surface->surface_destroy_listener); &xdg_surface->surface_destroy);
xdg_surface->surface_destroy_listener.notify = xdg_surface->surface_destroy.notify = xdg_surface_handle_surface_destroy;
xdg_surface_handle_surface_destroy;
wlr_surface_set_role_committed(xdg_surface->surface, wl_signal_add(&xdg_surface->surface->events.commit,
handle_surface_committed, xdg_surface); &xdg_surface->surface_commit);
xdg_surface->surface_commit.notify = xdg_surface_handle_surface_commit;
wlr_log(L_DEBUG, "new xdg_surface %p (res %p)", xdg_surface, wlr_log(L_DEBUG, "new xdg_surface %p (res %p)", xdg_surface,
xdg_surface->resource); xdg_surface->resource);

View File

@ -417,10 +417,15 @@ static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource) {
} }
} }
const struct wlr_surface_role xdg_toplevel_v6_surface_role = {
.name = "xdg_toplevel_v6",
.commit = handle_xdg_surface_v6_committed,
};
void create_xdg_toplevel_v6(struct wlr_xdg_surface_v6 *xdg_surface, void create_xdg_toplevel_v6(struct wlr_xdg_surface_v6 *xdg_surface,
uint32_t id) { uint32_t id) {
if (wlr_surface_set_role(xdg_surface->surface, XDG_TOPLEVEL_V6_ROLE, if (!wlr_surface_set_role(xdg_surface->surface, &xdg_toplevel_v6_surface_role,
xdg_surface->resource, ZXDG_SHELL_V6_ERROR_ROLE)) { xdg_surface, xdg_surface->resource, ZXDG_SHELL_V6_ERROR_ROLE)) {
return; return;
} }

View File

@ -79,11 +79,10 @@ const char *atom_map[ATOM_LAST] = {
"XdndActionPrivate", "XdndActionPrivate",
}; };
const char *wlr_xwayland_surface_role = "wlr_xwayland_surface"; static const struct wlr_surface_role xwayland_surface_role;
bool wlr_surface_is_xwayland_surface(struct wlr_surface *surface) { bool wlr_surface_is_xwayland_surface(struct wlr_surface *surface) {
return surface->role != NULL && return surface->role == &xwayland_surface_role;
strcmp(surface->role, wlr_xwayland_surface_role) == 0;
} }
struct wlr_xwayland_surface *wlr_xwayland_surface_from_wlr_surface( struct wlr_xwayland_surface *wlr_xwayland_surface_from_wlr_surface(
@ -314,7 +313,7 @@ static void xwayland_surface_destroy(
if (xsurface->surface) { if (xsurface->surface) {
wl_list_remove(&xsurface->surface_destroy.link); wl_list_remove(&xsurface->surface_destroy.link);
wlr_surface_set_role_committed(xsurface->surface, NULL, NULL); xsurface->surface->role_data = NULL;
} }
wl_event_source_remove(xsurface->ping_timer); wl_event_source_remove(xsurface->ping_timer);
@ -640,9 +639,12 @@ static void read_surface_property(struct wlr_xwm *xwm,
free(reply); free(reply);
} }
static void handle_surface_commit(struct wlr_surface *wlr_surface, static void xwayland_surface_role_commit(struct wlr_surface *wlr_surface) {
void *role_data) { assert(wlr_surface->role == &xwayland_surface_role);
struct wlr_xwayland_surface *surface = role_data; struct wlr_xwayland_surface *surface = wlr_surface->role_data;
if (surface == NULL) {
return;
}
if (!surface->mapped && wlr_surface_has_buffer(surface->surface)) { if (!surface->mapped && wlr_surface_has_buffer(surface->surface)) {
wlr_signal_emit_safe(&surface->events.map, surface); wlr_signal_emit_safe(&surface->events.map, surface);
@ -650,6 +652,11 @@ static void handle_surface_commit(struct wlr_surface *wlr_surface,
} }
} }
static const struct wlr_surface_role xwayland_surface_role = {
.name = "wlr_xwayland_surface",
.commit = xwayland_surface_role_commit,
};
static void handle_surface_destroy(struct wl_listener *listener, void *data) { static void handle_surface_destroy(struct wl_listener *listener, void *data) {
struct wlr_xwayland_surface *surface = struct wlr_xwayland_surface *surface =
wl_container_of(listener, surface, surface_destroy); wl_container_of(listener, surface, surface_destroy);
@ -658,6 +665,12 @@ static void handle_surface_destroy(struct wl_listener *listener, void *data) {
static void xwm_map_shell_surface(struct wlr_xwm *xwm, static void xwm_map_shell_surface(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *xsurface, struct wlr_surface *surface) { struct wlr_xwayland_surface *xsurface, struct wlr_surface *surface) {
if (!wlr_surface_set_role(surface, &xwayland_surface_role, xsurface,
NULL, 0)) {
wlr_log(L_ERROR, "Failed to set xwayland surface role");
return;
}
xsurface->surface = surface; xsurface->surface = surface;
// read all surface properties // read all surface properties
@ -678,10 +691,6 @@ static void xwm_map_shell_surface(struct wlr_xwm *xwm,
read_surface_property(xwm, xsurface, props[i]); read_surface_property(xwm, xsurface, props[i]);
} }
wlr_surface_set_role(xsurface->surface, wlr_xwayland_surface_role, NULL, 0);
wlr_surface_set_role_committed(xsurface->surface, handle_surface_commit,
xsurface);
xsurface->surface_destroy.notify = handle_surface_destroy; xsurface->surface_destroy.notify = handle_surface_destroy;
wl_signal_add(&surface->events.destroy, &xsurface->surface_destroy); wl_signal_add(&surface->events.destroy, &xsurface->surface_destroy);
} }
@ -701,8 +710,8 @@ static void xsurface_unmap(struct wlr_xwayland_surface *surface) {
} }
if (surface->surface) { if (surface->surface) {
wlr_surface_set_role_committed(surface->surface, NULL, NULL);
wl_list_remove(&surface->surface_destroy.link); wl_list_remove(&surface->surface_destroy.link);
surface->surface->role_data = NULL;
surface->surface = NULL; surface->surface = NULL;
} }
} }