mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-05-04 03:40:32 +00:00
Fix clipboard threading crash
This commit is contained in:
@@ -2,6 +2,7 @@ package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.util.GlobalClipboard;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.util.FailableRunnable;
|
||||
@@ -23,6 +24,7 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BrowserClipboard {
|
||||
@@ -32,44 +34,33 @@ public class BrowserClipboard {
|
||||
private static final DataFormat DATA_FORMAT = new DataFormat("application/xpipe-file-list");
|
||||
|
||||
static {
|
||||
Toolkit.getDefaultToolkit()
|
||||
.getSystemClipboard()
|
||||
.addFlavorListener(e -> ThreadHelper.runFailableAsync(new FailableRunnable<>() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void run() {
|
||||
// Fix clipboard open issues: https://stackoverflow.com/a/51797746
|
||||
ThreadHelper.sleep(20);
|
||||
|
||||
Clipboard clipboard = (Clipboard) e.getSource();
|
||||
try {
|
||||
if (!clipboard.isDataFlavorAvailable(DataFlavor.javaFileListFlavor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<File> data = (List<File>) clipboard.getData(DataFlavor.javaFileListFlavor);
|
||||
// Sometimes file data can contain invalid chars. Why?
|
||||
var files = data.stream()
|
||||
.filter(file ->
|
||||
file.toString().chars().noneMatch(value -> Character.isISOControl(value)))
|
||||
.map(f -> f.toPath())
|
||||
.toList();
|
||||
if (files.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var entries = new ArrayList<BrowserEntry>();
|
||||
for (Path file : files) {
|
||||
entries.add(BrowserLocalFileSystem.getLocalBrowserEntry(file));
|
||||
}
|
||||
|
||||
currentCopyClipboard.setValue(
|
||||
new Instance(UUID.randomUUID(), null, entries, BrowserFileTransferMode.COPY));
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).expected().omit().handle();
|
||||
}
|
||||
GlobalClipboard.addListener(new Consumer<>() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void accept(Clipboard clipboard) {
|
||||
try {
|
||||
if (!clipboard.isDataFlavorAvailable(DataFlavor.javaFileListFlavor)) {
|
||||
return;
|
||||
}
|
||||
}));
|
||||
|
||||
List<File> data = (List<File>) clipboard.getData(DataFlavor.javaFileListFlavor);
|
||||
// Sometimes file data can contain invalid chars. Why?
|
||||
var files = data.stream().filter(file -> file.toString().chars().noneMatch(value -> Character.isISOControl(value))).map(f -> f.toPath()).toList();
|
||||
if (files.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var entries = new ArrayList<BrowserEntry>();
|
||||
for (Path file : files) {
|
||||
entries.add(BrowserLocalFileSystem.getLocalBrowserEntry(file));
|
||||
}
|
||||
|
||||
currentCopyClipboard.setValue(new Instance(UUID.randomUUID(), null, entries, BrowserFileTransferMode.COPY));
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).expected().omit().handle();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
|
||||
@@ -122,7 +122,7 @@ public class ContextualFileReferenceChoiceComp extends Comp<CompStructure<HBox>>
|
||||
var pubSource = Path.of(source + ".pub");
|
||||
if (Files.exists(pubSource)) {
|
||||
var pubTarget = sync.getTargetLocation().apply(pubSource);
|
||||
DataStorageSyncHandler.getInstance()
|
||||
handler
|
||||
.addDataFile(
|
||||
pubSource, pubTarget, sync.getPerUser().test(pubSource));
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ public abstract class OperationMode {
|
||||
TrackEvent.info("Initial setup");
|
||||
AppMainWindow.loadingText("initializingApp");
|
||||
GlobalTimer.init();
|
||||
GlobalClipboard.init();
|
||||
AppProperties.init(args);
|
||||
NodeCallback.init();
|
||||
AppLogs.init();
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileTransferMode;
|
||||
import io.xpipe.app.browser.file.BrowserLocalFileSystem;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.util.FailableRunnable;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.input.DataFormat;
|
||||
import javafx.scene.input.Dragboard;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.Value;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GlobalClipboard {
|
||||
|
||||
private static final List<Consumer<Clipboard>> clipboardListeners = new ArrayList<>();
|
||||
|
||||
public static synchronized void addListener(Consumer<Clipboard> listener) {
|
||||
clipboardListeners.add(listener);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
// Only access from one thread to fix https://bugs.openjdk.org/browse/JDK-8332271
|
||||
Toolkit.getDefaultToolkit()
|
||||
.getSystemClipboard()
|
||||
.addFlavorListener(e -> {
|
||||
// Fix clipboard open issues: https://stackoverflow.com/a/51797746
|
||||
ThreadHelper.sleep(20);
|
||||
|
||||
var cp = (Clipboard) e.getSource();
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
synchronized (GlobalClipboard.class) {
|
||||
for (Consumer<Clipboard> clipboardListener : clipboardListeners) {
|
||||
clipboardListener.accept(cp);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user