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

bunch of cleanups

This commit is contained in:
bbedward
2025-07-19 10:56:32 -04:00
parent 5626335602
commit 063e9bb40f
9 changed files with 295 additions and 1062 deletions

View File

@@ -221,6 +221,7 @@ PanelWindow {
} }
Connections { Connections {
target: AppSearchService
function onApplicationsChanged() { function onApplicationsChanged() {
console.log("AppLauncher: DesktopEntries.applicationsChanged signal received"); console.log("AppLauncher: DesktopEntries.applicationsChanged signal received");
// Update categories when applications change // Update categories when applications change
@@ -231,8 +232,6 @@ PanelWindow {
})); }));
updateFilteredModel(); updateFilteredModel();
} }
target: DesktopEntries
} }
Connections { Connections {

View File

@@ -868,15 +868,6 @@ PanelWindow {
else else
console.warn("ClipboardHistory: Failed to load clipboard history"); console.warn("ClipboardHistory: Failed to load clipboard history");
} }
// Handle keyboard shortcuts
Keys.onPressed: (event) => {
if (event.key === Qt.Key_Escape)
clipboardHistory.hide();
}
Component.onCompleted: {
focus = true;
}
stdout: SplitParser { stdout: SplitParser {
splitMarker: "\n" splitMarker: "\n"

View File

@@ -123,7 +123,7 @@ Item {
radius: 6 radius: 6
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
z: 10 z: 10
opacity: networkTab.changingNetworkPreference ? 0.6 : 1 opacity: NetworkService.changingPreference ? 0.6 : 1
visible: NetworkService.networkStatus !== "ethernet" && NetworkService.wifiAvailable && NetworkService.wifiEnabled visible: NetworkService.networkStatus !== "ethernet" && NetworkService.wifiAvailable && NetworkService.wifiEnabled
Row { Row {
@@ -133,17 +133,17 @@ Item {
DankIcon { DankIcon {
id: ethernetPreferenceIcon id: ethernetPreferenceIcon
name: networkTab.changingNetworkPreference ? "sync" : "" name: NetworkService.changingPreference ? "sync" : ""
size: Theme.fontSizeSmall size: Theme.fontSizeSmall
color: networkTab.networkStatus === "ethernet" ? Theme.background : Theme.primary color: networkTab.networkStatus === "ethernet" ? Theme.background : Theme.primary
visible: networkTab.changingNetworkPreference visible: NetworkService.changingPreference
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
rotation: networkTab.changingNetworkPreference ? ethernetPreferenceIcon.rotation : 0 rotation: NetworkService.changingPreference ? ethernetPreferenceIcon.rotation : 0
RotationAnimation { RotationAnimation {
target: ethernetPreferenceIcon target: ethernetPreferenceIcon
property: "rotation" property: "rotation"
running: networkTab.changingNetworkPreference running: NetworkService.changingPreference
from: 0 from: 0
to: 360 to: 360
duration: 1000 duration: 1000
@@ -153,7 +153,7 @@ Item {
} }
Text { Text {
text: networkTab.changingNetworkPreference ? "Switching..." : (networkTab.networkStatus === "ethernet" ? "" : "Prefer over WiFi") text: NetworkService.changingPreference ? "Switching..." : (networkTab.networkStatus === "ethernet" ? "" : "Prefer over WiFi")
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: networkTab.networkStatus === "ethernet" ? Theme.background : Theme.primary color: networkTab.networkStatus === "ethernet" ? Theme.background : Theme.primary
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -167,7 +167,7 @@ Item {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
propagateComposedEvents: false propagateComposedEvents: false
enabled: !networkTab.changingNetworkPreference enabled: !NetworkService.changingPreference
onClicked: { onClicked: {
console.log("*** ETHERNET PREFERENCE BUTTON CLICKED ***"); console.log("*** ETHERNET PREFERENCE BUTTON CLICKED ***");
if (networkTab.networkStatus !== "ethernet") { if (networkTab.networkStatus !== "ethernet") {
@@ -356,7 +356,7 @@ Item {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Theme.spacingL + 48 + Theme.spacingM anchors.rightMargin: Theme.spacingL + 48 + Theme.spacingM
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
opacity: networkTab.changingNetworkPreference ? 0.6 : 1 opacity: NetworkService.changingPreference ? 0.6 : 1
visible: NetworkService.networkStatus !== "wifi" && NetworkService.ethernetConnected && NetworkService.wifiEnabled visible: NetworkService.networkStatus !== "wifi" && NetworkService.ethernetConnected && NetworkService.wifiEnabled
Row { Row {
@@ -366,17 +366,17 @@ Item {
DankIcon { DankIcon {
id: wifiPreferenceIcon id: wifiPreferenceIcon
name: networkTab.changingNetworkPreference ? "sync" : "" name: NetworkService.changingPreference ? "sync" : ""
size: Theme.fontSizeSmall size: Theme.fontSizeSmall
color: networkTab.networkStatus === "wifi" ? Theme.background : Theme.primary color: networkTab.networkStatus === "wifi" ? Theme.background : Theme.primary
visible: networkTab.changingNetworkPreference visible: NetworkService.changingPreference
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
rotation: networkTab.changingNetworkPreference ? wifiPreferenceIcon.rotation : 0 rotation: NetworkService.changingPreference ? wifiPreferenceIcon.rotation : 0
RotationAnimation { RotationAnimation {
target: wifiPreferenceIcon target: wifiPreferenceIcon
property: "rotation" property: "rotation"
running: networkTab.changingNetworkPreference running: NetworkService.changingPreference
from: 0 from: 0
to: 360 to: 360
duration: 1000 duration: 1000
@@ -386,7 +386,7 @@ Item {
} }
Text { Text {
text: NetworkService.changingNetworkPreference ? "Switching..." : "Prefer over Ethernet" text: NetworkService.changingPreference ? "Switching..." : "Prefer over Ethernet"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: NetworkService.networkStatus === "wifi" ? Theme.background : Theme.primary color: NetworkService.networkStatus === "wifi" ? Theme.background : Theme.primary
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -400,7 +400,7 @@ Item {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
propagateComposedEvents: false propagateComposedEvents: false
enabled: !networkTab.changingNetworkPreference enabled: !NetworkService.changingPreference
onClicked: { onClicked: {
console.log("Force WiFi preference clicked"); console.log("Force WiFi preference clicked");
if (NetworkService.networkStatus !== "wifi") if (NetworkService.networkStatus !== "wifi")

View File

@@ -373,78 +373,41 @@ PanelWindow {
border.width: 1 border.width: 1
clip: true clip: true
readonly property bool hasNotificationImage: modelData.latestNotification.image && modelData.latestNotification.image !== ""
IconImage { IconImage {
anchors.fill: parent anchors.fill: parent
anchors.margins: 6 anchors.margins: 2
source: { source: {
// Don't try to load icons for screenshots - let fallback handle them // Priority 1: Use notification image if available
const isScreenshot = modelData.latestNotification.isScreenshot; if (parent.hasNotificationImage) {
return modelData.latestNotification.cleanImage;
if (isScreenshot) {
return "";
} }
if (modelData.latestNotification.appIcon && modelData.latestNotification.appIcon !== "") // Priority 2: Use appIcon - handle URLs directly, use iconPath for icon names
return Quickshell.iconPath(modelData.latestNotification.appIcon, ""); if (modelData.latestNotification.appIcon) {
const appIcon = modelData.latestNotification.appIcon;
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://")) {
return appIcon;
}
return Quickshell.iconPath(appIcon, "");
}
return ""; return "";
} }
visible: status === Image.Ready visible: status === Image.Ready
onStatusChanged: {
if (status === Image.Error || status === Image.Null || source === "")
fallbackIcon.visible = true;
else if (status === Image.Ready)
fallbackIcon.visible = false;
}
} }
Item { Text {
id: fallbackIcon
anchors.centerIn: parent anchors.centerIn: parent
visible: true visible: !parent.hasNotificationImage && (!modelData.latestNotification.appIcon || modelData.latestNotification.appIcon === "")
width: parent.width text: {
height: parent.height const appName = modelData.appName || "?";
return appName.charAt(0).toUpperCase();
readonly property bool isScreenshot: modelData.latestNotification.isScreenshot
readonly property bool hasNotificationImage: modelData.latestNotification.image && modelData.latestNotification.image !== ""
// Priority 1: Notification image using Quickshell IconImage
Rectangle {
anchors.fill: parent
anchors.margins: 2
radius: 20
clip: true
visible: parent.hasNotificationImage && centerNotificationImage.status === Image.Ready
color: "transparent"
IconImage {
id: centerNotificationImage
anchors.fill: parent
source: modelData.latestNotification.image || ""
}
}
// Priority 2: Material Symbols icon for screenshots without notification images
DankIcon {
anchors.centerIn: parent
name: "screenshot_monitor"
size: 20
color: Theme.primaryText
visible: parent.isScreenshot && !parent.hasNotificationImage
}
// Priority 3: Fallback to first letter for other notifications
Text {
anchors.centerIn: parent
visible: !parent.hasNotificationImage && !parent.isScreenshot
text: {
const appName = modelData.appName || "?";
return appName.charAt(0).toUpperCase();
}
font.pixelSize: 20
font.weight: Font.Bold
color: Theme.primaryText
} }
font.pixelSize: 20
font.weight: Font.Bold
color: Theme.primaryText
} }
} }
@@ -828,35 +791,32 @@ PanelWindow {
readonly property bool hasNotificationImage: modelData.image && modelData.image !== "" readonly property bool hasNotificationImage: modelData.image && modelData.image !== ""
// Priority 1: Notification image using Quickshell IconImage IconImage {
Rectangle {
anchors.fill: parent anchors.fill: parent
anchors.margins: 1 anchors.margins: 1
radius: 14 source: {
clip: true // Priority 1: Use notification image if available
visible: parent.hasNotificationImage && centerIndividualNotificationImage.status === Image.Ready if (parent.hasNotificationImage) {
color: "transparent" return modelData.cleanImage;
}
IconImage { // Priority 2: Use appIcon - handle URLs directly, use iconPath for icon names
id: centerIndividualNotificationImage if (modelData.appIcon) {
anchors.fill: parent const appIcon = modelData.appIcon;
source: modelData.image || "" if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://")) {
return appIcon;
}
return Quickshell.iconPath(appIcon, "");
}
return "";
} }
visible: status === Image.Ready
} }
// Priority 2: Material Symbols icon for screenshots without notification images
DankIcon {
anchors.centerIn: parent
name: "screenshot_monitor"
size: 12
color: Theme.primaryText
visible: modelData.isScreenshot && !parent.hasNotificationImage
}
// Priority 3: Fallback text
Text { Text {
anchors.centerIn: parent anchors.centerIn: parent
visible: !parent.hasNotificationImage && !modelData.isScreenshot visible: !parent.hasNotificationImage && (!modelData.appIcon || modelData.appIcon === "")
text: { text: {
const appName = modelData.appName || "?"; const appName = modelData.appName || "?";
return appName.charAt(0).toUpperCase(); return appName.charAt(0).toUpperCase();

File diff suppressed because it is too large Load Diff

View File

@@ -79,7 +79,7 @@ PanelWindow {
Scale { Scale {
id: scaleTransform id: scaleTransform
origin.x: parent.width * 0.85 // Scale from top-right origin.x: dropdownContent.width * 0.85 // Scale from top-right
origin.y: 0 origin.y: 0
xScale: processListDropdown.isVisible ? 1 : 0.95 xScale: processListDropdown.isVisible ? 1 : 0.95
yScale: processListDropdown.isVisible ? 1 : 0.8 yScale: processListDropdown.isVisible ? 1 : 0.8

View File

@@ -239,6 +239,7 @@ PanelWindow {
} }
Connections { Connections {
target: AppSearchService
function onReadyChanged() { function onReadyChanged() {
if (AppSearchService.ready) { if (AppSearchService.ready) {
var allCategories = AppSearchService.getAllCategories().filter((cat) => { var allCategories = AppSearchService.getAllCategories().filter((cat) => {
@@ -254,11 +255,10 @@ PanelWindow {
} }
} }
target: DesktopEntries
} }
Connections { Connections {
target: AppSearchService
function onApplicationsChanged() { function onApplicationsChanged() {
console.log("SpotlightLauncher: DesktopEntries.applicationsChanged signal received"); console.log("SpotlightLauncher: DesktopEntries.applicationsChanged signal received");
// Update categories when applications change // Update categories when applications change
@@ -278,8 +278,6 @@ PanelWindow {
console.log("SpotlightLauncher: AppSearchService not ready, skipping update"); console.log("SpotlightLauncher: AppSearchService not ready, skipping update");
} }
} }
target: DesktopEntries
} }
// Dimmed overlay background // Dimmed overlay background

View File

@@ -134,7 +134,7 @@ PanelWindow {
LauncherButton { LauncherButton {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
isActive: launcher.isVisible isActive: appLauncher.isVisible
onClicked: { onClicked: {
appLauncher.toggle(); appLauncher.toggle();
} }

View File

@@ -30,7 +30,14 @@ Singleton {
inlineReplySupported: true inlineReplySupported: true
onNotification: notif => { onNotification: notif => {
console.log("New notification received:", notif.appName, "-", notif.summary); console.log("=== RAW NOTIFICATION DATA ===");
console.log("appName:", notif.appName);
console.log("summary:", notif.summary);
console.log("body:", notif.body);
console.log("appIcon:", notif.appIcon);
console.log("image:", notif.image);
console.log("urgency:", notif.urgency);
console.log("=============================");
notif.tracked = true; notif.tracked = true;
const wrapper = notifComponent.createObject(root, { const wrapper = notifComponent.createObject(root, {
@@ -70,35 +77,32 @@ Singleton {
readonly property string summary: notification.summary readonly property string summary: notification.summary
readonly property string body: notification.body readonly property string body: notification.body
readonly property string appIcon: notification.appIcon readonly property string appIcon: notification.appIcon
readonly property string cleanAppIcon: {
if (!appIcon) return "";
if (appIcon.startsWith("file://")) {
return appIcon.substring(7);
}
return appIcon;
}
readonly property string appName: notification.appName readonly property string appName: notification.appName
readonly property string image: notification.image readonly property string image: notification.image
readonly property string cleanImage: {
if (!image) return "";
if (image.startsWith("file://")) {
return image.substring(7);
}
return image;
}
readonly property int urgency: notification.urgency readonly property int urgency: notification.urgency
readonly property list<NotificationAction> actions: notification.actions readonly property list<NotificationAction> actions: notification.actions
// Enhanced properties for better handling // Enhanced properties for better handling
readonly property bool hasImage: image && image.length > 0 readonly property bool hasImage: image && image.length > 0
readonly property bool hasAppIcon: appIcon && appIcon.length > 0 readonly property bool hasAppIcon: appIcon && appIcon.length > 0
readonly property bool isConversation: detectIsConversation() readonly property bool isConversation: notification.hasInlineReply
readonly property bool isMedia: detectIsMedia() readonly property bool isMedia: detectIsMedia()
readonly property bool isSystem: detectIsSystem() readonly property bool isSystem: detectIsSystem()
readonly property bool isScreenshot: detectIsScreenshot()
function detectIsConversation() {
const appNameLower = appName.toLowerCase();
const summaryLower = summary.toLowerCase();
const bodyLower = body.toLowerCase();
return appNameLower.includes("discord") ||
appNameLower.includes("vesktop") ||
appNameLower.includes("vencord") ||
appNameLower.includes("telegram") ||
appNameLower.includes("whatsapp") ||
appNameLower.includes("signal") ||
appNameLower.includes("slack") ||
appNameLower.includes("message") ||
summaryLower.includes("message") ||
bodyLower.includes("message");
}
function detectIsMedia() { function detectIsMedia() {
const appNameLower = appName.toLowerCase(); const appNameLower = appName.toLowerCase();
@@ -123,24 +127,6 @@ Singleton {
summaryLower.includes("system"); summaryLower.includes("system");
} }
function detectIsScreenshot() {
const appNameLower = appName.toLowerCase();
const summaryLower = summary.toLowerCase();
const bodyLower = body.toLowerCase();
const imageLower = image.toLowerCase();
// Detect niri screenshot notifications
return appNameLower.includes("niri") &&
(summaryLower.includes("screenshot") ||
bodyLower.includes("screenshot") ||
imageLower.includes("screenshot") ||
imageLower.includes("pictures/screenshots")) ||
summaryLower.includes("screenshot") ||
bodyLower.includes("screenshot taken") ||
// Detect screenshot file paths being used as images/icons
imageLower.includes("/screenshots/") ||
imageLower.includes("screenshot from");
}
readonly property Timer timer: Timer { readonly property Timer timer: Timer {
running: wrapper.popup running: wrapper.popup
@@ -184,114 +170,32 @@ Singleton {
wrapper.notification.dismiss(); wrapper.notification.dismiss();
} }
function getNotificationIcon(wrapper) {
// Priority 1: Use notification image if available (Discord avatars, etc.)
// BUT NOT for screenshots - they use file paths which shouldn't be loaded as icons
if (wrapper.hasImage && !wrapper.isScreenshot) {
return wrapper.image;
}
// Priority 2: Use app icon if available and not a screenshot
if (wrapper.hasAppIcon && !wrapper.isScreenshot) {
return Quickshell.iconPath(wrapper.appIcon, "image-missing");
}
// Priority 3: Generate fallback icon based on type
return getFallbackIcon(wrapper);
}
function getFallbackIcon(wrapper) {
if (wrapper.isScreenshot) {
return Quickshell.iconPath("screenshot_monitor");
} else if (wrapper.isConversation) {
return Quickshell.iconPath("chat-symbolic");
} else if (wrapper.isMedia) {
return Quickshell.iconPath("audio-x-generic-symbolic");
} else if (wrapper.isSystem) {
return Quickshell.iconPath("preferences-system-symbolic");
}
return Quickshell.iconPath("application-x-executable-symbolic");
}
function getAppIconPath(wrapper) {
if (wrapper.hasAppIcon && !wrapper.isScreenshot) {
return Quickshell.iconPath(wrapper.appIcon);
}
return getFallbackIcon(wrapper);
}
// Android 16-style notification grouping functions // Android 16-style notification grouping functions
function getGroupKey(wrapper) { function getGroupKey(wrapper) {
const appName = wrapper.appName.toLowerCase(); const appName = wrapper.appName.toLowerCase();
// Enhanced grouping for conversation apps // Conversation apps with inline reply
if (wrapper.isConversation) { if (wrapper.isConversation) {
const summary = wrapper.summary.toLowerCase(); const summary = wrapper.summary.toLowerCase();
const body = wrapper.body.toLowerCase();
// Discord: Group by channel or conversation // Group by conversation/channel name from summary
if (appName.includes("discord") || appName.includes("vesktop")) { if (summary.includes("#")) {
// Channel notifications: "#general", "#announcements" const channelMatch = summary.match(/#[\w-]+/);
if (summary.includes("#")) { if (channelMatch) {
const channelMatch = summary.match(/#[\w-]+/); return `${appName}:${channelMatch[0]}`;
if (channelMatch) {
return `${appName}:${channelMatch[0]}`;
}
} }
// Direct messages: group by sender
if (summary && !summary.includes("new message") && !summary.includes("notification")) {
return `${appName}:dm:${summary}`;
}
// Server messages or general
return `${appName}:messages`;
} }
// Telegram: Group by chat/channel // Group by sender/conversation name if meaningful
if (appName.includes("telegram")) { if (summary && !summary.includes("new message") && !summary.includes("notification")) {
if (summary && !summary.includes("new message")) { return `${appName}:${summary}`;
return `${appName}:${summary}`;
}
return `${appName}:messages`;
}
// Signal: Group by conversation
if (appName.includes("signal")) {
if (summary && !summary.includes("new message")) {
return `${appName}:${summary}`;
}
return `${appName}:messages`;
}
// WhatsApp: Group by contact/group
if (appName.includes("whatsapp")) {
if (summary && !summary.includes("new message")) {
return `${appName}:${summary}`;
}
return `${appName}:messages`;
}
// Slack: Group by channel/DM
if (appName.includes("slack")) {
if (summary.includes("#")) {
const channelMatch = summary.match(/#[\w-]+/);
if (channelMatch) {
return `${appName}:${channelMatch[0]}`;
}
}
if (summary && !summary.includes("new message")) {
return `${appName}:dm:${summary}`;
}
return `${appName}:messages`;
} }
// Default conversation grouping // Default conversation grouping
return `${appName}:conversation`; return `${appName}:conversation`;
} }
// Screenshots: Group all screenshots together
if (wrapper.isScreenshot) {
return "screenshots";
}
// Media: Replace previous media notification from same app // Media: Replace previous media notification from same app
if (wrapper.isMedia) { if (wrapper.isMedia) {
@@ -332,8 +236,7 @@ Singleton {
hasInlineReply: false, hasInlineReply: false,
isConversation: notif.isConversation, isConversation: notif.isConversation,
isMedia: notif.isMedia, isMedia: notif.isMedia,
isSystem: notif.isSystem, isSystem: notif.isSystem
isScreenshot: notif.isScreenshot
}; };
} }
@@ -366,8 +269,7 @@ Singleton {
hasInlineReply: false, hasInlineReply: false,
isConversation: notif.isConversation, isConversation: notif.isConversation,
isMedia: notif.isMedia, isMedia: notif.isMedia,
isSystem: notif.isSystem, isSystem: notif.isSystem
isScreenshot: notif.isScreenshot
}; };
} }
@@ -419,17 +321,10 @@ Singleton {
} }
if (group.isConversation) { if (group.isConversation) {
// Extract conversation/channel name from group key
const keyParts = group.key.split(":"); const keyParts = group.key.split(":");
if (keyParts.length > 1) { if (keyParts.length > 1) {
const conversationKey = keyParts[keyParts.length - 1]; const conversationKey = keyParts[keyParts.length - 1];
if (conversationKey.startsWith("#")) { if (conversationKey !== "conversation") {
return `${conversationKey}: ${group.count} messages`;
}
if (keyParts.includes("dm")) {
return `${conversationKey}: ${group.count} messages`;
}
if (conversationKey !== "messages" && conversationKey !== "conversation") {
return `${conversationKey}: ${group.count} messages`; return `${conversationKey}: ${group.count} messages`;
} }
} }
@@ -440,12 +335,6 @@ Singleton {
return "Now playing"; return "Now playing";
} }
if (group.isScreenshot) {
if (group.count === 1) {
return "Screenshot saved";
}
return `${group.count} screenshots saved`;
}
if (group.isSystem) { if (group.isSystem) {
const keyParts = group.key.split(":"); const keyParts = group.key.split(":");
@@ -481,9 +370,6 @@ Singleton {
return group.latestNotification.body || "Media playback"; return group.latestNotification.body || "Media playback";
} }
if (group.isScreenshot) {
return group.latestNotification.body || "Screenshot available in Pictures/Screenshots";
}
return `Latest: ${group.latestNotification.summary}`; return `Latest: ${group.latestNotification.summary}`;
} }