| 509 | } |
| 510 | |
| 511 | void ClipboardGetFiles(Array<String>& result, X11::Atom source, X11::Atom atom, X11::Window window) |
| 512 | { |
| 513 | X11::Window selectionOwner = X11::XGetSelectionOwner(xDisplay, source); |
| 514 | if (selectionOwner == 0) |
| 515 | { |
| 516 | // No copy owner |
| 517 | return; |
| 518 | } |
| 519 | if (selectionOwner == window) |
| 520 | { |
| 521 | // Copy/paste from self |
| 522 | result.Clear(); |
| 523 | for (auto file : ClipboardFiles) |
| 524 | result.Add(String(file)); |
| 525 | return; |
| 526 | } |
| 527 | |
| 528 | // Send event to get data from the owner |
| 529 | int format; |
| 530 | unsigned long N, size; |
| 531 | char* data; |
| 532 | X11::Atom target; |
| 533 | X11::XEvent event; |
| 534 | X11::XConvertSelection(xDisplay, xAtomClipboard, atom, xAtomXselData, window, CurrentTime); |
| 535 | X11::XSync(xDisplay, 0); |
| 536 | if (X11::XCheckTypedEvent(xDisplay, SelectionNotify, &event)) |
| 537 | { |
| 538 | if (event.xselection.selection != xAtomClipboard) |
| 539 | return; |
| 540 | if (event.xselection.property) |
| 541 | { |
| 542 | X11::XGetWindowProperty(event.xselection.display, event.xselection.requestor, event.xselection.property, 0L, (~0L), 0, AnyPropertyType, &target, &format, &size, &N, (unsigned char**)&data); |
| 543 | if (target == atom) |
| 544 | { |
| 545 | String filesString(StringAnsi(data, size)); |
| 546 | filesString.Split('\n', result); |
| 547 | for (auto& file : result) |
| 548 | { |
| 549 | if (file.StartsWith(TEXT("file://"))) |
| 550 | file = file.Substring(7); |
| 551 | file = file.TrimTrailing(); // Trim '\r' |
| 552 | } |
| 553 | X11::XFree(data); |
| 554 | } |
| 555 | X11::XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property); |
| 556 | } |
| 557 | } |
| 558 | } |
| 559 | |
| 560 | Property ReadProperty(X11::Display* display, X11::Window window, X11::Atom property) |
| 561 | { |
no test coverage detected