data_device: Refactor code of drag and drop 16/280016/1
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 17 Aug 2022 01:15:01 +0000 (10:15 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 22 Aug 2022 09:08:16 +0000 (18:08 +0900)
Change-Id: Ie3c7230e28a892929309ca394a116dce9a10b986

src/data_device/data_device.c
src/data_device/data_device_private.h
src/data_device/drag.c

index ef2a89e..d62a4ae 100644 (file)
@@ -59,6 +59,67 @@ create_data_device_resource(struct ds_data_device_manager *manager,
         data_device_send_selection(data_device, resource);
 }
 
+bool
+data_device_send_drag_enter(struct ds_data_device *data_device,
+        struct ds_data_source *drag_source,
+        struct wl_resource *surface_resource,
+        double sx, double sy)
+{
+    struct ds_data_offer *offer;
+    struct wl_resource *device_resource;
+    uint32_t serial;
+
+    wl_resource_for_each(device_resource, &data_device->resources) {
+        offer = create_data_offer(device_resource, drag_source,
+                DS_DATA_OFFER_DRAG);
+        if (!offer) {
+            wl_resource_post_no_memory(device_resource);
+            return false;
+        }
+
+        data_offer_update_action(offer);
+
+        if (wl_resource_get_version(offer->resource) >=
+                WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION) {
+            wl_data_offer_send_source_actions(offer->resource,
+                    drag_source->actions);
+        }
+
+        serial = wl_display_next_serial(data_device->manager->display);
+        wl_data_device_send_enter(device_resource, serial, surface_resource,
+                wl_fixed_from_double(sx), wl_fixed_from_double(sy),
+                offer->resource);
+    }
+
+    return true;
+}
+
+void
+data_device_send_drag_leave(struct ds_data_device *data_device)
+{
+    struct wl_resource *device_resource;
+
+    wl_resource_for_each(device_resource, &data_device->resources)
+        wl_data_device_send_leave(device_resource);
+}
+
+void
+data_device_destroy_drag_offers(struct ds_data_device *data_device,
+        struct ds_data_source *drag_source)
+{
+    struct ds_data_offer *offer, *tmp;
+
+    wl_list_for_each_safe(offer, tmp, &data_device->drag_offers, link) {
+        if (offer->source != drag_source) {
+            ds_err("Something wrong, offer->source != drag_source");
+            continue;
+        }
+
+        offer->source = NULL;
+        data_offer_destroy(offer);
+    }
+}
+
 static struct ds_data_device *
 data_device_get_or_create(struct ds_data_device_manager *manager,
         struct ds_seat_client *seat_client)
index 26b0b91..235592d 100644 (file)
@@ -138,6 +138,16 @@ void create_data_device_resource(struct ds_data_device_manager *manager,
         struct wl_client *client, uint32_t version,
         uint32_t id, struct wl_resource *seat_resource);
 
+bool data_device_send_drag_enter(struct ds_data_device *data_device,
+        struct ds_data_source *drag_source,
+        struct wl_resource *surface_resource,
+        double sx, double sy);
+
+void data_device_send_drag_leave(struct ds_data_device *data_device);
+
+void data_device_destroy_drag_offers(struct ds_data_device *data_device,
+        struct ds_data_source *drag_source);
+
 struct ds_data_source_client *create_data_source_client(
         struct wl_client *wl_client, uint32_t version, uint32_t id);
 
index 9baf351..fc99c13 100644 (file)
@@ -11,13 +11,19 @@ static struct ds_drag_icon *create_drag_icon(struct ds_drag *drag,
 static void drag_handle_icon_destroy(struct wl_listener *listener, void *data);
 static void drag_handle_source_destroy(struct wl_listener *listener,
         void *data);
-static void drag_handle_seat_client_destroy(struct wl_listener *listener,
-        void *data);
 static void drag_start(struct ds_drag *drag, uint32_t serial);
 static void drag_set_focus(struct ds_drag *drag, struct ds_surface *surface,
         double sx, double sy);
 static void drag_drop(struct ds_drag *drag, uint32_t time);
 static void drag_icon_destroy(struct ds_drag_icon *icon);
+static void drag_enter(struct ds_drag *drag, struct ds_surface *surface,
+        double sx, double sy);
+static void drag_leave(struct ds_drag *drag);
+static void drag_set_focus_client(struct ds_drag *drag,
+        struct ds_seat_client *seat_client);
+static void drag_unset_focus_client(struct ds_drag *drag);
+static void drag_handle_seat_client_destroy(struct wl_listener *listener,
+        void *data);
 
 WL_EXPORT void
 ds_drag_destroy(struct ds_drag *drag)
@@ -332,7 +338,7 @@ drag_pointer_grab_iface_button(struct ds_seat_pointer_grab *grab,
         }
     }
 
-    grab_button_count = ds_seat_pointer_get_grab_button(drag->seat);
+    grab_button_count = ds_seat_pointer_get_grab_button_count(drag->seat);
     if (grab_button_count == 0 &&
             state == WL_POINTER_BUTTON_STATE_RELEASED) {
         drag_destroy(drag);
@@ -426,101 +432,15 @@ static void
 drag_set_focus(struct ds_drag *drag, struct ds_surface *surface,
         double sx, double sy)
 {
-    struct ds_seat_client *focused_client;
-    struct ds_data_device *data_device;
-    struct wl_resource *device_resource, *surface_resource;
-    struct ds_data_offer *offer, *tmp;
-    uint32_t serial;
-
     if (drag->focused_surface == surface)
         return;
 
-    if (drag->focused_client) {
-        wl_list_remove(&drag->seat_client_destroy.link);
-
-        wl_list_for_each(data_device,
-                &drag->data_device->manager->data_devices, link) {
-            if (data_device->seat !=
-                    ds_seat_client_get_seat(drag->focused_client))
-                continue;
-
-            wl_list_for_each_safe(offer, tmp,
-                    &data_device->drag_offers, link) {
-                if (!drag->dropped &&
-                        offer->source == drag->source &&
-                        (wl_resource_get_client(offer->resource) ==
-                         ds_seat_client_get_wl_client(drag->focused_client))) {
-                    offer->source = NULL;
-                    data_offer_destroy(offer);
-                }
-            }
-        }
-
-        data_device = data_device_for_seat_client(drag->data_device->manager,
-                drag->focused_client);
-        if (data_device) {
-            wl_resource_for_each(device_resource, &data_device->resources)
-                wl_data_device_send_leave(device_resource);
-        }
-
-        drag->focused_client = NULL;
-        drag->focused_surface = NULL;
-    }
-
-    if (!surface)
-        goto out;
-
-    surface_resource = ds_surface_get_wl_resource(surface);
-
-    focused_client = ds_seat_client_for_wl_client(drag->seat,
-            wl_resource_get_client(surface_resource));
-    if (!focused_client)
-        goto out;
-
-    if (!drag->source) {
-        if (wl_resource_get_client(surface_resource) !=
-                ds_seat_client_get_wl_client(drag->seat_client))
-            goto out;
-    }
-    else {
-        drag->source->accepted = false;
-
-        data_device = data_device_for_seat_client(drag->data_device->manager,
-                focused_client);
-        if (data_device) {
-            wl_resource_for_each(device_resource, &data_device->resources) {
-                offer = create_data_offer(device_resource, drag->source,
-                        DS_DATA_OFFER_DRAG);
-                if (!offer) {
-                    wl_resource_post_no_memory(device_resource);
-                    return;
-                }
-
-                data_offer_update_action(offer);
-
-                if (wl_resource_get_version(offer->resource) >=
-                        WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION) {
-                    wl_data_offer_send_source_actions(offer->resource,
-                            drag->source->actions);
-                }
-
-                serial = wl_display_next_serial(
-                        drag->data_device->manager->display);
-                wl_data_device_send_enter(device_resource, serial,
-                        surface_resource,
-                        wl_fixed_from_double(sx), wl_fixed_from_double(sy),
-                        offer->resource);
-            }
-        }
-    }
+    if (drag->focused_client)
+        drag_leave(drag);
 
-    drag->focused_surface = surface;
-    drag->focused_client = focused_client;
-    drag->seat_client_destroy.notify = drag_handle_seat_client_destroy;
-    ds_seat_client_add_destroy_listener(focused_client,
-            &drag->seat_client_destroy);
+    if (surface)
+        drag_enter(drag, surface, sx, sy);
 
-out:
     wl_signal_emit(&drag->events.focus, drag);
 }
 
@@ -552,12 +472,79 @@ drag_drop(struct ds_drag *drag, uint32_t time)
 }
 
 static void
+drag_enter(struct ds_drag *drag, struct ds_surface *surface,
+        double sx, double sy)
+{
+    struct ds_data_device *data_device;
+    struct ds_seat_client *focused_client;
+    struct wl_resource *surface_resource;
+
+    surface_resource = ds_surface_get_wl_resource(surface);
+    focused_client = ds_seat_client_for_wl_client(drag->seat,
+            wl_resource_get_client(surface_resource));
+    if (!focused_client)
+        return;
+
+    if (!drag->source &&
+            (wl_resource_get_client(surface_resource) !=
+             ds_seat_client_get_wl_client(drag->seat_client)))
+        return;
+
+    drag->source->accepted = false;
+
+    data_device = data_device_for_seat_client(drag->data_device->manager,
+            focused_client);
+    if (!data_device)
+        return;
+
+    if (data_device_send_drag_enter(data_device, drag->source,
+                surface_resource, sx, sy)) {
+        drag->focused_surface = surface;
+        drag_set_focus_client(drag, focused_client);
+    }
+}
+
+static void
+drag_leave(struct ds_drag *drag)
+{
+    struct ds_data_device *data_device;
+
+    data_device = data_device_for_seat_client(drag->data_device->manager,
+            drag->focused_client);
+    if (data_device) {
+        if (!drag->dropped && drag->source)
+            data_device_destroy_drag_offers(data_device, drag->source);
+
+        data_device_send_drag_leave(data_device);
+    }
+
+    drag_unset_focus_client(drag);
+}
+
+static void
+drag_set_focus_client(struct ds_drag *drag, struct ds_seat_client *seat_client)
+{
+    drag->focused_client = seat_client;
+
+    drag->seat_client_destroy.notify = drag_handle_seat_client_destroy;
+    ds_seat_client_add_destroy_listener(seat_client,
+            &drag->seat_client_destroy);
+}
+
+static void
+drag_unset_focus_client(struct ds_drag *drag)
+{
+    wl_list_remove(&drag->seat_client_destroy.link);
+
+    drag->focused_client = NULL;
+    drag->focused_surface = NULL;
+}
+
+static void
 drag_handle_seat_client_destroy(struct wl_listener *listener, void *data)
 {
     struct ds_drag *drag;
 
     drag = wl_container_of(listener, drag, seat_client_destroy);
-
-    drag->focused_client = NULL;
-    wl_list_remove(&drag->seat_client_destroy.link);
+    drag_unset_focus_client(drag);
 }