//go:build !ci && !android && !ios && !wasm && !test_web_driver package app import ( "fmt" "net/url" "os" "os/exec" "path/filepath" "strings" "syscall" "fyne.io/fyne/v2" internalapp "fyne.io/fyne/v2/internal/app" ) const notificationTemplate = `$title = "%s" $content = "%s" $iconPath = "file:///%s" [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null $template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastImageAndText02) $toastXml = [xml] $template.GetXml() $toastXml.GetElementsByTagName("text")[0].AppendChild($toastXml.CreateTextNode($title)) > $null $toastXml.GetElementsByTagName("text")[1].AppendChild($toastXml.CreateTextNode($content)) > $null $toastXml.GetElementsByTagName("image")[0].SetAttribute("src", $iconPath) > $null $xml = New-Object Windows.Data.Xml.Dom.XmlDocument $xml.LoadXml($toastXml.OuterXml) $toast = [Windows.UI.Notifications.ToastNotification]::new($xml) [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("%s").Show($toast);` func (a *fyneApp) OpenURL(url *url.URL) error { cmd := exec.Command("rundll32", "url.dll,FileProtocolHandler", url.String()) cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr return cmd.Run() } var scriptNum = 0 func (a *fyneApp) SendNotification(n *fyne.Notification) { title := escapeNotificationString(n.Title) content := escapeNotificationString(n.Content) iconFilePath := a.cachedIconPath() appID := a.UniqueID() if appID == "" || strings.Index(appID, "missing-id") == 0 { appID = a.Metadata().Name } script := fmt.Sprintf(notificationTemplate, title, content, iconFilePath, appID) go runScript("notify", script) } // 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) { a.Driver().(systrayDriver).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) { a.Driver().(systrayDriver).SetSystemTrayIcon(icon) } func escapeNotificationString(in string) string { noSlash := strings.ReplaceAll(in, "`", "``") return strings.ReplaceAll(noSlash, "\"", "`\"") } func runScript(name, script string) { scriptNum++ appID := fyne.CurrentApp().UniqueID() fileName := fmt.Sprintf("fyne-%s-%s-%d.ps1", appID, name, scriptNum) tmpFilePath := filepath.Join(os.TempDir(), fileName) err := os.WriteFile(tmpFilePath, []byte(script), 0600) if err != nil { fyne.LogError("Could not write script to show notification", err) return } defer os.Remove(tmpFilePath) launch := "(Get-Content -Encoding UTF8 -Path " + tmpFilePath + " -Raw) | Invoke-Expression" cmd := exec.Command("PowerShell", "-ExecutionPolicy", "Bypass", launch) cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} err = cmd.Run() if err != nil { fyne.LogError("Failed to launch windows notify script", err) } } func watchTheme(s *settings) { go internalapp.WatchTheme(func() { fyne.Do(s.setupTheme) }) } func (a *fyneApp) registerRepositories() { // no-op }