From 508a408a43469dc53553552d3175e7f6c038da8f Mon Sep 17 00:00:00 2001 From: Ivan Seredkin Date: Tue, 5 Nov 2024 11:15:42 -0500 Subject: [PATCH 1/6] #28 Fix "Do not call invokeLater when app is not yet fully initialized" error on startup --- CHANGELOG.md | 2 ++ .../com/github/siropkin/kursor/settings/KursorSettings.kt | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 010b572..a2afa97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Kursor Changelog ## [Unreleased] +### Fixed +- #28 Fix "Do not call invokeLater when app is not yet fully initialized" error on startup. ## [1.4.1] diff --git a/src/main/kotlin/com/github/siropkin/kursor/settings/KursorSettings.kt b/src/main/kotlin/com/github/siropkin/kursor/settings/KursorSettings.kt index 05fa185..51fc268 100644 --- a/src/main/kotlin/com/github/siropkin/kursor/settings/KursorSettings.kt +++ b/src/main/kotlin/com/github/siropkin/kursor/settings/KursorSettings.kt @@ -47,7 +47,11 @@ class KursorSettings : PersistentStateComponent { companion object { fun getInstance(): KursorSettings { - return ApplicationManager.getApplication().getService(KursorSettings::class.java) + return try { + ApplicationManager.getApplication().getService(KursorSettings::class.java) + } catch (e: Exception) { + KursorSettings() + } } } } From 1122dbb40b458ee65e724d1803c7bfe21ab26c87 Mon Sep 17 00:00:00 2001 From: Ivan Seredkin Date: Tue, 5 Nov 2024 11:23:38 -0500 Subject: [PATCH 2/6] #29 Fix "Migrate com.github.siropkin.kursor.KursorStartupActivity to ProjectActivity" development warning on startup --- CHANGELOG.md | 1 + .../com/github/siropkin/kursor/KursorStartupActivity.kt | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2afa97..5bde840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] ### Fixed - #28 Fix "Do not call invokeLater when app is not yet fully initialized" error on startup. +- #29 Fix "Migrate com.github.siropkin.kursor.KursorStartupActivity to ProjectActivity" development warning on startup. ## [1.4.1] diff --git a/src/main/kotlin/com/github/siropkin/kursor/KursorStartupActivity.kt b/src/main/kotlin/com/github/siropkin/kursor/KursorStartupActivity.kt index de7bd2e..05c7d03 100644 --- a/src/main/kotlin/com/github/siropkin/kursor/KursorStartupActivity.kt +++ b/src/main/kotlin/com/github/siropkin/kursor/KursorStartupActivity.kt @@ -6,14 +6,14 @@ import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.editor.event.EditorFactoryEvent import com.intellij.openapi.editor.event.EditorFactoryListener import com.intellij.openapi.project.Project -import com.intellij.openapi.startup.StartupActivity +import com.intellij.openapi.startup.ProjectActivity import java.awt.event.KeyEvent -class KursorStartupActivity: StartupActivity { +class KursorStartupActivity: ProjectActivity { private val kursors = mutableMapOf() - override fun runActivity(project: Project) { + override suspend fun execute(project: Project) { // add kursor to all existing editors val editors: Array = EditorFactory.getInstance().allEditors for (editor in editors) { From 134546fb2d3905ecf971a3dde47bf31275fa7c1b Mon Sep 17 00:00:00 2001 From: Ivan Seredkin Date: Tue, 5 Nov 2024 11:26:41 -0500 Subject: [PATCH 3/6] Add links to Chinese methods to README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1fdc8ac..83b18f4 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This feature is particularly beneficial for developers juggling multiple languag - **🔒 Caps Lock Indicator:** Shows the Caps Lock status on the cursor. - **🔧 Customization:** Customize the language indicator's font, size, opacity, and position. - **🖥️ Supported Operating Systems:** Available on Windows, Mac, and Linux. -- **🌐 Supported Languages And Input Methods:** Supports a wide range of languages and input methods, including Chinese Sogou Pinyin and Squirrel Methods on macOS. +- **🌐 Supported Languages And Input Methods:** Supports a wide range of languages and input methods, including [Sogou Pinyin](https://pinyin.sogou.com/mac) and [Squirrel](https://rime.im) Chinese methods on macOS. ## Usage From 7063f7c56dba6defad3c34015771b984d5fa8c1a Mon Sep 17 00:00:00 2001 From: Ivan Seredkin Date: Tue, 5 Nov 2024 11:28:23 -0500 Subject: [PATCH 4/6] Update plugin version to v1.4.2 --- CHANGELOG.md | 3 +++ gradle.properties | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bde840..e37ded2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Kursor Changelog ## [Unreleased] + + +## [1.4.2] ### Fixed - #28 Fix "Do not call invokeLater when app is not yet fully initialized" error on startup. - #29 Fix "Migrate com.github.siropkin.kursor.KursorStartupActivity to ProjectActivity" development warning on startup. diff --git a/gradle.properties b/gradle.properties index fd60f9f..4ac87f9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ pluginGroup = com.github.siropkin.kursor pluginName = Kursor pluginRepositoryUrl = https://github.com/siropkin/kursor # SemVer format -> https://semver.org -pluginVersion = 1.4.1 +pluginVersion = 1.4.2 # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html pluginSinceBuild = 232 From b49270e7a3998de135f481e05d9e0c552508bf59 Mon Sep 17 00:00:00 2001 From: Ivan Seredkin Date: Wed, 6 Nov 2024 08:47:48 -0500 Subject: [PATCH 5/6] #30 Code refactoring --- .../com/github/siropkin/kursor/Kursor.kt | 45 ++--- .../{ => keyboardlayout}/KeyboardLayout.kt | 182 +++++------------- .../keyboardlayout/KeyboardLayoutInfo.kt | 10 + .../keyboardlayout/MacKeyboardVariants.kt | 9 + .../keyboardlayout/WindowsKeyboardVariants.kt | 69 +++++++ .../settings/KursorSettingsComponent.kt | 11 +- 6 files changed, 166 insertions(+), 160 deletions(-) rename src/main/kotlin/com/github/siropkin/kursor/{ => keyboardlayout}/KeyboardLayout.kt (50%) create mode 100644 src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayoutInfo.kt create mode 100644 src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/MacKeyboardVariants.kt create mode 100644 src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/WindowsKeyboardVariants.kt diff --git a/src/main/kotlin/com/github/siropkin/kursor/Kursor.kt b/src/main/kotlin/com/github/siropkin/kursor/Kursor.kt index 947ecac..96891ac 100644 --- a/src/main/kotlin/com/github/siropkin/kursor/Kursor.kt +++ b/src/main/kotlin/com/github/siropkin/kursor/Kursor.kt @@ -1,7 +1,11 @@ package com.github.siropkin.kursor +import com.github.siropkin.kursor.keyboardlayout.KeyboardLayout import com.github.siropkin.kursor.settings.KursorSettings -import com.intellij.openapi.editor.* +import com.intellij.openapi.editor.Caret +import com.intellij.openapi.editor.CaretVisualAttributes +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.VisualPosition import com.intellij.openapi.editor.colors.EditorColors import com.intellij.openapi.editor.event.CaretEvent import com.intellij.openapi.editor.event.CaretListener @@ -113,39 +117,34 @@ class Kursor(private var editor: Editor): JComponent(), ComponentListener, Caret return } - val settings = getSettings() - val isCapsLockOn = settings.indicateCapsLock && getIsCapsLockOn() - val keyboardLayoutInfo = keyboardLayout.getInfo() - var keyboardLayoutStringInfo = keyboardLayoutInfo.toString() - if (keyboardLayoutStringInfo.isEmpty()) { + val keyboardLayoutString = keyboardLayout.getLayoutInfo().toString() + if (keyboardLayoutString.isEmpty()) { return } + val settings = getSettings() val caret = getPrimaryCaret() - var caretColor: Color? = null - if (settings.changeColorOnNonDefaultLanguage) { - if (keyboardLayoutStringInfo != settings.defaultLanguage) { - caretColor = settings.colorOnNonDefaultLanguage - } + val caretColor = if (settings.changeColorOnNonDefaultLanguage && keyboardLayoutString.lowercase() != settings.defaultLanguage.lowercase()) { + settings.colorOnNonDefaultLanguage + } else { + null } if (caret.visualAttributes.color != caretColor) { setCaretColor(caret, caretColor) } - if (!settings.showTextIndicator) { - return - } - - val showTextIndicator = settings.indicateDefaultLanguage || isCapsLockOn || keyboardLayoutStringInfo.lowercase() != settings.defaultLanguage.lowercase() + val isCapsLockOn = settings.indicateCapsLock && getIsCapsLockOn() + val showTextIndicator = settings.showTextIndicator && (settings.indicateDefaultLanguage || isCapsLockOn || keyboardLayoutString.lowercase() != settings.defaultLanguage.lowercase()) if (!showTextIndicator) { return } - if (isCapsLockOn) { - keyboardLayoutStringInfo = keyboardLayoutStringInfo.uppercase() + val displayText = if (isCapsLockOn) { + keyboardLayoutString.uppercase() + } else { + keyboardLayoutString.lowercase() } - val caretWidth = getCaretWidth(caret) val caretHeight = getCaretHeight(caret) val caretPosition = getCaretPosition(caret) @@ -159,11 +158,7 @@ class Kursor(private var editor: Editor): JComponent(), ComponentListener, Caret } g.font = Font(settings.textIndicatorFontName, settings.textIndicatorFontStyle, settings.textIndicatorFontSize) - g.color = if (caretColor == null) { - getColorWithAlpha(getDefaultCaretColor()!!, settings.textIndicatorFontAlpha) - } else { - getColorWithAlpha(caretColor, settings.textIndicatorFontAlpha) - } - g.drawString(keyboardLayoutStringInfo, caretPosition.x + indicatorOffsetX, caretPosition.y + indicatorOffsetY) + g.color = getColorWithAlpha(caretColor ?: getDefaultCaretColor()!!, settings.textIndicatorFontAlpha) + g.drawString(displayText, caretPosition.x + indicatorOffsetX, caretPosition.y + indicatorOffsetY) } } diff --git a/src/main/kotlin/com/github/siropkin/kursor/KeyboardLayout.kt b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayout.kt similarity index 50% rename from src/main/kotlin/com/github/siropkin/kursor/KeyboardLayout.kt rename to src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayout.kt index bbf0631..ec9e3f1 100644 --- a/src/main/kotlin/com/github/siropkin/kursor/KeyboardLayout.kt +++ b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayout.kt @@ -1,4 +1,4 @@ -package com.github.siropkin.kursor +package com.github.siropkin.kursor.keyboardlayout import com.sun.jna.Platform import com.sun.jna.platform.win32.User32 @@ -9,140 +9,69 @@ import java.io.BufferedReader import java.io.IOException -private const val unknown = "unk" - -// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-language-pack-default-values -private val windowsKeyboardVariantMap = mapOf( - "00000402" to "BG", - "00000404" to "CH", - "00000405" to "CZ", - "00000406" to "DK", - "00000407" to "DE", - "00000408" to "GK", - "00000409" to "US", - "0000040A" to "SP", - "0000040B" to "SU", - "0000040C" to "FR", - "0000040E" to "HU", - "0000040F" to "IS", - "00000410" to "IT", - "00000411" to "JP", - "00000412" to "KO", - "00000413" to "NL", - "00000414" to "NO", - "00000415" to "PL", - "00000416" to "BR", - "00000418" to "RO", - "00000419" to "RU", - "0000041A" to "YU", - "0000041B" to "SL", - "0000041C" to "US", - "0000041D" to "SV", - "0000041F" to "TR", - "00000422" to "US", - "00000423" to "US", - "00000424" to "YU", - "00000425" to "ET", - "00000426" to "US", - "00000427" to "US", - "00000804" to "CH", - "00000809" to "UK", - "0000080A" to "LA", - "0000080C" to "BE", - "00000813" to "BE", - "00000816" to "PO", - "00000C0C" to "CF", - "00000C1A" to "US", - "00001009" to "CAFR", - "0000100C" to "SF", - "00001809" to "US", - "00010402" to "US", - "00010405" to "CZ", - "00010407" to "DEI", - "00010408" to "GK", - "00010409" to "DV", - "0001040A" to "SP", - "0001040E" to "HU", - "00010410" to "IT", - "00010415" to "PL", - "00010419" to "RUT", - "0001041B" to "SL", - "0001041F" to "TRF", - "00010426" to "US", - "00010C0C" to "CF", - "00010C1A" to "US", - "00020408" to "GK", - "00020409" to "US", - "00030409" to "USL", - "00040409" to "USR", - "00050408" to "GK" -) - -private val macKeyboardVariantMap = mapOf( - "UserDefined_19458" to "RU", // Russian - "UserDefined_com.sogou.inputmethod.pinyin" to "ZH", // Sogou Pinyin: https://pinyin.sogou.com/mac - "UserDefined_im.rime.inputmethod.Squirrel.Hans" to "ZH", // Squirrel - Simplified: https://rime.im - "UserDefined_im.rime.inputmethod.Squirrel.Hant" to "ZH" // Squirrel - Traditional: https://rime.im -) - -class KeyboardLayoutInfo(private val language: String, private val country: String, private val variant: String) { - override fun toString(): String = variant.lowercase().ifEmpty { - country.lowercase().ifEmpty { - language.lowercase() - } - } -} - class KeyboardLayout { + private val unknown = "UNK" private var linuxDistribution: String = System.getenv("DESKTOP_SESSION")?.lowercase() ?: "" private var linuxDesktopGroup: String = System.getenv("XDG_SESSION_TYPE")?.lowercase() ?: "" - private var linuxNonUbuntuKeyboardLayouts: List = emptyList() + private var linuxKeyboardLayoutsCache: List = emptyList() - fun getInfo(): KeyboardLayoutInfo { + fun getLayoutInfo(): KeyboardLayoutInfo { return when { - Platform.isLinux() -> getLinuxKeyboardLayout() - Platform.isMac() -> getMacKeyboardLayout() - Platform.isWindows() -> getWindowsKeyboardLayout() - else -> KeyboardLayoutInfo(unknown, unknown, unknown) + Platform.isLinux() -> getLinuxLayoutInfo() + Platform.isMac() -> getMacLayoutInfo() + Platform.isWindows() -> getWindowsLayoutInfo() + else -> getUnknownLayoutInfo() } } - private fun getLinuxKeyboardLayout(): KeyboardLayoutInfo { + private fun getUnknownLayoutInfo(): KeyboardLayoutInfo { + return KeyboardLayoutInfo(unknown, unknown, unknown) + } + + private fun getLinuxLayoutInfo(): KeyboardLayoutInfo { // InputContext.getInstance().locale is not working on Linux: it always returns "en_US" // This is not the ideal solution because it involves executing a shell command to know the current keyboard layout // which might affect the performance. And we have different commands for different Linux distributions. // But it is the only solution I found that works on Linux. // For Linux we know only keyboard layout and do not know keyboard language - if (linuxDistribution == "ubuntu") { - // output example: [('xkb', 'us'), ('xkb', 'ru'), ('xkb', 'ca+eng')] - val split = executeNativeCommand(arrayOf("gsettings", "get", "org.gnome.desktop.input-sources", "mru-sources")) - .substringAfter("('xkb', '") - .substringBefore("')") - .split("+") - val language = if (split.size > 1) split[1] else "" - val country = split[0] - return KeyboardLayoutInfo(language, country, "") + return when { + linuxDistribution == "ubuntu" -> getUbuntuLayoutInfo() + linuxDesktopGroup == "wayland" -> getWaylandLayoutInfo() + else -> getOtherLinuxLayoutInfo() } + } + + private fun getUbuntuLayoutInfo(): KeyboardLayoutInfo { + // Output example: [('xkb', 'us'), ('xkb', 'ru'), ('xkb', 'ca+eng')] + val split = executeNativeCommand(arrayOf("gsettings", "get", "org.gnome.desktop.input-sources", "mru-sources")) + .substringAfter("('xkb', '") + .substringBefore("')") + .split("+") + val language = if (split.size > 1) split[1] else "" + val country = split[0] + return KeyboardLayoutInfo(language, country, "") + } - // FIXME: This command does not work on linuxDesktopGroup = "wayland", + private fun getWaylandLayoutInfo(): KeyboardLayoutInfo { + // FIXME: Other Linux distribution commands not working "Wayland", // see: https://github.com/siropkin/kursor/issues/3 - if (linuxDesktopGroup == "wayland") { - return KeyboardLayoutInfo(unknown, unknown, unknown) - } + return getUnknownLayoutInfo() + } - if (linuxNonUbuntuKeyboardLayouts.isEmpty()) { - // output example: rules: evdev + private fun getOtherLinuxLayoutInfo(): KeyboardLayoutInfo { + if (linuxKeyboardLayoutsCache.isEmpty()) { + // Output example: rules: evdev //model: pc105 //layout: us //options: grp:win_space_toggle,terminate:ctrl_alt_bksp - linuxNonUbuntuKeyboardLayouts = executeNativeCommand(arrayOf("setxkbmap", "-query")) + linuxKeyboardLayoutsCache = executeNativeCommand(arrayOf("setxkbmap", "-query")) .substringAfter("layout:") .substringBefore("\n") .trim() .split(",") } - // output example: Keyboard Control: + // Output example: Keyboard Control: // auto repeat: on key click percent: 0 LED mask: 00000000 // XKB indicators: // 00: Caps Lock: off 01: Num Lock: off 02: Scroll Lock: off @@ -177,27 +106,27 @@ class KeyboardLayout { .toInt(16) // Additional check to avoid out-of-bounds exception - if (linuxCurrentKeyboardLayoutIndex >= linuxNonUbuntuKeyboardLayouts.size) { - return KeyboardLayoutInfo(unknown, unknown, unknown) + if (linuxCurrentKeyboardLayoutIndex >= linuxKeyboardLayoutsCache.size) { + return getUnknownLayoutInfo() } // This is a bad solution because it returns 0 if it's a default layout and 1 in other cases, // and if user has more than two layouts, we do not know which one is really on - if (linuxNonUbuntuKeyboardLayouts.size > 2 && linuxCurrentKeyboardLayoutIndex > 0) { - return KeyboardLayoutInfo(unknown, unknown, unknown) + if (linuxKeyboardLayoutsCache.size > 2 && linuxCurrentKeyboardLayoutIndex > 0) { + return getUnknownLayoutInfo() } - val country = linuxNonUbuntuKeyboardLayouts[linuxCurrentKeyboardLayoutIndex] + val country = linuxKeyboardLayoutsCache[linuxCurrentKeyboardLayoutIndex] return KeyboardLayoutInfo("", country, "") } - private fun getMacKeyboardLayout(): KeyboardLayoutInfo { + private fun getMacLayoutInfo(): KeyboardLayoutInfo { val locale = InputContext.getInstance().locale - val variant = macKeyboardVariantMap[locale.variant] ?: "" // variant example for US: UserDefined_252 + val variant = MacKeyboardVariants[locale.variant] ?: "" // variant example for US: UserDefined_252 return KeyboardLayoutInfo(locale.language, locale.country, variant) } - private fun getWindowsKeyboardLayout(): KeyboardLayoutInfo { + private fun getWindowsLayoutInfo(): KeyboardLayoutInfo { val locale = InputContext.getInstance().locale // Standard locale object does not return correct info in case user set different keyboard inputs for one language // see: https://github.com/siropkin/kursor/issues/4 @@ -215,21 +144,12 @@ class KeyboardLayout { val inputMethod = hkl.pointer.toString().split("@")[1] var layoutId = inputMethod.substring(0, inputMethod.length - 4) layoutId = when (layoutId) { - "0xfffffffff008" -> { - "00010419" - } - "0xfffffffff014" -> { - "0001041F" - } - "0xfffffffff012" -> { - "00010407" - } - else -> { - layoutId.substring(2).padStart(8, '0') - } + "0xfffffffff008" -> "00010419" + "0xfffffffff014" -> "0001041F" + "0xfffffffff012" -> "00010407" + else -> layoutId.substring(2).padStart(8, '0') } - layoutId = layoutId.uppercase() - val variant = windowsKeyboardVariantMap[layoutId] ?: "" + val variant = WindowsKeyboardVariants[layoutId.uppercase()] ?: "" return KeyboardLayoutInfo(locale.language, locale.country, variant) } diff --git a/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayoutInfo.kt b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayoutInfo.kt new file mode 100644 index 0000000..61b46c1 --- /dev/null +++ b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayoutInfo.kt @@ -0,0 +1,10 @@ +package com.github.siropkin.kursor.keyboardlayout + + +class KeyboardLayoutInfo(private val language: String, private val country: String, private val variant: String) { + override fun toString(): String = variant.ifEmpty { + country.ifEmpty { + language + } + } +} diff --git a/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/MacKeyboardVariants.kt b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/MacKeyboardVariants.kt new file mode 100644 index 0000000..4d22386 --- /dev/null +++ b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/MacKeyboardVariants.kt @@ -0,0 +1,9 @@ +package com.github.siropkin.kursor.keyboardlayout + + +val MacKeyboardVariants = mapOf( + "UserDefined_19458" to "RU", // Russian + "UserDefined_com.sogou.inputmethod.pinyin" to "ZH", // Sogou Pinyin: https://pinyin.sogou.com/mac + "UserDefined_im.rime.inputmethod.Squirrel.Hans" to "ZH", // Squirrel - Simplified: https://rime.im + "UserDefined_im.rime.inputmethod.Squirrel.Hant" to "ZH" // Squirrel - Traditional: https://rime.im +) diff --git a/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/WindowsKeyboardVariants.kt b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/WindowsKeyboardVariants.kt new file mode 100644 index 0000000..dcdcf74 --- /dev/null +++ b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/WindowsKeyboardVariants.kt @@ -0,0 +1,69 @@ +package com.github.siropkin.kursor.keyboardlayout + + +// https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-language-pack-default-values +val WindowsKeyboardVariants = mapOf( + "00000402" to "BG", + "00000404" to "CH", + "00000405" to "CZ", + "00000406" to "DK", + "00000407" to "DE", + "00000408" to "GK", + "00000409" to "US", + "0000040A" to "SP", + "0000040B" to "SU", + "0000040C" to "FR", + "0000040E" to "HU", + "0000040F" to "IS", + "00000410" to "IT", + "00000411" to "JP", + "00000412" to "KO", + "00000413" to "NL", + "00000414" to "NO", + "00000415" to "PL", + "00000416" to "BR", + "00000418" to "RO", + "00000419" to "RU", + "0000041A" to "YU", + "0000041B" to "SL", + "0000041C" to "US", + "0000041D" to "SV", + "0000041F" to "TR", + "00000422" to "US", + "00000423" to "US", + "00000424" to "YU", + "00000425" to "ET", + "00000426" to "US", + "00000427" to "US", + "00000804" to "CH", + "00000809" to "UK", + "0000080A" to "LA", + "0000080C" to "BE", + "00000813" to "BE", + "00000816" to "PO", + "00000C0C" to "CF", + "00000C1A" to "US", + "00001009" to "CAFR", + "0000100C" to "SF", + "00001809" to "US", + "00010402" to "US", + "00010405" to "CZ", + "00010407" to "DEI", + "00010408" to "GK", + "00010409" to "DV", + "0001040A" to "SP", + "0001040E" to "HU", + "00010410" to "IT", + "00010415" to "PL", + "00010419" to "RUT", + "0001041B" to "SL", + "0001041F" to "TRF", + "00010426" to "US", + "00010C0C" to "CF", + "00010C1A" to "US", + "00020408" to "GK", + "00020409" to "US", + "00030409" to "USL", + "00040409" to "USR", + "00050408" to "GK" +) diff --git a/src/main/kotlin/com/github/siropkin/kursor/settings/KursorSettingsComponent.kt b/src/main/kotlin/com/github/siropkin/kursor/settings/KursorSettingsComponent.kt index 2c85543..be7f483 100644 --- a/src/main/kotlin/com/github/siropkin/kursor/settings/KursorSettingsComponent.kt +++ b/src/main/kotlin/com/github/siropkin/kursor/settings/KursorSettingsComponent.kt @@ -1,16 +1,19 @@ package com.github.siropkin.kursor.settings import com.github.siropkin.kursor.IndicatorPosition -import com.github.siropkin.kursor.KeyboardLayout +import com.github.siropkin.kursor.keyboardlayout.KeyboardLayout +import com.intellij.openapi.ui.ComboBox import com.intellij.ui.ColorPanel import com.intellij.ui.components.JBCheckBox import com.intellij.ui.components.JBLabel import com.intellij.ui.components.JBTextField import com.intellij.util.ui.FormBuilder -import com.intellij.openapi.ui.ComboBox import com.intellij.util.ui.JBUI import java.awt.* -import javax.swing.* +import javax.swing.BoxLayout +import javax.swing.JButton +import javax.swing.JComponent +import javax.swing.JPanel private const val LABEL_SPACING = 10 @@ -145,7 +148,7 @@ class KursorSettingsComponent { languagePanel.add(detectKeyboardLayoutButton, createRbc(2, 0, 1.0, COMPONENT_SPACING)) detectKeyboardLayoutButton.addActionListener { - defaultLanguageComponent.text = keyboardLayout.getInfo().toString() + defaultLanguageComponent.text = keyboardLayout.getLayoutInfo().toString().lowercase() } return languagePanel From f69a5b1242f1bc6055e12a4260ac4e7d353ede9e Mon Sep 17 00:00:00 2001 From: Ivan Seredkin Date: Wed, 6 Nov 2024 10:19:57 -0500 Subject: [PATCH 6/6] #30 Add support for "Ukrainian" and "Ukrainian-QWERTY" on macOS --- CHANGELOG.md | 7 +++++-- README.md | 2 +- .../kursor/keyboardlayout/KeyboardLayout.kt | 3 ++- .../kursor/keyboardlayout/MacKeyboardVariants.kt | 13 +++++++++---- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e37ded2..e0965a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ## [1.4.2] +### Changed +- #30 Add support for "Ukrainian" and "Ukrainian-QWERTY" on macOS. + ### Fixed - #28 Fix "Do not call invokeLater when app is not yet fully initialized" error on startup. - #29 Fix "Migrate com.github.siropkin.kursor.KursorStartupActivity to ProjectActivity" development warning on startup. @@ -11,7 +14,7 @@ ## [1.4.1] ### Changed -- #18 Add support for "Squirrel Method" (Chinese) (https://rime.im) on macOS. +- #18 Add support for [Squirrel](https://rime.im) method (Zhuyin) on macOS. - #20 Add support for "Russian - PC" on macOS. - #21 Fix color settings save bug; color settings now save correctly. @@ -30,7 +33,7 @@ Version skipped due to a mistake in the release process. ## [1.3.0] - 2024-07-31 ### Changed -- Add support of Sogou Pinyin Method (Chinese) for macOS. +- Add support of [Sogou Pinyin](https://pinyin.sogou.com/mac) method (Zhuyin) for macOS. ### For Contributors and Developers - Migrate from Gradle IntelliJ Plugin 1.x to 2.0. diff --git a/README.md b/README.md index 83b18f4..416b4e8 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This feature is particularly beneficial for developers juggling multiple languag - **🔒 Caps Lock Indicator:** Shows the Caps Lock status on the cursor. - **🔧 Customization:** Customize the language indicator's font, size, opacity, and position. - **🖥️ Supported Operating Systems:** Available on Windows, Mac, and Linux. -- **🌐 Supported Languages And Input Methods:** Supports a wide range of languages and input methods, including [Sogou Pinyin](https://pinyin.sogou.com/mac) and [Squirrel](https://rime.im) Chinese methods on macOS. +- **🌐 Supported Languages And Input Methods:** Supports a wide range of languages and input methods, including [Sogou Pinyin](https://pinyin.sogou.com/mac) and [Squirrel](https://rime.im) Zhuyin methods on macOS. ## Usage diff --git a/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayout.kt b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayout.kt index ec9e3f1..ab76fef 100644 --- a/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayout.kt +++ b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/KeyboardLayout.kt @@ -122,7 +122,8 @@ class KeyboardLayout { private fun getMacLayoutInfo(): KeyboardLayoutInfo { val locale = InputContext.getInstance().locale - val variant = MacKeyboardVariants[locale.variant] ?: "" // variant example for US: UserDefined_252 + // Variant example for US: UserDefined_252 + val variant = MacKeyboardVariants[locale.variant] ?: "" return KeyboardLayoutInfo(locale.language, locale.country, variant) } diff --git a/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/MacKeyboardVariants.kt b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/MacKeyboardVariants.kt index 4d22386..1ea4754 100644 --- a/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/MacKeyboardVariants.kt +++ b/src/main/kotlin/com/github/siropkin/kursor/keyboardlayout/MacKeyboardVariants.kt @@ -1,9 +1,14 @@ package com.github.siropkin.kursor.keyboardlayout +// https://github.com/acidanthera/OpenCorePkg/blob/master/Utilities/AppleKeyboardLayouts/AppleKeyboardLayouts.txt val MacKeyboardVariants = mapOf( - "UserDefined_19458" to "RU", // Russian - "UserDefined_com.sogou.inputmethod.pinyin" to "ZH", // Sogou Pinyin: https://pinyin.sogou.com/mac - "UserDefined_im.rime.inputmethod.Squirrel.Hans" to "ZH", // Squirrel - Simplified: https://rime.im - "UserDefined_im.rime.inputmethod.Squirrel.Hant" to "ZH" // Squirrel - Traditional: https://rime.im + // Standard layouts + "UserDefined_19458" to "RU", // Russian - PC + "UserDefined_-23205" to "UK", // Ukrainian-QWERTY + "UserDefined_-2354" to "UK", // Ukrainian + // Additional layouts + "UserDefined_com.sogou.inputmethod.pinyin" to "ZH", // Zhuyin, Sogou Pinyin: https://pinyin.sogou.com/mac + "UserDefined_im.rime.inputmethod.Squirrel.Hans" to "ZH", // Zhuyin , Squirrel - Simplified: https://rime.im + "UserDefined_im.rime.inputmethod.Squirrel.Hant" to "ZH" // Zhuyin, Squirrel - Traditional: https://rime.im )