1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-07 05:55:37 -05:00

smarter distance calculation

This commit is contained in:
bbedward
2025-07-24 15:09:28 -04:00
parent 8bcac36be3
commit c6df2bc11d
10 changed files with 423 additions and 486 deletions

View File

@@ -23,17 +23,16 @@ Item {
running: true running: true
onExited: (exitCode) => { onExited: (exitCode) => {
root.cavaAvailable = exitCode === 0; root.cavaAvailable = exitCode === 0;
if (root.cavaAvailable) { if (root.cavaAvailable)
cavaProcess.running = Qt.binding(() => { cavaProcess.running = Qt.binding(() => {
return root.hasActiveMedia && root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing; return root.hasActiveMedia && root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing;
}); });
} else { else
fallbackTimer.running = Qt.binding(() => { fallbackTimer.running = Qt.binding(() => {
return root.hasActiveMedia && root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing; return root.hasActiveMedia && root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing;
}); });
} }
} }
}
Process { Process {
id: cavaProcess id: cavaProcess

View File

@@ -28,6 +28,7 @@ PanelWindow {
PowerProfiles.profile = profile; PowerProfiles.profile = profile;
if (PowerProfiles.profile !== profile) if (PowerProfiles.profile !== profile)
ToastService.showError("Failed to set power profile"); ToastService.showError("Failed to set power profile");
} }
visible: batteryPopupVisible visible: batteryPopupVisible
@@ -51,25 +52,24 @@ PanelWindow {
onClicked: function(mouse) { onClicked: function(mouse) {
// Only close if click is outside the content loader // Only close if click is outside the content loader
var localPos = mapToItem(contentLoader, mouse.x, mouse.y); var localPos = mapToItem(contentLoader, mouse.x, mouse.y);
if (localPos.x < 0 || localPos.x > contentLoader.width || if (localPos.x < 0 || localPos.x > contentLoader.width || localPos.y < 0 || localPos.y > contentLoader.height)
localPos.y < 0 || localPos.y > contentLoader.height) {
batteryPopupVisible = false; batteryPopupVisible = false;
}
} }
} }
Loader { Loader {
id: contentLoader id: contentLoader
asynchronous: true
active: batteryPopupVisible
readonly property real targetWidth: Math.min(380, Screen.width - Theme.spacingL * 2) readonly property real targetWidth: Math.min(380, Screen.width - Theme.spacingL * 2)
readonly property real targetHeight: Math.min(450, Screen.height - Theme.barHeight - Theme.spacingS * 2) readonly property real targetHeight: Math.min(450, Screen.height - Theme.barHeight - Theme.spacingS * 2)
asynchronous: true
active: batteryPopupVisible
width: targetWidth width: targetWidth
height: targetHeight height: targetHeight
x: Math.max(Theme.spacingL, Screen.width - targetWidth - Theme.spacingL) x: Math.max(Theme.spacingL, Screen.width - targetWidth - Theme.spacingL)
y: Theme.barHeight + Theme.spacingS y: Theme.barHeight + Theme.spacingS
// GPU-accelerated scale + opacity animation // GPU-accelerated scale + opacity animation
opacity: batteryPopupVisible ? 1 : 0 opacity: batteryPopupVisible ? 1 : 0
scale: batteryPopupVisible ? 1 : 0.9 scale: batteryPopupVisible ? 1 : 0.9
@@ -80,6 +80,7 @@ PanelWindow {
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.emphasized easing.bezierCurve: Anims.emphasized
} }
} }
Behavior on scale { Behavior on scale {
@@ -88,6 +89,7 @@ PanelWindow {
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.emphasized easing.bezierCurve: Anims.emphasized
} }
} }
sourceComponent: Rectangle { sourceComponent: Rectangle {
@@ -95,12 +97,10 @@ PanelWindow {
radius: Theme.cornerRadiusLarge radius: Theme.cornerRadiusLarge
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 1 border.width: 1
// Remove layer rendering for better performance // Remove layer rendering for better performance
antialiasing: true antialiasing: true
smooth: true smooth: true
ScrollView { ScrollView {
anchors.fill: parent anchors.fill: parent
anchors.margins: Theme.spacingL anchors.margins: Theme.spacingL
@@ -486,9 +486,8 @@ PanelWindow {
} }
}
} }
}
} }

View File

@@ -6,6 +6,7 @@ Rectangle {
id: root id: root
property date currentDate: new Date() property date currentDate: new Date()
property bool compactMode: false
signal clockClicked() signal clockClicked()
@@ -36,6 +37,7 @@ Rectangle {
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5) color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: !compactMode
} }
Text { Text {
@@ -44,6 +46,7 @@ Rectangle {
color: Theme.surfaceText color: Theme.surfaceText
font.weight: Font.Medium font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: !compactMode
} }
} }

View File

@@ -16,11 +16,9 @@ Rectangle {
height: 30 height: 30
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: cpuArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) : Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08) color: cpuArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) : Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08)
Component.onCompleted: { Component.onCompleted: {
SysMonitorService.addRef(); SysMonitorService.addRef();
} }
Component.onDestruction: { Component.onDestruction: {
SysMonitorService.removeRef(); SysMonitorService.removeRef();
} }
@@ -35,6 +33,7 @@ Rectangle {
SysMonitorService.setSortBy("cpu"); SysMonitorService.setSortBy("cpu");
if (root.toggleProcessList) if (root.toggleProcessList)
root.toggleProcessList(); root.toggleProcessList();
} }
} }

View File

@@ -5,64 +5,13 @@ import qs.Services
Rectangle { Rectangle {
id: root id: root
// Dynamic screen detection for laptop vs desktop monitor property bool compactMode: false
readonly property bool isSmallScreen: { property int availableWidth: 400
// Walk up the parent chain to find the TopBar PanelWindow readonly property int baseWidth: contentRow.implicitWidth + Theme.spacingS * 2
let current = root.parent readonly property int maxNormalWidth: 456
while (current && !current.screen) { readonly property int maxCompactWidth: 200
current = current.parent
}
if (!current || !current.screen) { width: compactMode ? Math.min(baseWidth, maxCompactWidth) : Math.min(baseWidth, maxNormalWidth)
return true // Default to small if we can't detect
}
const s = current.screen
// Multi-method detection for laptop/small screens:
// Method 1: Check screen name for laptop indicators
const screenName = (s.name || "").toLowerCase()
if (screenName.includes("edp") || screenName.includes("lvds")) {
return true
}
// Method 2: Check pixel density if available
try {
if (s.pixelDensity && s.pixelDensity > 1.5) {
return true
}
} catch (e) { /* ignore */ }
// Method 3: Check device pixel ratio if available
try {
if (s.devicePixelRatio && s.devicePixelRatio > 1.25) {
return true
}
} catch (e) { /* ignore */ }
// Method 4: Resolution-based fallback for smaller displays
if (s.width <= 1920 && s.height <= 1200) {
return true
}
// Method 5: Check for high-res laptop displays
if ((s.width === 2400 && s.height === 1600) ||
(s.width === 2560 && s.height === 1600) ||
(s.width === 2880 && s.height === 1800)) {
return true
}
return false // Default to large screen
}
// Dynamic sizing based on screen type
readonly property int maxWidth: isSmallScreen ? 288 : 456
readonly property int appNameMaxWidth: isSmallScreen ? 130 : 180
readonly property int separatorWidth: 15
readonly property int titleMaxWidth: maxWidth - appNameMaxWidth - separatorWidth - (Theme.spacingS * 2)
width: Math.min(contentRow.implicitWidth + Theme.spacingS * 2, maxWidth)
height: 30 height: 30
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: mouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08) color: mouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08)
@@ -83,10 +32,9 @@ Rectangle {
font.weight: Font.Medium font.weight: Font.Medium
color: Theme.surfaceText color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
// App name gets reasonable space - only truncate if absolutely necessary
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
width: Math.min(implicitWidth, root.appNameMaxWidth) width: Math.min(implicitWidth, compactMode ? 80 : 180)
} }
Text { Text {
@@ -105,17 +53,15 @@ Rectangle {
font.weight: Font.Medium font.weight: Font.Medium
color: Theme.surfaceText color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
// Window title gets remaining space and shows ellipsis when truncated
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
width: Math.min(implicitWidth, root.titleMaxWidth) width: Math.min(implicitWidth, compactMode ? 60 : 250)
visible: !compactMode || text.length < 15
} }
} }
MouseArea { MouseArea {
// Non-interactive widget - just provides hover state for visual feedback
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
@@ -130,7 +76,6 @@ Rectangle {
} }
// Smooth width animation when the text changes
Behavior on width { Behavior on width {
NumberAnimation { NumberAnimation {
duration: Theme.shortDuration duration: Theme.shortDuration

View File

@@ -9,59 +9,10 @@ Rectangle {
readonly property MprisPlayer activePlayer: MprisController.activePlayer readonly property MprisPlayer activePlayer: MprisController.activePlayer
readonly property bool playerAvailable: activePlayer !== null readonly property bool playerAvailable: activePlayer !== null
property bool compactMode: false
// Screen detection for responsive design (same logic as FocusedApp) readonly property int baseContentWidth: mediaRow.implicitWidth + Theme.spacingS * 2
readonly property bool isSmallScreen: { readonly property int normalContentWidth: Math.min(280, baseContentWidth)
// Walk up the parent chain to find the TopBar PanelWindow readonly property int compactContentWidth: Math.min(120, baseContentWidth)
let current = root.parent
while (current && !current.screen) {
current = current.parent
}
if (!current || !current.screen) {
return true // Default to small if we can't detect
}
const s = current.screen
// Multi-method detection for laptop/small screens:
// Method 1: Check screen name for laptop indicators
const screenName = (s.name || "").toLowerCase()
if (screenName.includes("edp") || screenName.includes("lvds")) {
return true
}
// Method 2: Check pixel density if available
try {
if (s.pixelDensity && s.pixelDensity > 1.5) {
return true
}
} catch (e) { /* ignore */ }
// Method 3: Check device pixel ratio if available
try {
if (s.devicePixelRatio && s.devicePixelRatio > 1.25) {
return true
}
} catch (e) { /* ignore */ }
// Method 4: Resolution-based fallback for smaller displays
if (s.width <= 1920 && s.height <= 1200) {
return true
}
// Method 5: Check for high-res laptop displays
if ((s.width === 2400 && s.height === 1600) ||
(s.width === 2560 && s.height === 1600) ||
(s.width === 2880 && s.height === 1800)) {
return true
}
return false // Default to large screen
}
readonly property int contentWidth: Math.min(280, mediaRow.implicitWidth + Theme.spacingS * 2)
signal clicked() signal clicked()
@@ -76,7 +27,7 @@ Rectangle {
PropertyChanges { PropertyChanges {
target: root target: root
opacity: 1 opacity: 1
width: contentWidth width: compactMode ? compactContentWidth : normalContentWidth
} }
}, },
@@ -130,7 +81,6 @@ Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
spacing: Theme.spacingXS spacing: Theme.spacingXS
// Media info section (clickable to open full player)
Row { Row {
id: mediaInfo id: mediaInfo
@@ -144,8 +94,8 @@ Rectangle {
id: mediaText id: mediaText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 140 width: compactMode ? 60 : 140
visible: !root.isSmallScreen // Hide title text on small screens visible: !compactMode
text: { text: {
if (!activePlayer || !activePlayer.trackTitle) if (!activePlayer || !activePlayer.trackTitle)
return ""; return "";
@@ -185,12 +135,10 @@ Rectangle {
} }
// Control buttons
Row { Row {
spacing: Theme.spacingXS spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
// Previous button
Rectangle { Rectangle {
width: 20 width: 20
height: 20 height: 20
@@ -222,7 +170,6 @@ Rectangle {
} }
// Play/Pause button
Rectangle { Rectangle {
width: 24 width: 24
height: 24 height: 24
@@ -252,7 +199,6 @@ Rectangle {
} }
// Next button
Rectangle { Rectangle {
width: 20 width: 20
height: 20 height: 20

View File

@@ -16,11 +16,9 @@ Rectangle {
height: 30 height: 30
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: ramArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) : Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08) color: ramArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16) : Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08)
Component.onCompleted: { Component.onCompleted: {
SysMonitorService.addRef(); SysMonitorService.addRef();
} }
Component.onDestruction: { Component.onDestruction: {
SysMonitorService.removeRef(); SysMonitorService.removeRef();
} }
@@ -35,6 +33,7 @@ Rectangle {
SysMonitorService.setSortBy("memory"); SysMonitorService.setSortBy("memory");
if (root.toggleProcessList) if (root.toggleProcessList)
root.toggleProcessList(); root.toggleProcessList();
} }
} }

View File

@@ -47,11 +47,14 @@ Rectangle {
Behavior on color { Behavior on color {
enabled: trayItemArea.containsMouse !== undefined enabled: trayItemArea.containsMouse !== undefined
ColorAnimation { ColorAnimation {
duration: Theme.shortDuration duration: Theme.shortDuration
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
} }
Image { Image {
@@ -66,23 +69,27 @@ Rectangle {
MouseArea { MouseArea {
id: trayItemArea id: trayItemArea
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: (mouse) => { onClicked: (mouse) => {
if (!trayItem) return; if (!trayItem)
return ;
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
if (!trayItem.onlyMenu) if (!trayItem.onlyMenu)
trayItem.activate(); trayItem.activate();
} else if (mouse.button === Qt.RightButton) { } else if (mouse.button === Qt.RightButton) {
if (trayItem && trayItem.hasMenu) { if (trayItem && trayItem.hasMenu)
root.menuRequested(null, trayItem, mouse.x, mouse.y); root.menuRequested(null, trayItem, mouse.x, mouse.y);
} }
} }
} }
}
} }
} }

View File

@@ -110,6 +110,27 @@ PanelWindow {
} }
Item { Item {
id: topBarContent
readonly property int availableWidth: width
readonly property int leftSectionWidth: leftSection.width
readonly property int rightSectionWidth: rightSection.width
readonly property int clockWidth: clock.width
readonly property int mediaWidth: media.visible ? media.width : 0
readonly property int weatherWidth: weather.visible ? weather.width : 0
readonly property bool validLayout: availableWidth > 100 && leftSectionWidth > 0 && rightSectionWidth > 0
readonly property int clockLeftEdge: validLayout ? (availableWidth - clockWidth) / 2 : 0
readonly property int clockRightEdge: clockLeftEdge + clockWidth
readonly property int leftSectionRightEdge: leftSectionWidth
readonly property int mediaLeftEdge: clockLeftEdge - mediaWidth - Theme.spacingS
readonly property int rightSectionLeftEdge: availableWidth - rightSectionWidth
readonly property int leftToClockGap: validLayout ? Math.max(0, clockLeftEdge - leftSectionRightEdge) : 1000
readonly property int leftToMediaGap: (mediaWidth > 0 && validLayout) ? Math.max(0, mediaLeftEdge - leftSectionRightEdge) : leftToClockGap
readonly property int mediaToClockGap: mediaWidth > 0 ? Theme.spacingS : 0
readonly property int clockToRightGap: validLayout ? Math.max(0, rightSectionLeftEdge - clockRightEdge) : 1000
readonly property bool spacingTight: validLayout && (leftToMediaGap < 100 || clockToRightGap < 100)
readonly property bool overlapping: validLayout && (leftToMediaGap < 50 || clockToRightGap < 50)
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
anchors.rightMargin: Theme.spacingM anchors.rightMargin: Theme.spacingM
@@ -131,6 +152,7 @@ PanelWindow {
onClicked: { onClicked: {
if (appDrawerPopout) if (appDrawerPopout)
appDrawerPopout.toggle(); appDrawerPopout.toggle();
} }
} }
@@ -140,8 +162,12 @@ PanelWindow {
} }
FocusedApp { FocusedApp {
id: focusedApp
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: Prefs.showFocusedWindow visible: Prefs.showFocusedWindow
compactMode: topBarContent.spacingTight
availableWidth: topBarContent.leftToMediaGap
} }
} }
@@ -150,16 +176,20 @@ PanelWindow {
id: clock id: clock
anchors.centerIn: parent anchors.centerIn: parent
compactMode: topBarContent.overlapping
onClockClicked: { onClockClicked: {
centcomPopout.calendarVisible = !centcomPopout.calendarVisible; centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
} }
} }
Media { Media {
id: media
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: clock.left anchors.right: clock.left
anchors.rightMargin: Theme.spacingS anchors.rightMargin: Theme.spacingS
visible: Prefs.showMusic && MprisController.activePlayer visible: Prefs.showMusic && MprisController.activePlayer
compactMode: topBarContent.spacingTight || topBarContent.overlapping
onClicked: { onClicked: {
centcomPopout.calendarVisible = !centcomPopout.calendarVisible; centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
} }
@@ -237,21 +267,31 @@ PanelWindow {
Loader { Loader {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
active: Prefs.showSystemResources active: Prefs.showSystemResources
sourceComponent: Component { sourceComponent: Component {
CpuMonitor { CpuMonitor {
toggleProcessList: () => processListPopout.toggle() toggleProcessList: () => {
return processListPopout.toggle();
} }
} }
}
} }
Loader { Loader {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
active: Prefs.showSystemResources active: Prefs.showSystemResources
sourceComponent: Component { sourceComponent: Component {
RamMonitor { RamMonitor {
toggleProcessList: () => processListPopout.toggle() toggleProcessList: () => {
return processListPopout.toggle();
} }
} }
}
} }
NotificationCenterButton { NotificationCenterButton {