Add KeyboardLayoutService, add KeyboardLayout Widget, add KeyboardLayout to LockScreen
This commit is contained in:
parent
2029b5e1eb
commit
ca7e0cc105
4 changed files with 173 additions and 1 deletions
|
|
@ -65,7 +65,7 @@ QtObject {
|
||||||
// This is where you should add your Modules/Bar/Widgets/
|
// This is where you should add your Modules/Bar/Widgets/
|
||||||
// so it gets registered in the BarTab
|
// so it gets registered in the BarTab
|
||||||
function discoverAvailableWidgets() {
|
function discoverAvailableWidgets() {
|
||||||
const widgetFiles = ["ActiveWindow", "Battery", "Bluetooth", "Brightness", "Clock", "MediaMini", "NotificationHistory", "PowerProfile", "ScreenRecorderIndicator", "SidePanelToggle", "SystemMonitor", "Tray", "Volume", "WiFi", "Workspace"]
|
const widgetFiles = ["ActiveWindow", "Battery", "Bluetooth", "Brightness", "Clock", "KeyboardLayout", "MediaMini", "NotificationHistory", "PowerProfile", "ScreenRecorderIndicator", "SidePanelToggle", "SystemMonitor", "Tray", "Volume", "WiFi", "Workspace"]
|
||||||
|
|
||||||
const availableWidgets = []
|
const availableWidgets = []
|
||||||
|
|
||||||
|
|
|
||||||
34
Modules/Bar/Widgets/KeyboardLayout.qml
Normal file
34
Modules/Bar/Widgets/KeyboardLayout.qml
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: pill.width
|
||||||
|
height: pill.height
|
||||||
|
|
||||||
|
// Use the shared service for keyboard layout
|
||||||
|
property string currentLayout: KeyboardLayoutService.currentLayout
|
||||||
|
|
||||||
|
NPill {
|
||||||
|
id: pill
|
||||||
|
icon: "keyboard_alt"
|
||||||
|
iconCircleColor: Color.mPrimary
|
||||||
|
collapsedIconColor: Color.mOnSurface
|
||||||
|
autoHide: false // Important to be false so we can hover as long as we want
|
||||||
|
text: currentLayout
|
||||||
|
tooltipText: "Keyboard Layout: " + currentLayout
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
// You could open keyboard settings here if needed
|
||||||
|
// For now, just show the current layout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -163,6 +163,13 @@ Loader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keyboard layout indicator component
|
||||||
|
Item {
|
||||||
|
id: keyboardLayout
|
||||||
|
|
||||||
|
property string currentLayout: (typeof KeyboardLayoutService !== 'undefined' && KeyboardLayoutService.currentLayout) ? KeyboardLayoutService.currentLayout : "Unknown"
|
||||||
|
}
|
||||||
|
|
||||||
// Wallpaper image
|
// Wallpaper image
|
||||||
Image {
|
Image {
|
||||||
id: lockBgImage
|
id: lockBgImage
|
||||||
|
|
@ -580,6 +587,25 @@ Loader {
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keyboard layout indicator
|
||||||
|
Row {
|
||||||
|
spacing: Style.marginS * scaling
|
||||||
|
|
||||||
|
NText {
|
||||||
|
text: keyboardLayout.currentLayout
|
||||||
|
color: Color.mOnSurface
|
||||||
|
font.family: Settings.data.ui.fontFixed
|
||||||
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
|
font.weight: Style.fontWeightBold
|
||||||
|
}
|
||||||
|
|
||||||
|
NIcon {
|
||||||
|
text: "keyboard_alt"
|
||||||
|
font.pointSize: Style.fontSizeM * scaling
|
||||||
|
color: Color.mOnSurface
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
112
Services/KeyboardLayoutService.qml
Normal file
112
Services/KeyboardLayoutService.qml
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string currentLayout: "Unknown"
|
||||||
|
property int updateInterval: 1000 // Update every second
|
||||||
|
|
||||||
|
// Timer to periodically update the layout
|
||||||
|
Timer {
|
||||||
|
id: updateTimer
|
||||||
|
interval: updateInterval
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
updateLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process to get current keyboard layout using niri msg (Wayland native)
|
||||||
|
Process {
|
||||||
|
id: niriLayoutProcess
|
||||||
|
running: false
|
||||||
|
command: ["niri", "msg", "-j", "keyboard-layouts"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(text)
|
||||||
|
const layoutName = data.names[data.current_idx]
|
||||||
|
root.currentLayout = mapLayoutNameToCode(layoutName)
|
||||||
|
} catch (e) {
|
||||||
|
root.currentLayout = "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process to get current keyboard layout using hyprctl (Hyprland)
|
||||||
|
Process {
|
||||||
|
id: hyprlandLayoutProcess
|
||||||
|
running: false
|
||||||
|
command: ["hyprctl", "-j", "devices"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(text)
|
||||||
|
// Find the main keyboard and get its active keymap
|
||||||
|
const mainKeyboard = data.keyboards.find(kb => kb.main === true)
|
||||||
|
if (mainKeyboard && mainKeyboard.active_keymap) {
|
||||||
|
root.currentLayout = mapLayoutNameToCode(mainKeyboard.active_keymap)
|
||||||
|
} else {
|
||||||
|
root.currentLayout = "Unknown"
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
root.currentLayout = "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layout name to ISO code mapping
|
||||||
|
property var layoutMap: {
|
||||||
|
"German": "de",
|
||||||
|
"English (US)": "us",
|
||||||
|
"English (UK)": "gb",
|
||||||
|
"French": "fr",
|
||||||
|
"Spanish": "es",
|
||||||
|
"Italian": "it",
|
||||||
|
"Portuguese (Brazil)": "br",
|
||||||
|
"Portuguese": "pt",
|
||||||
|
"Russian": "ru",
|
||||||
|
"Polish": "pl",
|
||||||
|
"Swedish": "se",
|
||||||
|
"Norwegian": "no",
|
||||||
|
"Danish": "dk",
|
||||||
|
"Finnish": "fi",
|
||||||
|
"Hungarian": "hu",
|
||||||
|
"Turkish": "tr",
|
||||||
|
"Czech": "cz",
|
||||||
|
"Slovak": "sk",
|
||||||
|
"Japanese": "jp",
|
||||||
|
"Korean": "kr",
|
||||||
|
"Chinese": "cn"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map layout names to ISO codes
|
||||||
|
function mapLayoutNameToCode(layoutName) {
|
||||||
|
return layoutMap[layoutName] || layoutName // fallback to raw name if not found
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
Logger.log("KeyboardLayout", "Service started")
|
||||||
|
updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLayout() {
|
||||||
|
if (CompositorService.isHyprland) {
|
||||||
|
hyprlandLayoutProcess.running = true
|
||||||
|
} else if (CompositorService.isNiri) {
|
||||||
|
niriLayoutProcess.running = true
|
||||||
|
} else {
|
||||||
|
currentLayout = "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue