From 9e474fb8fe76b02960b3743e31015018e8666b7f Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal002@users.noreply.github.com> Date: Thu, 10 Aug 2023 17:44:07 +0200 Subject: Better Clipboard (#378) Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../at/hannibal2/skyhanni/utils/ClipboardUtils.kt | 83 ++++++++++++++++++++++ .../java/at/hannibal2/skyhanni/utils/OSUtils.kt | 21 +----- 2 files changed, 85 insertions(+), 19 deletions(-) create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt (limited to 'src/main/java/at/hannibal2/skyhanni/utils') diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt new file mode 100644 index 000000000..a7585702f --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/ClipboardUtils.kt @@ -0,0 +1,83 @@ +package at.hannibal2.skyhanni.utils + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.test.command.CopyErrorCommand +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.awt.Toolkit +import java.awt.datatransfer.Clipboard +import java.awt.datatransfer.DataFlavor +import java.awt.datatransfer.StringSelection +import java.awt.datatransfer.UnsupportedFlavorException +import java.util.* +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds + +object ClipboardUtils { + private var lastClipboardAccessTime = SimpleTimeMark.farPast() + + private fun canAccessClibpard(): Boolean { + val result = lastClipboardAccessTime.passedSince() > 10.milliseconds + if (result) { + lastClipboardAccessTime = SimpleTimeMark.now() + } + return result + } + + private fun runDelayed(duration: Duration, runnable: () -> Unit) { + Timer().schedule(object : TimerTask() { + override fun run() { + runnable() + } + }, duration.inWholeMilliseconds) + } + + private suspend fun getClipboard(): Clipboard? { + val deferred = CompletableDeferred() + if (canAccessClibpard()) { + deferred.complete(Toolkit.getDefaultToolkit().systemClipboard) + } else { + runDelayed(5.milliseconds) { + SkyHanniMod.coroutineScope.launch { + deferred.complete(getClipboard()) + } + } + } + return deferred.await() + } + + fun copyToClipboard(text: String, step: Int = 0) { + SkyHanniMod.coroutineScope.launch { + try { + getClipboard()?.setContents(StringSelection(text), null) + } catch (e: Exception) { + if (step == 3) { + CopyErrorCommand.logError(e, "Error while trying to access the clipboard.") + } else { + copyToClipboard(text, step + 1) + } + } + } + } + + suspend fun readFromClipboard(step: Int = 0): String? { + try { + return try { + withContext(Dispatchers.IO) { + getClipboard()?.getData(DataFlavor.stringFlavor)?.toString() + } + } catch (e: UnsupportedFlavorException) { + null + } + } catch (e: Exception) { + return if (step == 3) { + CopyErrorCommand.logError(e, "Error while trying to access the clipboard.") + null + } else { + readFromClipboard(step + 1) + } + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt index 9c56d142f..254d8ad09 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt @@ -1,13 +1,8 @@ package at.hannibal2.skyhanni.utils -import at.hannibal2.skyhanni.test.command.CopyErrorCommand import net.minecraft.client.settings.KeyBinding import org.lwjgl.input.Keyboard import java.awt.Desktop -import java.awt.Toolkit -import java.awt.datatransfer.DataFlavor -import java.awt.datatransfer.StringSelection -import java.awt.datatransfer.UnsupportedFlavorException import java.io.IOException import java.net.URI @@ -29,22 +24,10 @@ object OSUtils { } fun copyToClipboard(text: String) { - try { - Toolkit.getDefaultToolkit().systemClipboard.setContents(StringSelection(text), null) - } catch (e: Exception) { - CopyErrorCommand.logError(e, "Error while trying to set clipboard content.") - } + ClipboardUtils.copyToClipboard(text) } - fun readFromClipboard(): String? { - val systemClipboard = Toolkit.getDefaultToolkit().systemClipboard ?: return null - try { - val data = systemClipboard.getData(DataFlavor.stringFlavor) ?: return null - return data.toString() - } catch (e: UnsupportedFlavorException) { - return null - } - } + suspend fun readFromClipboard() = ClipboardUtils.readFromClipboard() fun KeyBinding.isActive(): Boolean { if (!Keyboard.isCreated()) return false -- cgit