Re: [PATCH weston 1/5] data-device: Implement DnD progress notification

2016-01-15 Thread Bryce Harrington
On Fri, Jan 15, 2016 at 09:14:23PM +0100, Carlos Garnacho wrote:
> Weston now sends wl_data_source.dnd_drop_performed and .dnd_finished in
> order to notify about the different phases of DnD.
> 
> wl_data_source.cancelled is also used as mentioned in the docs, being
> emitted also on DnD when the operation is meant to fail (eg. source
> and dest didn't agree on a mimetype).
> 
> The dnd demo is also fixed so the struct dnd_drag isn't leaked.
> 
> https://bugs.freedesktop.org/show_bug.cgi?id=91943
> https://bugs.freedesktop.org/show_bug.cgi?id=91944
> 
> Changes since v6:
>   - Add client-side version checks. Minor code shuffling.
> 
> Changes since v5:
>   - Dissociate source and offer after cancel. Updated to
> apply on top of c9f8f8a7f.
> 
> Changes since v4:
>   - Make wl_data_offer.finish with the wrong state an error.
> 
> Changes since v3:
>   - Fixed wl_data_source.dnd_finished vs cancelled emission on
> when interoperating with version < 3 drag destinations.
> 
> Changes since v2:
>   - Handle wl_data_offer.finish. Fixed commit log inconsistencies.
> Added version checks. Spaces vs tabs fixes. Fixed resource
> versioning.
> 
> Changes since v1:
>   - Updated to protocol v2.
> 
> Signed-off-by: Carlos Garnacho 
> Reviewed-by: Michael Catanzaro 
> Reviewed-by: Jonas Ådahl 
Reviewed-by: Bryce Harrington 

> ---
>  clients/dnd.c |  39 +
>  clients/window.c  |   6 ++-
>  src/compositor.h  |   3 ++
>  src/data-device.c | 125 
> +++---
>  4 files changed, 148 insertions(+), 25 deletions(-)
> 
> diff --git a/clients/dnd.c b/clients/dnd.c
> index e6a0c39..974429b 100644
> --- a/clients/dnd.c
> +++ b/clients/dnd.c
> @@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source 
> *source,
>  }
>  
>  static void
> -data_source_cancelled(void *data, struct wl_data_source *source)
> +dnd_drag_destroy(struct dnd_drag *dnd_drag)
>  {
> - struct dnd_drag *dnd_drag = data;
> -
> - /* The 'cancelled' event means that the source is no longer in
> -  * use by the drag (or current selection).  We need to clean
> -  * up the drag object created and the local state. */
> -
>   wl_data_source_destroy(dnd_drag->data_source);
>  
>   /* Destroy the item that has been dragged out */
> @@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct wl_data_source 
> *source)
>   free(dnd_drag);
>  }
>  
> +static void
> +data_source_cancelled(void *data, struct wl_data_source *source)
> +{
> + struct dnd_drag *dnd_drag = data;
> +
> + /* The 'cancelled' event means that the source is no longer in
> +  * use by the drag (or current selection).  We need to clean
> +  * up the drag object created and the local state. */
> + dnd_drag_destroy(dnd_drag);
> +}
> +
> +static void
> +data_source_dnd_drop_performed(void *data, struct wl_data_source *source)
> +{
> +}
> +
> +static void
> +data_source_dnd_finished(void *data, struct wl_data_source *source)
> +{
> + struct dnd_drag *dnd_drag = data;
> +
> + /* The operation is already finished, we can destroy all
> +  * related data.
> +  */
> + dnd_drag_destroy(dnd_drag);
> +}
> +
>  static const struct wl_data_source_listener data_source_listener = {
>   data_source_target,
>   data_source_send,
> - data_source_cancelled
> + data_source_cancelled,
> + data_source_dnd_drop_performed,
> + data_source_dnd_finished,
>  };
>  
>  static cairo_surface_t *
> diff --git a/clients/window.c b/clients/window.c
> index 5d69116..2baf9ea 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -3717,6 +3717,7 @@ offer_io_func(struct task *task, uint32_t events)
>  {
>   struct data_offer *offer =
>   container_of(task, struct data_offer, io_task);
> + struct display *display = offer->input->display;
>   unsigned int len;
>   char buffer[4096];
>  
> @@ -3725,6 +3726,9 @@ offer_io_func(struct task *task, uint32_t events)
>   offer->x, offer->y, offer->user_data);
>  
>   if (len == 0) {
> + if (display->data_device_manager_version >=
> + WL_DATA_OFFER_FINISH_SINCE_VERSION)
> + wl_data_offer_finish(offer->offer);
>   close(offer->fd);
>   data_offer_destroy(offer);
>   }
> @@ -5318,7 +5322,7 @@ registry_handle_global(void *data, struct wl_registry 
> *registry, uint32_t id,
>   d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
>   wl_shm_add_listener(d->shm, &shm_listener, d);
>   } else if (strcmp(interface, "wl_data_device_manager") == 0) {
> - d->data_device_manager_version = MIN(version, 2);
> + d->data_device_manager_version = MIN(version, 3);
>   d->data_device_manager =
>   wl_registry_bind(registry, id,
>&wl_data_device_manager_interface,
> diff --gi

[PATCH weston 1/5] data-device: Implement DnD progress notification

2016-01-15 Thread Carlos Garnacho
Weston now sends wl_data_source.dnd_drop_performed and .dnd_finished in
order to notify about the different phases of DnD.

wl_data_source.cancelled is also used as mentioned in the docs, being
emitted also on DnD when the operation is meant to fail (eg. source
and dest didn't agree on a mimetype).

The dnd demo is also fixed so the struct dnd_drag isn't leaked.

https://bugs.freedesktop.org/show_bug.cgi?id=91943
https://bugs.freedesktop.org/show_bug.cgi?id=91944

Changes since v6:
  - Add client-side version checks. Minor code shuffling.

Changes since v5:
  - Dissociate source and offer after cancel. Updated to
apply on top of c9f8f8a7f.

Changes since v4:
  - Make wl_data_offer.finish with the wrong state an error.

Changes since v3:
  - Fixed wl_data_source.dnd_finished vs cancelled emission on
when interoperating with version < 3 drag destinations.

Changes since v2:
  - Handle wl_data_offer.finish. Fixed commit log inconsistencies.
Added version checks. Spaces vs tabs fixes. Fixed resource
versioning.

Changes since v1:
  - Updated to protocol v2.

Signed-off-by: Carlos Garnacho 
Reviewed-by: Michael Catanzaro 
Reviewed-by: Jonas Ådahl 
---
 clients/dnd.c |  39 +
 clients/window.c  |   6 ++-
 src/compositor.h  |   3 ++
 src/data-device.c | 125 +++---
 4 files changed, 148 insertions(+), 25 deletions(-)

diff --git a/clients/dnd.c b/clients/dnd.c
index e6a0c39..974429b 100644
--- a/clients/dnd.c
+++ b/clients/dnd.c
@@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source *source,
 }
 
 static void
-data_source_cancelled(void *data, struct wl_data_source *source)
+dnd_drag_destroy(struct dnd_drag *dnd_drag)
 {
-   struct dnd_drag *dnd_drag = data;
-
-   /* The 'cancelled' event means that the source is no longer in
-* use by the drag (or current selection).  We need to clean
-* up the drag object created and the local state. */
-
wl_data_source_destroy(dnd_drag->data_source);
 
/* Destroy the item that has been dragged out */
@@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct wl_data_source 
*source)
free(dnd_drag);
 }
 
+static void
+data_source_cancelled(void *data, struct wl_data_source *source)
+{
+   struct dnd_drag *dnd_drag = data;
+
+   /* The 'cancelled' event means that the source is no longer in
+* use by the drag (or current selection).  We need to clean
+* up the drag object created and the local state. */
+   dnd_drag_destroy(dnd_drag);
+}
+
+static void
+data_source_dnd_drop_performed(void *data, struct wl_data_source *source)
+{
+}
+
+static void
+data_source_dnd_finished(void *data, struct wl_data_source *source)
+{
+   struct dnd_drag *dnd_drag = data;
+
+   /* The operation is already finished, we can destroy all
+* related data.
+*/
+   dnd_drag_destroy(dnd_drag);
+}
+
 static const struct wl_data_source_listener data_source_listener = {
data_source_target,
data_source_send,
-   data_source_cancelled
+   data_source_cancelled,
+   data_source_dnd_drop_performed,
+   data_source_dnd_finished,
 };
 
 static cairo_surface_t *
diff --git a/clients/window.c b/clients/window.c
index 5d69116..2baf9ea 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -3717,6 +3717,7 @@ offer_io_func(struct task *task, uint32_t events)
 {
struct data_offer *offer =
container_of(task, struct data_offer, io_task);
+   struct display *display = offer->input->display;
unsigned int len;
char buffer[4096];
 
@@ -3725,6 +3726,9 @@ offer_io_func(struct task *task, uint32_t events)
offer->x, offer->y, offer->user_data);
 
if (len == 0) {
+   if (display->data_device_manager_version >=
+   WL_DATA_OFFER_FINISH_SINCE_VERSION)
+   wl_data_offer_finish(offer->offer);
close(offer->fd);
data_offer_destroy(offer);
}
@@ -5318,7 +5322,7 @@ registry_handle_global(void *data, struct wl_registry 
*registry, uint32_t id,
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
wl_shm_add_listener(d->shm, &shm_listener, d);
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
-   d->data_device_manager_version = MIN(version, 2);
+   d->data_device_manager_version = MIN(version, 3);
d->data_device_manager =
wl_registry_bind(registry, id,
 &wl_data_device_manager_interface,
diff --git a/src/compositor.h b/src/compositor.h
index 130b258..8d6b051 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -317,6 +317,9 @@ struct weston_data_source {
struct wl_resource *resource;
struct wl_signal destroy_signal;
struct wl_array mime_types;
+   struct

[PATCH weston 1/5] data-device: Implement DnD progress notification

2015-12-23 Thread Carlos Garnacho
Weston now sends wl_data_source.dnd_drop_performed and .dnd_finished in
order to notify about the different phases of DnD.

wl_data_source.cancelled is also used as mentioned in the docs, being
emitted also on DnD when the operation is meant to fail (eg. source
and dest didn't agree on a mimetype).

The dnd demo is also fixed so the struct dnd_drag isn't leaked.

https://bugs.freedesktop.org/show_bug.cgi?id=91943
https://bugs.freedesktop.org/show_bug.cgi?id=91944

Changes since v3:
  - Fixed wl_data_source.dnd_finished vs cancelled emission on
when interoperating with version < 3 drag destinations.

Changes since v2:
  - Handle wl_data_offer.finish. Fixed commit log inconsistencies.
Added version checks. Spaces vs tabs fixes. Fixed resource
versioning.

Changes since v1:
  - Updated to protocol v2.

Signed-off-by: Carlos Garnacho 
Reviewed-by: Michael Catanzaro 
---
 clients/dnd.c | 39 ++-
 clients/window.c  |  3 +-
 src/compositor.h  |  3 ++
 src/data-device.c | 92 +--
 4 files changed, 119 insertions(+), 18 deletions(-)

diff --git a/clients/dnd.c b/clients/dnd.c
index e6a0c39..48111d9 100644
--- a/clients/dnd.c
+++ b/clients/dnd.c
@@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source *source,
 }
 
 static void
-data_source_cancelled(void *data, struct wl_data_source *source)
+dnd_drag_destroy(struct dnd_drag *dnd_drag)
 {
-   struct dnd_drag *dnd_drag = data;
-
-   /* The 'cancelled' event means that the source is no longer in
-* use by the drag (or current selection).  We need to clean
-* up the drag object created and the local state. */
-
wl_data_source_destroy(dnd_drag->data_source);
 
/* Destroy the item that has been dragged out */
@@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct wl_data_source 
*source)
free(dnd_drag);
 }
 
+static void
+data_source_cancelled(void *data, struct wl_data_source *source)
+{
+   struct dnd_drag *dnd_drag = data;
+
+   /* The 'cancelled' event means that the source is no longer in
+* use by the drag (or current selection).  We need to clean
+* up the drag object created and the local state. */
+   dnd_drag_destroy(dnd_drag);
+}
+
+static void
+data_source_drop_performed(void *data, struct wl_data_source *source)
+{
+}
+
+static void
+data_source_drag_finished(void *data, struct wl_data_source *source)
+{
+   struct dnd_drag *dnd_drag = data;
+
+   /* The operation is already finished, we can destroy all
+* related data.
+*/
+   dnd_drag_destroy(dnd_drag);
+}
+
 static const struct wl_data_source_listener data_source_listener = {
data_source_target,
data_source_send,
-   data_source_cancelled
+   data_source_cancelled,
+   data_source_drop_performed,
+   data_source_drag_finished,
 };
 
 static cairo_surface_t *
diff --git a/clients/window.c b/clients/window.c
index 47628de..db96185 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -3765,6 +3765,7 @@ offer_io_func(struct task *task, uint32_t events)
 
if (len == 0) {
close(offer->fd);
+   wl_data_offer_finish(offer->offer);
data_offer_destroy(offer);
}
 }
@@ -5376,7 +5377,7 @@ registry_handle_global(void *data, struct wl_registry 
*registry, uint32_t id,
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
wl_shm_add_listener(d->shm, &shm_listener, d);
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
-   d->data_device_manager_version = MIN(version, 2);
+   d->data_device_manager_version = MIN(version, 3);
d->data_device_manager =
wl_registry_bind(registry, id,
 &wl_data_device_manager_interface,
diff --git a/src/compositor.h b/src/compositor.h
index 4443c72..83d6f7f 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -304,6 +304,9 @@ struct weston_data_source {
struct wl_resource *resource;
struct wl_signal destroy_signal;
struct wl_array mime_types;
+   struct weston_data_offer *offer;
+   struct weston_seat *seat;
+   bool accepted;
 
void (*accept)(struct weston_data_source *source,
   uint32_t serial, const char *mime_type);
diff --git a/src/data-device.c b/src/data-device.c
index 1612091..9942a66 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -62,12 +62,16 @@ data_offer_accept(struct wl_client *client, struct 
wl_resource *resource,
 {
struct weston_data_offer *offer = wl_resource_get_user_data(resource);
 
+   /* Protect against untimely calls from older data offers */
+   if (!offer->source || offer != offer->source->offer)
+   return;
+
/* FIXME: Check that client is currently focused by the input
 * device t

Re: [PATCH weston 1/5] data-device: Implement DnD progress notification

2015-12-21 Thread Jonas Ådahl
On Tue, Dec 22, 2015 at 02:33:27AM +0100, Carlos Garnacho wrote:
> Weston now sends wl_data_source.dnd_drop_performed and .dnd_finished in
> order to notify about the different phases of DnD.
> 
> wl_data_source.cancelled is also used as mentioned in the docs, being
> emitted also on DnD when the operation is meant to fail (eg. source
> and dest didn't agree on a mimetype).
> 
> The dnd demo is also fixed so the struct dnd_drag isn't leaked.
> 
> https://bugs.freedesktop.org/show_bug.cgi?id=91943
> https://bugs.freedesktop.org/show_bug.cgi?id=91944
> 
> Changes since v2:
>   - Handle wl_data_offer.finish. Fixed commit log inconsistencies.
> Added version checks. Spaces vs tabs fixes. Fixed resource
> versioning.
> 
> Changes since v1:
>   - Updated to protocol v2.
> 
> Signed-off-by: Carlos Garnacho 
> Reviewed-by: Michael Catanzaro 

Mostly loooks good but I have a few questions below.

> ---
>  clients/dnd.c | 39 +++---
>  clients/window.c  |  3 ++-
>  src/compositor.h  |  2 ++
>  src/data-device.c | 71 
> ---
>  4 files changed, 98 insertions(+), 17 deletions(-)
> 
> diff --git a/clients/dnd.c b/clients/dnd.c
> index e6a0c39..48111d9 100644
> --- a/clients/dnd.c
> +++ b/clients/dnd.c
> @@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source 
> *source,
>  }
>  
>  static void
> -data_source_cancelled(void *data, struct wl_data_source *source)
> +dnd_drag_destroy(struct dnd_drag *dnd_drag)
>  {
> - struct dnd_drag *dnd_drag = data;
> -
> - /* The 'cancelled' event means that the source is no longer in
> -  * use by the drag (or current selection).  We need to clean
> -  * up the drag object created and the local state. */
> -
>   wl_data_source_destroy(dnd_drag->data_source);
>  
>   /* Destroy the item that has been dragged out */
> @@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct wl_data_source 
> *source)
>   free(dnd_drag);
>  }
>  
> +static void
> +data_source_cancelled(void *data, struct wl_data_source *source)
> +{
> + struct dnd_drag *dnd_drag = data;
> +
> + /* The 'cancelled' event means that the source is no longer in
> +  * use by the drag (or current selection).  We need to clean
> +  * up the drag object created and the local state. */
> + dnd_drag_destroy(dnd_drag);
> +}
> +
> +static void
> +data_source_drop_performed(void *data, struct wl_data_source *source)
> +{
> +}
> +
> +static void
> +data_source_drag_finished(void *data, struct wl_data_source *source)
> +{
> + struct dnd_drag *dnd_drag = data;
> +
> + /* The operation is already finished, we can destroy all
> +  * related data.
> +  */
> + dnd_drag_destroy(dnd_drag);
> +}
> +
>  static const struct wl_data_source_listener data_source_listener = {
>   data_source_target,
>   data_source_send,
> - data_source_cancelled
> + data_source_cancelled,
> + data_source_drop_performed,
> + data_source_drag_finished,
>  };
>  
>  static cairo_surface_t *
> diff --git a/clients/window.c b/clients/window.c
> index 47628de..db96185 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -3765,6 +3765,7 @@ offer_io_func(struct task *task, uint32_t events)
>  
>   if (len == 0) {
>   close(offer->fd);
> + wl_data_offer_finish(offer->offer);
>   data_offer_destroy(offer);
>   }
>  }
> @@ -5376,7 +5377,7 @@ registry_handle_global(void *data, struct wl_registry 
> *registry, uint32_t id,
>   d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
>   wl_shm_add_listener(d->shm, &shm_listener, d);
>   } else if (strcmp(interface, "wl_data_device_manager") == 0) {
> - d->data_device_manager_version = MIN(version, 2);
> + d->data_device_manager_version = MIN(version, 3);
>   d->data_device_manager =
>   wl_registry_bind(registry, id,
>&wl_data_device_manager_interface,
> diff --git a/src/compositor.h b/src/compositor.h
> index 4443c72..96a7b0d 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -304,6 +304,8 @@ struct weston_data_source {
>   struct wl_resource *resource;
>   struct wl_signal destroy_signal;
>   struct wl_array mime_types;
> + struct weston_data_offer *offer;
> + bool accepted;
>  
>   void (*accept)(struct weston_data_source *source,
>  uint32_t serial, const char *mime_type);
> diff --git a/src/data-device.c b/src/data-device.c
> index 1612091..d5b8f02 100644
> --- a/src/data-device.c
> +++ b/src/data-device.c
> @@ -62,12 +62,18 @@ data_offer_accept(struct wl_client *client, struct 
> wl_resource *resource,
>  {
>   struct weston_data_offer *offer = wl_resource_get_user_data(resource);
>  
> + /* Protect against untimely calls from older data offers */
> + if (!offer->source || offer !

[PATCH weston 1/5] data-device: Implement DnD progress notification

2015-12-21 Thread Carlos Garnacho
Weston now sends wl_data_source.dnd_drop_performed and .dnd_finished in
order to notify about the different phases of DnD.

wl_data_source.cancelled is also used as mentioned in the docs, being
emitted also on DnD when the operation is meant to fail (eg. source
and dest didn't agree on a mimetype).

The dnd demo is also fixed so the struct dnd_drag isn't leaked.

https://bugs.freedesktop.org/show_bug.cgi?id=91943
https://bugs.freedesktop.org/show_bug.cgi?id=91944

Changes since v2:
  - Handle wl_data_offer.finish. Fixed commit log inconsistencies.
Added version checks. Spaces vs tabs fixes. Fixed resource
versioning.

Changes since v1:
  - Updated to protocol v2.

Signed-off-by: Carlos Garnacho 
Reviewed-by: Michael Catanzaro 
---
 clients/dnd.c | 39 +++---
 clients/window.c  |  3 ++-
 src/compositor.h  |  2 ++
 src/data-device.c | 71 ---
 4 files changed, 98 insertions(+), 17 deletions(-)

diff --git a/clients/dnd.c b/clients/dnd.c
index e6a0c39..48111d9 100644
--- a/clients/dnd.c
+++ b/clients/dnd.c
@@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source *source,
 }
 
 static void
-data_source_cancelled(void *data, struct wl_data_source *source)
+dnd_drag_destroy(struct dnd_drag *dnd_drag)
 {
-   struct dnd_drag *dnd_drag = data;
-
-   /* The 'cancelled' event means that the source is no longer in
-* use by the drag (or current selection).  We need to clean
-* up the drag object created and the local state. */
-
wl_data_source_destroy(dnd_drag->data_source);
 
/* Destroy the item that has been dragged out */
@@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct wl_data_source 
*source)
free(dnd_drag);
 }
 
+static void
+data_source_cancelled(void *data, struct wl_data_source *source)
+{
+   struct dnd_drag *dnd_drag = data;
+
+   /* The 'cancelled' event means that the source is no longer in
+* use by the drag (or current selection).  We need to clean
+* up the drag object created and the local state. */
+   dnd_drag_destroy(dnd_drag);
+}
+
+static void
+data_source_drop_performed(void *data, struct wl_data_source *source)
+{
+}
+
+static void
+data_source_drag_finished(void *data, struct wl_data_source *source)
+{
+   struct dnd_drag *dnd_drag = data;
+
+   /* The operation is already finished, we can destroy all
+* related data.
+*/
+   dnd_drag_destroy(dnd_drag);
+}
+
 static const struct wl_data_source_listener data_source_listener = {
data_source_target,
data_source_send,
-   data_source_cancelled
+   data_source_cancelled,
+   data_source_drop_performed,
+   data_source_drag_finished,
 };
 
 static cairo_surface_t *
diff --git a/clients/window.c b/clients/window.c
index 47628de..db96185 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -3765,6 +3765,7 @@ offer_io_func(struct task *task, uint32_t events)
 
if (len == 0) {
close(offer->fd);
+   wl_data_offer_finish(offer->offer);
data_offer_destroy(offer);
}
 }
@@ -5376,7 +5377,7 @@ registry_handle_global(void *data, struct wl_registry 
*registry, uint32_t id,
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
wl_shm_add_listener(d->shm, &shm_listener, d);
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
-   d->data_device_manager_version = MIN(version, 2);
+   d->data_device_manager_version = MIN(version, 3);
d->data_device_manager =
wl_registry_bind(registry, id,
 &wl_data_device_manager_interface,
diff --git a/src/compositor.h b/src/compositor.h
index 4443c72..96a7b0d 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -304,6 +304,8 @@ struct weston_data_source {
struct wl_resource *resource;
struct wl_signal destroy_signal;
struct wl_array mime_types;
+   struct weston_data_offer *offer;
+   bool accepted;
 
void (*accept)(struct weston_data_source *source,
   uint32_t serial, const char *mime_type);
diff --git a/src/data-device.c b/src/data-device.c
index 1612091..d5b8f02 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -62,12 +62,18 @@ data_offer_accept(struct wl_client *client, struct 
wl_resource *resource,
 {
struct weston_data_offer *offer = wl_resource_get_user_data(resource);
 
+   /* Protect against untimely calls from older data offers */
+   if (!offer->source || offer != offer->source->offer)
+   return;
+
/* FIXME: Check that client is currently focused by the input
 * device that is currently dragging this data source.  Should
 * this be a wl_data_device request? */
 
-   if (offer->source)
+   if (offer->source) {
   

Re: [PATCH weston 1/5] data-device: Implement DnD progress notification

2015-12-16 Thread Jonas Ådahl
On Wed, Dec 16, 2015 at 04:03:14PM +0100, Carlos Garnacho wrote:
> Hey :),
> 
> On Wed, Dec 16, 2015 at 3:21 AM, Jonas Ådahl  wrote:
> > On Tue, Dec 15, 2015 at 06:56:21PM +0100, Carlos Garnacho wrote:
> >> Weston now sends wl_data_source.drop_performed and .drag_finished in
> >> order to notify about the different phases of DnD.
> >
> > s/drop_performed/dnd_drop_performed, and s/drag_finished/dnd_finished/.
> 
> Oops, missed the renames in the commit logs.
> 
> >
> >>
> >> wl_data_source.cancelled is also used as mentioned in the docs, being
> >> emitted also on DnD when the operation is meant to fail (eg. source
> >> and dest didn't agree on a mimetype).
> >>
> >> The dnd demo is also fixed so the struct dnd_drag isn't leaked.
> >>
> >> https://bugs.freedesktop.org/show_bug.cgi?id=91943
> >> https://bugs.freedesktop.org/show_bug.cgi?id=91944
> >>
> >> Changes since v1:
> >>   - Updated to protocol v2.
> >>
> >> Signed-off-by: Carlos Garnacho 
> >> Reviewed-by: Michael Catanzaro 
> >> ---
> >>  clients/dnd.c | 39 +++
> >>  clients/window.c  |  2 +-
> >>  src/compositor.h  |  2 ++
> >>  src/data-device.c | 37 +++--
> >>  4 files changed, 65 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/clients/dnd.c b/clients/dnd.c
> >> index e6a0c39..6c2ed57 100644
> >> --- a/clients/dnd.c
> >> +++ b/clients/dnd.c
> >> @@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source 
> >> *source,
> >>  }
> >>
> >>  static void
> >> -data_source_cancelled(void *data, struct wl_data_source *source)
> >> +destroy_dnd_drag(struct dnd_drag *dnd_drag)
> >
> > naming nit: dnd_drag_destroy().
> >
> >>  {
> >> - struct dnd_drag *dnd_drag = data;
> >> -
> >> - /* The 'cancelled' event means that the source is no longer in
> >> -  * use by the drag (or current selection).  We need to clean
> >> -  * up the drag object created and the local state. */
> >> -
> >>   wl_data_source_destroy(dnd_drag->data_source);
> >>
> >>   /* Destroy the item that has been dragged out */
> >> @@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct 
> >> wl_data_source *source)
> >>   free(dnd_drag);
> >>  }
> >>
> >> +static void
> >> +data_source_cancelled(void *data, struct wl_data_source *source)
> >> +{
> >> + struct dnd_drag *dnd_drag = data;
> >> +
> >> + /* The 'cancelled' event means that the source is no longer in
> >> +  * use by the drag (or current selection).  We need to clean
> >> +  * up the drag object created and the local state. */
> >> +destroy_dnd_drag(dnd_drag);
> >
> > Tab instead of spaces.
> >
> >> +}
> >> +
> >> +static void
> >> +data_source_drop_performed(void *data, struct wl_data_source *source)
> >> +{
> >> +}
> >> +
> >> +static void
> >> +data_source_drag_finished(void *data, struct wl_data_source *source)
> >> +{
> >> + struct dnd_drag *dnd_drag = data;
> >> +
> >> +/* The operation is already finished, we can destroy all
> >> + * related data.
> >> + */
> >
> > Tab instead of spaces.
> >
> >> + destroy_dnd_drag(dnd_drag);
> >> +}
> >> +
> >>  static const struct wl_data_source_listener data_source_listener = {
> >>   data_source_target,
> >>   data_source_send,
> >> - data_source_cancelled
> >> + data_source_cancelled,
> >> + data_source_drop_performed,
> >> + data_source_drag_finished,
> >>  };
> >>
> >>  static cairo_surface_t *
> >> diff --git a/clients/window.c b/clients/window.c
> >> index 47628de..24aa517 100644
> >> --- a/clients/window.c
> >> +++ b/clients/window.c
> >> @@ -5376,7 +5376,7 @@ registry_handle_global(void *data, struct 
> >> wl_registry *registry, uint32_t id,
> >>   d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 
> >> 1);
> >>   wl_shm_add_listener(d->shm, &shm_listener, d);
> >>   } else if (strcmp(interface, "wl_data_device_manager") == 0) {
> >> - d->data_device_manager_version = MIN(version, 2);
> >> + d->data_device_manager_version = MIN(version, 3);
> >>   d->data_device_manager =
> >>   wl_registry_bind(registry, id,
> >>&wl_data_device_manager_interface,
> >> diff --git a/src/compositor.h b/src/compositor.h
> >> index 4443c72..96a7b0d 100644
> >> --- a/src/compositor.h
> >> +++ b/src/compositor.h
> >> @@ -304,6 +304,8 @@ struct weston_data_source {
> >>   struct wl_resource *resource;
> >>   struct wl_signal destroy_signal;
> >>   struct wl_array mime_types;
> >> + struct weston_data_offer *offer;
> >> + bool accepted;
> >>
> >>   void (*accept)(struct weston_data_source *source,
> >>  uint32_t serial, const char *mime_type);
> >> diff --git a/src/data-device.c b/src/data-device.c
> >> index 1612091..2b55f7b 100644
> >> --- a/src/data-device.c
> >> +++ b/src/data-device.c
> >> @@ -62,12 +62,18 @@ data_offer_acce

Re: [PATCH weston 1/5] data-device: Implement DnD progress notification

2015-12-16 Thread Carlos Garnacho
Hey :),

On Wed, Dec 16, 2015 at 3:21 AM, Jonas Ådahl  wrote:
> On Tue, Dec 15, 2015 at 06:56:21PM +0100, Carlos Garnacho wrote:
>> Weston now sends wl_data_source.drop_performed and .drag_finished in
>> order to notify about the different phases of DnD.
>
> s/drop_performed/dnd_drop_performed, and s/drag_finished/dnd_finished/.

Oops, missed the renames in the commit logs.

>
>>
>> wl_data_source.cancelled is also used as mentioned in the docs, being
>> emitted also on DnD when the operation is meant to fail (eg. source
>> and dest didn't agree on a mimetype).
>>
>> The dnd demo is also fixed so the struct dnd_drag isn't leaked.
>>
>> https://bugs.freedesktop.org/show_bug.cgi?id=91943
>> https://bugs.freedesktop.org/show_bug.cgi?id=91944
>>
>> Changes since v1:
>>   - Updated to protocol v2.
>>
>> Signed-off-by: Carlos Garnacho 
>> Reviewed-by: Michael Catanzaro 
>> ---
>>  clients/dnd.c | 39 +++
>>  clients/window.c  |  2 +-
>>  src/compositor.h  |  2 ++
>>  src/data-device.c | 37 +++--
>>  4 files changed, 65 insertions(+), 15 deletions(-)
>>
>> diff --git a/clients/dnd.c b/clients/dnd.c
>> index e6a0c39..6c2ed57 100644
>> --- a/clients/dnd.c
>> +++ b/clients/dnd.c
>> @@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source 
>> *source,
>>  }
>>
>>  static void
>> -data_source_cancelled(void *data, struct wl_data_source *source)
>> +destroy_dnd_drag(struct dnd_drag *dnd_drag)
>
> naming nit: dnd_drag_destroy().
>
>>  {
>> - struct dnd_drag *dnd_drag = data;
>> -
>> - /* The 'cancelled' event means that the source is no longer in
>> -  * use by the drag (or current selection).  We need to clean
>> -  * up the drag object created and the local state. */
>> -
>>   wl_data_source_destroy(dnd_drag->data_source);
>>
>>   /* Destroy the item that has been dragged out */
>> @@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct 
>> wl_data_source *source)
>>   free(dnd_drag);
>>  }
>>
>> +static void
>> +data_source_cancelled(void *data, struct wl_data_source *source)
>> +{
>> + struct dnd_drag *dnd_drag = data;
>> +
>> + /* The 'cancelled' event means that the source is no longer in
>> +  * use by the drag (or current selection).  We need to clean
>> +  * up the drag object created and the local state. */
>> +destroy_dnd_drag(dnd_drag);
>
> Tab instead of spaces.
>
>> +}
>> +
>> +static void
>> +data_source_drop_performed(void *data, struct wl_data_source *source)
>> +{
>> +}
>> +
>> +static void
>> +data_source_drag_finished(void *data, struct wl_data_source *source)
>> +{
>> + struct dnd_drag *dnd_drag = data;
>> +
>> +/* The operation is already finished, we can destroy all
>> + * related data.
>> + */
>
> Tab instead of spaces.
>
>> + destroy_dnd_drag(dnd_drag);
>> +}
>> +
>>  static const struct wl_data_source_listener data_source_listener = {
>>   data_source_target,
>>   data_source_send,
>> - data_source_cancelled
>> + data_source_cancelled,
>> + data_source_drop_performed,
>> + data_source_drag_finished,
>>  };
>>
>>  static cairo_surface_t *
>> diff --git a/clients/window.c b/clients/window.c
>> index 47628de..24aa517 100644
>> --- a/clients/window.c
>> +++ b/clients/window.c
>> @@ -5376,7 +5376,7 @@ registry_handle_global(void *data, struct wl_registry 
>> *registry, uint32_t id,
>>   d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
>>   wl_shm_add_listener(d->shm, &shm_listener, d);
>>   } else if (strcmp(interface, "wl_data_device_manager") == 0) {
>> - d->data_device_manager_version = MIN(version, 2);
>> + d->data_device_manager_version = MIN(version, 3);
>>   d->data_device_manager =
>>   wl_registry_bind(registry, id,
>>&wl_data_device_manager_interface,
>> diff --git a/src/compositor.h b/src/compositor.h
>> index 4443c72..96a7b0d 100644
>> --- a/src/compositor.h
>> +++ b/src/compositor.h
>> @@ -304,6 +304,8 @@ struct weston_data_source {
>>   struct wl_resource *resource;
>>   struct wl_signal destroy_signal;
>>   struct wl_array mime_types;
>> + struct weston_data_offer *offer;
>> + bool accepted;
>>
>>   void (*accept)(struct weston_data_source *source,
>>  uint32_t serial, const char *mime_type);
>> diff --git a/src/data-device.c b/src/data-device.c
>> index 1612091..2b55f7b 100644
>> --- a/src/data-device.c
>> +++ b/src/data-device.c
>> @@ -62,12 +62,18 @@ data_offer_accept(struct wl_client *client, struct 
>> wl_resource *resource,
>>  {
>>   struct weston_data_offer *offer = wl_resource_get_user_data(resource);
>>
>> + /* Protect against untimely calls from older data offers */
>> + if (!offer->source || offer != offer->source->offer)
>> + return;
>> +
>>   /* FIXME: Check that clie

Re: [PATCH weston 1/5] data-device: Implement DnD progress notification

2015-12-15 Thread Jonas Ådahl
On Tue, Dec 15, 2015 at 06:56:21PM +0100, Carlos Garnacho wrote:
> Weston now sends wl_data_source.drop_performed and .drag_finished in
> order to notify about the different phases of DnD.

s/drop_performed/dnd_drop_performed, and s/drag_finished/dnd_finished/.

> 
> wl_data_source.cancelled is also used as mentioned in the docs, being
> emitted also on DnD when the operation is meant to fail (eg. source
> and dest didn't agree on a mimetype).
> 
> The dnd demo is also fixed so the struct dnd_drag isn't leaked.
> 
> https://bugs.freedesktop.org/show_bug.cgi?id=91943
> https://bugs.freedesktop.org/show_bug.cgi?id=91944
> 
> Changes since v1:
>   - Updated to protocol v2.
> 
> Signed-off-by: Carlos Garnacho 
> Reviewed-by: Michael Catanzaro 
> ---
>  clients/dnd.c | 39 +++
>  clients/window.c  |  2 +-
>  src/compositor.h  |  2 ++
>  src/data-device.c | 37 +++--
>  4 files changed, 65 insertions(+), 15 deletions(-)
> 
> diff --git a/clients/dnd.c b/clients/dnd.c
> index e6a0c39..6c2ed57 100644
> --- a/clients/dnd.c
> +++ b/clients/dnd.c
> @@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source 
> *source,
>  }
>  
>  static void
> -data_source_cancelled(void *data, struct wl_data_source *source)
> +destroy_dnd_drag(struct dnd_drag *dnd_drag)

naming nit: dnd_drag_destroy().

>  {
> - struct dnd_drag *dnd_drag = data;
> -
> - /* The 'cancelled' event means that the source is no longer in
> -  * use by the drag (or current selection).  We need to clean
> -  * up the drag object created and the local state. */
> -
>   wl_data_source_destroy(dnd_drag->data_source);
>  
>   /* Destroy the item that has been dragged out */
> @@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct wl_data_source 
> *source)
>   free(dnd_drag);
>  }
>  
> +static void
> +data_source_cancelled(void *data, struct wl_data_source *source)
> +{
> + struct dnd_drag *dnd_drag = data;
> +
> + /* The 'cancelled' event means that the source is no longer in
> +  * use by the drag (or current selection).  We need to clean
> +  * up the drag object created and the local state. */
> +destroy_dnd_drag(dnd_drag);

Tab instead of spaces.

> +}
> +
> +static void
> +data_source_drop_performed(void *data, struct wl_data_source *source)
> +{
> +}
> +
> +static void
> +data_source_drag_finished(void *data, struct wl_data_source *source)
> +{
> + struct dnd_drag *dnd_drag = data;
> +
> +/* The operation is already finished, we can destroy all
> + * related data.
> + */

Tab instead of spaces.

> + destroy_dnd_drag(dnd_drag);
> +}
> +
>  static const struct wl_data_source_listener data_source_listener = {
>   data_source_target,
>   data_source_send,
> - data_source_cancelled
> + data_source_cancelled,
> + data_source_drop_performed,
> + data_source_drag_finished,
>  };
>  
>  static cairo_surface_t *
> diff --git a/clients/window.c b/clients/window.c
> index 47628de..24aa517 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -5376,7 +5376,7 @@ registry_handle_global(void *data, struct wl_registry 
> *registry, uint32_t id,
>   d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
>   wl_shm_add_listener(d->shm, &shm_listener, d);
>   } else if (strcmp(interface, "wl_data_device_manager") == 0) {
> - d->data_device_manager_version = MIN(version, 2);
> + d->data_device_manager_version = MIN(version, 3);
>   d->data_device_manager =
>   wl_registry_bind(registry, id,
>&wl_data_device_manager_interface,
> diff --git a/src/compositor.h b/src/compositor.h
> index 4443c72..96a7b0d 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -304,6 +304,8 @@ struct weston_data_source {
>   struct wl_resource *resource;
>   struct wl_signal destroy_signal;
>   struct wl_array mime_types;
> + struct weston_data_offer *offer;
> + bool accepted;
>  
>   void (*accept)(struct weston_data_source *source,
>  uint32_t serial, const char *mime_type);
> diff --git a/src/data-device.c b/src/data-device.c
> index 1612091..2b55f7b 100644
> --- a/src/data-device.c
> +++ b/src/data-device.c
> @@ -62,12 +62,18 @@ data_offer_accept(struct wl_client *client, struct 
> wl_resource *resource,
>  {
>   struct weston_data_offer *offer = wl_resource_get_user_data(resource);
>  
> + /* Protect against untimely calls from older data offers */
> + if (!offer->source || offer != offer->source->offer)
> + return;
> +
>   /* FIXME: Check that client is currently focused by the input
>* device that is currently dragging this data source.  Should
>* this be a wl_data_device request? */
>  
> - if (offer->source)
> + if (offer->source) {
>   offer

[PATCH weston 1/5] data-device: Implement DnD progress notification

2015-12-15 Thread Carlos Garnacho
Weston now sends wl_data_source.drop_performed and .drag_finished in
order to notify about the different phases of DnD.

wl_data_source.cancelled is also used as mentioned in the docs, being
emitted also on DnD when the operation is meant to fail (eg. source
and dest didn't agree on a mimetype).

The dnd demo is also fixed so the struct dnd_drag isn't leaked.

https://bugs.freedesktop.org/show_bug.cgi?id=91943
https://bugs.freedesktop.org/show_bug.cgi?id=91944

Changes since v1:
  - Updated to protocol v2.

Signed-off-by: Carlos Garnacho 
Reviewed-by: Michael Catanzaro 
---
 clients/dnd.c | 39 +++
 clients/window.c  |  2 +-
 src/compositor.h  |  2 ++
 src/data-device.c | 37 +++--
 4 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/clients/dnd.c b/clients/dnd.c
index e6a0c39..6c2ed57 100644
--- a/clients/dnd.c
+++ b/clients/dnd.c
@@ -318,14 +318,8 @@ data_source_send(void *data, struct wl_data_source *source,
 }
 
 static void
-data_source_cancelled(void *data, struct wl_data_source *source)
+destroy_dnd_drag(struct dnd_drag *dnd_drag)
 {
-   struct dnd_drag *dnd_drag = data;
-
-   /* The 'cancelled' event means that the source is no longer in
-* use by the drag (or current selection).  We need to clean
-* up the drag object created and the local state. */
-
wl_data_source_destroy(dnd_drag->data_source);
 
/* Destroy the item that has been dragged out */
@@ -339,10 +333,39 @@ data_source_cancelled(void *data, struct wl_data_source 
*source)
free(dnd_drag);
 }
 
+static void
+data_source_cancelled(void *data, struct wl_data_source *source)
+{
+   struct dnd_drag *dnd_drag = data;
+
+   /* The 'cancelled' event means that the source is no longer in
+* use by the drag (or current selection).  We need to clean
+* up the drag object created and the local state. */
+destroy_dnd_drag(dnd_drag);
+}
+
+static void
+data_source_drop_performed(void *data, struct wl_data_source *source)
+{
+}
+
+static void
+data_source_drag_finished(void *data, struct wl_data_source *source)
+{
+   struct dnd_drag *dnd_drag = data;
+
+/* The operation is already finished, we can destroy all
+ * related data.
+ */
+   destroy_dnd_drag(dnd_drag);
+}
+
 static const struct wl_data_source_listener data_source_listener = {
data_source_target,
data_source_send,
-   data_source_cancelled
+   data_source_cancelled,
+   data_source_drop_performed,
+   data_source_drag_finished,
 };
 
 static cairo_surface_t *
diff --git a/clients/window.c b/clients/window.c
index 47628de..24aa517 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -5376,7 +5376,7 @@ registry_handle_global(void *data, struct wl_registry 
*registry, uint32_t id,
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
wl_shm_add_listener(d->shm, &shm_listener, d);
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
-   d->data_device_manager_version = MIN(version, 2);
+   d->data_device_manager_version = MIN(version, 3);
d->data_device_manager =
wl_registry_bind(registry, id,
 &wl_data_device_manager_interface,
diff --git a/src/compositor.h b/src/compositor.h
index 4443c72..96a7b0d 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -304,6 +304,8 @@ struct weston_data_source {
struct wl_resource *resource;
struct wl_signal destroy_signal;
struct wl_array mime_types;
+   struct weston_data_offer *offer;
+   bool accepted;
 
void (*accept)(struct weston_data_source *source,
   uint32_t serial, const char *mime_type);
diff --git a/src/data-device.c b/src/data-device.c
index 1612091..2b55f7b 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -62,12 +62,18 @@ data_offer_accept(struct wl_client *client, struct 
wl_resource *resource,
 {
struct weston_data_offer *offer = wl_resource_get_user_data(resource);
 
+   /* Protect against untimely calls from older data offers */
+   if (!offer->source || offer != offer->source->offer)
+   return;
+
/* FIXME: Check that client is currently focused by the input
 * device that is currently dragging this data source.  Should
 * this be a wl_data_device request? */
 
-   if (offer->source)
+   if (offer->source) {
offer->source->accept(offer->source, serial, mime_type);
+   offer->source->accepted = mime_type != NULL;
+   }
 }
 
 static void
@@ -76,7 +82,7 @@ data_offer_receive(struct wl_client *client, struct 
wl_resource *resource,
 {
struct weston_data_offer *offer = wl_resource_get_user_data(resource);
 
-   if (offer->source)
+   if (offer->source && offer == offer->source->offer