无法使用 Compose 桌面将 window 置于前台
Unable to bring window to foreground with compose desktop
使用以下代码可以使用按钮隐藏应用程序 window 并使用全局快捷键 ALT+S 恢复。
现在我还想使用快捷方式将 window 带到前台(如果它没有被隐藏)。
在下面找到我失败的尝试。 (我对jetpack compose这件事比较陌生。)
var windowVisible = mutableStateOf(true)
@Composable
fun App(windowFocusRequester: FocusRequester) {
MaterialTheme() {
Button(modifier = Modifier.focusRequester(windowFocusRequester), onClick = {
println("click to hide received")
windowVisible.value = false
}) {
Text("Hide window (ALT+S to show)")
}
}
}
fun main() = application() {
Window(onCloseRequest = ::exitApplication, visible = windowVisible.value, focusable = true,
) {
val windowFocusRequester = remember { FocusRequester() }
val provider = Provider.getCurrentProvider(false)
provider.register(
KeyStroke.getKeyStroke("alt S")
) {
println("shortcut to show received")
windowVisible.value = true
windowFocusRequester.requestFocus()
}
App(windowFocusRequester)
}
}
可能您需要将 FocusRequester 作为修饰符添加到 Window 但这似乎不可能。
为了能够运行需要这个库的代码
implementation("com.github.tulskiy:jkeymaster:1.3")
感谢您提供任何尝试、推进甚至解决方法的想法! (也许访问 awt window?)
我遇到了同样的问题并最终得到了这个解决方案:
import androidx.compose.runtime.*
import androidx.compose.ui.window.FrameWindowScope
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowState
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun FrameWindowScope.WindowFocusRequester(state: WindowState): () -> Unit {
var requestFocus by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
var showFakeWindow by remember { mutableStateOf(false) }
if (requestFocus) {
requestFocus = false
showFakeWindow = true
scope.launch {
delay(1)
showFakeWindow = false
}
}
if (showFakeWindow) {
Window({}) {}
window.toFront()
state.isMinimized = false
}
return { requestFocus = true }
}
使用这样的代码:
fun main() = application {
val state = rememberWindowState()
Window({ exitApplication() }, state) {
val requestWindowFocus = WindowFocusRequester(state)
// Inside some listener just invoke the returned lambda
requestWindowFocus()
}
}
这是一个黑客。所以也许它不会在每个 OS 上都有效。我用 Ubuntu 20 和 Compose 1.1.1
.
测试了它
如果这对您不起作用,请尝试增加 delay
持续时间或将 toFront()
调用与提到的内容交换 here。
找到更好的解决方案(没有闪烁):使用 alwaysOnTop
,灵感来自 this answer...(没有 state-thingy 就无法工作)
var windowVisible = mutableStateOf(true)
@Composable
fun App() {
MaterialTheme() {
Button(onClick = {
println("click to hide received")
windowVisible.value = false
}) {
Text("Hide window (ALT+S to show)")
}
}
}
fun main() = application() {
val windowAlwaysOnTop = remember { mutableStateOf(false) }
val state = rememberWindowState(width = 320.dp, height = 200.dp)
Window(
onCloseRequest = ::exitApplication, state = state, visible = windowVisible.value,
alwaysOnTop = windowAlwaysOnTop.value, focusable = true,
) {
val provider = Provider.getCurrentProvider(false)
provider.register(
KeyStroke.getKeyStroke("alt S")
) {
println("shortcut to show received")
windowVisible.value = true
windowAlwaysOnTop.value = true
windowAlwaysOnTop.value = false
}
App()
}
}
使用以下代码可以使用按钮隐藏应用程序 window 并使用全局快捷键 ALT+S 恢复。 现在我还想使用快捷方式将 window 带到前台(如果它没有被隐藏)。
在下面找到我失败的尝试。 (我对jetpack compose这件事比较陌生。)
var windowVisible = mutableStateOf(true)
@Composable
fun App(windowFocusRequester: FocusRequester) {
MaterialTheme() {
Button(modifier = Modifier.focusRequester(windowFocusRequester), onClick = {
println("click to hide received")
windowVisible.value = false
}) {
Text("Hide window (ALT+S to show)")
}
}
}
fun main() = application() {
Window(onCloseRequest = ::exitApplication, visible = windowVisible.value, focusable = true,
) {
val windowFocusRequester = remember { FocusRequester() }
val provider = Provider.getCurrentProvider(false)
provider.register(
KeyStroke.getKeyStroke("alt S")
) {
println("shortcut to show received")
windowVisible.value = true
windowFocusRequester.requestFocus()
}
App(windowFocusRequester)
}
}
可能您需要将 FocusRequester 作为修饰符添加到 Window 但这似乎不可能。
为了能够运行需要这个库的代码
implementation("com.github.tulskiy:jkeymaster:1.3")
感谢您提供任何尝试、推进甚至解决方法的想法! (也许访问 awt window?)
我遇到了同样的问题并最终得到了这个解决方案:
import androidx.compose.runtime.*
import androidx.compose.ui.window.FrameWindowScope
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowState
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun FrameWindowScope.WindowFocusRequester(state: WindowState): () -> Unit {
var requestFocus by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
var showFakeWindow by remember { mutableStateOf(false) }
if (requestFocus) {
requestFocus = false
showFakeWindow = true
scope.launch {
delay(1)
showFakeWindow = false
}
}
if (showFakeWindow) {
Window({}) {}
window.toFront()
state.isMinimized = false
}
return { requestFocus = true }
}
使用这样的代码:
fun main() = application {
val state = rememberWindowState()
Window({ exitApplication() }, state) {
val requestWindowFocus = WindowFocusRequester(state)
// Inside some listener just invoke the returned lambda
requestWindowFocus()
}
}
这是一个黑客。所以也许它不会在每个 OS 上都有效。我用 Ubuntu 20 和 Compose 1.1.1
.
如果这对您不起作用,请尝试增加 delay
持续时间或将 toFront()
调用与提到的内容交换 here。
找到更好的解决方案(没有闪烁):使用 alwaysOnTop
,灵感来自 this answer...(没有 state-thingy 就无法工作)
var windowVisible = mutableStateOf(true)
@Composable
fun App() {
MaterialTheme() {
Button(onClick = {
println("click to hide received")
windowVisible.value = false
}) {
Text("Hide window (ALT+S to show)")
}
}
}
fun main() = application() {
val windowAlwaysOnTop = remember { mutableStateOf(false) }
val state = rememberWindowState(width = 320.dp, height = 200.dp)
Window(
onCloseRequest = ::exitApplication, state = state, visible = windowVisible.value,
alwaysOnTop = windowAlwaysOnTop.value, focusable = true,
) {
val provider = Provider.getCurrentProvider(false)
provider.register(
KeyStroke.getKeyStroke("alt S")
) {
println("shortcut to show received")
windowVisible.value = true
windowAlwaysOnTop.value = true
windowAlwaysOnTop.value = false
}
App()
}
}