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/
|
||||
// so it gets registered in the BarTab
|
||||
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 = []
|
||||
|
||||
|
|
|
|||
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
|
||||
Image {
|
||||
id: lockBgImage
|
||||
|
|
@ -580,6 +587,25 @@ Loader {
|
|||
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