From 190af60f243da337df7196ec020b71208333a04c Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 3 Jan 2024 16:20:13 +0000 Subject: [PATCH] Fallback to a nil icon so the UI can choose what to display --- internal/icon/fdo.go | 38 +++++++++++++-------------- internal/icon/macos.go | 7 +++-- internal/x11/win/client_properties.go | 6 +++-- internal/x11/win/property.go | 17 +++++++----- wm/border.go | 5 +--- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/internal/icon/fdo.go b/internal/icon/fdo.go index 8f0a2d25..76bb9b26 100644 --- a/internal/icon/fdo.go +++ b/internal/icon/fdo.go @@ -13,8 +13,6 @@ import ( "fyne.io/fyne/v2" "fyshos.com/fynedesk" - wmTheme "fyshos.com/fynedesk/theme" - _ "github.com/fyne-io/image/xpm" // load XPM icons to supported image format ) @@ -26,7 +24,7 @@ var ( "Office", "Science", "Settings", "System", "Utility"} ) -//fdoApplicationData is a structure that contains information about .desktop files +// fdoApplicationData is a structure that contains information about .desktop files type fdoApplicationData struct { name string // Application name iconName string // Icon name @@ -38,12 +36,12 @@ type fdoApplicationData struct { iconCache fyne.Resource } -//Name returns the name associated with an fdo app +// Name returns the name associated with an fdo app func (data *fdoApplicationData) Name() string { return data.name } -//Categories returns a list of the categories this icon has configured +// Categories returns a list of the categories this icon has configured func (data *fdoApplicationData) Categories() []string { return data.categories } @@ -52,12 +50,12 @@ func (data *fdoApplicationData) Hidden() bool { return data.hide } -//IconName returns the name of the icon that an fdo app wishes to use +// IconName returns the name of the icon that an fdo app wishes to use func (data *fdoApplicationData) IconName() string { return data.iconName } -//IconPath returns the path of the icon that an fdo app wishes to use +// IconPath returns the path of the icon that an fdo app wishes to use func (data *fdoApplicationData) Icon(theme string, size int) fyne.Resource { if data.iconCache != nil { return data.iconCache @@ -67,7 +65,7 @@ func (data *fdoApplicationData) Icon(theme string, size int) fyne.Resource { if path == "" { path = FdoLookupIconPath(theme, size, data.iconName) if path == "" { - return wmTheme.BrokenImageIcon + return nil } } @@ -75,7 +73,7 @@ func (data *fdoApplicationData) Icon(theme string, size int) fyne.Resource { return data.iconCache } -//extractArgs sanitises argument parameters from an Exec configuration +// extractArgs sanitises argument parameters from an Exec configuration func extractArgs(args []string) []string { var ret []string for _, arg := range args { @@ -88,7 +86,7 @@ func extractArgs(args []string) []string { return ret } -//Run executes the command for this fdo app +// Run executes the command for this fdo app func (data *fdoApplicationData) Run(env []string) error { vars := os.Environ() vars = append(vars, env...) @@ -135,7 +133,7 @@ func loadIcon(path string) fyne.Resource { return fyne.NewStaticResource(filepath.Base(path), data) } -//fdoLookupXdgDataDirs returns a string slice of all XDG_DATA_DIRS +// fdoLookupXdgDataDirs returns a string slice of all XDG_DATA_DIRS func fdoLookupXdgDataDirs() []string { dataLocation := os.Getenv("XDG_DATA_DIRS") locationLookup := strings.Split(dataLocation, ":") @@ -177,7 +175,7 @@ func fdoForEachApplicationFile(f func(data fynedesk.AppData) bool) { } } -//lookupApplicationByMetadata looks up an application by comparing the requested name to the contents of .desktop files +// lookupApplicationByMetadata looks up an application by comparing the requested name to the contents of .desktop files func (f *fdoIconProvider) lookupApplicationByMetadata(appName string) fynedesk.AppData { var returnIcon fynedesk.AppData f.cache.forEachCachedApplication(func(_ string, icon fynedesk.AppData) bool { @@ -190,7 +188,7 @@ func (f *fdoIconProvider) lookupApplicationByMetadata(appName string) fynedesk.A return returnIcon } -//lookupApplication looks up an application by name and returns an fdoApplicationData struct +// lookupApplication looks up an application by name and returns an fdoApplicationData struct func (f *fdoIconProvider) lookupApplication(appName string) fynedesk.AppData { if appName == "" { return nil @@ -388,7 +386,7 @@ func FdoLookupIconPathInTheme(iconSize string, dir string, parentDir string, ico return "" } -//FdoLookupIconPath will take the name of an icon and find a matching image file +// FdoLookupIconPath will take the name of an icon and find a matching image file func FdoLookupIconPath(theme string, size int, iconName string) string { locationLookup := fdoLookupXdgDataDirs() iconTheme := theme @@ -442,7 +440,7 @@ func fdoLookupAvailableThemes() []string { return themes } -//newFdoIconData creates and returns a struct that contains needed fields from a .desktop file +// newFdoIconData creates and returns a struct that contains needed fields from a .desktop file func newFdoIconData(desktopPath string) fynedesk.AppData { file, err := os.Open(desktopPath) if err != nil { @@ -495,7 +493,7 @@ type fdoIconProvider struct { cache *appCache } -//AvailableApps returns all of the available applications in a AppData slice +// AvailableApps returns all of the available applications in a AppData slice func (f *fdoIconProvider) AvailableApps() []fynedesk.AppData { var icons []fynedesk.AppData fdoForEachApplicationFile(func(icon fynedesk.AppData) bool { @@ -508,17 +506,17 @@ func (f *fdoIconProvider) AvailableApps() []fynedesk.AppData { return icons } -//AvailableThemes returns all available icon themes in a string slice +// AvailableThemes returns all available icon themes in a string slice func (f *fdoIconProvider) AvailableThemes() []string { return fdoLookupAvailableThemes() } -//FindAppFromName matches an icon name to a location and returns an AppData interface +// FindAppFromName matches an icon name to a location and returns an AppData interface func (f *fdoIconProvider) FindAppFromName(appName string) fynedesk.AppData { return f.lookupApplication(appName) } -//FindAppsMatching returns a list of icons that match a partial name of an app and returns an AppData slice +// FindAppsMatching returns a list of icons that match a partial name of an app and returns an AppData slice func (f *fdoIconProvider) FindAppsMatching(appName string) []fynedesk.AppData { var icons []fynedesk.AppData f.cache.forEachCachedApplication(func(_ string, icon fynedesk.AppData) bool { @@ -536,7 +534,7 @@ func (f *fdoIconProvider) FindAppsMatching(appName string) []fynedesk.AppData { return icons } -//FindAppFromWinInfo matches window information to an icon location and returns an AppData interface +// FindAppFromWinInfo matches window information to an icon location and returns an AppData interface func (f *fdoIconProvider) FindAppFromWinInfo(win fynedesk.Window) fynedesk.AppData { app := f.lookupApplication(win.Properties().Command()) if app != nil { diff --git a/internal/icon/macos.go b/internal/icon/macos.go index 7403bd6b..9dcd0131 100644 --- a/internal/icon/macos.go +++ b/internal/icon/macos.go @@ -16,7 +16,6 @@ import ( "fyne.io/fyne/v2" "fyshos.com/fynedesk" - wmtheme "fyshos.com/fynedesk/theme" ) type macOSAppBundle struct { @@ -52,20 +51,20 @@ func (m *macOSAppBundle) Icon(_ string, _ int) fyne.Resource { src, err := os.Open(m.iconPath) if err != nil { fyne.LogError("Failed to read icon data for "+m.iconPath, err) - return wmtheme.BrokenImageIcon + return nil } icon, err := icns.Decode(src) if err != nil { fyne.LogError("Failed to parse icon data for "+m.iconPath, err) - return wmtheme.BrokenImageIcon + return nil } var data bytes.Buffer err = png.Encode(&data, icon) if err != nil { fyne.LogError("Failed to encode icon data for "+m.iconPath, err) - return wmtheme.BrokenImageIcon + return nil } iconName := filepath.Base(m.iconPath) diff --git a/internal/x11/win/client_properties.go b/internal/x11/win/client_properties.go index d3578733..9b6a6c93 100644 --- a/internal/x11/win/client_properties.go +++ b/internal/x11/win/client_properties.go @@ -52,9 +52,11 @@ func (c *clientProperties) Icon() fyne.Resource { settings := fynedesk.Instance().Settings() iconSize := int(settings.LauncherIconSize() * settings.LauncherZoomScale()) xIcon := windowIcon(c.c.wm.X(), c.c.win, iconSize, iconSize) - if len(xIcon.Bytes()) != 0 { - c.iconCache = fyne.NewStaticResource(c.Title(), xIcon.Bytes()) + if xIcon == nil { + return nil } + + c.iconCache = fyne.NewStaticResource(c.Title(), xIcon.Bytes()) return c.iconCache } diff --git a/internal/x11/win/property.go b/internal/x11/win/property.go index 163de30d..a7b061b6 100644 --- a/internal/x11/win/property.go +++ b/internal/x11/win/property.go @@ -7,7 +7,6 @@ import ( "bytes" "math" - "fyne.io/fyne/v2" "github.com/BurntSushi/xgb/xproto" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/ewmh" @@ -16,6 +15,8 @@ import ( "github.com/BurntSushi/xgbutil/xgraphics" "github.com/BurntSushi/xgbutil/xprop" + "fyne.io/fyne/v2" + "fyshos.com/fynedesk" "fyshos.com/fynedesk/internal/x11" ) @@ -69,16 +70,18 @@ func windowCommand(x *xgbutil.XUtil, win xproto.Window) string { return command } -func windowIcon(x *xgbutil.XUtil, win xproto.Window, width int, height int) bytes.Buffer { - var w bytes.Buffer +func windowIcon(x *xgbutil.XUtil, win xproto.Window, width int, height int) *bytes.Buffer { img, err := xgraphics.FindIcon(x, win, width, height) if err != nil { - fyne.LogError("Could not get window icon", err) - return w + fyne.LogError("ICON: Could not get window icon", err) + return nil } - err = img.WritePng(&w) + + w := &bytes.Buffer{} + err = img.WritePng(w) if err != nil { - fyne.LogError("Could not convert icon to png", err) + fyne.LogError("ICON: Could not convert icon to png", err) + return nil } return w } diff --git a/wm/border.go b/wm/border.go index 88f46e06..b9530dad 100644 --- a/wm/border.go +++ b/wm/border.go @@ -33,10 +33,6 @@ func NewBorder(win fynedesk.Window, icon fyne.Resource, canMaximize bool) *Borde if app != nil { icon = app.Icon(iconTheme, int(wmTheme.TitleHeight*2)) } - - if icon == nil { - icon = wmTheme.BrokenImageIcon - } } max := &widget.Button{Icon: wmTheme.MaximizeIcon, Importance: widget.LowImportance, OnTapped: func() { @@ -188,6 +184,7 @@ func (c *Border) CreateRenderer() fyne.WidgetRenderer { // SetIcon tells the border to change the icon that should be used func (c *Border) SetIcon(icon fyne.Resource) { if icon == nil { + c.appIcon.Icon = nil return }