Launcher: should respect the same design as other panels

- mTertiary for hover
- no special gradient
- classic thin border
This commit is contained in:
LemmyCook 2025-08-21 21:25:13 -04:00
parent cb554f106b
commit 7d47b98621
4 changed files with 135 additions and 125 deletions

View file

@ -11,9 +11,11 @@ Singleton {
try { try {
if (iconName && typeof Quickshell !== 'undefined' && Quickshell.iconPath) { if (iconName && typeof Quickshell !== 'undefined' && Quickshell.iconPath) {
const p = Quickshell.iconPath(iconName, fallback) const p = Quickshell.iconPath(iconName, fallback)
if (p && p !== "") return p if (p && p !== "")
return p
} }
} catch (e) { } catch (e) {
// ignore and fall back // ignore and fall back
} }
try { try {
@ -26,7 +28,8 @@ Singleton {
// Resolve icon path for a DesktopEntries appId - safe on missing entries // Resolve icon path for a DesktopEntries appId - safe on missing entries
function iconForAppId(appId, fallbackName) { function iconForAppId(appId, fallbackName) {
const fallback = fallbackName || "application-x-executable" const fallback = fallbackName || "application-x-executable"
if (!appId) return iconFromName(fallback, fallback) if (!appId)
return iconFromName(fallback, fallback)
try { try {
if (typeof DesktopEntries === 'undefined' || !DesktopEntries.byId) if (typeof DesktopEntries === 'undefined' || !DesktopEntries.byId)
return iconFromName(fallback, fallback) return iconFromName(fallback, fallback)
@ -38,5 +41,3 @@ Singleton {
} }
} }
} }

View file

@ -33,11 +33,20 @@ Item {
} }
} }
// For backward compatibility, should be removed soon(tmc)
IpcHandler { IpcHandler {
target: "appLauncher" target: "appLauncher"
function toggle() { function toggle() {
appLauncherPanel.toggle(Quickshell.screens[0]) launcherPanel.toggle(Quickshell.screens[0])
}
}
IpcHandler {
target: "launcher"
function toggle() {
launcherPanel.toggle(Quickshell.screens[0])
} }
} }

View file

@ -113,7 +113,8 @@ NPanel {
} }
// Handle direct math expressions after ">" // Handle direct math expressions after ">"
if (query.startsWith(">") && query.length > 1 && (!Settings.data.appLauncher.enableClipboardHistory || !query.startsWith(">clip")) && !query.startsWith(">calc")) { if (query.startsWith(">") && query.length > 1 && (!Settings.data.appLauncher.enableClipboardHistory
|| !query.startsWith(">clip")) && !query.startsWith(">calc")) {
const mathResults = calculator.processQuery(query, "direct") const mathResults = calculator.processQuery(query, "direct")
if (mathResults.length > 0) { if (mathResults.length > 0) {
return mathResults return mathResults
@ -210,18 +211,7 @@ NPanel {
// Main content container // Main content container
panelContent: Rectangle { panelContent: Rectangle {
color: Color.transparent
// Subtle gradient background
gradient: Gradient {
GradientStop {
position: 0.0
color: Qt.lighter(Color.mSurface, 1.02)
}
GradientStop {
position: 1.0
color: Qt.darker(Color.mSurface, 1.1)
}
}
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
@ -235,7 +225,7 @@ NPanel {
Layout.bottomMargin: Style.marginM * scaling Layout.bottomMargin: Style.marginM * scaling
radius: Style.radiusM * scaling radius: Style.radiusM * scaling
color: Color.mSurface color: Color.mSurface
border.color: searchInput.activeFocus ? Color.mPrimary : Color.mOutline border.color: searchInput.activeFocus ? Color.mTertiary : Color.mOutline
border.width: Math.max(1, searchInput.activeFocus ? Style.borderM * scaling : Style.borderS * scaling) border.width: Math.max(1, searchInput.activeFocus ? Style.borderM * scaling : Style.borderS * scaling)
Item { Item {
@ -356,130 +346,136 @@ NPanel {
positionViewAtIndex(currentIndex, ListView.Contain) positionViewAtIndex(currentIndex, ListView.Contain)
} }
} }
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded } ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
delegate: Rectangle { delegate: Rectangle {
width: appsList.width - Style.marginS * scaling width: appsList.width - Style.marginS * scaling
height: 65 * scaling height: 65 * scaling
radius: Style.radiusM * scaling radius: Style.radiusM * scaling
property bool isSelected: index === selectedIndex property bool isSelected: index === selectedIndex
color: (appCardArea.containsMouse || isSelected) ? Qt.darker(Color.mPrimary, 1.1) : Color.mSurface color: (appCardArea.containsMouse || isSelected) ? Color.mTertiary : Color.mSurface
border.color: (appCardArea.containsMouse || isSelected) ? Color.mPrimary : Color.transparent
border.width: Math.max(1, (appCardArea.containsMouse || isSelected) ? Style.borderM * scaling : 0)
Behavior on color { Behavior on color {
ColorAnimation { ColorAnimation {
duration: Style.animationFast duration: Style.animationFast
}
} }
}
Behavior on border.color { Behavior on border.color {
ColorAnimation { ColorAnimation {
duration: Style.animationFast duration: Style.animationFast
}
} }
}
Behavior on border.width { Behavior on border.width {
NumberAnimation { NumberAnimation {
duration: Style.animationFast duration: Style.animationFast
}
} }
}
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
anchors.margins: Style.marginM * scaling anchors.margins: Style.marginM * scaling
spacing: Style.marginM * scaling spacing: Style.marginM * scaling
// App/clipboard icon with background
Rectangle {
Layout.preferredWidth: Style.baseWidgetSize * 1.25 * scaling
Layout.preferredHeight: Style.baseWidgetSize * 1.25 * scaling
radius: Style.radiusS * scaling
color: appCardArea.containsMouse ? Qt.darker(Color.mPrimary, 1.1) : Color.mSurfaceVariant
property bool iconLoaded: (modelData.isCalculator || modelData.isClipboard || modelData.isCommand)
|| (iconImg.status === Image.Ready && iconImg.source !== ""
&& iconImg.status !== Image.Error && iconImg.source !== "")
visible: !searchText.startsWith(">calc")
// Clipboard image display (pull from cache)
Image {
id: clipboardImage
anchors.fill: parent
anchors.margins: Style.marginXS * scaling
visible: modelData.type === 'image'
source: modelData.type === 'image' ? (CliphistService.imageDataById[modelData.id] || "") : ""
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: true
}
IconImage {
id: iconImg
anchors.fill: parent
anchors.margins: Style.marginXS * scaling
asynchronous: true
source: modelData.isCalculator ? "" : modelData.isClipboard ? "" : modelData.isCommand ? modelData.icon : Icons.iconFromName(
modelData.icon,
"application-x-executable")
visible: (modelData.isCalculator || modelData.isClipboard || modelData.isCommand || parent.iconLoaded)
&& modelData.type !== 'image'
}
// App/clipboard icon with background
Rectangle { Rectangle {
Layout.preferredWidth: Style.baseWidgetSize * 1.25 * scaling anchors.fill: parent
Layout.preferredHeight: Style.baseWidgetSize * 1.25 * scaling anchors.margins: Style.marginXS * scaling
radius: Style.radiusS * scaling radius: Style.radiusXS * scaling
color: appCardArea.containsMouse ? Qt.darker(Color.mPrimary, 1.1) : Color.mSurfaceVariant color: Color.mPrimary
property bool iconLoaded: (modelData.isCalculator || modelData.isClipboard || modelData.isCommand) opacity: Style.opacityMedium
|| (iconImg.status === Image.Ready && iconImg.source !== "" visible: !parent.iconLoaded
&& iconImg.status !== Image.Error && iconImg.source !== "")
visible: !searchText.startsWith(">calc")
// Clipboard image display (pull from cache)
Image {
id: clipboardImage
anchors.fill: parent
anchors.margins: Style.marginXS * scaling
visible: modelData.type === 'image'
source: modelData.type === 'image' ? (CliphistService.imageDataById[modelData.id] || "") : ""
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: true
}
IconImage {
id: iconImg
anchors.fill: parent
anchors.margins: Style.marginXS * scaling
asynchronous: true
source: modelData.isCalculator ? "" : modelData.isClipboard ? "" : modelData.isCommand ? modelData.icon : Icons.iconFromName(modelData.icon, "application-x-executable")
visible: (modelData.isCalculator || modelData.isClipboard || modelData.isCommand || parent.iconLoaded)
&& modelData.type !== 'image'
}
Rectangle {
anchors.fill: parent
anchors.margins: Style.marginXS * scaling
radius: Style.radiusXS * scaling
color: Color.mPrimary
opacity: Style.opacityMedium
visible: !parent.iconLoaded
}
NText {
anchors.centerIn: parent
visible: !parent.iconLoaded && !(modelData.isCalculator || modelData.isClipboard || modelData.isCommand)
text: modelData.name ? modelData.name.charAt(0).toUpperCase() : "?"
font.pointSize: Style.fontSizeXXL * scaling
font.weight: Style.fontWeightBold
color: Color.mPrimary
}
Behavior on color { ColorAnimation { duration: Style.animationFast } }
} }
// App info NText {
ColumnLayout { anchors.centerIn: parent
visible: !parent.iconLoaded && !(modelData.isCalculator || modelData.isClipboard || modelData.isCommand)
text: modelData.name ? modelData.name.charAt(0).toUpperCase() : "?"
font.pointSize: Style.fontSizeXXL * scaling
font.weight: Style.fontWeightBold
color: Color.mPrimary
}
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
// App info
ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginXXS * scaling
NText {
text: modelData.name || "Unknown"
font.pointSize: Style.fontSizeL * scaling
font.weight: Style.fontWeightBold
color: (appCardArea.containsMouse || isSelected) ? Color.mOnPrimary : Color.mOnSurface
elide: Text.ElideRight
Layout.fillWidth: true Layout.fillWidth: true
spacing: Style.marginXXS * scaling }
NText { NText {
text: modelData.name || "Unknown" text: modelData.isCalculator ? (modelData.expr + " = " + modelData.result) : modelData.isClipboard ? modelData.content : modelData.isCommand ? modelData.content : (modelData.genericName || modelData.comment || "")
font.pointSize: Style.fontSizeL * scaling font.pointSize: Style.fontSizeM * scaling
font.weight: Style.fontWeightBold color: (appCardArea.containsMouse || isSelected) ? Color.mOnPrimary : Color.mOnSurface
color: (appCardArea.containsMouse || isSelected) ? Color.mOnPrimary : Color.mOnSurface elide: Text.ElideRight
elide: Text.ElideRight Layout.fillWidth: true
Layout.fillWidth: true visible: text !== ""
}
NText {
text: modelData.isCalculator ? (modelData.expr + " = " + modelData.result) : modelData.isClipboard ? modelData.content : modelData.isCommand ? modelData.content : (modelData.genericName || modelData.comment || "")
font.pointSize: Style.fontSizeM * scaling
color: (appCardArea.containsMouse || isSelected) ? Color.mOnPrimary : Color.mOnSurface
elide: Text.ElideRight
Layout.fillWidth: true
visible: text !== ""
}
} }
} }
}
MouseArea { MouseArea {
id: appCardArea id: appCardArea
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
selectedIndex = index selectedIndex = index
activateSelected() activateSelected()
}
} }
}
} }
} }
@ -495,7 +491,11 @@ NPanel {
// Results count // Results count
NText { NText {
text: searchText.startsWith(">clip") ? (Settings.data.appLauncher.enableClipboardHistory ? `${filteredEntries.length} clipboard item${filteredEntries.length !== 1 ? 's' : ''}` : `Clipboard history is disabled`) : searchText.startsWith(">calc") ? `${filteredEntries.length} result${filteredEntries.length !== 1 ? 's' : ''}` : `${filteredEntries.length} application${filteredEntries.length !== 1 ? 's' : ''}` text: searchText.startsWith(
">clip") ? (Settings.data.appLauncher.enableClipboardHistory ? `${filteredEntries.length} clipboard item${filteredEntries.length !== 1 ? 's' : ''}` : `Clipboard history is disabled`) : searchText.startsWith(
">calc") ? `${filteredEntries.length} result${filteredEntries.length
!== 1 ? 's' : ''}` : `${filteredEntries.length} application${filteredEntries.length
!== 1 ? 's' : ''}`
font.pointSize: Style.fontSizeXS * scaling font.pointSize: Style.fontSizeXS * scaling
color: Color.mOnSurface color: Color.mOnSurface
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter

View file

@ -39,7 +39,7 @@ ShellRoot {
Dock {} Dock {}
Launcher { Launcher {
id: appLauncherPanel id: launcherPanel
} }
SidePanel { SidePanel {