无法将窗户带到前景的桌面

发布于 2025-01-23 16:32:59 字数 1320 浏览 4 评论 0原文

使用以下代码,可以使用按钮隐藏应用程序窗口,并使用全局快捷方式ALT+S恢复。 现在,我也想使用快捷方式将窗户带到前景(如果没有隐藏的话)。

在下面找到我失败的尝试。 (我对Jetpack组成的问题是相对较新的。)

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添加为窗口的修饰符,但这似乎是不可能的。

为了能够运行代码,需要此LIB,

implementation("com.github.tulskiy:jkeymaster:1.3")

感谢您尝试,提前甚至解决方法的任何想法! (也许访问AWT窗口?)

With the following code the application window can be hidden using the button and restored using a global shortcut ALT+S.
Now I would like to also use the shortcut to bring the window to the foreground (if it wasn't hidden).

Find below my failed attempt to do so. (I am relatively new to the matter of 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)
    }
}

Probably you would need to add the FocusRequester as a modifier to the Window but this does not seem to be possible.

To be able to run the code this lib is needed

implementation("com.github.tulskiy:jkeymaster:1.3")

Thanks for any ideas to try, advance or even workaround! (maybe accessing awt window?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

多情出卖 2025-01-30 16:32:59

找到了一个更好的解决方案(无闪烁):使用ewaysOntop,灵感来自此答案 .. 。

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()
    }
}

Found a better solution (without the flickering): using alwaysOnTop, inspired by this answer... (does not work without the 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()
    }
}
他不在意 2025-01-30 16:32:59

我遇到了同一问题,最终得到了此解决方案:

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()
    }
}

这是一个黑客。因此,也许它不会在每个操作系统上使用。我用Ubuntu 20进行了测试,并组成1.1.1

如果这对您不起作用,请尝试增加delay持续时间或交换tofront()与上述内容在这里

I came across the same issue and ended up with this solution:

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 }
}

Use the code like this:

fun main() = application {
    val state = rememberWindowState()
    Window({ exitApplication() }, state) {
        val requestWindowFocus = WindowFocusRequester(state)

        // Inside some listener just invoke the returned lambda
        requestWindowFocus()
    }
}

It is a hack. So maybe it will not work on every OS. I tested it with Ubuntu 20 and Compose 1.1.1.

If this is not working for you, try to increase the delay duration or exchange the toFront() call with something mentioned here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文