ecore-wl2: handle null offer drags more effectively
authorMike Blumenkrantz <zmike@osg.samsung.com>
Mon, 24 Jul 2017 12:28:39 +0000 (08:28 -0400)
committerMike Blumenkrantz <zmike@osg.samsung.com>
Mon, 24 Jul 2017 12:30:05 +0000 (08:30 -0400)
this is valid and refers to an offer with no types; a leave event
with no enter is a protocol error, however

fix T5770

@fix

src/lib/ecore_wl2/ecore_wl2_dnd.c
src/lib/ecore_wl2/ecore_wl2_input.c
src/lib/ecore_wl2/ecore_wl2_private.h

index cd04a12..4a17084 100644 (file)
@@ -251,46 +251,42 @@ _ecore_wl2_dnd_enter(Ecore_Wl2_Input *input, struct wl_data_offer *offer, struct
 
    if (offer)
      {
-        input->drag = wl_data_offer_get_user_data(offer);
+        input->drag.offer = wl_data_offer_get_user_data(offer);
 
-        if (!input->drag)
-          {
-             ERR("Userdata of offer not found");
-             return;
-          }
-
-        input->drag->serial = serial;
-        input->drag->window_id = window->id;
+        input->drag.offer->serial = serial;
+        input->drag.offer->window_id = window->id;
 
         if (input->display->wl.data_device_manager_version >=
             WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION)
           {
-             ecore_wl2_offer_actions_set(input->drag,
-                ECORE_WL2_DRAG_ACTION_MOVE | ECORE_WL2_DRAG_ACTION_COPY,
-                ECORE_WL2_DRAG_ACTION_MOVE);
+             if (input->drag.offer)
+               ecore_wl2_offer_actions_set(input->drag.offer,
+                  ECORE_WL2_DRAG_ACTION_MOVE | ECORE_WL2_DRAG_ACTION_COPY,
+                  ECORE_WL2_DRAG_ACTION_MOVE);
           }
      }
    else
      {
-        input->drag = NULL;
+        input->drag.offer = NULL;
      }
+   input->drag.enter_serial = serial;
+   input->drag.window_id = window->id;
 
    ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Enter));
    if (!ev) return;
 
    if (input->focus.keyboard)
      ev->source = input->focus.keyboard->id;
-   if (input->drag)
-     ev->win = input->drag->window_id;
+   ev->win = input->drag.window_id;
 
    ev->x = x;
    ev->y = y;
-   ev->offer = input->drag;
+   ev->offer = input->drag.offer;
    ev->seat = input->id;
    ev->display = input->display;
    ev->display->refs++;
 
-   ecore_event_add(ECORE_WL2_EVENT_DND_ENTER, ev, _unset_serial, input->drag);
+   ecore_event_add(ECORE_WL2_EVENT_DND_ENTER, ev, _unset_serial, input->drag.offer);
 }
 
 static void
@@ -310,22 +306,26 @@ _ecore_wl2_dnd_leave(Ecore_Wl2_Input *input)
 {
    Ecore_Wl2_Event_Dnd_Leave *ev;
 
+   EINA_SAFETY_ON_TRUE_RETURN(!input->drag.enter_serial);
+
    ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Leave));
    if (!ev) return;
 
    if (input->focus.keyboard)
      ev->source = input->focus.keyboard->id;
 
-   ev->win = input->drag->window_id;
-   ev->offer = input->drag;
-   ev->offer->ref++;
+   ev->win = input->drag.window_id;
+   ev->offer = input->drag.offer;
+   if (ev->offer)
+     ev->offer->ref++;
    ev->seat = input->id;
    ev->display = input->display;
    ev->display->refs++;
 
-   input->drag->window_id = 0;
+   input->drag.window_id = 0;
+   input->drag.enter_serial = 0;
+   input->drag.offer = NULL;
    ecore_event_add(ECORE_WL2_EVENT_DND_LEAVE, ev, _delay_offer_destroy, ev->offer);
-   input->drag = NULL;
 }
 
 void
@@ -339,20 +339,21 @@ _ecore_wl2_dnd_motion(Ecore_Wl2_Input *input, int x, int y, uint32_t serial)
    ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Motion));
    if (!ev) return;
 
-   input->drag->serial = serial;
+   if (input->drag.offer)
+     input->drag.offer->serial = serial;
 
    if (input->focus.keyboard)
      ev->source = input->focus.keyboard->id;
 
-   ev->win = input->drag->window_id;
+   ev->win = input->drag.window_id;
    ev->x = x;
    ev->y = y;
-   ev->offer = input->drag;
+   ev->offer = input->drag.offer;
    ev->seat = input->id;
    ev->display = input->display;
    ev->display->refs++;
 
-   ecore_event_add(ECORE_WL2_EVENT_DND_MOTION, ev, _unset_serial, input->drag);
+   ecore_event_add(ECORE_WL2_EVENT_DND_MOTION, ev, _unset_serial, input->drag.offer);
 }
 
 void
@@ -366,10 +367,10 @@ _ecore_wl2_dnd_drop(Ecore_Wl2_Input *input)
    if (input->focus.keyboard)
      ev->source = input->focus.keyboard->id;
 
-   ev->win = input->drag->window_id;
+   ev->win = input->drag.window_id;
    ev->x = input->pointer.sx;
    ev->y = input->pointer.sy;
-   ev->offer = input->drag;
+   ev->offer = input->drag.offer;
    ev->seat = input->id;
    ev->display = input->display;
    ev->display->refs++;
@@ -382,11 +383,12 @@ _ecore_wl2_dnd_selection(Ecore_Wl2_Input *input, struct wl_data_offer *offer)
 {
    Ecore_Wl2_Event_Seat_Selection *ev;
 
-   if (input->selection) _ecore_wl2_offer_unref(input->selection);
-   input->selection = NULL;
+   if (input->selection.offer) _ecore_wl2_offer_unref(input->selection.offer);
+   input->selection.offer = NULL;
 
    if (offer)
-     input->selection = wl_data_offer_get_user_data(offer);
+     input->selection.offer = wl_data_offer_get_user_data(offer);
+   input->selection.enter_serial = input->display->serial;
    ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Selection));
    EINA_SAFETY_ON_NULL_RETURN(ev);
    ev->seat = input->id;
@@ -539,7 +541,7 @@ ecore_wl2_dnd_selection_get(Ecore_Wl2_Input *input)
 {
    EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL);
 
-   return input->selection;
+   return input->selection.offer;
 }
 
 EAPI uint32_t
@@ -911,8 +913,8 @@ _ecore_wl2_offer_unref(Ecore_Wl2_Offer *offer)
         offer->mimetypes = NULL;
      }
 
-   if (offer->input->drag == offer) offer->input->drag = NULL;
-   if (offer->input->selection == offer) offer->input->selection = NULL;
+   if (offer->input->drag.offer == offer) offer->input->drag.offer = NULL;
+   if (offer->input->selection.offer == offer) offer->input->selection.offer = NULL;
 
    free(offer);
 }
index 43d09cc..da6fe7c 100644 (file)
@@ -1691,8 +1691,8 @@ _ecore_wl2_input_del(Ecore_Wl2_Input *input)
      wl_data_source_destroy(input->data.selection.source);
    if (input->data.drag.source)
      wl_data_source_destroy(input->data.drag.source);
-   if (input->drag) _ecore_wl2_offer_unref(input->drag);
-   if (input->selection) _ecore_wl2_offer_unref(input->selection);
+   if (input->drag.offer) _ecore_wl2_offer_unref(input->drag.offer);
+   if (input->selection.offer) _ecore_wl2_offer_unref(input->selection.offer);
    if (input->data.device) wl_data_device_destroy(input->data.device);
 
    if (input->xkb.state) xkb_state_unref(input->xkb.state);
index ec2f887..ba74ba3 100644 (file)
@@ -450,7 +450,12 @@ struct _Ecore_Wl2_Input
         Eina_Bool repeating : 1;
      } repeat;
 
-   Ecore_Wl2_Offer *drag, *selection;
+   struct
+   {
+      Ecore_Wl2_Offer *offer;
+      uint32_t enter_serial;
+      Ecore_Window window_id;
+   } drag, selection;
 
    unsigned int seat_version;
    unsigned int id;