Merge branch 'main' of github.com:noctalia-dev/noctalia-shell
This commit is contained in:
commit
b157d855a8
8 changed files with 423 additions and 33 deletions
202
Commons/KeyboardLayout.qml
Normal file
202
Commons/KeyboardLayout.qml
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// Comprehensive language name to ISO code mapping
|
||||||
|
property var languageMap: {
|
||||||
|
"english"// English variants
|
||||||
|
: "us",
|
||||||
|
"american": "us",
|
||||||
|
"united states": "us",
|
||||||
|
"us english": "us",
|
||||||
|
"british": "gb",
|
||||||
|
"uk": "gb",
|
||||||
|
"united kingdom": "gb",
|
||||||
|
"english (uk)": "gb",
|
||||||
|
"canadian": "ca",
|
||||||
|
"canada": "ca",
|
||||||
|
"canadian english": "ca",
|
||||||
|
"australian": "au",
|
||||||
|
"australia": "au",
|
||||||
|
"swedish"// Nordic countries
|
||||||
|
: "se",
|
||||||
|
"svenska": "se",
|
||||||
|
"sweden": "se",
|
||||||
|
"norwegian": "no",
|
||||||
|
"norsk": "no",
|
||||||
|
"norway": "no",
|
||||||
|
"danish": "dk",
|
||||||
|
"dansk": "dk",
|
||||||
|
"denmark": "dk",
|
||||||
|
"finnish": "fi",
|
||||||
|
"suomi": "fi",
|
||||||
|
"finland": "fi",
|
||||||
|
"icelandic": "is",
|
||||||
|
"íslenska": "is",
|
||||||
|
"iceland": "is",
|
||||||
|
"german"// Western/Central European Germanic
|
||||||
|
: "de",
|
||||||
|
"deutsch": "de",
|
||||||
|
"germany": "de",
|
||||||
|
"austrian": "at",
|
||||||
|
"austria": "at",
|
||||||
|
"österreich": "at",
|
||||||
|
"swiss": "ch",
|
||||||
|
"switzerland": "ch",
|
||||||
|
"schweiz": "ch",
|
||||||
|
"suisse": "ch",
|
||||||
|
"dutch": "nl",
|
||||||
|
"nederlands": "nl",
|
||||||
|
"netherlands": "nl",
|
||||||
|
"holland": "nl",
|
||||||
|
"belgian": "be",
|
||||||
|
"belgium": "be",
|
||||||
|
"belgië": "be",
|
||||||
|
"belgique": "be",
|
||||||
|
"french"// Romance languages (Western/Southern Europe)
|
||||||
|
: "fr",
|
||||||
|
"français": "fr",
|
||||||
|
"france": "fr",
|
||||||
|
"canadian french": "ca",
|
||||||
|
"spanish": "es",
|
||||||
|
"español": "es",
|
||||||
|
"spain": "es",
|
||||||
|
"castilian": "es",
|
||||||
|
"italian": "it",
|
||||||
|
"italiano": "it",
|
||||||
|
"italy": "it",
|
||||||
|
"portuguese": "pt",
|
||||||
|
"português": "pt",
|
||||||
|
"portugal": "pt",
|
||||||
|
"catalan": "ad",
|
||||||
|
"català": "ad",
|
||||||
|
"andorra": "ad",
|
||||||
|
"romanian"// Eastern European Romance
|
||||||
|
: "ro",
|
||||||
|
"română": "ro",
|
||||||
|
"romania": "ro",
|
||||||
|
"russian"// Slavic languages (Eastern Europe)
|
||||||
|
: "ru",
|
||||||
|
"русский": "ru",
|
||||||
|
"russia": "ru",
|
||||||
|
"polish": "pl",
|
||||||
|
"polski": "pl",
|
||||||
|
"poland": "pl",
|
||||||
|
"czech": "cz",
|
||||||
|
"čeština": "cz",
|
||||||
|
"czech republic": "cz",
|
||||||
|
"slovak": "sk",
|
||||||
|
"slovenčina": "sk",
|
||||||
|
"slovakia": "sk",
|
||||||
|
"ukrainian": "ua",
|
||||||
|
"українська": "ua",
|
||||||
|
"ukraine": "ua",
|
||||||
|
"bulgarian": "bg",
|
||||||
|
"български": "bg",
|
||||||
|
"bulgaria": "bg",
|
||||||
|
"serbian": "rs",
|
||||||
|
"srpski": "rs",
|
||||||
|
"serbia": "rs",
|
||||||
|
"croatian": "hr",
|
||||||
|
"hrvatski": "hr",
|
||||||
|
"croatia": "hr",
|
||||||
|
"slovenian": "si",
|
||||||
|
"slovenščina": "si",
|
||||||
|
"slovenia": "si",
|
||||||
|
"bosnian": "ba",
|
||||||
|
"bosanski": "ba",
|
||||||
|
"bosnia": "ba",
|
||||||
|
"macedonian": "mk",
|
||||||
|
"македонски": "mk",
|
||||||
|
"macedonia": "mk",
|
||||||
|
"irish"// Celtic languages (Western Europe)
|
||||||
|
: "ie",
|
||||||
|
"gaeilge": "ie",
|
||||||
|
"ireland": "ie",
|
||||||
|
"welsh": "gb",
|
||||||
|
"cymraeg": "gb",
|
||||||
|
"wales": "gb",
|
||||||
|
"scottish": "gb",
|
||||||
|
"gàidhlig": "gb",
|
||||||
|
"scotland": "gb",
|
||||||
|
"estonian"// Baltic languages (Northern Europe)
|
||||||
|
: "ee",
|
||||||
|
"eesti": "ee",
|
||||||
|
"estonia": "ee",
|
||||||
|
"latvian": "lv",
|
||||||
|
"latviešu": "lv",
|
||||||
|
"latvia": "lv",
|
||||||
|
"lithuanian": "lt",
|
||||||
|
"lietuvių": "lt",
|
||||||
|
"lithuania": "lt",
|
||||||
|
"hungarian"// Other European languages
|
||||||
|
: "hu",
|
||||||
|
"magyar": "hu",
|
||||||
|
"hungary": "hu",
|
||||||
|
"greek": "gr",
|
||||||
|
"ελληνικά": "gr",
|
||||||
|
"greece": "gr",
|
||||||
|
"albanian": "al",
|
||||||
|
"shqip": "al",
|
||||||
|
"albania": "al",
|
||||||
|
"maltese": "mt",
|
||||||
|
"malti": "mt",
|
||||||
|
"malta": "mt",
|
||||||
|
"turkish"// West/Southwest Asian languages
|
||||||
|
: "tr",
|
||||||
|
"türkçe": "tr",
|
||||||
|
"turkey": "tr",
|
||||||
|
"arabic": "ar",
|
||||||
|
"العربية": "ar",
|
||||||
|
"arab": "ar",
|
||||||
|
"hebrew": "il",
|
||||||
|
"עברית": "il",
|
||||||
|
"israel": "il",
|
||||||
|
"brazilian"// South American languages
|
||||||
|
: "br",
|
||||||
|
"brazilian portuguese": "br",
|
||||||
|
"brasil": "br",
|
||||||
|
"brazil": "br",
|
||||||
|
"japanese"// East Asian languages
|
||||||
|
: "jp",
|
||||||
|
"日本語": "jp",
|
||||||
|
"japan": "jp",
|
||||||
|
"korean": "kr",
|
||||||
|
"한국어": "kr",
|
||||||
|
"korea": "kr",
|
||||||
|
"south korea": "kr",
|
||||||
|
"chinese": "cn",
|
||||||
|
"中文": "cn",
|
||||||
|
"china": "cn",
|
||||||
|
"simplified chinese": "cn",
|
||||||
|
"traditional chinese": "tw",
|
||||||
|
"taiwan": "tw",
|
||||||
|
"繁體中文": "tw",
|
||||||
|
"thai"// Southeast Asian languages
|
||||||
|
: "th",
|
||||||
|
"ไทย": "th",
|
||||||
|
"thailand": "th",
|
||||||
|
"vietnamese": "vn",
|
||||||
|
"tiếng việt": "vn",
|
||||||
|
"vietnam": "vn",
|
||||||
|
"hindi"// South Asian languages
|
||||||
|
: "in",
|
||||||
|
"हिन्दी": "in",
|
||||||
|
"india": "in",
|
||||||
|
"afrikaans"// African languages
|
||||||
|
: "za",
|
||||||
|
"south africa": "za",
|
||||||
|
"south african": "za",
|
||||||
|
"qwerty"// Layout variants
|
||||||
|
: "us",
|
||||||
|
"dvorak": "us",
|
||||||
|
"colemak": "us",
|
||||||
|
"workman": "us",
|
||||||
|
"azerty": "fr",
|
||||||
|
"norman": "fr",
|
||||||
|
"qwertz": "de"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,26 @@ Item {
|
||||||
property ShellScreen screen
|
property ShellScreen screen
|
||||||
property real scaling: 1.0
|
property real scaling: 1.0
|
||||||
|
|
||||||
|
// Widget properties passed from Bar.qml for per-instance settings
|
||||||
|
property string widgetId: ""
|
||||||
|
property string barSection: ""
|
||||||
|
property int sectionWidgetIndex: -1
|
||||||
|
property int sectionWidgetsCount: 0
|
||||||
|
|
||||||
|
property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
|
||||||
|
property var widgetSettings: {
|
||||||
|
var section = barSection.replace("Section", "").toLowerCase()
|
||||||
|
if (section && sectionWidgetIndex >= 0) {
|
||||||
|
var widgets = Settings.data.bar.widgets[section]
|
||||||
|
if (widgets && sectionWidgetIndex < widgets.length) {
|
||||||
|
return widgets[sectionWidgetIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property bool forceOpen: (widgetSettings.forceOpen !== undefined) ? widgetSettings.forceOpen : widgetMetadata.forceOpen
|
||||||
|
|
||||||
// Use the shared service for keyboard layout
|
// Use the shared service for keyboard layout
|
||||||
property string currentLayout: KeyboardLayoutService.currentLayout
|
property string currentLayout: KeyboardLayoutService.currentLayout
|
||||||
|
|
||||||
|
|
@ -26,8 +46,10 @@ Item {
|
||||||
rightOpen: BarWidgetRegistry.getNPillDirection(root)
|
rightOpen: BarWidgetRegistry.getNPillDirection(root)
|
||||||
icon: "keyboard"
|
icon: "keyboard"
|
||||||
autoHide: false // Important to be false so we can hover as long as we want
|
autoHide: false // Important to be false so we can hover as long as we want
|
||||||
text: currentLayout
|
text: currentLayout.toUpperCase()
|
||||||
tooltipText: "Keyboard layout: " + currentLayout
|
tooltipText: "Keyboard layout: " + currentLayout.toUpperCase()
|
||||||
|
forceOpen: root.forceOpen
|
||||||
|
fontSize: Style.fontSizeS // Use larger font size
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,7 @@ NPanel {
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
context: Qt.WidgetShortcut
|
||||||
enabled: root.opened
|
enabled: root.opened
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ Popup {
|
||||||
"Brightness": "WidgetSettings/BrightnessSettings.qml",
|
"Brightness": "WidgetSettings/BrightnessSettings.qml",
|
||||||
"Clock": "WidgetSettings/ClockSettings.qml",
|
"Clock": "WidgetSettings/ClockSettings.qml",
|
||||||
"CustomButton": "WidgetSettings/CustomButtonSettings.qml",
|
"CustomButton": "WidgetSettings/CustomButtonSettings.qml",
|
||||||
|
"KeyboardLayout": "WidgetSettings/KeyboardLayoutSettings.qml",
|
||||||
"MediaMini": "WidgetSettings/MediaMiniSettings.qml",
|
"MediaMini": "WidgetSettings/MediaMiniSettings.qml",
|
||||||
"Microphone": "WidgetSettings/MicrophoneSettings.qml",
|
"Microphone": "WidgetSettings/MicrophoneSettings.qml",
|
||||||
"NotificationHistory": "WidgetSettings/NotificationHistorySettings.qml",
|
"NotificationHistory": "WidgetSettings/NotificationHistorySettings.qml",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Widgets
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
spacing: Style.marginM * scaling
|
||||||
|
|
||||||
|
// Properties to receive data from parent
|
||||||
|
property var widgetData: null
|
||||||
|
property var widgetMetadata: null
|
||||||
|
|
||||||
|
// Local state
|
||||||
|
property bool valueForceOpen: widgetData.forceOpen !== undefined ? widgetData.forceOpen : widgetMetadata.forceOpen
|
||||||
|
|
||||||
|
function saveSettings() {
|
||||||
|
var settings = Object.assign({}, widgetData || {})
|
||||||
|
settings.forceOpen = valueForceOpen
|
||||||
|
return settings
|
||||||
|
}
|
||||||
|
|
||||||
|
NToggle {
|
||||||
|
label: "Force open"
|
||||||
|
description: "Keep the keyboard layout widget always expanded."
|
||||||
|
checked: valueForceOpen
|
||||||
|
onToggled: checked => valueForceOpen = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -104,6 +104,10 @@ Singleton {
|
||||||
"Volume": {
|
"Volume": {
|
||||||
"allowUserSettings": true,
|
"allowUserSettings": true,
|
||||||
"alwaysShowPercentage": false
|
"alwaysShowPercentage": false
|
||||||
|
},
|
||||||
|
"KeyboardLayout": {
|
||||||
|
"allowUserSettings": true,
|
||||||
|
"forceOpen": false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import qs.Services
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string currentLayout: "Unknown"
|
property string currentLayout: "Unknown"
|
||||||
property int updateInterval: 1000 // Update every second
|
property int updateInterval: 1000 // Update every second
|
||||||
|
|
||||||
|
|
@ -34,8 +33,9 @@ Singleton {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(text)
|
const data = JSON.parse(text)
|
||||||
const layoutName = data.names[data.current_idx]
|
const layoutName = data.names[data.current_idx]
|
||||||
root.currentLayout = mapLayoutNameToCode(layoutName)
|
root.currentLayout = extractLayoutCode(layoutName)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.log("Niri layout error:", e)
|
||||||
root.currentLayout = "Unknown"
|
root.currentLayout = "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -54,45 +54,157 @@ Singleton {
|
||||||
// Find the main keyboard and get its active keymap
|
// Find the main keyboard and get its active keymap
|
||||||
const mainKeyboard = data.keyboards.find(kb => kb.main === true)
|
const mainKeyboard = data.keyboards.find(kb => kb.main === true)
|
||||||
if (mainKeyboard && mainKeyboard.active_keymap) {
|
if (mainKeyboard && mainKeyboard.active_keymap) {
|
||||||
root.currentLayout = mapLayoutNameToCode(mainKeyboard.active_keymap)
|
root.currentLayout = extractLayoutCode(mainKeyboard.active_keymap)
|
||||||
} else {
|
} else {
|
||||||
root.currentLayout = "Unknown"
|
root.currentLayout = "Unknown"
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.log("Hyprland layout error:", e)
|
||||||
root.currentLayout = "Unknown"
|
root.currentLayout = "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout name to ISO code mapping
|
// Process for X11 systems using setxkbmap
|
||||||
property var layoutMap: {
|
Process {
|
||||||
"German": "de",
|
id: x11LayoutProcess
|
||||||
"English (US)": "us",
|
running: false
|
||||||
"English (UK)": "gb",
|
command: ["setxkbmap", "-query"]
|
||||||
"French": "fr",
|
stdout: StdioCollector {
|
||||||
"Spanish": "es",
|
onStreamFinished: {
|
||||||
"Italian": "it",
|
try {
|
||||||
"Portuguese (Brazil)": "br",
|
const lines = text.split('\n')
|
||||||
"Portuguese": "pt",
|
for (const line of lines) {
|
||||||
"Russian": "ru",
|
if (line.startsWith('layout:')) {
|
||||||
"Polish": "pl",
|
const layout = line.split(':')[1].trim()
|
||||||
"Swedish": "se",
|
root.currentLayout = layout
|
||||||
"Norwegian": "no",
|
return
|
||||||
"Danish": "dk",
|
}
|
||||||
"Finnish": "fi",
|
}
|
||||||
"Hungarian": "hu",
|
root.currentLayout = "Unknown"
|
||||||
"Turkish": "tr",
|
} catch (e) {
|
||||||
"Czech": "cz",
|
console.log("X11 layout error:", e)
|
||||||
"Slovak": "sk",
|
root.currentLayout = "Unknown"
|
||||||
"Japanese": "jp",
|
}
|
||||||
"Korean": "kr",
|
}
|
||||||
"Chinese": "cn"
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map layout names to ISO codes
|
// Process for general Wayland using localectl (systemd)
|
||||||
function mapLayoutNameToCode(layoutName) {
|
Process {
|
||||||
return layoutMap[layoutName] || layoutName // fallback to raw name if not found
|
id: localectlProcess
|
||||||
|
running: false
|
||||||
|
command: ["localectl", "status"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
try {
|
||||||
|
const lines = text.split('\n')
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.includes('X11 Layout:')) {
|
||||||
|
const layout = line.split(':')[1].trim()
|
||||||
|
if (layout && layout !== "n/a") {
|
||||||
|
root.currentLayout = layout
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line.includes('VC Keymap:')) {
|
||||||
|
const keymap = line.split(':')[1].trim()
|
||||||
|
if (keymap && keymap !== "n/a") {
|
||||||
|
root.currentLayout = extractLayoutCode(keymap)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root.currentLayout = "Unknown"
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Localectl error:", e)
|
||||||
|
root.currentLayout = "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process for generic keyboard layout detection using gsettings (GNOME-based)
|
||||||
|
Process {
|
||||||
|
id: gsettingsProcess
|
||||||
|
running: false
|
||||||
|
command: ["gsettings", "get", "org.gnome.desktop.input-sources", "current"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
try {
|
||||||
|
const currentIndex = parseInt(text.trim())
|
||||||
|
gsettingsSourcesProcess.running = true
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Gsettings current error:", e)
|
||||||
|
fallbackToLocalectl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: gsettingsSourcesProcess
|
||||||
|
running: false
|
||||||
|
command: ["gsettings", "get", "org.gnome.desktop.input-sources", "sources"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
try {
|
||||||
|
// Parse the sources array and extract layout codes
|
||||||
|
const sourcesText = text.trim()
|
||||||
|
const matches = sourcesText.match(/\('xkb', '([^']+)'\)/g)
|
||||||
|
if (matches && matches.length > 0) {
|
||||||
|
// Get the first layout as default
|
||||||
|
const layoutMatch = matches[0].match(/\('xkb', '([^']+)'\)/)
|
||||||
|
if (layoutMatch) {
|
||||||
|
root.currentLayout = layoutMatch[1].split('+')[0] // Take first part before any variants
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fallbackToLocalectl()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Gsettings sources error:", e)
|
||||||
|
fallbackToLocalectl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fallbackToLocalectl() {
|
||||||
|
localectlProcess.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract layout code from various format strings using Commons data
|
||||||
|
function extractLayoutCode(layoutString) {
|
||||||
|
if (!layoutString)
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
const str = layoutString.toLowerCase()
|
||||||
|
|
||||||
|
// If it's already a short code (2-3 chars), return as-is
|
||||||
|
if (/^[a-z]{2,3}(\+.*)?$/.test(str)) {
|
||||||
|
return str.split('+')[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract from parentheses like "English (US)"
|
||||||
|
const parenMatch = str.match(/\(([a-z]{2,3})\)/)
|
||||||
|
if (parenMatch) {
|
||||||
|
return parenMatch[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for exact matches or partial matches in language map from Commons
|
||||||
|
const entries = Object.entries(KeyboardLayout.languageMap)
|
||||||
|
for (var i = 0; i < entries.length; i++) {
|
||||||
|
const lang = entries[i][0]
|
||||||
|
const code = entries[i][1]
|
||||||
|
if (str.includes(lang)) {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If nothing matches, try first 2-3 characters if they look like a code
|
||||||
|
const codeMatch = str.match(/^([a-z]{2,3})/)
|
||||||
|
return codeMatch ? codeMatch[1] : "unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
@ -101,12 +213,28 @@ Singleton {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLayout() {
|
function updateLayout() {
|
||||||
|
// Try compositor-specific methods first
|
||||||
if (CompositorService.isHyprland) {
|
if (CompositorService.isHyprland) {
|
||||||
hyprlandLayoutProcess.running = true
|
hyprlandLayoutProcess.running = true
|
||||||
} else if (CompositorService.isNiri) {
|
} else if (CompositorService.isNiri) {
|
||||||
niriLayoutProcess.running = true
|
niriLayoutProcess.running = true
|
||||||
} else {
|
} else {
|
||||||
currentLayout = "Unknown"
|
// Try detection methods in order of preference
|
||||||
|
if (Qt.platform.os === "linux") {
|
||||||
|
// Check if we're in X11 or Wayland
|
||||||
|
const sessionType = Qt.application.arguments.find(arg => arg.includes("QT_QPA_PLATFORM"))
|
||||||
|
|| process.env.XDG_SESSION_TYPE
|
||||||
|
|
||||||
|
if (sessionType && sessionType.includes("xcb") || process.env.DISPLAY) {
|
||||||
|
// X11 system
|
||||||
|
x11LayoutProcess.running = true
|
||||||
|
} else {
|
||||||
|
// Wayland or unknown - try gsettings first, then localectl
|
||||||
|
gsettingsProcess.running = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentLayout = "Unknown"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ Item {
|
||||||
property bool disableOpen: false
|
property bool disableOpen: false
|
||||||
property bool rightOpen: false
|
property bool rightOpen: false
|
||||||
property bool hovered: false
|
property bool hovered: false
|
||||||
|
property real fontSize: Style.fontSizeXS
|
||||||
|
|
||||||
// Effective shown state (true if hovered/animated open or forced)
|
// Effective shown state (true if hovered/animated open or forced)
|
||||||
readonly property bool revealed: forceOpen || showPill
|
readonly property bool revealed: forceOpen || showPill
|
||||||
|
|
@ -69,7 +70,7 @@ Item {
|
||||||
return centerX + offset
|
return centerX + offset
|
||||||
}
|
}
|
||||||
text: root.text
|
text: root.text
|
||||||
font.pointSize: Style.fontSizeXS * scaling
|
font.pointSize: root.fontSize * scaling
|
||||||
font.weight: Style.fontWeightBold
|
font.weight: Style.fontWeightBold
|
||||||
color: Color.mPrimary
|
color: Color.mPrimary
|
||||||
visible: revealed
|
visible: revealed
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue