mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-08 14:35:39 -05:00
Implement icon for niri screenshots
- Fixed debug icon warning logic - Add linux os environment script
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
//NotificationCenter.qml
|
//NotificationCenter.qml
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Effects
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
@@ -373,6 +374,13 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 6
|
anchors.margins: 6
|
||||||
source: {
|
source: {
|
||||||
|
// Don't try to load icons for screenshots - let fallback handle them
|
||||||
|
const isScreenshot = modelData.latestNotification.isScreenshot;
|
||||||
|
|
||||||
|
if (isScreenshot) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
if (modelData.latestNotification.appIcon && modelData.latestNotification.appIcon !== "")
|
if (modelData.latestNotification.appIcon && modelData.latestNotification.appIcon !== "")
|
||||||
return Quickshell.iconPath(modelData.latestNotification.appIcon, "");
|
return Quickshell.iconPath(modelData.latestNotification.appIcon, "");
|
||||||
|
|
||||||
@@ -387,18 +395,41 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Item {
|
||||||
id: fallbackIcon
|
id: fallbackIcon
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: true
|
visible: true
|
||||||
text: {
|
width: parent.width
|
||||||
const appName = modelData.appName || "?";
|
height: parent.height
|
||||||
return appName.charAt(0).toUpperCase();
|
|
||||||
|
readonly property bool isScreenshot: {
|
||||||
|
// Check if this is a screenshot notification using NotificationService detection
|
||||||
|
return modelData.latestNotification.isScreenshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Use Material Symbols icon for screenshots with fallback
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "screenshot_monitor"
|
||||||
|
size: 20
|
||||||
|
color: Theme.primaryText
|
||||||
|
visible: parent.isScreenshot
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to first letter for non-screenshot notifications
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: !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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -658,13 +689,31 @@ PanelWindow {
|
|||||||
IconImage {
|
IconImage {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 4
|
anchors.margins: 4
|
||||||
source: modelData.latestNotification.appIcon ? Quickshell.iconPath(modelData.latestNotification.appIcon, "") : ""
|
source: {
|
||||||
|
// Don't try to load icons for screenshots - let fallback handle them
|
||||||
|
const isScreenshot = modelData.latestNotification.isScreenshot;
|
||||||
|
|
||||||
|
if (isScreenshot) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelData.latestNotification.appIcon ? Quickshell.iconPath(modelData.latestNotification.appIcon, "") : "";
|
||||||
|
}
|
||||||
visible: status === Image.Ready
|
visible: status === Image.Ready
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Material Symbols icon for screenshots in expanded header
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "screenshot_monitor"
|
||||||
|
size: 16
|
||||||
|
color: Theme.primaryText
|
||||||
|
visible: modelData.latestNotification.isScreenshot
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !modelData.latestNotification.appIcon || modelData.latestNotification.appIcon === ""
|
visible: !modelData.latestNotification.isScreenshot && (!modelData.latestNotification.appIcon || modelData.latestNotification.appIcon === "")
|
||||||
text: {
|
text: {
|
||||||
const appName = modelData.appName || "?";
|
const appName = modelData.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase();
|
return appName.charAt(0).toUpperCase();
|
||||||
@@ -784,8 +833,18 @@ PanelWindow {
|
|||||||
border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2)
|
border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2)
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
|
||||||
|
// Material Symbols icon for individual screenshot notifications
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "screenshot_monitor"
|
||||||
|
size: 12
|
||||||
|
color: Theme.primaryText
|
||||||
|
visible: modelData.isScreenshot
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
visible: !modelData.isScreenshot
|
||||||
text: {
|
text: {
|
||||||
const appName = modelData.appName || "?";
|
const appName = modelData.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase();
|
return appName.charAt(0).toUpperCase();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Effects
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
@@ -144,6 +145,11 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 6
|
anchors.margins: 6
|
||||||
source: {
|
source: {
|
||||||
|
// Don't try to load icons for screenshots - let fallback handle them
|
||||||
|
if (modelData.latestNotification.isScreenshot) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
if (modelData.latestNotification.appIcon && modelData.latestNotification.appIcon !== "")
|
if (modelData.latestNotification.appIcon && modelData.latestNotification.appIcon !== "")
|
||||||
return Quickshell.iconPath(modelData.latestNotification.appIcon, "");
|
return Quickshell.iconPath(modelData.latestNotification.appIcon, "");
|
||||||
|
|
||||||
@@ -158,20 +164,40 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback icon - show by default, hide when real icon loads
|
// Fallback icon - show by default, hide when real icon loads
|
||||||
Text {
|
Item {
|
||||||
id: fallbackIcon
|
id: fallbackIcon
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: true // Start visible, hide when real icon loads
|
visible: true // Start visible, hide when real icon loads
|
||||||
text: {
|
width: parent.width
|
||||||
// Use first letter of app name as fallback
|
height: parent.height
|
||||||
const appName = modelData.appName || "?";
|
|
||||||
return appName.charAt(0).toUpperCase();
|
readonly property bool isScreenshot: modelData.latestNotification.isScreenshot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Use Material Symbols icon for screenshots with fallback
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "screenshot_monitor"
|
||||||
|
size: 24
|
||||||
|
color: Theme.primaryText
|
||||||
|
visible: parent.isScreenshot
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to first letter for non-screenshot notifications
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: !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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -441,14 +467,30 @@ PanelWindow {
|
|||||||
IconImage {
|
IconImage {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 4
|
anchors.margins: 4
|
||||||
source: modelData.latestNotification.appIcon ? Quickshell.iconPath(modelData.latestNotification.appIcon, "") : ""
|
source: {
|
||||||
|
// Don't try to load icons for screenshots - let fallback handle them
|
||||||
|
if (modelData.latestNotification.isScreenshot) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelData.latestNotification.appIcon ? Quickshell.iconPath(modelData.latestNotification.appIcon, "") : "";
|
||||||
|
}
|
||||||
visible: status === Image.Ready
|
visible: status === Image.Ready
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Material Symbols icon for screenshots in expanded view
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "screenshot_monitor"
|
||||||
|
size: 16
|
||||||
|
color: Theme.primaryText
|
||||||
|
visible: modelData.latestNotification.isScreenshot
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback for expanded view
|
// Fallback for expanded view
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !modelData.latestNotification.appIcon || modelData.latestNotification.appIcon === ""
|
visible: !modelData.latestNotification.isScreenshot && (!modelData.latestNotification.appIcon || modelData.latestNotification.appIcon === "")
|
||||||
text: {
|
text: {
|
||||||
const appName = modelData.appName || "?";
|
const appName = modelData.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase();
|
return appName.charAt(0).toUpperCase();
|
||||||
@@ -580,14 +622,30 @@ PanelWindow {
|
|||||||
IconImage {
|
IconImage {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 3
|
anchors.margins: 3
|
||||||
source: modelData.appIcon ? Quickshell.iconPath(modelData.appIcon, "") : ""
|
source: {
|
||||||
|
// Don't try to load icons for screenshots
|
||||||
|
if (modelData.isScreenshot) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelData.appIcon ? Quickshell.iconPath(modelData.appIcon, "") : "";
|
||||||
|
}
|
||||||
visible: status === Image.Ready
|
visible: status === Image.Ready
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Material Symbols icon for individual screenshot notifications
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "screenshot_monitor"
|
||||||
|
size: 12
|
||||||
|
color: Theme.primaryText
|
||||||
|
visible: modelData.isScreenshot
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback for individual notifications
|
// Fallback for individual notifications
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !modelData.appIcon || modelData.appIcon === ""
|
visible: !modelData.isScreenshot && (!modelData.appIcon || modelData.appIcon === "")
|
||||||
text: {
|
text: {
|
||||||
const appName = modelData.appName || "?";
|
const appName = modelData.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase();
|
return appName.charAt(0).toUpperCase();
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ Singleton {
|
|||||||
readonly property bool isConversation: detectIsConversation()
|
readonly property bool isConversation: detectIsConversation()
|
||||||
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() {
|
function detectIsConversation() {
|
||||||
const appNameLower = appName.toLowerCase();
|
const appNameLower = appName.toLowerCase();
|
||||||
@@ -121,6 +122,25 @@ 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
|
||||||
interval: wrapper.notification.expireTimeout > 0 ? wrapper.notification.expireTimeout : 5000 // 5 second default
|
interval: wrapper.notification.expireTimeout > 0 ? wrapper.notification.expireTimeout : 5000 // 5 second default
|
||||||
@@ -165,12 +185,13 @@ Singleton {
|
|||||||
|
|
||||||
function getNotificationIcon(wrapper) {
|
function getNotificationIcon(wrapper) {
|
||||||
// Priority 1: Use notification image if available (Discord avatars, etc.)
|
// Priority 1: Use notification image if available (Discord avatars, etc.)
|
||||||
if (wrapper.hasImage) {
|
// BUT NOT for screenshots - they use file paths which shouldn't be loaded as icons
|
||||||
|
if (wrapper.hasImage && !wrapper.isScreenshot) {
|
||||||
return wrapper.image;
|
return wrapper.image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 2: Use app icon if available
|
// Priority 2: Use app icon if available and not a screenshot
|
||||||
if (wrapper.hasAppIcon) {
|
if (wrapper.hasAppIcon && !wrapper.isScreenshot) {
|
||||||
return Quickshell.iconPath(wrapper.appIcon, "image-missing");
|
return Quickshell.iconPath(wrapper.appIcon, "image-missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +200,9 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFallbackIcon(wrapper) {
|
function getFallbackIcon(wrapper) {
|
||||||
if (wrapper.isConversation) {
|
if (wrapper.isScreenshot) {
|
||||||
|
return Quickshell.iconPath("screenshot_monitor");
|
||||||
|
} else if (wrapper.isConversation) {
|
||||||
return Quickshell.iconPath("chat-symbolic");
|
return Quickshell.iconPath("chat-symbolic");
|
||||||
} else if (wrapper.isMedia) {
|
} else if (wrapper.isMedia) {
|
||||||
return Quickshell.iconPath("audio-x-generic-symbolic");
|
return Quickshell.iconPath("audio-x-generic-symbolic");
|
||||||
@@ -190,7 +213,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getAppIconPath(wrapper) {
|
function getAppIconPath(wrapper) {
|
||||||
if (wrapper.hasAppIcon) {
|
if (wrapper.hasAppIcon && !wrapper.isScreenshot) {
|
||||||
return Quickshell.iconPath(wrapper.appIcon);
|
return Quickshell.iconPath(wrapper.appIcon);
|
||||||
}
|
}
|
||||||
return getFallbackIcon(wrapper);
|
return getFallbackIcon(wrapper);
|
||||||
@@ -264,6 +287,11 @@ Singleton {
|
|||||||
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) {
|
||||||
return `${appName}:media`;
|
return `${appName}:media`;
|
||||||
@@ -303,7 +331,8 @@ 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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +365,8 @@ 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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +430,13 @@ 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(":");
|
||||||
if (keyParts.length > 1) {
|
if (keyParts.length > 1) {
|
||||||
@@ -434,6 +471,10 @@ 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}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,43 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "Testing notification fixes..."
|
|
||||||
echo "This will test:"
|
|
||||||
echo "1. Icon visibility (should show round icons or emoji fallbacks)"
|
|
||||||
echo "2. Expand/collapse in popup (should work smoothly)"
|
|
||||||
echo "3. Expand/collapse in history (should work reliably)"
|
|
||||||
echo "4. Button alignment (should not be glitchy)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Wait for shell to be ready
|
|
||||||
sleep 3
|
|
||||||
|
|
||||||
echo "Sending test notifications..."
|
|
||||||
|
|
||||||
# Test Discord grouping with multiple messages
|
|
||||||
notify-send -a "Discord" "User1" "First message in Discord"
|
|
||||||
sleep 0.5
|
|
||||||
notify-send -a "Discord" "User2" "Second message in Discord"
|
|
||||||
sleep 0.5
|
|
||||||
notify-send -a "Discord" "User3" "Third message in Discord"
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# Test app with likely good icon
|
|
||||||
notify-send -a "firefox" "Download" "File downloaded successfully"
|
|
||||||
sleep 0.5
|
|
||||||
notify-send -a "firefox" "Update" "Browser updated"
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
# Test app that might not have icon (fallback test)
|
|
||||||
notify-send -a "TestApp" "Test 1" "This should show fallback icon"
|
|
||||||
sleep 0.5
|
|
||||||
notify-send -a "TestApp" "Test 2" "Another test notification"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Notifications sent! Please test:"
|
|
||||||
echo "1. Check notification popup - icons should be visible (round)"
|
|
||||||
echo "2. Try expand/collapse buttons in popup"
|
|
||||||
echo "3. Open notification history"
|
|
||||||
echo "4. Try expand/collapse buttons in history"
|
|
||||||
echo "5. Check that buttons stay aligned when collapsing"
|
|
||||||
echo ""
|
|
||||||
echo "Look for console logs in quickshell terminal for debugging info"
|
|
||||||
233
scripts/linux_env_diagnostics.sh
Executable file
233
scripts/linux_env_diagnostics.sh
Executable file
@@ -0,0 +1,233 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Diagnostic script for Qt/QML environment differences
|
||||||
|
|
||||||
|
echo "==== Qt Version ===="
|
||||||
|
qmake --version 2>/dev/null || qtpaths --qt-version 2>/dev/null || echo "qmake/qtpaths not found"
|
||||||
|
|
||||||
|
echo "\n==== Qt Platform Theme ===="
|
||||||
|
echo "QT_QPA_PLATFORMTHEME: $QT_QPA_PLATFORMTHEME"
|
||||||
|
|
||||||
|
echo "\n==== Qt Scale/Font DPI ===="
|
||||||
|
echo "QT_SCALE_FACTOR: $QT_SCALE_FACTOR"
|
||||||
|
echo "QT_FONT_DPI: $QT_FONT_DPI"
|
||||||
|
echo "GDK_SCALE: $GDK_SCALE"
|
||||||
|
echo "GDK_DPI_SCALE: $GDK_DPI_SCALE"
|
||||||
|
|
||||||
|
if command -v xrdb >/dev/null; then
|
||||||
|
echo "\n==== X11 DPI (xrdb) ===="
|
||||||
|
xrdb -query | grep dpi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\n==== Icon Font Availability (for cross-distro compatibility) ===="
|
||||||
|
echo "Checking icon fonts used by Quickshell Icon component..."
|
||||||
|
|
||||||
|
# Check Material Design Icons
|
||||||
|
echo -n "Material Symbols Rounded: "
|
||||||
|
if fc-list | grep -q "Material Symbols Rounded"; then
|
||||||
|
echo "✓ FOUND"
|
||||||
|
MATERIAL_SYMBOLS_FOUND=1
|
||||||
|
else
|
||||||
|
echo "✗ NOT FOUND"
|
||||||
|
MATERIAL_SYMBOLS_FOUND=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "Material Icons Round: "
|
||||||
|
if fc-list | grep -q "Material Icons Round"; then
|
||||||
|
echo "✓ FOUND"
|
||||||
|
MATERIAL_ICONS_FOUND=1
|
||||||
|
else
|
||||||
|
echo "✗ NOT FOUND"
|
||||||
|
MATERIAL_ICONS_FOUND=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check FontAwesome 6
|
||||||
|
echo -n "Font Awesome 6 Free: "
|
||||||
|
if fc-list | grep -q "Font Awesome 6 Free"; then
|
||||||
|
echo "✓ FOUND"
|
||||||
|
FONTAWESOME_FOUND=1
|
||||||
|
else
|
||||||
|
echo "✗ NOT FOUND"
|
||||||
|
FONTAWESOME_FOUND=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check JetBrains Mono Nerd Font
|
||||||
|
echo -n "JetBrainsMono Nerd Font: "
|
||||||
|
if fc-list | grep -q "JetBrainsMono Nerd Font"; then
|
||||||
|
echo "✓ FOUND"
|
||||||
|
JETBRAINS_NERD_FOUND=1
|
||||||
|
else
|
||||||
|
echo -n "✗ NOT FOUND, checking JetBrains Mono: "
|
||||||
|
if fc-list | grep -q "JetBrains Mono"; then
|
||||||
|
echo "✓ FOUND (fallback available)"
|
||||||
|
JETBRAINS_FALLBACK_FOUND=1
|
||||||
|
else
|
||||||
|
echo "✗ NOT FOUND"
|
||||||
|
JETBRAINS_FALLBACK_FOUND=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\n==== Icon System Recommendation ===="
|
||||||
|
if [ $MATERIAL_SYMBOLS_FOUND -eq 1 ]; then
|
||||||
|
echo "✓ OPTIMAL: Material Symbols Rounded found - best icon experience"
|
||||||
|
elif [ $MATERIAL_ICONS_FOUND -eq 1 ]; then
|
||||||
|
echo "✓ GOOD: Material Icons Round found - good icon experience"
|
||||||
|
elif [ $FONTAWESOME_FOUND -eq 1 ]; then
|
||||||
|
echo "⚠ FAIR: FontAwesome 6 found - acceptable icon experience"
|
||||||
|
elif [ $JETBRAINS_NERD_FOUND -eq 1 ] || [ $JETBRAINS_FALLBACK_FOUND -eq 1 ]; then
|
||||||
|
echo "⚠ BASIC: JetBrains Mono found - basic icon experience"
|
||||||
|
else
|
||||||
|
echo "⚠ FALLBACK: No icon fonts found - will use emoji fallback"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\n==== Font Installation Recommendations ===="
|
||||||
|
if [ $MATERIAL_SYMBOLS_FOUND -eq 0 ] && [ $MATERIAL_ICONS_FOUND -eq 0 ]; then
|
||||||
|
echo "📦 Install Material Design Icons for best experience:"
|
||||||
|
echo " • Ubuntu/Debian: sudo apt install fonts-material-design-icons-iconfont"
|
||||||
|
echo " • Fedora: sudo dnf install google-material-design-icons-fonts"
|
||||||
|
echo " • Arch: sudo pacman -S ttf-material-design-icons"
|
||||||
|
echo " • Or download from: https://fonts.google.com/icons"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $FONTAWESOME_FOUND -eq 0 ]; then
|
||||||
|
echo "📦 Install FontAwesome 6 for broader compatibility:"
|
||||||
|
echo " • Ubuntu/Debian: sudo apt install fonts-font-awesome"
|
||||||
|
echo " • Fedora: sudo dnf install fontawesome-fonts"
|
||||||
|
echo " • Arch: sudo pacman -S ttf-font-awesome"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${JETBRAINS_NERD_FOUND:-0}" -eq 0 ]; then
|
||||||
|
echo "📦 Install JetBrains Mono Nerd Font for developer icons:"
|
||||||
|
echo " • Download from: https://github.com/ryanoasis/nerd-fonts/releases"
|
||||||
|
echo " • Or install via package manager if available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\n==== Quickshell Icon Component Test ===="
|
||||||
|
if command -v qs >/dev/null 2>&1; then
|
||||||
|
echo "Testing Icon component fallback system..."
|
||||||
|
# Create a temporary test QML file
|
||||||
|
cat > /tmp/icon_test.qml << 'EOF'
|
||||||
|
import QtQuick
|
||||||
|
import "../Common"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Component.onCompleted: {
|
||||||
|
var icon = Qt.createQmlObject('import QtQuick; import "../Common"; Icon { name: "battery"; level: 75; charging: false; available: true }', parent)
|
||||||
|
console.log("Icon system detected:", icon.iconSystem)
|
||||||
|
console.log("Font family:", icon.font.family)
|
||||||
|
console.log("Battery icon:", icon.text)
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Test if we can run the icon test
|
||||||
|
if [ -f "../Common/Icon.qml" ]; then
|
||||||
|
echo "Running Icon component test..."
|
||||||
|
timeout 5s qs -c /tmp/icon_test.qml 2>&1 | grep -E "(Icon system|Font family|Battery icon)" || echo "Icon test failed or timed out"
|
||||||
|
else
|
||||||
|
echo "Icon.qml not found - make sure you're running from the quickshell directory"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f /tmp/icon_test.qml
|
||||||
|
else
|
||||||
|
echo "Quickshell (qs) not found - cannot test Icon component"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\n==== All Available Fonts ===="
|
||||||
|
fc-list : family | sort | uniq | grep -E 'Material|Sans|Serif|Mono|Noto|DejaVu|Roboto|Symbols|Awesome|Nerd' || echo "fc-list not found or no relevant fonts"
|
||||||
|
|
||||||
|
echo "\n==== Qt Plugins ===="
|
||||||
|
QT_DEBUG_PLUGINS=1 qtpaths --plugin-dir 2>&1 | head -20 || echo "qtpaths not found or no plugin info"
|
||||||
|
|
||||||
|
echo "\n==== QML Import Paths ===="
|
||||||
|
qtpaths --qml-imports 2>/dev/null || echo "qtpaths not found"
|
||||||
|
|
||||||
|
echo "\n==== System Info ===="
|
||||||
|
uname -a
|
||||||
|
cat /etc/os-release
|
||||||
|
|
||||||
|
echo "\n==== Graphics Drivers ===="
|
||||||
|
lspci | grep -i vga || echo "lspci not found"
|
||||||
|
|
||||||
|
echo "\n==== Wayland/X11 Session ===="
|
||||||
|
echo "XDG_SESSION_TYPE: ${XDG_SESSION_TYPE:-not set}"
|
||||||
|
echo "WAYLAND_DISPLAY: ${WAYLAND_DISPLAY:-not set}"
|
||||||
|
echo "DISPLAY: ${DISPLAY:-not set}"
|
||||||
|
|
||||||
|
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
|
||||||
|
echo "✓ Running on Wayland"
|
||||||
|
else
|
||||||
|
echo "✓ Running on X11"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\n==== Qt Environment Variables ===="
|
||||||
|
echo "QT_QPA_PLATFORM: ${QT_QPA_PLATFORM:-not set}"
|
||||||
|
echo "QT_WAYLAND_DECORATION: ${QT_WAYLAND_DECORATION:-not set}"
|
||||||
|
echo "QT_AUTO_SCREEN_SCALE_FACTOR: ${QT_AUTO_SCREEN_SCALE_FACTOR:-not set}"
|
||||||
|
echo "QT_ENABLE_HIGHDPI_SCALING: ${QT_ENABLE_HIGHDPI_SCALING:-not set}"
|
||||||
|
|
||||||
|
echo "\n==== Cross-Distro Compatibility Issues ===="
|
||||||
|
echo "Checking for common cross-distro problems..."
|
||||||
|
|
||||||
|
# Check for common Qt issues
|
||||||
|
if [ -z "$QT_QPA_PLATFORMTHEME" ]; then
|
||||||
|
echo "⚠ QT_QPA_PLATFORMTHEME not set - may cause theme inconsistencies"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for font rendering issues
|
||||||
|
if [ -z "$FONTCONFIG_PATH" ]; then
|
||||||
|
echo "ℹ FONTCONFIG_PATH not set - using system defaults"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for missing libraries that might cause QML issues
|
||||||
|
echo -n "Checking for essential libraries: "
|
||||||
|
MISSING_LIBS=""
|
||||||
|
for lib in libQt6Core.so.6 libQt6Gui.so.6 libQt6Qml.so.6 libQt6Quick.so.6; do
|
||||||
|
if ! ldconfig -p | grep -q "$lib"; then
|
||||||
|
MISSING_LIBS="$MISSING_LIBS $lib"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$MISSING_LIBS" ]; then
|
||||||
|
echo "✓ All essential Qt6 libraries found"
|
||||||
|
else
|
||||||
|
echo "⚠ Missing libraries:$MISSING_LIBS"
|
||||||
|
echo " Install Qt6 development packages for your distro"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\n==== Notification System Check ===="
|
||||||
|
echo "Checking for common notification issues..."
|
||||||
|
|
||||||
|
# Check if notification daemon is running
|
||||||
|
if pgrep -x "mako" > /dev/null; then
|
||||||
|
echo "✓ Mako notification daemon running"
|
||||||
|
elif pgrep -x "dunst" > /dev/null; then
|
||||||
|
echo "✓ Dunst notification daemon running"
|
||||||
|
elif pgrep -x "swaync" > /dev/null; then
|
||||||
|
echo "✓ SwayNC notification daemon running"
|
||||||
|
else
|
||||||
|
echo "⚠ No common notification daemon detected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check D-Bus notification service
|
||||||
|
if busctl --user status org.freedesktop.Notifications >/dev/null 2>&1; then
|
||||||
|
echo "✓ D-Bus notification service available"
|
||||||
|
else
|
||||||
|
echo "⚠ D-Bus notification service not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for notification image format issues
|
||||||
|
echo "ℹ Common notification warnings to expect:"
|
||||||
|
echo " - 'Unable to parse pixmap as rowstride is incorrect' - Discord/Telegram images"
|
||||||
|
echo " - This is a known issue with some applications sending malformed image data"
|
||||||
|
echo " - Does not affect notification functionality, only image display"
|
||||||
|
|
||||||
|
echo "\n==== Diagnostic Summary ===="
|
||||||
|
echo "Run this script on different distros to compare environments."
|
||||||
|
echo "Save output with: ./qt_env_diagnostics.sh > my_system_info.txt"
|
||||||
|
echo "Share with developers for troubleshooting cross-distro issues."
|
||||||
|
echo ""
|
||||||
|
echo "If you see pixmap rowstride warnings, this is normal for some applications."
|
||||||
|
echo "The notification system will fall back to app icons or default icons."
|
||||||
|
|
||||||
|
# End of diagnostics
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
echo "Waiting for notification service to be ready..."
|
echo "Waiting for notification service to be ready..."
|
||||||
|
|
||||||
# Wait for the notification service to be available
|
# Wait for the notification service to be available
|
||||||
max_attempts=20
|
max_attempts=8
|
||||||
attempt=0
|
attempt=0
|
||||||
|
|
||||||
while [ $attempt -lt $max_attempts ]; do
|
while [ $attempt -lt $max_attempts ]; do
|
||||||
@@ -43,11 +43,3 @@ notify-send -a "code" "VS Code 2" "Code notification 2"
|
|||||||
echo ""
|
echo ""
|
||||||
echo "✅ All notifications sent successfully!"
|
echo "✅ All notifications sent successfully!"
|
||||||
echo ""
|
echo ""
|
||||||
echo "🧪 Test Results Expected:"
|
|
||||||
echo "1. ✅ Button container stays within bounds on collapse"
|
|
||||||
echo "2. ✅ Count badges show as small circles (not parentheses)"
|
|
||||||
echo "3. ✅ App icons show with themed backgrounds (not black)"
|
|
||||||
echo "4. ✅ First letter fallbacks when icons don't load"
|
|
||||||
echo "5. ✅ Expand/collapse works in both popup and history"
|
|
||||||
echo ""
|
|
||||||
echo "Check your notification popup and history panel!"
|
|
||||||
Reference in New Issue
Block a user