Skip to content

Commit 5194fbc

Browse files
authored
✨ Add a switch to control whether to read pasteboard content set before application startup (#1877)
1 parent 5191d68 commit 5194fbc

File tree

11 files changed

+101
-28
lines changed

11 files changed

+101
-28
lines changed

composeApp/src/commonMain/kotlin/com/crosspaste/config/AppConfig.kt

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ data class AppConfig(
2121
val cleanupPercentage: Int = 20,
2222
val isAllowDiscovery: Boolean = true,
2323
val blacklist: String = "[]",
24+
val enableSkipPriorPasteboardContent: Boolean = true,
2425
val lastPasteboardChangeCount: Int = -1,
2526
val enablePasteboardListening: Boolean = true,
2627
val showTutorial: Boolean = true,
@@ -51,6 +52,12 @@ data class AppConfig(
5152
cleanupPercentage = if (key == "cleanupPercentage") value as Int else cleanupPercentage,
5253
isAllowDiscovery = if (key == "isAllowDiscovery") value as Boolean else isAllowDiscovery,
5354
blacklist = if (key == "blacklist") value as String else blacklist,
55+
enableSkipPriorPasteboardContent =
56+
if (key == "enableSkipPriorPasteboardContent") {
57+
value as Boolean
58+
} else {
59+
enableSkipPriorPasteboardContent
60+
},
5461
lastPasteboardChangeCount = if (key == "lastPasteboardChangeCount") value as Int else lastPasteboardChangeCount,
5562
enablePasteboardListening = if (key == "enablePasteboardListening") value as Boolean else enablePasteboardListening,
5663
showTutorial = if (key == "showTutorial") value as Boolean else showTutorial,

composeApp/src/commonMain/kotlin/com/crosspaste/ui/base/BaseIcon.kt

+5
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,8 @@ fun circle(): Painter {
123123
fun archive(): Painter {
124124
return painterResource("icon/base/archive.svg")
125125
}
126+
127+
@Composable
128+
fun skipForward(): Painter {
129+
return painterResource("icon/base/skip-forward.svg")
130+
}

composeApp/src/commonMain/kotlin/com/crosspaste/ui/settings/PasteboardSettingsView.kt

+27-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import com.crosspaste.i18n.GlobalCopywriter
3030
import com.crosspaste.ui.base.Counter
3131
import com.crosspaste.ui.base.CustomSwitch
3232
import com.crosspaste.ui.base.file
33+
import com.crosspaste.ui.base.skipForward
3334
import com.crosspaste.ui.base.sync
3435
import org.koin.compose.koinInject
3536

@@ -56,6 +57,31 @@ fun PasteboardSettingsView() {
5657
.clip(RoundedCornerShape(8.dp))
5758
.background(MaterialTheme.colors.background),
5859
) {
60+
SettingItemView(
61+
painter = skipForward(),
62+
text = "skip_prior_pasteboard_content",
63+
tint = Color(0xFFFF885B),
64+
) {
65+
var enableSkipPriorPasteboardContent by remember {
66+
mutableStateOf(
67+
configManager.config.enableSkipPriorPasteboardContent,
68+
)
69+
}
70+
71+
CustomSwitch(
72+
modifier =
73+
Modifier.width(32.dp)
74+
.height(20.dp),
75+
checked = enableSkipPriorPasteboardContent,
76+
onCheckedChange = { newEnableSkipPriorPasteboardContent ->
77+
configManager.updateConfig("enableSkipPriorPasteboardContent", newEnableSkipPriorPasteboardContent)
78+
enableSkipPriorPasteboardContent = configManager.config.enableSkipPriorPasteboardContent
79+
},
80+
)
81+
}
82+
83+
Divider(modifier = Modifier.padding(start = 35.dp))
84+
5985
SettingItemView(
6086
painter = file(),
6187
text = "max_back_up_file_size",
@@ -81,7 +107,7 @@ fun PasteboardSettingsView() {
81107
SettingItemView(
82108
painter = sync(),
83109
text = "sync_file_size_limit",
84-
tint = MaterialTheme.colors.onBackground,
110+
tint = Color(0xFF825B32),
85111
) {
86112
var enabledSyncFileSizeLimit by remember {
87113
mutableStateOf(
Loading

composeApp/src/desktopMain/kotlin/com/crosspaste/paste/LinuxPasteboardService.kt

+39-23
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ class LinuxPasteboardService(
6666

6767
private fun run(): Job {
6868
return serviceScope.launch(CoroutineName("LinuxPasteboardService")) {
69+
val firstChange = changeCount == configManager.config.lastPasteboardChangeCount
70+
71+
if (firstChange && !configManager.config.enableSkipPriorPasteboardContent) {
72+
onChange(this, true)
73+
}
74+
6975
val x11 = X11Api.INSTANCE
7076
x11.XOpenDisplay(null)?.let { display ->
7177
try {
@@ -106,29 +112,7 @@ class LinuxPasteboardService(
106112
if (selectionNotify.selection?.toLong() == clipboardAtom.toLong()) {
107113
logger.info { "notify change event" }
108114
changeCount++
109-
110-
val source =
111-
controlUtils.ensureMinExecutionTime(delayTime = 20) {
112-
appWindowManager.getCurrentActiveAppName()
113-
}
114-
115-
val contents =
116-
controlUtils.exponentialBackoffUntilValid(
117-
initTime = 20L,
118-
maxTime = 1000L,
119-
isValidResult = ::isValidContents,
120-
) {
121-
getPasteboardContentsBySafe()
122-
}
123-
if (contents != ownerTransferable) {
124-
contents?.let {
125-
ownerTransferable = it
126-
launch(CoroutineName("LinuxPasteboardServiceConsumer")) {
127-
val pasteTransferable = DesktopReadTransferable(it)
128-
pasteConsumer.consume(pasteTransferable, source, remote = false)
129-
}
130-
}
131-
}
115+
onChange(this)
132116
}
133117
selectionNotify.clear()
134118
}
@@ -143,6 +127,38 @@ class LinuxPasteboardService(
143127
}
144128
}
145129

130+
private suspend fun onChange(
131+
scope: CoroutineScope,
132+
firstChange: Boolean = false,
133+
) {
134+
val source =
135+
if (firstChange) {
136+
null
137+
} else {
138+
controlUtils.ensureMinExecutionTime(delayTime = 20) {
139+
appWindowManager.getCurrentActiveAppName()
140+
}
141+
}
142+
143+
val contents =
144+
controlUtils.exponentialBackoffUntilValid(
145+
initTime = 20L,
146+
maxTime = 1000L,
147+
isValidResult = ::isValidContents,
148+
) {
149+
getPasteboardContentsBySafe()
150+
}
151+
if (contents != ownerTransferable) {
152+
contents?.let {
153+
ownerTransferable = it
154+
scope.launch(CoroutineName("LinuxPasteboardServiceConsumer")) {
155+
val pasteTransferable = DesktopReadTransferable(it)
156+
pasteConsumer.consume(pasteTransferable, source, remote = false)
157+
}
158+
}
159+
}
160+
}
161+
146162
override fun start() {
147163
if (configManager.config.enablePasteboardListening) {
148164
if (job?.isActive != true) {

composeApp/src/desktopMain/kotlin/com/crosspaste/paste/MacosPasteboardService.kt

+6
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ class MacosPasteboardService(
7070
logger.info { "currentChangeCount $currentChangeCount changeCount $changeCount" }
7171
val firstChange = changeCount == configManager.config.lastPasteboardChangeCount
7272
changeCount = currentChangeCount
73+
74+
if (firstChange && configManager.config.enableSkipPriorPasteboardContent) {
75+
logger.debug { "Ignoring prior pasteboard" }
76+
return@let
77+
}
78+
7379
if (isCrossPaste.value != 0) {
7480
logger.debug { "Ignoring crosspaste change" }
7581
} else {

composeApp/src/desktopMain/kotlin/com/crosspaste/paste/WindowsPasteboardService.kt

+11-3
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ class WindowsPasteboardService(
144144
if (job?.isActive != true) {
145145
job =
146146
serviceScope.launch(CoroutineName("WindowsPasteboardService")) {
147+
val firstChange = changeCount == configManager.config.lastPasteboardChangeCount
148+
if (firstChange && !configManager.config.enableSkipPriorPasteboardContent) {
149+
onChange(true)
150+
}
147151
run()
148152
}
149153
}
@@ -155,11 +159,15 @@ class WindowsPasteboardService(
155159
configManager.updateConfig("lastPasteboardChangeCount", changeCount)
156160
}
157161

158-
private fun onChange() {
162+
private fun onChange(firstChange: Boolean = false) {
159163
try {
160164
val source =
161-
controlUtils.blockEnsureMinExecutionTime(delayTime = 20) {
162-
appWindowManager.getCurrentActiveAppName()
165+
if (firstChange) {
166+
null
167+
} else {
168+
controlUtils.blockEnsureMinExecutionTime(delayTime = 20) {
169+
appWindowManager.getCurrentActiveAppName()
170+
}
163171
}
164172

165173
val contents =

composeApp/src/desktopMain/resources/i18n/en.properties

+2-1
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@ service_discovery=Service Discovery
138138
settings=Settings
139139
show_main=Show Main Window
140140
show_search=Show Search Window
141-
size=Size
142141
shortcut_keys=Shortcut Keys
142+
size=Size
143+
skip_prior_pasteboard_content=Skip prior pasteboard content
143144
sort_by_creation_time=Sort by creation time
144145
source=Source
145146
state=State

composeApp/src/desktopMain/resources/i18n/es.properties

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ shortcut_keys=Teclas de acceso rápido
140140
show_main=Mostrar ventana principal
141141
show_search=Mostrar ventana de búsqueda
142142
size=Tamaño
143+
skip_prior_pasteboard_content=Omitir contenido previo del portapapeles
143144
sort_by_creation_time=Ordenar por tiempo de creación
144145
source=Fuente
145146
state=Estado

composeApp/src/desktopMain/resources/i18n/jp.properties

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ shortcut_keys=ショートカットキー
140140
show_main=メインウィンドウを表示
141141
show_search=検索ウィンドウを表示
142142
size=サイズ
143+
skip_prior_pasteboard_content=以前のペーストボードコンテンツをスキップ
143144
sort_by_creation_time=作成時間でソート
144145
source=ソース
145146
state=状態

composeApp/src/desktopMain/resources/i18n/zh.properties

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ shortcut_keys=快捷键
140140
show_main=显示主窗口
141141
show_search=显示搜索窗口
142142
size=大小
143+
skip_prior_pasteboard_content=跳过之前的剪贴板内容
143144
sort_by_creation_time=按创建时间排序
144145
source=来源
145146
state=状态

0 commit comments

Comments
 (0)