1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 21:45:38 -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
onExited: (exitCode) => {
root.cavaAvailable = exitCode === 0;
if (root.cavaAvailable) {
if (root.cavaAvailable)
cavaProcess.running = Qt.binding(() => {
return root.hasActiveMedia && root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing;
});
} else {
else
fallbackTimer.running = Qt.binding(() => {
return root.hasActiveMedia && root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing;
});
}
}
}
Process {
id: cavaProcess

View File

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

View File

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

View File

@@ -16,11 +16,9 @@ Rectangle {
height: 30
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)
Component.onCompleted: {
SysMonitorService.addRef();
}
Component.onDestruction: {
SysMonitorService.removeRef();
}
@@ -35,6 +33,7 @@ Rectangle {
SysMonitorService.setSortBy("cpu");
if (root.toggleProcessList)
root.toggleProcessList();
}
}

View File

@@ -5,64 +5,13 @@ import qs.Services
Rectangle {
id: root
// Dynamic screen detection for laptop vs desktop monitor
readonly property bool isSmallScreen: {
// Walk up the parent chain to find the TopBar PanelWindow
let current = root.parent
while (current && !current.screen) {
current = current.parent
}
property bool compactMode: false
property int availableWidth: 400
readonly property int baseWidth: contentRow.implicitWidth + Theme.spacingS * 2
readonly property int maxNormalWidth: 456
readonly property int maxCompactWidth: 200
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
}
// 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)
width: compactMode ? Math.min(baseWidth, maxCompactWidth) : Math.min(baseWidth, maxNormalWidth)
height: 30
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)
@@ -83,10 +32,9 @@ Rectangle {
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
// App name gets reasonable space - only truncate if absolutely necessary
elide: Text.ElideRight
maximumLineCount: 1
width: Math.min(implicitWidth, root.appNameMaxWidth)
width: Math.min(implicitWidth, compactMode ? 80 : 180)
}
Text {
@@ -105,17 +53,15 @@ Rectangle {
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
// Window title gets remaining space and shows ellipsis when truncated
elide: Text.ElideRight
maximumLineCount: 1
width: Math.min(implicitWidth, root.titleMaxWidth)
width: Math.min(implicitWidth, compactMode ? 60 : 250)
visible: !compactMode || text.length < 15
}
}
MouseArea {
// Non-interactive widget - just provides hover state for visual feedback
id: mouseArea
anchors.fill: parent
@@ -130,7 +76,6 @@ Rectangle {
}
// Smooth width animation when the text changes
Behavior on width {
NumberAnimation {
duration: Theme.shortDuration

View File

@@ -9,59 +9,10 @@ Rectangle {
readonly property MprisPlayer activePlayer: MprisController.activePlayer
readonly property bool playerAvailable: activePlayer !== null
// Screen detection for responsive design (same logic as FocusedApp)
readonly property bool isSmallScreen: {
// Walk up the parent chain to find the TopBar PanelWindow
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)
property bool compactMode: false
readonly property int baseContentWidth: mediaRow.implicitWidth + Theme.spacingS * 2
readonly property int normalContentWidth: Math.min(280, baseContentWidth)
readonly property int compactContentWidth: Math.min(120, baseContentWidth)
signal clicked()
@@ -76,7 +27,7 @@ Rectangle {
PropertyChanges {
target: root
opacity: 1
width: contentWidth
width: compactMode ? compactContentWidth : normalContentWidth
}
},
@@ -130,7 +81,6 @@ Rectangle {
anchors.centerIn: parent
spacing: Theme.spacingXS
// Media info section (clickable to open full player)
Row {
id: mediaInfo
@@ -144,8 +94,8 @@ Rectangle {
id: mediaText
anchors.verticalCenter: parent.verticalCenter
width: 140
visible: !root.isSmallScreen // Hide title text on small screens
width: compactMode ? 60 : 140
visible: !compactMode
text: {
if (!activePlayer || !activePlayer.trackTitle)
return "";
@@ -185,12 +135,10 @@ Rectangle {
}
// Control buttons
Row {
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
// Previous button
Rectangle {
width: 20
height: 20
@@ -222,7 +170,6 @@ Rectangle {
}
// Play/Pause button
Rectangle {
width: 24
height: 24
@@ -252,7 +199,6 @@ Rectangle {
}
// Next button
Rectangle {
width: 20
height: 20

View File

@@ -16,11 +16,9 @@ Rectangle {
height: 30
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)
Component.onCompleted: {
SysMonitorService.addRef();
}
Component.onDestruction: {
SysMonitorService.removeRef();
}
@@ -35,6 +33,7 @@ Rectangle {
SysMonitorService.setSortBy("memory");
if (root.toggleProcessList)
root.toggleProcessList();
}
}

View File

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

View File

@@ -110,6 +110,27 @@ PanelWindow {
}
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.leftMargin: Theme.spacingM
anchors.rightMargin: Theme.spacingM
@@ -131,6 +152,7 @@ PanelWindow {
onClicked: {
if (appDrawerPopout)
appDrawerPopout.toggle();
}
}
@@ -140,8 +162,12 @@ PanelWindow {
}
FocusedApp {
id: focusedApp
anchors.verticalCenter: parent.verticalCenter
visible: Prefs.showFocusedWindow
compactMode: topBarContent.spacingTight
availableWidth: topBarContent.leftToMediaGap
}
}
@@ -150,16 +176,20 @@ PanelWindow {
id: clock
anchors.centerIn: parent
compactMode: topBarContent.overlapping
onClockClicked: {
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
}
}
Media {
id: media
anchors.verticalCenter: parent.verticalCenter
anchors.right: clock.left
anchors.rightMargin: Theme.spacingS
visible: Prefs.showMusic && MprisController.activePlayer
compactMode: topBarContent.spacingTight || topBarContent.overlapping
onClicked: {
centcomPopout.calendarVisible = !centcomPopout.calendarVisible;
}
@@ -237,21 +267,31 @@ PanelWindow {
Loader {
anchors.verticalCenter: parent.verticalCenter
active: Prefs.showSystemResources
sourceComponent: Component {
CpuMonitor {
toggleProcessList: () => processListPopout.toggle()
toggleProcessList: () => {
return processListPopout.toggle();
}
}
}
}
Loader {
anchors.verticalCenter: parent.verticalCenter
active: Prefs.showSystemResources
sourceComponent: Component {
RamMonitor {
toggleProcessList: () => processListPopout.toggle()
toggleProcessList: () => {
return processListPopout.toggle();
}
}
}
}
NotificationCenterButton {