Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Turning off listening to the pasteboard does not turn it on again #1256

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,74 +6,31 @@ import com.clipevery.dao.clip.ClipDao
import com.clipevery.dao.clip.ClipData
import io.github.oshai.kotlinlogging.KLogger
import kotlinx.coroutines.channels.Channel
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.ClipboardOwner
import java.awt.datatransfer.Transferable

interface ClipboardService : ClipboardMonitor, ClipboardOwner {

val logger: KLogger

var owner: Boolean

var ownerTransferable: Transferable?

val systemClipboard: Clipboard

val appWindowManager: AppWindowManager

val clipDao: ClipDao

val configManager: ConfigManager

val clipConsumer: TransferableConsumer

val clipProducer: TransferableProducer

val clipboardChannel: Channel<suspend () -> Unit>

fun isValidContents(contents: Transferable?): Boolean {
return contents != null && contents.transferDataFlavors.isNotEmpty()
}

fun getClipboardContentsBySafe(): Transferable? {
return try {
systemClipboard.getContents(null)
} catch (e: Exception) {
logger.error(e) { "getContentsBySafe error" }
null
}
}

suspend fun tryWriteClipboard(
clipData: ClipData,
localOnly: Boolean = false,
filterFile: Boolean = false,
) {
try {
clipProducer.produce(clipData, localOnly, filterFile)?.let {
ownerTransferable = it
owner = true
systemClipboard.setContents(ownerTransferable, this)
}
} catch (e: Exception) {
logger.error(e) { "tryWriteClipboard error" }
}
}
)

suspend fun tryWriteRemoteClipboard(clipData: ClipData) {
clipDao.releaseRemoteClipData(clipData) { storeClipData, filterFile ->
clipboardChannel.trySend { tryWriteClipboard(storeClipData, localOnly = true, filterFile = filterFile) }
}
}
suspend fun tryWriteRemoteClipboard(clipData: ClipData)

suspend fun tryWriteRemoteClipboardWithFile(clipData: ClipData) {
clipDao.releaseRemoteClipDataWithFile(clipData.id) { storeClipData ->
clipboardChannel.trySend { tryWriteClipboard(storeClipData, localOnly = true, filterFile = false) }
}
}
suspend fun tryWriteRemoteClipboardWithFile(clipData: ClipData)

suspend fun clearRemoteClipboard(clipData: ClipData) {
clipDao.markDeleteClipData(clipData.id)
}
suspend fun clearRemoteClipboard(clipData: ClipData)
}
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ fun SettingsView(currentPageViewContext: MutableState<PageViewContext>) {
.height(20.dp),
checked = enableClipboardListening,
onCheckedChange = {
enableClipboardListening = it
clipboardService.toggle()
enableClipboardListening = configManager.config.enableClipboardListening
},
)
}
Expand Down
4 changes: 3 additions & 1 deletion composeApp/src/desktopMain/kotlin/com/clipevery/Clipevery.kt
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,9 @@ class Clipevery {
try {
val pair = koinApplication.koin.get<AppLock>().acquireLock()
if (pair.first) {
koinApplication.koin.get<ClipboardService>().start()
if (koinApplication.koin.get<ConfigManager>().config.enableClipboardListening) {
koinApplication.koin.get<ClipboardService>().start()
}
koinApplication.koin.get<QRCodeGenerator>()
koinApplication.koin.get<ClipServer>().start()
koinApplication.koin.get<ClipClient>()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.clipevery.clip

import com.clipevery.dao.clip.ClipData
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.Transferable

abstract class AbstractClipboardService : ClipboardService {

abstract var ownerTransferable: Transferable?

abstract val systemClipboard: Clipboard

abstract val clipConsumer: TransferableConsumer

abstract val clipProducer: TransferableProducer

fun isValidContents(contents: Transferable?): Boolean {
return contents != null && contents.transferDataFlavors.isNotEmpty()
}

fun getClipboardContentsBySafe(): Transferable? {
return try {
systemClipboard.getContents(null)
} catch (e: Exception) {
logger.error(e) { "getContentsBySafe error" }
null
}
}

override suspend fun tryWriteClipboard(
clipData: ClipData,
localOnly: Boolean,
filterFile: Boolean,
) {
try {
clipProducer.produce(clipData, localOnly, filterFile)?.let {
ownerTransferable = it
owner = true
systemClipboard.setContents(ownerTransferable, this)
}
} catch (e: Exception) {
logger.error(e) { "tryWriteClipboard error" }
}
}

override suspend fun tryWriteRemoteClipboard(clipData: ClipData) {
clipDao.releaseRemoteClipData(clipData) { storeClipData, filterFile ->
clipboardChannel.trySend { tryWriteClipboard(storeClipData, localOnly = true, filterFile = filterFile) }
}
}

override suspend fun tryWriteRemoteClipboardWithFile(clipData: ClipData) {
clipDao.releaseRemoteClipDataWithFile(clipData.id) { storeClipData ->
clipboardChannel.trySend { tryWriteClipboard(storeClipData, localOnly = true, filterFile = false) }
}
}

override suspend fun clearRemoteClipboard(clipData: ClipData) {
clipDao.markDeleteClipData(clipData.id)
}

@Synchronized
override fun toggle() {
val enableClipboardListening = configManager.config.enableClipboardListening
if (enableClipboardListening) {
stop()
} else {
start()
}
configManager.updateConfig { it.copy(enableClipboardListening = !enableClipboardListening) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fun getDesktopClipboardService(
configManager: ConfigManager,
clipConsumer: TransferableConsumer,
clipProducer: TransferableProducer,
): ClipboardService {
): AbstractClipboardService {
val currentPlatform = currentPlatform()
return if (currentPlatform.isMacos()) {
MacosClipboardService(appWindowManager, clipDao, configManager, clipConsumer, clipProducer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class LinuxClipboardService(
override val configManager: ConfigManager,
override val clipConsumer: TransferableConsumer,
override val clipProducer: TransferableProducer,
) : ClipboardService {
) : AbstractClipboardService() {

companion object {
const val XFIXES_SET_SELECTION_OWNER_NOTIFY_MASK = (1 shl 0).toLong()
Expand Down Expand Up @@ -161,16 +161,6 @@ class LinuxClipboardService(
configManager.updateConfig { it.copy(lastClipboardChangeCount = changeCount) }
}

override fun toggle() {
val enableClipboardListening = configManager.config.enableClipboardListening
if (enableClipboardListening) {
stop()
} else {
start()
}
configManager.updateConfig { it.copy(enableClipboardListening = !enableClipboardListening) }
}

override fun lostOwnership(
clipboard: Clipboard?,
contents: Transferable?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class MacosClipboardService(
override val configManager: ConfigManager,
override val clipConsumer: TransferableConsumer,
override val clipProducer: TransferableProducer,
) : ClipboardService {
) : AbstractClipboardService() {
override val logger: KLogger = KotlinLogging.logger {}

private var changeCount = configManager.config.lastClipboardChangeCount
Expand Down Expand Up @@ -110,10 +110,8 @@ class MacosClipboardService(

@Synchronized
override fun start() {
if (configManager.config.enableClipboardListening) {
if (job?.isActive != true) {
job = run()
}
if (job?.isActive != true) {
job = run()
}
}

Expand All @@ -122,15 +120,4 @@ class MacosClipboardService(
job?.cancel()
configManager.updateConfig { it.copy(lastClipboardChangeCount = changeCount) }
}

@Synchronized
override fun toggle() {
val enableClipboardListening = configManager.config.enableClipboardListening
configManager.updateConfig { it.copy(enableClipboardListening = !enableClipboardListening) }
if (!enableClipboardListening) {
start()
} else {
stop()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class WindowsClipboardService(
override val configManager: ConfigManager,
override val clipConsumer: TransferableConsumer,
override val clipProducer: TransferableProducer,
) : ClipboardService, User32.WNDPROC {
) : AbstractClipboardService(), User32.WNDPROC {
override val logger: KLogger = KotlinLogging.logger {}

@Volatile
Expand Down Expand Up @@ -131,13 +131,11 @@ class WindowsClipboardService(
}

override fun start() {
if (configManager.config.enableClipboardListening) {
if (job?.isActive != true) {
job =
serviceScope.launch(CoroutineName("WindowsClipboardService")) {
run()
}
}
if (job?.isActive != true) {
job =
serviceScope.launch(CoroutineName("WindowsClipboardService")) {
run()
}
}
}

Expand All @@ -147,17 +145,6 @@ class WindowsClipboardService(
configManager.updateConfig { it.copy(lastClipboardChangeCount = changeCount) }
}

@Synchronized
override fun toggle() {
val enableClipboardListening = configManager.config.enableClipboardListening
if (enableClipboardListening) {
stop()
} else {
start()
}
configManager.updateConfig { it.copy(enableClipboardListening = !enableClipboardListening) }
}

private fun onChange() {
try {
val source =
Expand Down
Loading