mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-04 04:42:05 -04:00
commit051b7576f7Author: purian23 <purian23@gmail.com> Date: Sun Feb 15 16:38:45 2026 -0500 Height for realz commit7784488a61Author: purian23 <purian23@gmail.com> Date: Sun Feb 15 16:34:09 2026 -0500 Fix height and truncate text/URLs commit31b328d428Author: bbedward <bbedward@gmail.com> Date: Sun Feb 15 16:25:57 2026 -0500 notifications: handle URL encoding in markdown2html commitdbb04f74a2Author: bbedward <bbedward@gmail.com> Date: Sun Feb 15 16:10:20 2026 -0500 notifications: more comprehensive decoder commitb29c7192c2Author: bbedward <bbedward@gmail.com> Date: Sun Feb 15 15:51:37 2026 -0500 notifications: html unescape commit8a48fa11ecAuthor: purian23 <purian23@gmail.com> Date: Sun Feb 15 15:04:33 2026 -0500 Add expressive curve on init toast commitee124f5e04Author: purian23 <purian23@gmail.com> Date: Sun Feb 15 15:02:16 2026 -0500 Expressive curves on swipe & btn height commit0fce904635Author: purian23 <purian23@gmail.com> Date: Sun Feb 15 13:40:02 2026 -0500 Provide bottom button clearance commit00d3829999Author: bbedward <bbedward@gmail.com> Date: Sun Feb 15 13:24:31 2026 -0500 notifications: cleanup popup display logic commitfd05768059Author: purian23 <purian23@gmail.com> Date: Sun Feb 15 01:00:55 2026 -0500 Add Privacy Mode - Smoother notification expansions - Shadow & Privacy Toggles commit0dba11d845Author: purian23 <purian23@gmail.com> Date: Sat Feb 14 22:48:46 2026 -0500 Further M3 enhancements commit949c216964Author: purian23 <purian23@gmail.com> Date: Sat Feb 14 19:59:38 2026 -0500 Right-Click to set Rules on Notifications directly commit62bc25782cAuthor: bbedward <bbedward@gmail.com> Date: Fri Feb 13 21:44:27 2026 -0500 notifications: fix compact spacing, reveal header bar, add bottom center position, pointing hand cursor fix commited495d4396Author: purian23 <purian23@gmail.com> Date: Fri Feb 13 20:25:40 2026 -0500 Tighten init toast commitebe38322a0Author: purian23 <purian23@gmail.com> Date: Fri Feb 13 20:09:59 2026 -0500 Update more m3 baselines & spacing commitb1735bb701Author: purian23 <purian23@gmail.com> Date: Fri Feb 13 14:10:05 2026 -0500 Expand rules on-Click commit9f13546b4dAuthor: purian23 <purian23@gmail.com> Date: Fri Feb 13 12:59:29 2026 -0500 Add Notification Rules - Additional right-click ops - Allow for 3rd boy line on init notification popup commitbe133b73c7Author: purian23 <purian23@gmail.com> Date: Fri Feb 13 10:10:03 2026 -0500 Truncate long title in groups commit4fc275beadAuthor: bbedward <bbedward@gmail.com> Date: Thu Feb 12 23:27:34 2026 -0500 notification: expand/collapse animation adjustment commit00e6172a68Author: purian23 <purian23@gmail.com> Date: Thu Feb 12 22:50:11 2026 -0500 Fix global warnings commit0772f6deb7Author: purian23 <purian23@gmail.com> Date: Thu Feb 12 22:46:40 2026 -0500 Tweak expansion duration commit0ffeed3ff0Author: purian23 <purian23@gmail.com> Date: Thu Feb 12 22:16:16 2026 -0500 notifications: Update Material 3 baselines - New right-click to mute option - New independent Notification Animation settings
181 lines
3.2 KiB
Go
181 lines
3.2 KiB
Go
package notify
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"syscall"
|
|
|
|
"github.com/godbus/dbus/v5"
|
|
)
|
|
|
|
const (
|
|
notifyDest = "org.freedesktop.Notifications"
|
|
notifyPath = "/org/freedesktop/Notifications"
|
|
notifyInterface = "org.freedesktop.Notifications"
|
|
|
|
maxSummaryLen = 29
|
|
maxBodyLen = 80
|
|
)
|
|
|
|
type Notification struct {
|
|
AppName string
|
|
Icon string
|
|
Summary string
|
|
Body string
|
|
FilePath string
|
|
Timeout int32
|
|
}
|
|
|
|
func Send(n Notification) error {
|
|
conn, err := dbus.SessionBus()
|
|
if err != nil {
|
|
return fmt.Errorf("dbus session failed: %w", err)
|
|
}
|
|
|
|
if n.AppName == "" {
|
|
n.AppName = "DMS"
|
|
}
|
|
if n.Timeout == 0 {
|
|
n.Timeout = 5000
|
|
}
|
|
|
|
if len(n.Summary) > maxSummaryLen {
|
|
n.Summary = n.Summary[:maxSummaryLen-3] + "..."
|
|
}
|
|
if len(n.Body) > maxBodyLen {
|
|
n.Body = n.Body[:maxBodyLen-3] + "..."
|
|
}
|
|
|
|
var actions []string
|
|
if n.FilePath != "" {
|
|
actions = []string{
|
|
"open", "Open",
|
|
"folder", "Open Folder",
|
|
}
|
|
}
|
|
|
|
hints := map[string]dbus.Variant{}
|
|
if n.FilePath != "" {
|
|
hints["image_path"] = dbus.MakeVariant(n.FilePath)
|
|
}
|
|
|
|
obj := conn.Object(notifyDest, notifyPath)
|
|
call := obj.Call(
|
|
notifyInterface+".Notify",
|
|
0,
|
|
n.AppName,
|
|
uint32(0),
|
|
n.Icon,
|
|
n.Summary,
|
|
n.Body,
|
|
actions,
|
|
hints,
|
|
n.Timeout,
|
|
)
|
|
|
|
if call.Err != nil {
|
|
return fmt.Errorf("notify call failed: %w", call.Err)
|
|
}
|
|
|
|
var notificationID uint32
|
|
if err := call.Store(¬ificationID); err != nil {
|
|
return fmt.Errorf("failed to get notification id: %w", err)
|
|
}
|
|
|
|
if len(actions) > 0 && n.FilePath != "" {
|
|
spawnActionListener(notificationID, n.FilePath)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func spawnActionListener(notificationID uint32, filePath string) {
|
|
exe, err := os.Executable()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
cmd := exec.Command(exe, "notify-action-generic", fmt.Sprintf("%d", notificationID), filePath)
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
Setsid: true,
|
|
}
|
|
cmd.Start()
|
|
}
|
|
|
|
func RunActionListener(args []string) {
|
|
if len(args) < 2 {
|
|
return
|
|
}
|
|
|
|
notificationID, err := strconv.ParseUint(args[0], 10, 32)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
filePath := args[1]
|
|
|
|
conn, err := dbus.SessionBus()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if err := conn.AddMatchSignal(
|
|
dbus.WithMatchObjectPath(notifyPath),
|
|
dbus.WithMatchInterface(notifyInterface),
|
|
); err != nil {
|
|
return
|
|
}
|
|
|
|
signals := make(chan *dbus.Signal, 10)
|
|
conn.Signal(signals)
|
|
|
|
for sig := range signals {
|
|
switch sig.Name {
|
|
case notifyInterface + ".ActionInvoked":
|
|
if len(sig.Body) < 2 {
|
|
continue
|
|
}
|
|
id, ok := sig.Body[0].(uint32)
|
|
if !ok || id != uint32(notificationID) {
|
|
continue
|
|
}
|
|
action, ok := sig.Body[1].(string)
|
|
if !ok {
|
|
continue
|
|
}
|
|
handleAction(action, filePath)
|
|
return
|
|
|
|
case notifyInterface + ".NotificationClosed":
|
|
if len(sig.Body) < 1 {
|
|
continue
|
|
}
|
|
id, ok := sig.Body[0].(uint32)
|
|
if !ok || id != uint32(notificationID) {
|
|
continue
|
|
}
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleAction(action, filePath string) {
|
|
switch action {
|
|
case "open", "default":
|
|
openPath(filePath)
|
|
case "folder":
|
|
openPath(filepath.Dir(filePath))
|
|
}
|
|
}
|
|
|
|
func openPath(path string) {
|
|
cmd := exec.Command("xdg-open", path)
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
Setsid: true,
|
|
}
|
|
cmd.Start()
|
|
}
|