1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-29 07:52:50 -05:00

dankbar: enhance widget click targets

- Fitt's law stuff, whole height on horiz, whole width in vertical
- Probably missed stuff or breaks stuff, pretty big refactor
This commit is contained in:
bbedward
2025-10-22 00:12:41 -04:00
parent 8ab25ef8e4
commit 951136bc4c
28 changed files with 2507 additions and 2923 deletions

View File

@@ -4,21 +4,15 @@ import Quickshell.Wayland
import Quickshell.Widgets
import Quickshell.Hyprland
import qs.Common
import qs.Modules.Plugins
import qs.Services
import qs.Widgets
Rectangle {
BasePill {
id: root
property bool isVertical: axis?.isVertical ?? false
property var axis: null
property var parentScreen
property bool compactMode: SettingsData.focusedWindowCompactMode
property int availableWidth: 400
property real widgetThickness: 30
property real barThickness: 48
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
readonly property int baseWidth: contentRow.implicitWidth + horizontalPadding * 2
readonly property int maxNormalWidth: 456
readonly property int maxCompactWidth: 288
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
@@ -93,148 +87,141 @@ Rectangle {
return activeWindow && activeWindow.title
}
width: !hasWindowsOnCurrentWorkspace ? 0 : (isVertical ? widgetThickness : (compactMode ? Math.min(baseWidth, maxCompactWidth) : Math.min(baseWidth, maxNormalWidth)))
height: !hasWindowsOnCurrentWorkspace ? 0 : (isVertical ? widgetThickness : widgetThickness)
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
color: {
if (!activeWindow || !activeWindow.title) {
return "transparent";
}
if (SettingsData.dankBarNoBackground) {
return "transparent";
}
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
}
clip: true
visible: hasWindowsOnCurrentWorkspace
IconImage {
id: appIcon
anchors.centerIn: parent
width: 18
height: 18
visible: root.isVertical && activeWindow && status === Image.Ready
source: {
if (!activeWindow || !activeWindow.appId) return ""
const moddedId = Paths.moddedAppId(activeWindow.appId)
if (moddedId.toLowerCase().includes("steam_app")) return ""
return Quickshell.iconPath(activeDesktopEntry?.icon, true)
}
smooth: true
mipmap: true
asynchronous: true
}
DankIcon {
anchors.centerIn: parent
size: 18
name: "sports_esports"
color: Theme.surfaceText
visible: {
if (!root.isVertical || !activeWindow || !activeWindow.appId) return false
const moddedId = Paths.moddedAppId(activeWindow.appId)
return moddedId.toLowerCase().includes("steam_app")
}
}
Text {
anchors.centerIn: parent
visible: {
if (!root.isVertical || !activeWindow || !activeWindow.appId) return false
if (appIcon.status === Image.Ready) return false
const moddedId = Paths.moddedAppId(activeWindow.appId)
return !moddedId.toLowerCase().includes("steam_app")
}
text: {
if (!activeWindow || !activeWindow.appId) return "?"
if (activeDesktopEntry && activeDesktopEntry.name) {
return activeDesktopEntry.name.charAt(0).toUpperCase()
content: Component {
Item {
implicitWidth: {
if (!root.hasWindowsOnCurrentWorkspace) return 0
if (root.isVerticalOrientation) return root.widgetThickness - root.horizontalPadding * 2
const baseWidth = contentRow.implicitWidth
return compactMode ? Math.min(baseWidth, maxCompactWidth - root.horizontalPadding * 2) : Math.min(baseWidth, maxNormalWidth - root.horizontalPadding * 2)
}
return activeWindow.appId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
font.weight: Font.Medium
}
implicitHeight: root.widgetThickness - root.horizontalPadding * 2
clip: true
Row {
id: contentRow
anchors.centerIn: parent
spacing: Theme.spacingS
visible: !root.isVertical
StyledText {
id: appText
text: {
if (!activeWindow || !activeWindow.appId) {
return "";
IconImage {
id: appIcon
anchors.centerIn: parent
width: 18
height: 18
visible: root.isVerticalOrientation && activeWindow && status === Image.Ready
source: {
if (!activeWindow || !activeWindow.appId) return ""
const moddedId = Paths.moddedAppId(activeWindow.appId)
if (moddedId.toLowerCase().includes("steam_app")) return ""
return Quickshell.iconPath(activeDesktopEntry?.icon, true)
}
const desktopEntry = DesktopEntries.heuristicLookup(activeWindow.appId);
return desktopEntry && desktopEntry.name ? desktopEntry.name : activeWindow.appId;
smooth: true
mipmap: true
asynchronous: true
}
font.pixelSize: Theme.barTextSize(barThickness)
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
maximumLineCount: 1
width: Math.min(implicitWidth, compactMode ? 80 : 180)
visible: !compactMode && text.length > 0
}
StyledText {
text: "•"
font.pixelSize: Theme.barTextSize(barThickness)
color: Theme.outlineButton
anchors.verticalCenter: parent.verticalCenter
visible: !compactMode && appText.text && titleText.text
}
StyledText {
id: titleText
text: {
const title = activeWindow && activeWindow.title ? activeWindow.title : "";
const appName = appText.text;
if (!title || !appName) {
return title;
DankIcon {
anchors.centerIn: parent
size: 18
name: "sports_esports"
color: Theme.surfaceText
visible: {
if (!root.isVerticalOrientation || !activeWindow || !activeWindow.appId) return false
const moddedId = Paths.moddedAppId(activeWindow.appId)
return moddedId.toLowerCase().includes("steam_app")
}
if (title.endsWith(" - " + appName)) {
return title.substring(0, title.length - (" - " + appName).length);
}
if (title.endsWith(appName)) {
return title.substring(0, title.length - appName.length).replace(/ - $/, "");
}
return title;
}
font.pixelSize: Theme.barTextSize(barThickness)
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
maximumLineCount: 1
width: Math.min(implicitWidth, compactMode ? 280 : 250)
visible: text.length > 0
}
Text {
anchors.centerIn: parent
visible: {
if (!root.isVerticalOrientation || !activeWindow || !activeWindow.appId) return false
if (appIcon.status === Image.Ready) return false
const moddedId = Paths.moddedAppId(activeWindow.appId)
return !moddedId.toLowerCase().includes("steam_app")
}
text: {
if (!activeWindow || !activeWindow.appId) return "?"
if (activeDesktopEntry && activeDesktopEntry.name) {
return activeDesktopEntry.name.charAt(0).toUpperCase()
}
return activeWindow.appId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
font.weight: Font.Medium
}
Row {
id: contentRow
anchors.centerIn: parent
spacing: Theme.spacingS
visible: !root.isVerticalOrientation
StyledText {
id: appText
text: {
if (!activeWindow || !activeWindow.appId) {
return "";
}
const desktopEntry = DesktopEntries.heuristicLookup(activeWindow.appId);
return desktopEntry && desktopEntry.name ? desktopEntry.name : activeWindow.appId;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
maximumLineCount: 1
width: Math.min(implicitWidth, compactMode ? 80 : 180)
visible: !compactMode && text.length > 0
}
StyledText {
text: "•"
font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.outlineButton
anchors.verticalCenter: parent.verticalCenter
visible: !compactMode && appText.text && titleText.text
}
StyledText {
id: titleText
text: {
const title = activeWindow && activeWindow.title ? activeWindow.title : "";
const appName = appText.text;
if (!title || !appName) {
return title;
}
if (title.endsWith(" - " + appName)) {
return title.substring(0, title.length - (" - " + appName).length);
}
if (title.endsWith(appName)) {
return title.substring(0, title.length - appName.length).replace(/ - $/, "");
}
return title;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
maximumLineCount: 1
width: Math.min(implicitWidth, compactMode ? 280 : 250)
visible: text.length > 0
}
}
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: root.isVertical
hoverEnabled: root.isVerticalOrientation
acceptedButtons: Qt.NoButton
onEntered: {
if (root.isVertical && activeWindow && activeWindow.appId && root.parentScreen) {
if (root.isVerticalOrientation && activeWindow && activeWindow.appId && root.parentScreen) {
tooltipLoader.active = true
if (tooltipLoader.item) {
const globalPos = mapToGlobal(width / 2, height / 2)
@@ -266,14 +253,4 @@ Rectangle {
active: false
sourceComponent: DankTooltip {}
}
Behavior on width {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}