-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
app_xdg.go
131 lines (111 loc) · 3.88 KB
/
app_xdg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//go:build !ci && !wasm && !test_web_driver && !android && !ios && !mobile && (linux || openbsd || freebsd || netbsd)
package app
import (
"net/url"
"os"
"os/exec"
"sync/atomic"
"github.com/godbus/dbus/v5"
"github.com/rymdport/portal/notification"
"github.com/rymdport/portal/openuri"
portalSettings "github.com/rymdport/portal/settings"
"github.com/rymdport/portal/settings/appearance"
"fyne.io/fyne/v2"
internalapp "fyne.io/fyne/v2/internal/app"
"fyne.io/fyne/v2/internal/build"
"fyne.io/fyne/v2/theme"
)
func (a *fyneApp) OpenURL(url *url.URL) error {
if build.IsFlatpak {
err := openuri.OpenURI("", url.String(), nil)
if err != nil {
fyne.LogError("Opening url in portal failed", err)
}
return err
}
cmd := exec.Command("xdg-open", url.String())
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
return cmd.Start()
}
// fetch color variant from dbus portal desktop settings.
func findFreedesktopColorScheme() fyne.ThemeVariant {
colorScheme, err := appearance.GetColorScheme()
if err != nil {
return theme.VariantDark
}
return colorSchemeToThemeVariant(colorScheme)
}
func colorSchemeToThemeVariant(colorScheme appearance.ColorScheme) fyne.ThemeVariant {
switch colorScheme {
case appearance.Light:
return theme.VariantLight
case appearance.Dark:
return theme.VariantDark
}
// Default to light theme to support Gnome's default see https://github.com/fyne-io/fyne/pull/3561
return theme.VariantLight
}
func (a *fyneApp) SendNotification(n *fyne.Notification) {
if build.IsFlatpak {
err := a.sendNotificationThroughPortal(n)
if err != nil {
fyne.LogError("Sending notification using portal failed", err)
}
return
}
conn, err := dbus.SessionBus() // shared connection, don't close
if err != nil {
fyne.LogError("Unable to connect to session D-Bus", err)
return
}
appIcon := a.cachedIconPath()
timeout := int32(0) // we don't support this yet
obj := conn.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
call := obj.Call("org.freedesktop.Notifications.Notify", 0, a.uniqueID, uint32(0),
appIcon, n.Title, n.Content, []string{}, map[string]dbus.Variant{}, timeout)
if call.Err != nil {
fyne.LogError("Failed to send message to bus", call.Err)
}
}
// Sending with same ID replaces the old notification.
var notificationID atomic.Uint64
// See https://flatpak.github.io/xdg-desktop-portal/docs/#gdbus-org.freedesktop.portal.Notification.
func (a *fyneApp) sendNotificationThroughPortal(n *fyne.Notification) error {
return notification.Add(
uint(notificationID.Add(1)),
notification.Content{
Title: n.Title,
Body: n.Content,
Icon: a.uniqueID,
},
)
}
// SetSystemTrayMenu creates a system tray item and attaches the specified menu.
// By default this will use the application icon.
func (a *fyneApp) SetSystemTrayMenu(menu *fyne.Menu) {
if desk, ok := a.Driver().(systrayDriver); ok { // don't use this on mobile tag
desk.SetSystemTrayMenu(menu)
}
}
// SetSystemTrayIcon sets a custom image for the system tray icon.
// You should have previously called `SetSystemTrayMenu` to initialise the menu icon.
func (a *fyneApp) SetSystemTrayIcon(icon fyne.Resource) {
if desk, ok := a.Driver().(systrayDriver); ok { // don't use this on mobile tag
desk.SetSystemTrayIcon(icon)
}
}
func watchTheme(s *settings) {
go func() {
// Theme lookup hangs on some desktops. Update theme variant cache from within goroutine.
themeVariant := findFreedesktopColorScheme()
internalapp.CurrentVariant.Store(uint64(themeVariant))
s.applyVariant(themeVariant)
portalSettings.OnSignalSettingChanged(func(changed portalSettings.Changed) {
if changed.Namespace == appearance.Namespace && changed.Key == "color-scheme" {
themeVariant := colorSchemeToThemeVariant(appearance.ColorScheme(changed.Value.(uint32)))
internalapp.CurrentVariant.Store(uint64(themeVariant))
s.applyVariant(themeVariant)
}
})
}()
}