diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt b/composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt index c5b9759cc..7f8ef6308 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/ClipeveryApp.kt @@ -16,9 +16,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.shadow +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.focusTarget import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.dp +import com.clipevery.app.AppWindowManager import com.clipevery.ui.AboutView import com.clipevery.ui.ClipeveryTheme import com.clipevery.ui.HomeView @@ -31,13 +34,18 @@ import com.clipevery.ui.devices.DeviceDetailView import com.clipevery.ui.devices.TokenView import com.clipevery.ui.settings.SettingsView import com.clipevery.ui.settings.ShortcutKeysView +import com.clipevery.utils.GlobalCoroutineScope +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.launch @Composable -fun ClipeveryWindow(hideWindow: () -> Unit) { +fun ClipeveryWindow(hideWindow: suspend () -> Unit) { val current = LocalKoinApplication.current + val appWindowManager = current.koin.get() val toastManager = current.koin.get() val dialogService = current.koin.get() - + val globalCoroutineScope = current.koin.get() + val mainCoroutineDispatcher = globalCoroutineScope.mainCoroutineDispatcher val toast by toastManager.toast ClipeveryTheme { @@ -48,13 +56,19 @@ fun ClipeveryWindow(hideWindow: () -> Unit) { .pointerInput(Unit) { detectTapGestures( onDoubleTap = { - hideWindow() + mainCoroutineDispatcher.launch(CoroutineName("Hide Clipevery")) { + hideWindow() + } }, onTap = { - hideWindow() + mainCoroutineDispatcher.launch(CoroutineName("Hide Clipevery")) { + hideWindow() + } }, onLongPress = { - hideWindow() + mainCoroutineDispatcher.launch(CoroutineName("Hide Clipevery")) { + hideWindow() + } }, onPress = {}, ) @@ -84,7 +98,9 @@ fun ClipeveryWindow(hideWindow: () -> Unit) { Modifier .clip(RoundedCornerShape(10.dp)) .background(MaterialTheme.colors.background) - .fillMaxWidth(), + .fillMaxWidth() + .focusTarget() + .focusRequester(appWindowManager.mainFocusRequester), horizontalAlignment = Alignment.CenterHorizontally, ) { ClipeveryContent() diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/app/AppWindowManager.kt b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppWindowManager.kt index 04addb703..b83d218a6 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/app/AppWindowManager.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/app/AppWindowManager.kt @@ -10,6 +10,8 @@ interface AppWindowManager { var mainWindowState: WindowState + var mainFocusRequester: FocusRequester + var showMainDialog: Boolean var showSearchWindow: Boolean @@ -22,11 +24,11 @@ interface AppWindowManager { fun getCurrentActiveAppName(): String? - fun activeMainWindow() + suspend fun activeMainWindow() - fun unActiveMainWindow() + suspend fun unActiveMainWindow() - fun switchMainWindow() { + suspend fun switchMainWindow() { if (showMainWindow) { unActiveMainWindow() } else { diff --git a/composeApp/src/commonMain/kotlin/com/clipevery/utils/PlatformUtils.kt b/composeApp/src/commonMain/kotlin/com/clipevery/utils/PlatformUtils.kt index e6577d7aa..7166525b8 100644 --- a/composeApp/src/commonMain/kotlin/com/clipevery/utils/PlatformUtils.kt +++ b/composeApp/src/commonMain/kotlin/com/clipevery/utils/PlatformUtils.kt @@ -1,6 +1,7 @@ package com.clipevery.utils import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope expect val ioDispatcher: CoroutineDispatcher @@ -9,3 +10,12 @@ expect val mainDispatcher: CoroutineDispatcher expect val cpuDispatcher: CoroutineDispatcher expect val unconfinedDispatcher: CoroutineDispatcher + +interface GlobalCoroutineScope { + + val mainCoroutineDispatcher: CoroutineScope + + val ioCoroutineDispatcher: CoroutineScope + + val cpuCoroutineDispatcher: CoroutineScope +} diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/Clipevery.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/Clipevery.kt index af6e6fb31..a3c2f182a 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/Clipevery.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/Clipevery.kt @@ -146,6 +146,9 @@ import com.clipevery.ui.base.UISupport import com.clipevery.ui.resource.ClipResourceLoader import com.clipevery.ui.resource.DesktopAbsoluteClipResourceLoader import com.clipevery.ui.search.ClipeverySearchWindow +import com.clipevery.utils.GlobalCoroutineScope +import com.clipevery.utils.GlobalCoroutineScopeImpl +import com.clipevery.utils.GlobalCoroutineScopeImpl.mainCoroutineDispatcher import com.clipevery.utils.IDGenerator import com.clipevery.utils.IDGeneratorFactory import com.clipevery.utils.QRCodeGenerator @@ -197,6 +200,7 @@ class Clipevery { single { DesktopAppStartUpService(get()) } single { DesktopAppRestartService } single { DesktopEndpointInfoFactory(lazy { get() }) } + single { GlobalCoroutineScopeImpl } single { DesktopSyncInfoFactory(get(), get()) } single { DesktopPathProvider } single { DesktopFilePersist } @@ -434,8 +438,10 @@ class Clipevery { } override fun windowLostFocus(e: WindowEvent?) { - if (!appWindowManager.showMainDialog) { - appWindowManager.unActiveMainWindow() + mainCoroutineDispatcher.launch(CoroutineName("Hide Clipevery")) { + if (!appWindowManager.showMainDialog) { + appWindowManager.unActiveMainWindow() + } } } } diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/app/AbstractAppWindowManager.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/app/AbstractAppWindowManager.kt index f0c8c9bb4..09aecd6e2 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/app/AbstractAppWindowManager.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/app/AbstractAppWindowManager.kt @@ -47,6 +47,8 @@ abstract class AbstractAppWindowManager : AppWindowManager { ), ) + override var mainFocusRequester = FocusRequester() + override var showMainDialog by mutableStateOf(false) override var showSearchWindow by mutableStateOf(false) diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/app/LinuxAppWindowManager.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/app/LinuxAppWindowManager.kt index e125338ac..fd4be1852 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/app/LinuxAppWindowManager.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/app/LinuxAppWindowManager.kt @@ -50,16 +50,19 @@ class LinuxAppWindowManager( } } - override fun activeMainWindow() { + override suspend fun activeMainWindow() { logger.info { "active main window" } showMainWindow = true prevLinuxAppInfo = X11Api.bringToFront(MAIN_WINDOW_TITLE) + delay(500) + mainFocusRequester.requestFocus() } - override fun unActiveMainWindow() { + override suspend fun unActiveMainWindow() { logger.info { "unActive main window" } X11Api.bringToBack(prevLinuxAppInfo) showMainWindow = false + mainFocusRequester.freeFocus() } override suspend fun activeSearchWindow() { diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/app/MacAppWindowManager.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/app/MacAppWindowManager.kt index f6e362019..7c9c6bbd2 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/app/MacAppWindowManager.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/app/MacAppWindowManager.kt @@ -62,7 +62,7 @@ class MacAppWindowManager( } } - override fun activeMainWindow() { + override suspend fun activeMainWindow() { logger.info { "active main window" } showMainWindow = true MacosApi.INSTANCE.bringToFront(MAIN_WINDOW_TITLE).let { @@ -73,19 +73,17 @@ class MacAppWindowManager( } } } + delay(500) + mainFocusRequester.requestFocus() } - override fun unActiveMainWindow() { + override suspend fun unActiveMainWindow() { logger.info { "unActive main window" } - val pair = macPasteUtils.getPasteMemory() - MacosApi.INSTANCE.bringToBack( - MAIN_WINDOW_TITLE, + MacosApi.INSTANCE.mainToBack( prevMacAppInfo?.bundleIdentifier ?: "", - toPaste = false, - pair.first, - pair.second, ) showMainWindow = false + mainFocusRequester.freeFocus() } override suspend fun activeSearchWindow() { @@ -113,8 +111,7 @@ class MacAppWindowManager( logger.info { "unActive search window" } val toPaste = preparePaste() val pair = macPasteUtils.getPasteMemory() - MacosApi.INSTANCE.bringToBack( - SEARCH_WINDOW_TITLE, + MacosApi.INSTANCE.searchToBack( prevMacAppInfo?.bundleIdentifier ?: "", toPaste = toPaste, pair.first, diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/app/WinAppWindowManager.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/app/WinAppWindowManager.kt index 57610911e..3df94242b 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/app/WinAppWindowManager.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/app/WinAppWindowManager.kt @@ -66,13 +66,15 @@ class WinAppWindowManager( } } - override fun activeMainWindow() { + override suspend fun activeMainWindow() { logger.info { "active main window" } showMainWindow = true prevWinAppInfo = User32.bringToFront(MAIN_WINDOW_TITLE, mainHWND, searchHWND) + delay(500) + mainFocusRequester.requestFocus() } - override fun unActiveMainWindow() { + override suspend fun unActiveMainWindow() { logger.info { "unActive main window" } val keyCodes = lazyShortcutKeys.value.shortcutKeysCore.keys["Paste"]?.let { @@ -80,6 +82,7 @@ class WinAppWindowManager( } ?: listOf() User32.bringToBack(MAIN_WINDOW_TITLE, mainHWND, searchHWND, prevWinAppInfo?.hwnd, false, keyCodes) showMainWindow = false + mainFocusRequester.freeFocus() } override suspend fun activeSearchWindow() { @@ -90,9 +93,10 @@ class WinAppWindowManager( searchWindowState.position = calPosition(graphicsDevice.defaultConfiguration.bounds) } - prevWinAppInfo = User32.bringToFront(SEARCH_WINDOW_TITLE, mainHWND, searchHWND) - + // Wait for the window to be ready, otherwise bringToFront may cause the window to fail to get focus delay(500) + + prevWinAppInfo = User32.bringToFront(SEARCH_WINDOW_TITLE, mainHWND, searchHWND) searchFocusRequester.requestFocus() } diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/listen/DesktopShortKeysAction.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/listen/DesktopShortKeysAction.kt index 8797a5d94..5bd1319f5 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/listen/DesktopShortKeysAction.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/listen/DesktopShortKeysAction.kt @@ -9,11 +9,10 @@ import com.clipevery.dao.clip.ClipDao import com.clipevery.dao.clip.ClipData import com.clipevery.listener.ShortcutKeysAction import com.clipevery.ui.base.DialogService -import com.clipevery.utils.mainDispatcher +import com.clipevery.utils.GlobalCoroutineScopeImpl.mainCoroutineDispatcher import io.github.oshai.kotlinlogging.KotlinLogging import io.realm.kotlin.query.RealmQuery import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch class DesktopShortKeysAction( @@ -28,8 +27,6 @@ class DesktopShortKeysAction( private val logger = KotlinLogging.logger {} - private val mainDispatcherScope = CoroutineScope(mainDispatcher) - override val action: (String) -> Unit = { actionName -> when (actionName) { "Paste_Local_Last" -> pasteLast(true) @@ -44,21 +41,21 @@ class DesktopShortKeysAction( private fun showMainWindow() { logger.info { "Open main window" } - mainDispatcherScope.launch(CoroutineName("OpenMainWindow")) { + mainCoroutineDispatcher.launch(CoroutineName("OpenMainWindow")) { appWindowManager.activeMainWindow() } } private fun showSearchWindow() { logger.info { "Open search window" } - mainDispatcherScope.launch(CoroutineName("OpenSearchWindow")) { + mainCoroutineDispatcher.launch(CoroutineName("OpenSearchWindow")) { clipSearchService.activeWindow() } } private fun hideWindow() { logger.info { "Hide window" } - mainDispatcherScope.launch(CoroutineName("HideWindow")) { + mainCoroutineDispatcher.launch(CoroutineName("HideWindow")) { if (appWindowManager.showMainWindow && dialogService.dialogs.isEmpty()) { appWindowManager.unActiveMainWindow() } @@ -78,7 +75,7 @@ class DesktopShortKeysAction( } else { { it.query("appInstanceId != $0", appInfo.appInstanceId) } } - mainDispatcherScope.launch(CoroutineName("Paste")) { + mainCoroutineDispatcher.launch(CoroutineName("Paste")) { val result = clipDao.searchClipData( searchTerms = listOf(), @@ -96,14 +93,14 @@ class DesktopShortKeysAction( private fun switchMonitorPasteboard() { logger.info { "Switch Monitor Pasteboard" } - mainDispatcherScope.launch(CoroutineName("SwitchMonitorPasteboard")) { + mainCoroutineDispatcher.launch(CoroutineName("SwitchMonitorPasteboard")) { clipboardService.toggle() } } private fun switchEncrypt() { logger.info { "Switch Encrypt" } - mainDispatcherScope.launch(CoroutineName("SwitchEncrypt")) { + mainCoroutineDispatcher.launch(CoroutineName("SwitchEncrypt")) { configManager.updateConfig { config -> config.copy(isEncryptSync = !configManager.config.isEncryptSync) } } } diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/api/MacosApi.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/api/MacosApi.kt index fe30dcb45..2c0d1aebd 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/api/MacosApi.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/os/macos/api/MacosApi.kt @@ -46,8 +46,9 @@ interface MacosApi : Library { path: String, ) - fun bringToBack( - windowTitle: String, + fun mainToBack(appName: String) + + fun searchToBack( appName: String, toPaste: Boolean, array: Pointer, diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/ui/LinuxTrayView.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/ui/LinuxTrayView.kt index 5ea138339..3ca680294 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/ui/LinuxTrayView.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/ui/LinuxTrayView.kt @@ -3,9 +3,12 @@ package com.clipevery.ui import androidx.compose.ui.unit.dp import androidx.compose.ui.window.WindowPosition import com.clipevery.app.AppWindowManager +import com.clipevery.utils.GlobalCoroutineScopeImpl.mainCoroutineDispatcher import com.clipevery.utils.getResourceUtils import dorkbox.systemTray.MenuItem import dorkbox.systemTray.SystemTray +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.launch import org.koin.core.KoinApplication import java.awt.GraphicsEnvironment import java.awt.Toolkit @@ -23,7 +26,11 @@ object LinuxTrayView { systemTray.setImage(resourceUtils.resourceInputStream("icon/clipevery.tray.linux.png")) systemTray.setTooltip("Clipevery") systemTray.menu?.add( - MenuItem("Open Clipevery") { appWindowManager.activeMainWindow() }, + MenuItem("Open Clipevery") { + mainCoroutineDispatcher.launch(CoroutineName("Open Clipevery")) { + appWindowManager.activeMainWindow() + } + }, ) systemTray.menu?.add( diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/ui/MacTrayView.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/ui/MacTrayView.kt index 290a71de6..9ee3062be 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/ui/MacTrayView.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/ui/MacTrayView.kt @@ -20,7 +20,10 @@ import com.clipevery.app.AppWindowManager import com.clipevery.i18n.GlobalCopywriter import com.clipevery.ui.base.NotificationManager import com.clipevery.ui.base.UISupport +import com.clipevery.utils.GlobalCoroutineScopeImpl.mainCoroutineDispatcher import com.clipevery.utils.contains +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.launch import org.koin.core.KoinApplication import java.awt.Frame import java.awt.GraphicsEnvironment @@ -62,10 +65,14 @@ fun MacTray() { mouseListener = MacTrayMouseClicked(appWindowManager) { event, rectangle, _ -> if (event.button == MouseEvent.BUTTON1) { - appWindowManager.switchMainWindow() + mainCoroutineDispatcher.launch(CoroutineName("Switch Clipevery")) { + appWindowManager.switchMainWindow() + } } else { - if (appWindowManager.showMainWindow) { - appWindowManager.unActiveMainWindow() + mainCoroutineDispatcher.launch(CoroutineName("Hide Clipevery")) { + if (appWindowManager.showMainWindow) { + appWindowManager.unActiveMainWindow() + } } val stepWidth = with(density) { 48.dp.roundToPx() } menu.show(frame, event.x - stepWidth, rectangle.y + 5) @@ -87,22 +94,28 @@ fun createPopupMenu( popup.add( createMenuItem(copywriter.getText("Settings")) { - appWindowManager.activeMainWindow() - currentPage.value = PageViewContext(PageViewType.SETTINGS, currentPage.value) + mainCoroutineDispatcher.launch(CoroutineName("Open settings")) { + appWindowManager.activeMainWindow() + currentPage.value = PageViewContext(PageViewType.SETTINGS, currentPage.value) + } }, ) popup.add( createMenuItem(copywriter.getText("Shortcut_Keys")) { - appWindowManager.activeMainWindow() - currentPage.value = PageViewContext(PageViewType.SHORTCUT_KEYS, currentPage.value) + mainCoroutineDispatcher.launch(CoroutineName("Open shortcut keys")) { + appWindowManager.activeMainWindow() + currentPage.value = PageViewContext(PageViewType.SHORTCUT_KEYS, currentPage.value) + } }, ) popup.add( createMenuItem(copywriter.getText("About")) { - appWindowManager.activeMainWindow() - currentPage.value = PageViewContext(PageViewType.ABOUT, currentPage.value) + mainCoroutineDispatcher.launch(CoroutineName("Open about")) { + appWindowManager.activeMainWindow() + currentPage.value = PageViewContext(PageViewType.ABOUT, currentPage.value) + } }, ) diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/ui/WindowsTrayView.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/ui/WindowsTrayView.kt index a4d83a2d3..f134b8139 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/ui/WindowsTrayView.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/ui/WindowsTrayView.kt @@ -31,6 +31,9 @@ import com.clipevery.LocalKoinApplication import com.clipevery.app.AppWindowManager import com.clipevery.app.WinAppWindowManager import com.clipevery.ui.base.NotificationManager +import com.clipevery.utils.GlobalCoroutineScopeImpl.mainCoroutineDispatcher +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.launch import java.awt.GraphicsDevice import java.awt.GraphicsEnvironment import java.awt.Insets @@ -64,7 +67,9 @@ fun WindowsTray() { mouseListener = WindowsTrayMouseClicked(appWindowManager) { event, gd, insets -> if (event.button == MouseEvent.BUTTON1) { - appWindowManager.switchMainWindow() + mainCoroutineDispatcher.launch(CoroutineName("Switch Clipevery")) { + appWindowManager.switchMainWindow() + } } else { showMenu = true val bounds = gd.defaultConfiguration.bounds @@ -163,7 +168,11 @@ fun WindowTrayMenu(hideMenu: () -> Unit) { contentAlignment = Alignment.Center, ) { MenuView( - openMainWindow = { appWindowManager.activeMainWindow() }, + openMainWindow = { + mainCoroutineDispatcher.launch(CoroutineName("Open Menu")) { + appWindowManager.activeMainWindow() + } + }, close = { hideMenu() }, ) } diff --git a/composeApp/src/desktopMain/kotlin/com/clipevery/utils/PlatformUtils.desktop.kt b/composeApp/src/desktopMain/kotlin/com/clipevery/utils/PlatformUtils.desktop.kt index 81e5d62c4..6af851b43 100644 --- a/composeApp/src/desktopMain/kotlin/com/clipevery/utils/PlatformUtils.desktop.kt +++ b/composeApp/src/desktopMain/kotlin/com/clipevery/utils/PlatformUtils.desktop.kt @@ -1,6 +1,7 @@ package com.clipevery.utils import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers actual val ioDispatcher: CoroutineDispatcher = Dispatchers.IO @@ -10,3 +11,12 @@ actual val mainDispatcher: CoroutineDispatcher = Dispatchers.Main actual val cpuDispatcher: CoroutineDispatcher = Dispatchers.Default actual val unconfinedDispatcher: CoroutineDispatcher = Dispatchers.Unconfined + +object GlobalCoroutineScopeImpl : GlobalCoroutineScope { + + override val mainCoroutineDispatcher = CoroutineScope(mainDispatcher) + + override val ioCoroutineDispatcher = CoroutineScope(ioDispatcher) + + override val cpuCoroutineDispatcher = CoroutineScope(cpuDispatcher) +} diff --git a/composeApp/src/desktopMain/swift/MacosApi.swift b/composeApp/src/desktopMain/swift/MacosApi.swift index c40e2db8e..9ee6bfd42 100644 --- a/composeApp/src/desktopMain/swift/MacosApi.swift +++ b/composeApp/src/desktopMain/swift/MacosApi.swift @@ -169,19 +169,41 @@ public func saveAppIcon(bundleIdentifier: UnsafePointer, path: UnsafePoin } } -@_cdecl("bringToBack") -public func bringToBack( - windowTitle: UnsafePointer, +@_cdecl("mainToBack") +public func mainToBack( + appName: UnsafePointer +) { + DispatchQueue.main.async { + let windows = NSApplication.shared.windows + for window in windows { + if window.title == "Clipevery" { + if (NSApp.isActive) { + window.orderBack(nil) + NSApp.hide(nil) + } + break + } + } + + let appNameString = String(cString: appName) + let apps = NSRunningApplication.runningApplications(withBundleIdentifier: appNameString) + if let app = apps.first { + app.activate(options: [.activateIgnoringOtherApps]) + } + } +} + +@_cdecl("searchToBack") +public func searchToBack( appName: UnsafePointer, toPaste: Bool, keyCodesPointer: UnsafePointer, count: Int ) { DispatchQueue.main.async { - let title = String(cString: windowTitle) let windows = NSApplication.shared.windows for window in windows { - if window.title == title { + if window.title == "Clipevery Search" { if (NSApp.isActive) { window.orderBack(nil) NSApp.hide(nil) @@ -190,8 +212,8 @@ public func bringToBack( } } - if (toPaste) { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + if (toPaste) { simulatePasteCommand(keyCodesPointer: keyCodesPointer, count: count) } } @@ -209,10 +231,9 @@ public func bringToFront(windowTitle: UnsafePointer) -> UnsafePointer