| 739 | } |
| 740 | |
| 741 | DragDropEffect Window::DoDragDropX11(const StringView& data) |
| 742 | { |
| 743 | using namespace X11Impl; |
| 744 | auto cursorWrong = X11::XCreateFontCursor(xDisplay, 54); |
| 745 | auto cursorTransient = X11::XCreateFontCursor(xDisplay, 24); |
| 746 | auto cursorGood = X11::XCreateFontCursor(xDisplay, 4); |
| 747 | Array<X11::Atom, FixedAllocation<3>> formats; |
| 748 | formats.Add(X11::XInternAtom(xDisplay, "text/plain", 0)); |
| 749 | formats.Add(xAtomText); |
| 750 | formats.Add(xAtomString); |
| 751 | StringAnsi dataAnsi(data); |
| 752 | LinuxDropTextData dropData; |
| 753 | dropData.Text = data; |
| 754 | #if !PLATFORM_SDL |
| 755 | X11::Window mainWindow = _window; |
| 756 | #else |
| 757 | X11::Window mainWindow = reinterpret_cast<X11::Window>(GetNativePtr()); |
| 758 | #endif |
| 759 | |
| 760 | // Make sure SDL hasn't grabbed the pointer, and force ungrab it |
| 761 | XUngrabPointer(xDisplay, CurrentTime); |
| 762 | auto hintAutoCapture = SDL_GetHint(SDL_HINT_MOUSE_AUTO_CAPTURE); |
| 763 | SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0"); |
| 764 | |
| 765 | // Begin dragging |
| 766 | auto screen = X11::XDefaultScreen(xDisplay); |
| 767 | auto rootWindow = X11::XRootWindow(xDisplay, screen); |
| 768 | |
| 769 | if (X11::XGrabPointer(xDisplay, mainWindow, 1, Button1MotionMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, rootWindow, cursorWrong, CurrentTime) != GrabSuccess) |
| 770 | { |
| 771 | SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, hintAutoCapture); |
| 772 | return DragDropEffect::None; |
| 773 | } |
| 774 | X11::XSetSelectionOwner(xDisplay, xAtomXdndSelection, mainWindow, CurrentTime); |
| 775 | |
| 776 | // Process events |
| 777 | X11::XEvent event; |
| 778 | enum Status |
| 779 | { |
| 780 | Unaware, |
| 781 | Unreceptive, |
| 782 | CanDrop, |
| 783 | }; |
| 784 | int status = Unaware, previousVersion = -1; |
| 785 | X11::Window previousWindow = 0; |
| 786 | DragDropEffect result = DragDropEffect::None; |
| 787 | float lastDraw = Platform::GetTimeSeconds(); |
| 788 | float startTime = lastDraw; |
| 789 | while (true) |
| 790 | { |
| 791 | X11::XNextEvent(xDisplay, &event); |
| 792 | |
| 793 | // Hardcoded hack for SDL3 with X11 to end drag |
| 794 | if (event.type == XFixesSelectionNotifyEvent - 2) |
| 795 | break; |
| 796 | |
| 797 | if (event.type == GenericEvent) |
| 798 | { |
nothing calls this directly
no test coverage detected