noctalia-shell/Bar/Modules/Taskbar.qml
Sébastien Atoch 260c74b3e0 Improve images resizing quality accross the board
- Using mipmap: true and smooth: true for images that are downscaled
(avatar, icons, ...)
- Using mipmap: false and smooth: true for images that are potentially
upscaled (background, overview, ...)
2025-08-02 21:04:26 -04:00

142 lines
4.8 KiB
QML

import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Settings
import qs.Components
Item {
id: taskbar
width: runningAppsRow.width
height: Settings.settings.taskbarIconSize
visible: Settings.settings.showTaskbar
// Attach custom tooltip
StyledTooltip {
id: styledTooltip
}
function getAppIcon(toplevel: Toplevel): string {
if (!toplevel)
return "";
let icon = Quickshell.iconPath(toplevel.appId?.toLowerCase(), true);
if (!icon) {
icon = Quickshell.iconPath(toplevel.appId, true);
}
if (!icon) {
icon = Quickshell.iconPath(toplevel.title?.toLowerCase(), true);
}
if (!icon) {
icon = Quickshell.iconPath(toplevel.title, true);
}
if (!icon) {
icon = Quickshell.iconPath("application-x-executable", true);
}
return icon || "";
}
Row {
id: runningAppsRow
spacing: 8
height: parent.height
Repeater {
model: ToplevelManager ? ToplevelManager.toplevels : null
delegate: Rectangle {
id: appButton
width: Settings.settings.taskbarIconSize
height: Settings.settings.taskbarIconSize
radius: Math.max(4, Settings.settings.taskbarIconSize * 0.25)
color: isActive ? Theme.accentPrimary : (hovered ? Theme.surfaceVariant : "transparent")
border.color: isActive ? Qt.darker(Theme.accentPrimary, 1.2) : "transparent"
border.width: 1
property bool isActive: ToplevelManager.activeToplevel && ToplevelManager.activeToplevel === modelData
property bool hovered: mouseArea.containsMouse
property string appId: modelData ? modelData.appId : ""
property string appTitle: modelData ? modelData.title : ""
Behavior on color {
ColorAnimation { duration: 150 }
}
Behavior on border.color {
ColorAnimation { duration: 150 }
}
IconImage {
id: appIcon
width: Math.max(12, Settings.settings.taskbarIconSize * 0.625)
height: Math.max(12, Settings.settings.taskbarIconSize * 0.625)
anchors.centerIn: parent
source: getAppIcon(modelData)
smooth: true
mipmap: true
visible: source.toString() !== ""
}
Text {
anchors.centerIn: parent
visible: !appIcon.visible
text: appButton.appId ? appButton.appId.charAt(0).toUpperCase() : "?"
font.family: Theme.fontFamily
font.pixelSize: Math.max(10, Settings.settings.taskbarIconSize * 0.4375)
font.bold: true
color: appButton.isActive ? Theme.onAccent : Theme.textPrimary
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: {
styledTooltip.text = appTitle || appId;
styledTooltip.targetItem = appButton;
styledTooltip.tooltipVisible = true;
}
onExited: {
styledTooltip.tooltipVisible = false;
}
onClicked: function(mouse) {
if (mouse.button === Qt.MiddleButton) {
if (modelData && modelData.close) {
modelData.close();
}
}
if (mouse.button === Qt.LeftButton) {
if (modelData && modelData.activate) {
modelData.activate();
}
}
}
onPressed: mouse => {
if (mouse.button === Qt.RightButton) {
// context menu logic (optional)
}
}
}
Rectangle {
visible: isActive
width: 4
height: 4
radius: 2
color: Theme.onAccent
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottomMargin: -6
}
}
}
}
}