Merge "Added UIThreadLoader to GLIB framework" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / drag-and-drop / tizen-wayland / drag-and-drop-impl-ecore-wl2.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/common/singleton-service.h>
23 #include <dali/integration-api/debug.h>
24 #include <unistd.h>
25
26 // INTERNAL INCLUDES
27 #include <dali/internal/adaptor/tizen-wayland/dali-ecore-wl2.h>
28 #include <dali/internal/window-system/common/window-system.h>
29 #include <dali/internal/window-system/common/window-impl.h>
30
31 ///////////////////////////////////////////////////////////////////////////////////////////////////
32 // DragAndDrop
33 ///////////////////////////////////////////////////////////////////////////////////////////////////
34
35 namespace Dali
36 {
37 namespace Internal
38 {
39 namespace Adaptor
40 {
41 namespace
42 {
43 static constexpr int32_t DEFAULT_POSITION            = -1;
44 static constexpr int32_t INVALID_ECORE_WL2_WINDOW_ID = -1;
45 } // namespace
46
47 static bool IsIntersection(int px, int py, int tx, int ty, int tw, int th)
48 {
49   if(px > tx && py > ty && px < (tx + tw) && py < (ty + th))
50   {
51     return true;
52   }
53   return false;
54 }
55
56 static Eina_Bool EcoreEventDataSend(void* data, int type, void* event)
57 {
58   DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
59   dndImpl->SendData(event);
60
61   return ECORE_CALLBACK_PASS_ON;
62 }
63
64 static Eina_Bool EcoreEventDataSourceEnd(void* data, int type, void* event)
65 {
66   Ecore_Wl2_Event_Data_Source_End* ev      = reinterpret_cast<Ecore_Wl2_Event_Data_Source_End*>(event);
67   DragAndDropEcoreWl*              dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
68   if(ev->cancelled)
69   {
70     dndImpl->CallSourceEvent(Dali::DragAndDrop::SourceEventType::CANCEL);
71   }
72   else
73   {
74     dndImpl->CallSourceEvent(Dali::DragAndDrop::SourceEventType::ACCEPT);
75   }
76
77   return ECORE_CALLBACK_PASS_ON;
78 }
79
80 static Eina_Bool EcoreEventDataSourceDrop(void* data, int type, void* event)
81 {
82   DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
83   dndImpl->CallSourceEvent(Dali::DragAndDrop::SourceEventType::FINISH);
84   return ECORE_CALLBACK_PASS_ON;
85 }
86
87 static Eina_Bool EcoreEventOfferDataReady(void* data, int type, void* event)
88 {
89   DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
90   dndImpl->ReceiveData(event);
91
92   return ECORE_CALLBACK_PASS_ON;
93 }
94
95 static Eina_Bool EcoreEventDataMotion(void* data, int type, void* event)
96 {
97   DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
98   dndImpl->CalculateDragEvent(event);
99
100   return ECORE_CALLBACK_PASS_ON;
101 }
102
103 static Eina_Bool EcoreEventDataDrop(void* data, int type, void* event)
104 {
105   DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
106   dndImpl->CalculateViewRegion(event);
107
108   return ECORE_CALLBACK_PASS_ON;
109 }
110
111 static Eina_Bool EcoreEventDataEnter(void* data, int type, void* event)
112 {
113   Ecore_Wl2_Event_Dnd_Enter* ev = reinterpret_cast<Ecore_Wl2_Event_Dnd_Enter*>(event);
114
115   // Set default offer is reject
116   ecore_wl2_offer_accept(ev->offer, NULL);
117   return ECORE_CALLBACK_PASS_ON;
118 }
119
120 static Eina_Bool EcoreEventDataLeave(void* data, int type, void* event)
121 {
122   DragAndDropEcoreWl* dndImpl = reinterpret_cast<DragAndDropEcoreWl*>(data);
123   dndImpl->ResetDropTargets();
124
125   return ECORE_CALLBACK_PASS_ON;
126 }
127
128 Dali::DragAndDrop GetDragAndDrop()
129 {
130   Dali::DragAndDrop dnd;
131
132   Dali::SingletonService service(SingletonService::Get());
133   if(service)
134   {
135     // Check whether the singleton is already created
136     Dali::BaseHandle handle = service.GetSingleton(typeid(Dali::DragAndDrop));
137     if(handle)
138     {
139       // If so, downcast the handle
140       dnd = Dali::DragAndDrop(dynamic_cast<DragAndDrop*>(handle.GetObjectPtr()));
141     }
142     else
143     {
144       // Create a singleon instance
145       DragAndDropEcoreWl* dndImpl = new DragAndDropEcoreWl();
146
147       dnd = Dali::DragAndDrop(dndImpl);
148       service.Register(typeid(Dali::DragAndDrop), dnd);
149     }
150   }
151
152   return dnd;
153 }
154
155 DragAndDropEcoreWl::DragAndDropEcoreWl()
156 {
157   // Source Events
158   mSendHandler       = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, this);
159   mSourceEndHandler  = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_END, EcoreEventDataSourceEnd, this);
160   mSourceDropHandler = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_DROP, EcoreEventDataSourceDrop, this);
161
162   // Target Events
163   mReceiveHandler = ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY, EcoreEventOfferDataReady, this);
164   mMotionHandler  = ecore_event_handler_add(ECORE_WL2_EVENT_DND_MOTION, EcoreEventDataMotion, this);
165   mDropHandler    = ecore_event_handler_add(ECORE_WL2_EVENT_DND_DROP, EcoreEventDataDrop, this);
166   mEnterHandler   = ecore_event_handler_add(ECORE_WL2_EVENT_DND_ENTER, EcoreEventDataEnter, this);
167   mLeaveHandler   = ecore_event_handler_add(ECORE_WL2_EVENT_DND_LEAVE, EcoreEventDataLeave, this);
168 }
169
170 DragAndDropEcoreWl::~DragAndDropEcoreWl()
171 {
172   // Source Events
173   ecore_event_handler_del(mSendHandler);
174   ecore_event_handler_del(mSourceEndHandler);
175   ecore_event_handler_del(mSourceDropHandler);
176
177   // Target Events
178   ecore_event_handler_del(mReceiveHandler);
179   ecore_event_handler_del(mMotionHandler);
180   ecore_event_handler_del(mDropHandler);
181   ecore_event_handler_del(mEnterHandler);
182 }
183
184 bool DragAndDropEcoreWl::StartDragAndDrop(Dali::Actor source, Dali::Window shadowWindow, const Dali::DragAndDrop::DragData& data, Dali::DragAndDrop::SourceFunction callback)
185 {
186   // Get Parent Window
187   auto parent = Dali::DevelWindow::Get(source);
188
189   // Set Drag Source Data
190   mMimeType = data.GetMimeType();
191   mData     = data.GetData();
192
193   // Set Source Event
194   mSourceCallback = callback;
195
196   // Set Drag Window
197   mDragWindow = shadowWindow;
198
199   // Start Drag and Drop
200   Ecore_Wl2_Window*  parentWindow = AnyCast<Ecore_Wl2_Window*>(parent.GetNativeHandle());
201   Ecore_Wl2_Window*  dragWindow   = AnyCast<Ecore_Wl2_Window*>(mDragWindow.GetNativeHandle());
202   Ecore_Wl2_Display* display      = ecore_wl2_connected_display_get(NULL);
203   Ecore_Wl2_Input*   input        = ecore_wl2_input_default_input_get(display);
204
205   // Set mime type for drag and drop
206   const char* mimeTypes[2];
207   mimeTypes[0] = mMimeType.c_str();
208   mimeTypes[1] = NULL;
209
210   // Set mime type
211   ecore_wl2_dnd_drag_types_set(input, (const char**)mimeTypes);
212
213   // Start wayland drag and drop
214   mSerial = ecore_wl2_dnd_drag_start(input, parentWindow, dragWindow);
215
216   // Call Start Event
217   CallSourceEvent(Dali::DragAndDrop::SourceEventType::START);
218
219   return true;
220 }
221
222 bool DragAndDropEcoreWl::AddListener(Dali::Actor target, Dali::DragAndDrop::DragAndDropFunction callback)
223 {
224   std::vector<DropTarget>::iterator itr;
225   for(itr = mDropTargets.begin(); itr < mDropTargets.end(); itr++)
226   {
227     if((*itr).target == target)
228     {
229       return false;
230     }
231   }
232
233   auto window = Dali::DevelWindow::Get(target);
234
235   int parentWindowId = INVALID_ECORE_WL2_WINDOW_ID;
236
237   if(!window)
238   {
239     // Target is stil not scene-on
240     // Add dummy target data, and wait until target is on scene.
241     target.OnSceneSignal().Connect(this, &DragAndDropEcoreWl::DropTargetSceneOn);
242   }
243   else
244   {
245     Ecore_Wl2_Window* parentWindow = AnyCast<Ecore_Wl2_Window*>(window.GetNativeHandle());
246     if(parentWindow == nullptr)
247     {
248       return false;
249     }
250     parentWindowId = ecore_wl2_window_id_get(parentWindow);
251   }
252
253   DropTarget targetData;
254   targetData.target         = target;
255   targetData.callback       = callback;
256   targetData.inside         = false;
257   targetData.parentWindowId = parentWindowId;
258
259   mDropTargets.push_back(targetData);
260
261   return true;
262 }
263
264 bool DragAndDropEcoreWl::AddListener(Dali::Window target, Dali::DragAndDrop::DragAndDropFunction callback)
265 {
266   std::vector<DropWindowTarget>::iterator itr;
267   for(itr = mDropWindowTargets.begin(); itr < mDropWindowTargets.end(); itr++)
268   {
269     if((*itr).target == target)
270     {
271       return false;
272     }
273   }
274
275   int windowId = INVALID_ECORE_WL2_WINDOW_ID;
276
277   Ecore_Wl2_Window* window = AnyCast<Ecore_Wl2_Window*>(target.GetNativeHandle());
278   if(window == nullptr)
279   {
280     return false;
281   }
282   windowId = ecore_wl2_window_id_get(window);
283
284   DropWindowTarget targetData;
285   targetData.target   = target;
286   targetData.callback = callback;
287   targetData.inside   = false;
288   targetData.windowId = windowId;
289
290   mDropWindowTargets.push_back(targetData);
291
292   return true;
293 }
294
295 bool DragAndDropEcoreWl::RemoveListener(Dali::Actor target)
296 {
297   std::vector<DropTarget>::iterator itr;
298   for(itr = mDropTargets.begin(); itr < mDropTargets.end(); itr++)
299   {
300     if((*itr).target == target)
301     {
302       mDropTargets.erase(itr);
303       break;
304     }
305   }
306
307   return true;
308 }
309
310 bool DragAndDropEcoreWl::RemoveListener(Dali::Window target)
311 {
312   std::vector<DropWindowTarget>::iterator itr;
313   for(itr = mDropWindowTargets.begin(); itr < mDropWindowTargets.end(); itr++)
314   {
315     if((*itr).target == target)
316     {
317       mDropWindowTargets.erase(itr);
318       break;
319     }
320   }
321
322   return true;
323 }
324
325 void DragAndDropEcoreWl::CallSourceEvent(Dali::DragAndDrop::SourceEventType type)
326 {
327   if(mSourceCallback)
328   {
329     mSourceCallback(type);
330     if(type != Dali::DragAndDrop::SourceEventType::START)
331     {
332        mDragWindow.Reset();
333     }
334   }
335 }
336
337 void DragAndDropEcoreWl::ResetDropTargets()
338 {
339   for(std::size_t i = 0; i < mDropTargets.size(); i++)
340   {
341     if(mDropTargets[i].inside)
342     {
343       Dali::DragAndDrop::DragEvent dragEvent;
344       dragEvent.SetAction(Dali::DragAndDrop::DragType::LEAVE);
345       Dali::Vector2 position(DEFAULT_POSITION, DEFAULT_POSITION);
346       dragEvent.SetPosition(position);
347       mDropTargets[i].callback(dragEvent);
348     }
349     mDropTargets[i].inside = false;
350   }
351
352   for(std::size_t i = 0; i < mDropWindowTargets.size(); i++)
353   {
354     if(mDropWindowTargets[i].inside)
355     {
356       Dali::DragAndDrop::DragEvent dragEvent;
357       dragEvent.SetAction(Dali::DragAndDrop::DragType::LEAVE);
358       Dali::Vector2 position(DEFAULT_POSITION, DEFAULT_POSITION);
359       dragEvent.SetPosition(position);
360       mDropWindowTargets[i].callback(dragEvent);
361     }
362     mDropWindowTargets[i].inside = false;
363   }
364 }
365
366 void DragAndDropEcoreWl::SendData(void* event)
367 {
368   Ecore_Wl2_Event_Data_Source_Send* ev = reinterpret_cast<Ecore_Wl2_Event_Data_Source_Send*>(event);
369   if(ev->serial != mSerial)
370   {
371     return;
372   }
373
374   int dataLength = strlen(mData.c_str());
375   int bufferSize = dataLength;
376   if((mMimeType.find("text") != std::string::npos) ||
377      (mMimeType.find("markup") != std::string::npos) ||
378      (mMimeType.find("image") != std::string::npos))
379   {
380     bufferSize += 1;
381   }
382
383   char* buffer = new char[bufferSize];
384   if(!buffer)
385   {
386     return;
387   }
388
389   memcpy(buffer, mData.c_str(), dataLength);
390   buffer[dataLength] = '\0';
391
392   auto ret = write(ev->fd, buffer, bufferSize);
393   if(DALI_UNLIKELY(ret != bufferSize))
394   {
395     DALI_LOG_ERROR("write(ev->fd) return %d! Pleacse check it\n", static_cast<int>(ret));
396   }
397
398   close(ev->fd);
399
400   if(mDragWindow)
401   {
402     mDragWindow.Hide();
403   }
404
405   delete[] buffer;
406 }
407
408 void DragAndDropEcoreWl::ReceiveData(void* event)
409 {
410   Ecore_Wl2_Event_Offer_Data_Ready* ev = reinterpret_cast<Ecore_Wl2_Event_Offer_Data_Ready*>(event);
411
412   if(mTargetIndex != -1)
413   {
414     Dali::DragAndDrop::DragEvent dragEvent(Dali::DragAndDrop::DragType::DROP, mPosition, ev->mimetype, ev->data);
415     mDropTargets[mTargetIndex].callback(dragEvent);
416     mDropTargets[mTargetIndex].inside = false;
417   }
418   mTargetIndex = -1;
419
420   if(mWindowTargetIndex != -1)
421   {
422     Dali::DragAndDrop::DragEvent dragEvent(Dali::DragAndDrop::DragType::DROP, mWindowPosition, ev->mimetype, ev->data);
423     mDropWindowTargets[mWindowTargetIndex].callback(dragEvent);
424     mDropWindowTargets[mWindowTargetIndex].inside = false;
425   }
426   mWindowTargetIndex = -1;
427
428 }
429
430 Vector2 DragAndDropEcoreWl::RecalculatePositionByOrientation(int x, int y, Dali::Window window)
431 {
432   int screenWidth, screenHeight;
433   Internal::Adaptor::WindowSystem::GetScreenSize(screenWidth, screenHeight);
434   int angle = DevelWindow::GetPhysicalOrientation(window);
435
436   int newX, newY;
437   Dali::Vector2 newPosition;
438
439   if(angle == 90)
440   {
441     newX = screenHeight - y;
442     newY = x;
443   }
444   else if(angle == 180)
445   {
446     newX = screenWidth - x;
447     newY = screenHeight - y;
448   }
449   else if(angle == 270)
450   {
451     newX = y;
452     newY = screenWidth - x;
453   }
454   else
455   {
456     newX = x;
457     newY = y;
458   }
459
460   newPosition.x = newX;
461   newPosition.y = newY;
462
463   return newPosition;
464 }
465
466 bool DragAndDropEcoreWl::CalculateDragEvent(void* event)
467 {
468   Ecore_Wl2_Event_Dnd_Motion* ev = reinterpret_cast<Ecore_Wl2_Event_Dnd_Motion*>(event);
469
470   Dali::DragAndDrop::DragEvent dragEvent;
471   Dali::Vector2                curPosition(ev->x, ev->y);
472
473   for(std::size_t i = 0; i < mDropTargets.size(); i++)
474   {
475     if(ev->win != mDropTargets[i].parentWindowId)
476     {
477       continue;
478     }
479
480     Vector2 position      = mDropTargets[i].target.GetProperty<Vector2>(Dali::Actor::Property::SCREEN_POSITION);
481     Vector2 size          = mDropTargets[i].target.GetProperty<Vector2>(Dali::Actor::Property::SIZE);
482
483     // Recalculate Cursor by Orientation
484     Dali::Window window = Dali::DevelWindow::Get(mDropTargets[i].target);
485     Dali::Vector2 cursor = RecalculatePositionByOrientation(ev->x, ev->y, window);
486
487     bool currentInside = IsIntersection(cursor.x, cursor.y, position.x, position.y, size.width, size.height);
488
489     // Calculate Drag Enter, Leave, Move Event
490     if(currentInside && !mDropTargets[i].inside)
491     {
492       mDropTargets[i].inside = true;
493       // Call Enter Event
494       dragEvent.SetAction(Dali::DragAndDrop::DragType::ENTER);
495       dragEvent.SetPosition(curPosition);
496       mDropTargets[i].callback(dragEvent);
497       // Accept Offer
498       ecore_wl2_offer_mimes_set(ev->offer, ecore_wl2_offer_mimes_get(ev->offer));
499     }
500     else if(!currentInside && mDropTargets[i].inside)
501     {
502       mDropTargets[i].inside = false;
503       // Call Leave Event
504       dragEvent.SetAction(Dali::DragAndDrop::DragType::LEAVE);
505       dragEvent.SetPosition(curPosition);
506       mDropTargets[i].callback(dragEvent);
507       // Reject Offer
508       ecore_wl2_offer_accept(ev->offer, NULL);
509     }
510     else if(currentInside && mDropTargets[i].inside)
511     {
512       // Call Move Event
513       dragEvent.SetAction(Dali::DragAndDrop::DragType::MOVE);
514       dragEvent.SetPosition(curPosition);
515       mDropTargets[i].callback(dragEvent);
516     }
517   }
518
519   for(std::size_t i = 0; i < mDropWindowTargets.size(); i++)
520   {
521     if(ev->win != mDropWindowTargets[i].windowId)
522     {
523       continue;
524     }
525
526     // Recalculate Cursor by Orientation
527     Dali::Window window = mDropWindowTargets[i].target;
528     Dali::Window::WindowPosition position = window.GetPosition();
529     Dali::Window::WindowSize size = window.GetSize();
530
531     bool currentInside = IsIntersection(ev->x + position.GetX(), ev->y + position.GetY(), position.GetX(), position.GetY(), size.GetWidth(), size.GetHeight());
532
533     // Calculate Drag Enter, Leave, Move Event
534     if(currentInside && !mDropWindowTargets[i].inside)
535     {
536       mDropWindowTargets[i].inside = true;
537       // Call Enter Event
538       dragEvent.SetAction(Dali::DragAndDrop::DragType::ENTER);
539       dragEvent.SetPosition(curPosition);
540       mDropWindowTargets[i].callback(dragEvent);
541       // Accept Offer
542       ecore_wl2_offer_mimes_set(ev->offer, ecore_wl2_offer_mimes_get(ev->offer));
543     }
544     else if(!currentInside && mDropWindowTargets[i].inside)
545     {
546       mDropWindowTargets[i].inside = false;
547       // Call Leave Event
548       dragEvent.SetAction(Dali::DragAndDrop::DragType::LEAVE);
549       dragEvent.SetPosition(curPosition);
550       mDropWindowTargets[i].callback(dragEvent);
551       // Reject Offer
552       ecore_wl2_offer_accept(ev->offer, NULL);
553     }
554     else if(currentInside && mDropWindowTargets[i].inside)
555     {
556       // Call Move Event
557       dragEvent.SetAction(Dali::DragAndDrop::DragType::MOVE);
558       dragEvent.SetPosition(curPosition);
559       mDropWindowTargets[i].callback(dragEvent);
560     }
561   }
562
563   return true;
564 }
565
566 bool DragAndDropEcoreWl::CalculateViewRegion(void* event)
567 {
568   Ecore_Wl2_Event_Dnd_Drop* ev = reinterpret_cast<Ecore_Wl2_Event_Dnd_Drop*>(event);
569
570   // Check the target object region
571   mTargetIndex = -1;
572   mWindowTargetIndex = -1;
573
574   for(std::size_t i = 0; i < mDropTargets.size(); i++)
575   {
576     if(ev->win != mDropTargets[i].parentWindowId)
577     {
578       continue;
579     }
580
581     Vector2 position = mDropTargets[i].target.GetProperty<Vector2>(Dali::Actor::Property::SCREEN_POSITION);
582     Vector2 size     = mDropTargets[i].target.GetProperty<Vector2>(Dali::Actor::Property::SIZE);
583
584     // Recalculate Cursor by Orientation
585     Dali::Window window = Dali::DevelWindow::Get(mDropTargets[i].target);
586     Dali::Vector2 cursor = RecalculatePositionByOrientation(ev->x, ev->y, window);
587
588     // If the drop position is in the target object region, request drop data to the source object
589     if(IsIntersection(cursor.x, cursor.y, position.x, position.y, size.width, size.height))
590     {
591       mTargetIndex        = i;
592       mPosition           = position;
593       Dali::Window window = Dali::DevelWindow::Get(mDropTargets[i].target);
594
595       char* mimetype = (char*)eina_array_data_get(ecore_wl2_offer_mimes_get(ev->offer), 0);
596       if(mimetype)
597       {
598         ecore_wl2_offer_receive(ev->offer, mimetype);
599         Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL);
600         Ecore_Wl2_Input*   input   = ecore_wl2_input_default_input_get(display);
601         ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
602       }
603       return true;
604     }
605   }
606
607   for(std::size_t i = 0; i < mDropWindowTargets.size(); i++)
608   {
609     if(ev->win != mDropWindowTargets[i].windowId)
610     {
611       continue;
612     }
613
614     // Recalculate Cursor by Orientation
615     Dali::Window window = mDropWindowTargets[i].target;
616     Dali::Window::WindowPosition position = window.GetPosition();
617     Dali::Window::WindowSize size = window.GetSize();
618
619     // If the drop position is in the target object region, request drop data to the source object
620     if(IsIntersection(ev->x + position.GetX(), ev->y + position.GetY(), position.GetX(), position.GetY(), size.GetWidth(), size.GetHeight()))
621     {
622       mWindowTargetIndex = i;
623       mWindowPosition  = Dali::Vector2(position.GetX(), position.GetY());
624
625       char* mimetype = (char*)eina_array_data_get(ecore_wl2_offer_mimes_get(ev->offer), 0);
626       if(mimetype)
627       {
628         ecore_wl2_offer_receive(ev->offer, mimetype);
629         Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL);
630         Ecore_Wl2_Input*   input   = ecore_wl2_input_default_input_get(display);
631         ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
632       }
633       return true;
634     }
635   }
636
637   return false;
638 }
639
640 void DragAndDropEcoreWl::DropTargetSceneOn(Dali::Actor target)
641 {
642   // Disconnect scene on signal
643   target.OnSceneSignal().Disconnect(this, &DragAndDropEcoreWl::DropTargetSceneOn);
644
645   for(auto iter = mDropTargets.begin(), iterEnd = mDropTargets.end(); iter != iterEnd; iter++)
646   {
647     if((*iter).target == target)
648     {
649       auto window = Dali::DevelWindow::Get(target);
650
651       Ecore_Wl2_Window* parentWindow = AnyCast<Ecore_Wl2_Window*>(window.GetNativeHandle());
652       if(parentWindow == nullptr)
653       {
654         return;
655       }
656
657       (*iter).parentWindowId = ecore_wl2_window_id_get(parentWindow);
658       break;
659     }
660   }
661 }
662
663 } // namespace Adaptor
664
665 } // namespace Internal
666
667 } // namespace Dali