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:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,11 +47,14 @@ Rectangle {
|
||||
|
||||
Behavior on color {
|
||||
enabled: trayItemArea.containsMouse !== undefined
|
||||
|
||||
ColorAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Image {
|
||||
@@ -66,23 +69,27 @@ 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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user