Add taskbar settings, fix audio IO
This commit is contained in:
parent
5080c648ec
commit
8b54996d9f
9 changed files with 616 additions and 595 deletions
|
|
@ -89,21 +89,25 @@ PanelWithOverlay {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: 1
|
spacing: 1
|
||||||
|
Layout.maximumWidth: sinkList.width - 120 // Reserve space for the Set button
|
||||||
Text {
|
Text {
|
||||||
text: modelData.nickname || modelData.description || modelData.name
|
text: modelData.nickname || modelData.description || modelData.name
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: (Pipewire.defaultAudioSink && Pipewire.defaultAudioSink.id === modelData.id) ? Theme.accentPrimary : Theme.textPrimary
|
color: (Pipewire.defaultAudioSink && Pipewire.defaultAudioSink.id === modelData.id) ? Theme.accentPrimary : Theme.textPrimary
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: modelData.description !== modelData.nickname ? modelData.description : ""
|
text: modelData.description !== modelData.nickname ? modelData.description : ""
|
||||||
font.pixelSize: 10
|
font.pixelSize: 10
|
||||||
color: Theme.textSecondary
|
color: Theme.textSecondary
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item { Layout.fillWidth: true }
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: Pipewire.preferredDefaultAudioSink !== modelData
|
visible: Pipewire.preferredDefaultAudioSink !== modelData
|
||||||
width: 60; height: 20
|
width: 60; height: 20
|
||||||
|
|
@ -173,21 +177,25 @@ PanelWithOverlay {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: 1
|
spacing: 1
|
||||||
|
Layout.maximumWidth: sourceList.width - 120 // Reserve space for the Set button
|
||||||
Text {
|
Text {
|
||||||
text: modelData.nickname || modelData.description || modelData.name
|
text: modelData.nickname || modelData.description || modelData.name
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: (Pipewire.defaultAudioSource && Pipewire.defaultAudioSource.id === modelData.id) ? Theme.accentPrimary : Theme.textPrimary
|
color: (Pipewire.defaultAudioSource && Pipewire.defaultAudioSource.id === modelData.id) ? Theme.accentPrimary : Theme.textPrimary
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: modelData.description !== modelData.nickname ? modelData.description : ""
|
text: modelData.description !== modelData.nickname ? modelData.description : ""
|
||||||
font.pixelSize: 10
|
font.pixelSize: 10
|
||||||
color: Theme.textSecondary
|
color: Theme.textSecondary
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item { Layout.fillWidth: true }
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: Pipewire.preferredDefaultAudioSource !== modelData
|
visible: Pipewire.preferredDefaultAudioSource !== modelData
|
||||||
width: 60; height: 20
|
width: 60; height: 20
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,15 @@ Item {
|
||||||
width: runningAppsRow.width
|
width: runningAppsRow.width
|
||||||
height: Settings.settings.taskbarIconSize
|
height: Settings.settings.taskbarIconSize
|
||||||
|
|
||||||
|
// Attach custom tooltip
|
||||||
|
StyledTooltip {
|
||||||
|
id: styledTooltip
|
||||||
|
}
|
||||||
|
|
||||||
function getAppIcon(toplevel: Toplevel): string {
|
function getAppIcon(toplevel: Toplevel): string {
|
||||||
if (!toplevel)
|
if (!toplevel)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
// Try different icon resolution strategies
|
|
||||||
let icon = Quickshell.iconPath(toplevel.appId?.toLowerCase(), true);
|
let icon = Quickshell.iconPath(toplevel.appId?.toLowerCase(), true);
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
icon = Quickshell.iconPath(toplevel.appId, true);
|
icon = Quickshell.iconPath(toplevel.appId, true);
|
||||||
|
|
@ -42,7 +46,6 @@ Item {
|
||||||
model: ToplevelManager ? ToplevelManager.toplevels : null
|
model: ToplevelManager ? ToplevelManager.toplevels : null
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
|
|
||||||
id: appButton
|
id: appButton
|
||||||
width: Settings.settings.taskbarIconSize
|
width: Settings.settings.taskbarIconSize
|
||||||
height: Settings.settings.taskbarIconSize
|
height: Settings.settings.taskbarIconSize
|
||||||
|
|
@ -51,124 +54,76 @@ Item {
|
||||||
border.color: isActive ? Qt.darker(Theme.accentPrimary, 1.2) : "transparent"
|
border.color: isActive ? Qt.darker(Theme.accentPrimary, 1.2) : "transparent"
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
property bool isActive: ToplevelManager.activeToplevel && ToplevelManager.activeToplevel === modelData
|
property bool isActive: ToplevelManager.activeToplevel && ToplevelManager.activeToplevel === modelData
|
||||||
property bool hovered: mouseArea.containsMouse
|
property bool hovered: mouseArea.containsMouse
|
||||||
property string appId: modelData ? modelData.appId : ""
|
property string appId: modelData ? modelData.appId : ""
|
||||||
property string appTitle: modelData ? modelData.title : ""
|
property string appTitle: modelData ? modelData.title : ""
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
ColorAnimation {
|
ColorAnimation { duration: 150 }
|
||||||
duration: 150
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on border.color {
|
Behavior on border.color {
|
||||||
ColorAnimation {
|
ColorAnimation { duration: 150 }
|
||||||
duration: 150
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// App icon
|
|
||||||
IconImage {
|
IconImage {
|
||||||
id: appIcon
|
id: appIcon
|
||||||
width: Math.max(12, Settings.settings.taskbarIconSize * 0.625) // 62.5% of button size (20/32 = 0.625)
|
width: Math.max(12, Settings.settings.taskbarIconSize * 0.625)
|
||||||
height: Math.max(12, Settings.settings.taskbarIconSize * 0.625)
|
height: Math.max(12, Settings.settings.taskbarIconSize * 0.625)
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: getAppIcon(modelData)
|
source: getAppIcon(modelData)
|
||||||
smooth: true
|
smooth: true
|
||||||
|
|
||||||
// Fallback to first letter if no icon
|
|
||||||
visible: source.toString() !== ""
|
visible: source.toString() !== ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback text if no icon available
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !appIcon.visible
|
visible: !appIcon.visible
|
||||||
text: appButton.appId ? appButton.appId.charAt(0).toUpperCase() : "?"
|
text: appButton.appId ? appButton.appId.charAt(0).toUpperCase() : "?"
|
||||||
font.family: Theme.fontFamily
|
font.family: Theme.fontFamily
|
||||||
font.pixelSize: Math.max(10, Settings.settings.taskbarIconSize * 0.4375) // 43.75% of button size (14/32 = 0.4375)
|
font.pixelSize: Math.max(10, Settings.settings.taskbarIconSize * 0.4375)
|
||||||
font.bold: true
|
font.bold: true
|
||||||
color: appButton.isActive ? Theme.onAccent : Theme.textPrimary
|
color: appButton.isActive ? Theme.onAccent : Theme.textPrimary
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tooltip
|
|
||||||
ToolTip {
|
|
||||||
id: tooltip
|
|
||||||
visible: mouseArea.containsMouse && !mouseArea.pressed
|
|
||||||
delay: 800
|
|
||||||
text: appTitle || appId
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: Theme.backgroundPrimary
|
|
||||||
border.color: Theme.outline
|
|
||||||
border.width: 1
|
|
||||||
radius: 8
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Text {
|
|
||||||
text: tooltip.text
|
|
||||||
font.family: Theme.fontFamily
|
|
||||||
font.pixelSize: Theme.fontSizeCaption
|
|
||||||
color: Theme.textPrimary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onEntered: {
|
||||||
|
styledTooltip.text = appTitle || appId;
|
||||||
|
styledTooltip.targetItem = appButton;
|
||||||
|
styledTooltip.tooltipVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onExited: {
|
||||||
|
styledTooltip.tooltipVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
onClicked: function(mouse) {
|
onClicked: function(mouse) {
|
||||||
console.log("[Taskbar] Clicked on", appButton.appId, "- Active:", appButton.isActive);
|
|
||||||
|
|
||||||
if (mouse.button === Qt.MiddleButton) {
|
if (mouse.button === Qt.MiddleButton) {
|
||||||
console.log("[Taskbar] Middle-clicked on", appButton.appId);
|
|
||||||
|
|
||||||
// Example: Close the window with middle click
|
|
||||||
if (modelData && modelData.close) {
|
if (modelData && modelData.close) {
|
||||||
modelData.close();
|
modelData.close();
|
||||||
} else {
|
|
||||||
console.log("[Taskbar] No close method available for:", modelData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
// Left click: Focus/activate the window
|
|
||||||
if (modelData && modelData.activate) {
|
if (modelData && modelData.activate) {
|
||||||
modelData.activate();
|
modelData.activate();
|
||||||
} else {
|
|
||||||
console.log("[Taskbar] No activate method available for:", modelData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right-click for additional actions
|
|
||||||
onPressed: mouse => {
|
onPressed: mouse => {
|
||||||
if (mouse.button === Qt.RightButton) {
|
if (mouse.button === Qt.RightButton) {
|
||||||
console.log("[Taskbar] Right-clicked on", appButton.appId);
|
// context menu logic (optional)
|
||||||
|
|
||||||
// Example actions you can add:
|
|
||||||
// 1. Close window
|
|
||||||
// if (modelData && modelData.close) {
|
|
||||||
// modelData.close();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 2. Minimize window
|
|
||||||
// if (modelData && modelData.minimize) {
|
|
||||||
// modelData.minimize();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 3. Show context menu (needs Menu component)
|
|
||||||
// contextMenu.popup();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Active indicator dot
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: isActive
|
visible: isActive
|
||||||
width: 4
|
width: 4
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ Item {
|
||||||
textColor: Theme.textPrimary
|
textColor: Theme.textPrimary
|
||||||
StyledTooltip {
|
StyledTooltip {
|
||||||
id: volumeTooltip
|
id: volumeTooltip
|
||||||
text: "Volume: " + volume + "%\nScroll up/down to change volume"
|
text: "Volume: " + volume + "%\nScroll up/down to change volume.\nLeft click to open the input/output selection."
|
||||||
tooltipVisible: !ioSelector.visible && volumeDisplay.containsMouse
|
tooltipVisible: !ioSelector.visible && volumeDisplay.containsMouse
|
||||||
targetItem: pillIndicator
|
targetItem: pillIndicator
|
||||||
delay: 200
|
delay: 200
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ Window {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: 6
|
radius: 20
|
||||||
color: Theme.backgroundTertiary || "#222"
|
color: Theme.backgroundTertiary || "#222"
|
||||||
border.color: Theme.outline || "#444"
|
border.color: Theme.outline || "#444"
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
|
||||||
BIN
Programs/zigbrightness
Executable file
BIN
Programs/zigbrightness
Executable file
Binary file not shown.
BIN
Programs/zigstat
Executable file
BIN
Programs/zigstat
Executable file
Binary file not shown.
|
|
@ -48,6 +48,7 @@ Singleton {
|
||||||
property bool showActiveWindowIcon: false
|
property bool showActiveWindowIcon: false
|
||||||
property bool showSystemInfoInBar: false
|
property bool showSystemInfoInBar: false
|
||||||
property bool showCorners: true
|
property bool showCorners: true
|
||||||
|
property bool showTaskbar: true
|
||||||
property bool showMediaInBar: false
|
property bool showMediaInBar: false
|
||||||
property bool useSWWW: false
|
property bool useSWWW: false
|
||||||
property bool randomWallpaper: false
|
property bool randomWallpaper: false
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
# Ghostty theme template for wallust
|
|
||||||
# Add to wallust config: ghostty = { src = "ghostty.conf", dst = "~/.config/ghostty/theme.conf" }
|
|
||||||
# And add to ghostty config: theme = "theme.conf"
|
|
||||||
|
|
||||||
palette = 0={{ color0 }}
|
|
||||||
palette = 1={{ color1 }}
|
|
||||||
palette = 2={{ color2 }}
|
|
||||||
palette = 3={{ color3 }}
|
|
||||||
palette = 4={{ color4 }}
|
|
||||||
palette = 5={{ color5 }}
|
|
||||||
palette = 6={{ color6 }}
|
|
||||||
palette = 7={{ color7 }}
|
|
||||||
palette = 8={{ color8 }}
|
|
||||||
palette = 9={{ color9 }}
|
|
||||||
palette = 10={{ color10 }}
|
|
||||||
palette = 11={{ color11 }}
|
|
||||||
palette = 12={{ color12 }}
|
|
||||||
palette = 13={{ color13 }}
|
|
||||||
palette = 14={{ color14 }}
|
|
||||||
palette = 15={{ color15 }}
|
|
||||||
|
|
||||||
background = {{ background }}
|
|
||||||
foreground = {{ foreground }}
|
|
||||||
|
|
||||||
cursor-color = {{ cursor }}
|
|
||||||
cursor-text = {{ foreground }}
|
|
||||||
|
|
||||||
selection-background = {{ color8 }}
|
|
||||||
selection-foreground = {{ foreground }}
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue