Major improvements to UnifiedPlayer: 1. GetFrameImage() now works when paused for responsive UI updates 2. Play() method properly starts FFmpeg process 3. Frame display loop runs continuously for smooth video display 4. Disabled audio temporarily to fix video playback fundamentals 5. Simplified FFmpeg command to focus on video stream only Player now: - Generates video frames correctly - Shows video when paused - Has responsive progress tracking - Starts playback properly Next steps: Re-enable audio playback once video is stable
151 lines
4.4 KiB
Go
151 lines
4.4 KiB
Go
//go:build !ci && !wasm && !test_web_driver && !android && !ios && !mobile && (linux || openbsd || freebsd || netbsd) && !tinygo && !noos && !tamago
|
|
|
|
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"
|
|
)
|
|
|
|
const systemTheme = fyne.ThemeVariant(99)
|
|
|
|
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 systemTheme
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
// SetSystemTrayWindow assigns a window to be shown with the system tray menu is tapped.
|
|
// You should have previously called `SetSystemTrayMenu` to initialise the menu icon.
|
|
func (a *fyneApp) SetSystemTrayWindow(w fyne.Window) {
|
|
a.Driver().(systrayDriver).SetSystemTrayWindow(w)
|
|
}
|
|
|
|
func watchTheme(s *settings) {
|
|
go func() {
|
|
// Theme lookup hangs on some desktops. Update theme variant cache from within goroutine.
|
|
themeVariant := findFreedesktopColorScheme()
|
|
if themeVariant != systemTheme {
|
|
internalapp.CurrentVariant.Store(uint64(themeVariant))
|
|
fyne.Do(func() { 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))
|
|
fyne.Do(func() { s.applyVariant(themeVariant) })
|
|
}
|
|
})
|
|
}()
|
|
}
|
|
|
|
func (a *fyneApp) registerRepositories() {
|
|
// no-op
|
|
}
|
|
|
|
func (s *settings) applyVariant(variant fyne.ThemeVariant) {
|
|
s.variant = variant
|
|
s.apply()
|
|
}
|