mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-216655 T: Attempt to load key 'ide.linux.window.buttons.config'
- The fix is rewritten GitOrigin-RevId: 9cdb7bef61d0bfa0f2cc83fac3f916d9d1527613
This commit is contained in:
committed by
intellij-monorepo-bot
parent
26de18eda7
commit
cc50b5d607
+50
-30
@@ -1,19 +1,23 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:ApiStatus.Internal
|
||||
|
||||
package com.intellij.openapi.wm.impl
|
||||
|
||||
import com.intellij.ide.AppLifecycleListener
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.StoragePathMacros
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.util.registry.RegistryManager
|
||||
import com.intellij.util.concurrency.ThreadingAssertions
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@@ -22,7 +26,7 @@ import org.jetbrains.annotations.ApiStatus
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@State(name = "WindowButtonsConfiguration", storages = [Storage(StoragePathMacros.CACHE_FILE)])
|
||||
class WindowButtonsConfiguration(private val scope: CoroutineScope) : PersistentStateComponent<WindowButtonsConfiguration.State?> {
|
||||
class WindowButtonsConfiguration(scope: CoroutineScope) : PersistentStateComponent<WindowButtonsConfiguration.State?> {
|
||||
enum class WindowButton {
|
||||
MINIMIZE,
|
||||
MAXIMIZE,
|
||||
@@ -32,6 +36,9 @@ class WindowButtonsConfiguration(private val scope: CoroutineScope) : Persistent
|
||||
companion object {
|
||||
fun getInstance(): WindowButtonsConfiguration? = if (isSupported()) service<WindowButtonsConfiguration>() else null
|
||||
|
||||
private val log = thisLogger()
|
||||
private const val WINDOW_BUTTONS_CONFIG_KEY = "ide.linux.window.buttons.config"
|
||||
|
||||
private fun isSupported(): Boolean {
|
||||
return SystemInfoRt.isLinux
|
||||
}
|
||||
@@ -40,35 +47,55 @@ class WindowButtonsConfiguration(private val scope: CoroutineScope) : Persistent
|
||||
private var mutableStateFlow = MutableStateFlow<State?>(null)
|
||||
val stateFlow: StateFlow<State?> = mutableStateFlow.asStateFlow()
|
||||
|
||||
init {
|
||||
if (isSupported()) {
|
||||
scope.launch(CoroutineName("WindowButtonsConfiguration")) {
|
||||
val registryManager = RegistryManager.getInstanceAsync()
|
||||
registryManager.awaitRegistryLoad()
|
||||
|
||||
var state = loadStateFromRegistry(registryManager) ?: loadStateFromOs()
|
||||
mutableStateFlow.update { state }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getState(): State? {
|
||||
return mutableStateFlow.value
|
||||
}
|
||||
|
||||
override fun loadState(state: State) {
|
||||
mutableStateFlow.value = state
|
||||
scheduleUpdateFromOs()
|
||||
}
|
||||
|
||||
override fun noStateLoaded() {
|
||||
scheduleUpdateFromOs()
|
||||
}
|
||||
|
||||
fun scheduleUpdateFromOs(customConfig: String? = null) {
|
||||
scope.launch {
|
||||
loadStateFromOs(customConfig)
|
||||
mutableStateFlow.update { currentState ->
|
||||
// The saved state is used only for caching, the actual computed state takes priority.
|
||||
// Normally the state isn't computed yet, unless loadState is called when the service is already up and running.
|
||||
// This is possible, according to the API docs, but only if the files are modified when the IDE is running.
|
||||
// In this case we definitely don't want to pick up the modified value, as the sources of truth are the OS and the registry.
|
||||
currentState ?: state
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadStateFromOs(customConfig: String?) {
|
||||
var windowButtonsState: State? = null
|
||||
|
||||
if (isSupported()) {
|
||||
val config = if (customConfig.isNullOrBlank()) X11UiUtil.getWindowButtonsConfig() else customConfig
|
||||
if (config != null) {
|
||||
windowButtonsState = parseFromString(config)
|
||||
}
|
||||
private fun loadStateFromRegistry(registryManager: RegistryManager): State? {
|
||||
val value = registryManager.stringValue(WINDOW_BUTTONS_CONFIG_KEY)
|
||||
if (value.isNullOrEmpty()) {
|
||||
return null
|
||||
}
|
||||
mutableStateFlow.value = windowButtonsState
|
||||
|
||||
val result = parseFromString(value)
|
||||
if (result == null) {
|
||||
log.warn("Failed to parse '$WINDOW_BUTTONS_CONFIG_KEY' registry value: $value")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun loadStateFromOs(): State? {
|
||||
ThreadingAssertions.assertBackgroundThread()
|
||||
|
||||
val config = X11UiUtil.getWindowButtonsConfig() ?: return null
|
||||
val result = parseFromString(config)
|
||||
if (result == null) {
|
||||
log.warn("Failed to parse OS window buttons config: $config")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
class State {
|
||||
@@ -113,10 +140,3 @@ private fun stringsToWindowButtons(strings: List<String>): List<WindowButtonsCon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class WindowButtonsAppLifecycleListener : AppLifecycleListener {
|
||||
|
||||
override fun appStarted() {
|
||||
WindowButtonsConfiguration.getInstance()?.scheduleUpdateFromOs(Registry.stringValue("ide.linux.window.buttons.config"))
|
||||
}
|
||||
}
|
||||
@@ -2114,7 +2114,6 @@
|
||||
topic="com.intellij.ide.ui.UISettingsListener"/>
|
||||
<listener class="com.intellij.ui.MacCustomAppIconStartupService" topic="com.intellij.ide.AppLifecycleListener"/>
|
||||
<listener class="com.intellij.openapi.editor.actions.ResetFontSizeAppInitListener" topic="com.intellij.ide.AppLifecycleListener"/>
|
||||
<listener class="com.intellij.openapi.wm.impl.WindowButtonsAppLifecycleListener" topic="com.intellij.ide.AppLifecycleListener" os="linux"/>
|
||||
|
||||
<listener class="com.intellij.ui.ExperimentalUiAppLifecycleListener" topic="com.intellij.ide.AppLifecycleListener"/>
|
||||
<listener class="com.intellij.ide.ui.laf.LafAndEditorColorSchemeDynamicPluginListener"
|
||||
|
||||
@@ -1886,6 +1886,7 @@ ide.linux.use.undecorated.border.restartRequired=true
|
||||
|
||||
ide.linux.window.buttons.config=
|
||||
ide.linux.window.buttons.config.description=Custom window buttons configuration, which is get by `gsettings get org.gnome.desktop.wm.preferences button-layout` command by default. Format should be similar to the command result, e.g. `:minimize,maximize,close`
|
||||
ide.linux.window.buttons.config.restartRequired=true
|
||||
|
||||
ide.tree.large.model.allowed=false
|
||||
ide.tree.large.model.allowed.description=Allows using FixedHeightLayoutCache if setLargeModel(true)
|
||||
|
||||
Reference in New Issue
Block a user