data-device: remove wlr_data_source.seat_client

Since the source doesn't always come from a client, this field
doesn't make sense. It is replaced by a new "finalized" field in
wlr_client_data_source. This is used to make sure set_actions is
not sent after start_drag has been sent.

A check in data_offer_choose_action has been removed: if an offer
has been sent then start_drag has been called, no need to check.

I also wanted to add a check for wl_data_source.offer, but it
turns out (1) this isn't in the spec (2) it breaks GTK+.

This is some preliminary work for Firefox on Wayland compatibility.
This commit is contained in:
emersion 2018-10-07 15:57:08 +02:00
parent eb44d18cdd
commit f44003f04b
5 changed files with 23 additions and 19 deletions

View file

@ -11,6 +11,7 @@ struct wlr_client_data_source {
struct wlr_data_source source; struct wlr_data_source source;
struct wlr_data_source_impl impl; struct wlr_data_source_impl impl;
struct wl_resource *resource; struct wl_resource *resource;
bool finalized;
}; };
extern const struct wlr_surface_role drag_icon_surface_role; extern const struct wlr_surface_role drag_icon_surface_role;

View file

@ -73,7 +73,6 @@ struct wlr_data_source {
// source status // source status
bool accepted; bool accepted;
struct wlr_data_offer *offer; struct wlr_data_offer *offer;
struct wlr_seat_client *seat_client;
// drag'n'drop status // drag'n'drop status
enum wl_data_device_manager_dnd_action current_dnd_action; enum wl_data_device_manager_dnd_action current_dnd_action;

View file

@ -25,16 +25,21 @@ static struct wlr_seat_client *seat_client_from_data_device_resource(
static void data_device_set_selection(struct wl_client *client, static void data_device_set_selection(struct wl_client *client,
struct wl_resource *device_resource, struct wl_resource *device_resource,
struct wl_resource *source_resource, uint32_t serial) { struct wl_resource *source_resource, uint32_t serial) {
struct wlr_seat_client *seat_client =
seat_client_from_data_device_resource(device_resource);
struct wlr_client_data_source *source = NULL; struct wlr_client_data_source *source = NULL;
if (source_resource != NULL) { if (source_resource != NULL) {
source = client_data_source_from_resource(source_resource); source = client_data_source_from_resource(source_resource);
} }
struct wlr_seat_client *seat_client = struct wlr_data_source *wlr_source =
seat_client_from_data_device_resource(device_resource); source != NULL ? &source->source : NULL;
struct wlr_data_source *wlr_source = (struct wlr_data_source *)source;
wlr_seat_set_selection(seat_client->seat, wlr_source, serial); wlr_seat_set_selection(seat_client->seat, wlr_source, serial);
if (source != NULL) {
source->finalized = true;
}
} }
static void data_device_start_drag(struct wl_client *client, static void data_device_start_drag(struct wl_client *client,
@ -45,15 +50,13 @@ static void data_device_start_drag(struct wl_client *client,
struct wlr_seat_client *seat_client = struct wlr_seat_client *seat_client =
seat_client_from_data_device_resource(device_resource); seat_client_from_data_device_resource(device_resource);
struct wlr_surface *origin = wlr_surface_from_resource(origin_resource); struct wlr_surface *origin = wlr_surface_from_resource(origin_resource);
struct wlr_data_source *source = NULL;
struct wlr_surface *icon = NULL;
if (source_resource) { struct wlr_client_data_source *source = NULL;
struct wlr_client_data_source *client_source = if (source_resource != NULL) {
client_data_source_from_resource(source_resource); source = client_data_source_from_resource(source_resource);
source = (struct wlr_data_source *)client_source;
} }
struct wlr_surface *icon = NULL;
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 (!wlr_surface_set_role(icon, &drag_icon_surface_role, NULL,
@ -62,13 +65,16 @@ static void data_device_start_drag(struct wl_client *client,
} }
} }
if (!seat_client_start_drag(seat_client, source, icon, origin, serial)) { struct wlr_data_source *wlr_source =
source != NULL ? &source->source : NULL;
if (!seat_client_start_drag(seat_client, wlr_source, icon,
origin, serial)) {
wl_resource_post_no_memory(device_resource); wl_resource_post_no_memory(device_resource);
return; return;
} }
if (source) { if (source != NULL) {
source->seat_client = seat_client; source->finalized = true;
} }
} }

View file

@ -41,8 +41,7 @@ static uint32_t data_offer_choose_action(struct wlr_data_offer *offer) {
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
} }
if (offer->source->seat_client && if (offer->source->compositor_action & available_actions) {
offer->source->compositor_action & available_actions) {
return offer->source->compositor_action; return offer->source->compositor_action;
} }

View file

@ -207,11 +207,10 @@ static void data_source_set_actions(struct wl_client *client,
return; return;
} }
if (source->source.seat_client) { if (source->finalized) {
wl_resource_post_error(source->resource, wl_resource_post_error(source->resource,
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK, WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
"invalid action change after " "invalid action change after wl_data_device.start_drag");
"wl_data_device.start_drag");
return; return;
} }