Merge branch 'rebuild' of https://github.com/Ly-sec/Noctalia into rebuild

This commit is contained in:
Ly-sec 2025-08-15 23:27:36 +02:00
commit 2629b4707d
3 changed files with 109 additions and 104 deletions

View file

@ -9,10 +9,10 @@ Row {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Style.marginSmall * scaling spacing: Style.marginSmall * scaling
visible: Settings.data.bar.showActiveWindow visible: Settings.data.bar.showActiveWindow
property bool showingFullTitle: false property bool showingFullTitle: false
property int lastWindowIndex: -1 property int lastWindowIndex: -1
// Timer to hide full title after window switch // Timer to hide full title after window switch
Timer { Timer {
id: fullTitleTimer id: fullTitleTimer
@ -23,7 +23,7 @@ Row {
titleText.text = getDisplayText() titleText.text = getDisplayText()
} }
} }
// Update text when window changes // Update text when window changes
Connections { Connections {
target: typeof Niri !== "undefined" ? Niri : null target: typeof Niri !== "undefined" ? Niri : null
@ -37,7 +37,7 @@ Row {
titleText.text = getDisplayText() titleText.text = getDisplayText()
} }
} }
// Window icon // Window icon
NText { NText {
id: windowIcon id: windowIcon
@ -49,21 +49,21 @@ Row {
color: Colors.mPrimary color: Colors.mPrimary
visible: getDisplayText() !== "" visible: getDisplayText() !== ""
} }
// Window title container // Window title container
Item { Item {
id: titleContainer id: titleContainer
width: titleText.width width: titleText.width
height: titleText.height height: titleText.height
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
Behavior on width { Behavior on width {
NumberAnimation { NumberAnimation {
duration: 300 duration: 300
easing.type: Easing.OutCubic easing.type: Easing.OutCubic
} }
} }
NText { NText {
id: titleText id: titleText
text: getDisplayText() text: getDisplayText()
@ -73,79 +73,76 @@ Row {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight elide: Text.ElideRight
} }
// Mouse area for hover detection
MouseArea {
id: titleContainerMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.IBeamCursor
onEntered: {
titleText.text = getDisplayText()
}
onExited: {
titleText.text = getDisplayText()
}
}
}
// Mouse area for hover detection
MouseArea {
id: titleContainerMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.IBeamCursor
onEntered: {
titleText.text = getDisplayText()
}
onExited: {
titleText.text = getDisplayText()
}
}
}
function getDisplayText() { function getDisplayText() {
// Check if Niri service is available // Check if Niri service is available
if (typeof Niri === "undefined") { if (typeof Niri === "undefined") {
return "" return ""
} }
// Get the focused window data // Get the focused window data
const focusedWindow = Niri.focusedWindowIndex >= 0 && Niri.focusedWindowIndex < Niri.windows.length const focusedWindow = Niri.focusedWindowIndex >= 0
? Niri.windows[Niri.focusedWindowIndex] && Niri.focusedWindowIndex < Niri.windows.length ? Niri.windows[Niri.focusedWindowIndex] : null
: null
if (!focusedWindow) { if (!focusedWindow) {
return "" return ""
} }
const appId = focusedWindow.appId || "" const appId = focusedWindow.appId || ""
const title = focusedWindow.title || "" const title = focusedWindow.title || ""
// If no appId, fall back to title processing // If no appId, fall back to title processing
if (!appId) { if (!appId) {
if (!title || title === "(No active window)" || title === "(Unnamed window)") { if (!title || title === "(No active window)" || title === "(Unnamed window)") {
return "" return ""
} }
// Extract program name from title (before first space or special characters) // Extract program name from title (before first space or special characters)
const programName = title.split(/[\s\-_]/)[0] const programName = title.split(/[\s\-_]/)[0]
if (programName.length <= 2 || programName === title) { if (programName.length <= 2 || programName === title) {
return truncateTitle(title) return truncateTitle(title)
} }
if (showingFullTitle || titleContainerMouseArea.containsMouse || isGenericName(programName)) { if (showingFullTitle || titleContainerMouseArea.containsMouse || isGenericName(programName)) {
return truncateTitle(title) return truncateTitle(title)
} }
return programName return programName
} }
// Use appId for program name, show full title on hover or window switch // Use appId for program name, show full title on hover or window switch
if (showingFullTitle || titleContainerMouseArea.containsMouse) { if (showingFullTitle || titleContainerMouseArea.containsMouse) {
return truncateTitle(title || appId) return truncateTitle(title || appId)
} }
return appId return appId
} }
function truncateTitle(title) { function truncateTitle(title) {
if (title.length > 50) { if (title.length > 50) {
return title.substring(0, 47) + "..." return title.substring(0, 47) + "..."
} }
return title return title
} }
function isGenericName(name) { function isGenericName(name) {
const genericNames = ["window", "application", "app", "program", "process", "unknown"] const genericNames = ["window", "application", "app", "program", "process", "unknown"]
return genericNames.includes(name.toLowerCase()) return genericNames.includes(name.toLowerCase())
} }
} }

View file

@ -9,27 +9,27 @@ ColumnLayout {
id: root id: root
spacing: 0 spacing: 0
// Helper function to get color from scheme file // Helper function to get color from scheme file
function getSchemeColor(schemePath, colorKey) { function getSchemeColor(schemePath, colorKey) {
// Extract scheme name from path // Extract scheme name from path
var schemeName = schemePath.split("/").pop().replace(".json", "") var schemeName = schemePath.split("/").pop().replace(".json", "")
// Try to get from cached data first // Try to get from cached data first
if (schemeColorsCache[schemeName] && schemeColorsCache[schemeName][colorKey]) { if (schemeColorsCache[schemeName] && schemeColorsCache[schemeName][colorKey]) {
return schemeColorsCache[schemeName][colorKey] return schemeColorsCache[schemeName][colorKey]
} }
// Return a default color if not cached yet // Return a default color if not cached yet
return "#000000" return "#000000"
} }
// Cache for scheme colors // Cache for scheme colors
property var schemeColorsCache: ({}) property var schemeColorsCache: ({})
// Array to hold FileView objects // Array to hold FileView objects
property var fileViews: [] property var fileViews: []
// Load color scheme data when schemes are available // Load color scheme data when schemes are available
Connections { Connections {
target: ColorSchemes target: ColorSchemes
@ -37,11 +37,11 @@ ColumnLayout {
loadSchemeColors() loadSchemeColors()
} }
} }
function loadSchemeColors() { function loadSchemeColors() {
// Clear existing cache // Clear existing cache
schemeColorsCache = {} schemeColorsCache = {}
// Destroy existing FileViews // Destroy existing FileViews
for (var i = 0; i < fileViews.length; i++) { for (var i = 0; i < fileViews.length; i++) {
if (fileViews[i]) { if (fileViews[i]) {
@ -49,19 +49,19 @@ ColumnLayout {
} }
} }
fileViews = [] fileViews = []
// Create FileViews for each scheme // Create FileViews for each scheme
for (var i = 0; i < ColorSchemes.schemes.length; i++) { for (var i = 0; i < ColorSchemes.schemes.length; i++) {
var schemePath = ColorSchemes.schemes[i] var schemePath = ColorSchemes.schemes[i]
var schemeName = schemePath.split("/").pop().replace(".json", "") var schemeName = schemePath.split("/").pop().replace(".json", "")
// Create FileView component // Create FileView component
var component = Qt.createComponent("SchemeFileView.qml") var component = Qt.createComponent("SchemeFileView.qml")
if (component.status === Component.Ready) { if (component.status === Component.Ready) {
var fileView = component.createObject(root, { var fileView = component.createObject(root, {
"path": schemePath, "path": schemePath,
"schemeName": schemeName "schemeName": schemeName
}) })
fileViews.push(fileView) fileViews.push(fileView)
} else { } else {
// Fallback: create inline FileView // Fallback: create inline FileView
@ -69,28 +69,28 @@ ColumnLayout {
} }
} }
} }
function createInlineFileView(schemePath, schemeName) { function createInlineFileView(schemePath, schemeName) {
var fileViewQml = ` var fileViewQml = `
import QtQuick import QtQuick
import Quickshell.Io import Quickshell.Io
FileView { FileView {
property string schemeName: "${schemeName}" property string schemeName: "${schemeName}"
path: "${schemePath}" path: "${schemePath}"
blockLoading: true blockLoading: true
onLoaded: { onLoaded: {
try { try {
var jsonData = JSON.parse(text()) var jsonData = JSON.parse(text())
root.schemeLoaded(schemeName, jsonData) root.schemeLoaded(schemeName, jsonData)
} catch (e) { } catch (e) {
console.warn("Failed to parse JSON for scheme:", schemeName, e) console.warn("Failed to parse JSON for scheme:", schemeName, e)
} }
} }
} }
` `
try { try {
var fileView = Qt.createQmlObject(fileViewQml, root, "dynamicFileView_" + schemeName) var fileView = Qt.createQmlObject(fileViewQml, root, "dynamicFileView_" + schemeName)
fileViews.push(fileView) fileViews.push(fileView)
@ -98,12 +98,12 @@ ColumnLayout {
console.warn("Failed to create FileView for scheme:", schemeName, e) console.warn("Failed to create FileView for scheme:", schemeName, e)
} }
} }
function schemeLoaded(schemeName, jsonData) { function schemeLoaded(schemeName, jsonData) {
console.log("Loading scheme colors for:", schemeName) console.log("Loading scheme colors for:", schemeName)
var colors = {} var colors = {}
// Extract colors from JSON data // Extract colors from JSON data
if (jsonData && typeof jsonData === 'object') { if (jsonData && typeof jsonData === 'object') {
colors.mPrimary = jsonData.mPrimary || jsonData.primary || "#000000" colors.mPrimary = jsonData.mPrimary || jsonData.primary || "#000000"
@ -116,21 +116,21 @@ ColumnLayout {
} else { } else {
// Default colors // Default colors
colors = { colors = {
mPrimary: "#000000", "mPrimary": "#000000",
mSecondary: "#000000", "mSecondary": "#000000",
mTertiary: "#000000", "mTertiary": "#000000",
mError: "#ff0000", "mError": "#ff0000",
mSurface: "#ffffff", "mSurface": "#ffffff",
mOnSurface: "#000000", "mOnSurface": "#000000",
mOutline: "#666666" "mOutline": "#666666"
} }
} }
// Update cache // Update cache
var newCache = schemeColorsCache var newCache = schemeColorsCache
newCache[schemeName] = colors newCache[schemeName] = colors
schemeColorsCache = newCache schemeColorsCache = newCache
console.log("Cached colors for", schemeName, ":", JSON.stringify(colors)) console.log("Cached colors for", schemeName, ":", JSON.stringify(colors))
} }
@ -204,7 +204,7 @@ ColumnLayout {
Repeater { Repeater {
model: ColorSchemes.schemes model: ColorSchemes.schemes
Rectangle { Rectangle {
id: schemeCard id: schemeCard
Layout.fillWidth: true Layout.fillWidth: true
@ -213,9 +213,9 @@ ColumnLayout {
color: getSchemeColor(modelData, "mSurface") color: getSchemeColor(modelData, "mSurface")
border.width: 2 border.width: 2
border.color: Settings.data.colorSchemes.predefinedScheme === modelData ? Colors.mPrimary : Colors.mOutline border.color: Settings.data.colorSchemes.predefinedScheme === modelData ? Colors.mPrimary : Colors.mOutline
property string schemePath: modelData property string schemePath: modelData
// Mouse area for selection // Mouse area for selection
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@ -227,24 +227,24 @@ ColumnLayout {
} }
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onEntered: { onEntered: {
schemeCard.scale = 1.05 schemeCard.scale = 1.05
schemeCard.border.width = 3 schemeCard.border.width = 3
} }
onExited: { onExited: {
schemeCard.scale = 1.0 schemeCard.scale = 1.0
schemeCard.border.width = 2 schemeCard.border.width = 2
} }
} }
// Card content // Card content
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
anchors.margins: 16 * scaling anchors.margins: 16 * scaling
spacing: 8 * scaling spacing: 8 * scaling
// Scheme name // Scheme name
NText { NText {
text: { text: {
@ -259,13 +259,13 @@ ColumnLayout {
elide: Text.ElideRight elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
// Color swatches // Color swatches
RowLayout { RowLayout {
spacing: 8 * scaling spacing: 8 * scaling
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
// Primary color swatch // Primary color swatch
Rectangle { Rectangle {
width: 28 * scaling width: 28 * scaling
@ -273,7 +273,7 @@ ColumnLayout {
radius: 14 * scaling radius: 14 * scaling
color: getSchemeColor(modelData, "mPrimary") color: getSchemeColor(modelData, "mPrimary")
} }
// Secondary color swatch // Secondary color swatch
Rectangle { Rectangle {
width: 28 * scaling width: 28 * scaling
@ -281,7 +281,7 @@ ColumnLayout {
radius: 14 * scaling radius: 14 * scaling
color: getSchemeColor(modelData, "mSecondary") color: getSchemeColor(modelData, "mSecondary")
} }
// Tertiary color swatch // Tertiary color swatch
Rectangle { Rectangle {
width: 28 * scaling width: 28 * scaling
@ -289,7 +289,7 @@ ColumnLayout {
radius: 14 * scaling radius: 14 * scaling
color: getSchemeColor(modelData, "mTertiary") color: getSchemeColor(modelData, "mTertiary")
} }
// Error color swatch // Error color swatch
Rectangle { Rectangle {
width: 28 * scaling width: 28 * scaling
@ -299,7 +299,7 @@ ColumnLayout {
} }
} }
} }
// Selection indicator // Selection indicator
Rectangle { Rectangle {
visible: Settings.data.colorSchemes.predefinedScheme === schemePath visible: Settings.data.colorSchemes.predefinedScheme === schemePath
@ -310,7 +310,7 @@ ColumnLayout {
height: 24 * scaling height: 24 * scaling
radius: 12 * scaling radius: 12 * scaling
color: Colors.mPrimary color: Colors.mPrimary
NText { NText {
anchors.centerIn: parent anchors.centerIn: parent
text: "✓" text: "✓"
@ -319,18 +319,25 @@ ColumnLayout {
color: Colors.mOnPrimary color: Colors.mOnPrimary
} }
} }
// Smooth animations // Smooth animations
Behavior on scale { Behavior on scale {
NumberAnimation { duration: 200; easing.type: Easing.OutCubic } NumberAnimation {
duration: 200
easing.type: Easing.OutCubic
}
} }
Behavior on border.color { Behavior on border.color {
ColorAnimation { duration: 300 } ColorAnimation {
duration: 300
}
} }
Behavior on border.width { Behavior on border.width {
NumberAnimation { duration: 200 } NumberAnimation {
duration: 200
}
} }
} }
} }
@ -339,4 +346,4 @@ ColumnLayout {
} }
} }
} }
} }

View file

@ -30,6 +30,7 @@ Singleton {
return return
} }
} catch (e) { } catch (e) {
} }
if (typeof Niri !== "undefined") { if (typeof Niri !== "undefined") {