staging.inyokaproject.org

Icon cache, desktop files: Wie ressourcenschonend Namen auflösen?

Status: Ungelöst | Ubuntu-Version: Kubuntu 20.10 (Groovy Gorilla)
Antworten |

ChickenLipsRfun2eat Team-Icon

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Hallo zusammen!

Ich bin gerade auf der Suche nach einer C/C++-Möglichkeit die Icons aus bspw. desktop-files zu ermitteln. Es gibt bspw. die Möglichkeit, das über QIcon zu machen, allerdings bringt mir das für meinen konkreten Fall gerade nichts, da ich den absoluten Dateipfad brauche und QIcon diesen intern verwirft. Hintergrund ist, dass QImage/QIcon in QML Probleme mit svg hat, was es für mich gerade unbrauchbar macht.
In desktop-Dateien können ja absolute Pfade — oder relative Namen wie „system-file-manager“ stehen. Letztere Versuche ich aufzulösen und dann noch entsprechend der vorhandenen Größen zu sortieren, bzw. anhand des aktuellen Fensters die passende Größe zu bestimmen. Allerdings ist es relativ träge die Bilddateien einzeln zu öffnen, die Bildgröße zu ermitteln und auszuwerten. Der Dateiname des aktuellen Themes ist auch nicht immer hilfreich, da nicht jedes Icon-Theme die gleichen Unterordner hat und sich die Abschnitte in …[Theme]/index.theme auch unterscheiden. KDE legt sich dafür einen icon-cache an, in der GTK-Welt gibt es sicherlich etwas ähnliches.

Gibt es auch sowas unabhängig vom desktop environment oder muss ich mir da eine eigene DB erstellen?

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6532

Auch nach mehrfachen Lesens ist mir nicht 100%ig klar, was Du benötigst. Wahrscheinlich weil ich das Inenleben von KDE nicht kenne. Aber einige Dinge klingen so als wenn ich dafür schon Teillösungen habe, allerdings auf mehrere Programme verteilt.

Für Bildgrößen gängiger Dateien habe ich etwas, svg ist allerdings nicht dabei. Und was in die Datenbank soll, ist mir auch noch nicht klar.

Andererseits könnte man auch einfach mit find nach *.desktop suchen und die Liste (Inhalt der Dateien) dann mit sed oder einem eigenen Programm abarbeiten.

ChickenLipsRfun2eat Team-Icon

(Themenstarter)

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Dakuan schrieb:

Andererseits könnte man auch einfach mit find nach *.desktop suchen und die Liste (Inhalt der Dateien) dann mit sed oder einem eigenen Programm abarbeiten.

Hallo!

Die Desktop-Dateien selbst sind nicht relevant, das sind ja schnell zu parsende Textdateien. Mir geht es um das zuordnen des korrekten Icons. Also nehmen wir xy.desktop und in dieser steht

Icon=system-file-manager

Dann muss ich anhand des aktuellen Themes den entsprechenden Ordner ermitteln, darin das passende Icon anhand der darzustellenden Größe ermitteln (außer bei svg), und den Pfad zu diesem Icon dann als absoluten Pfad weiterverarbeiten.

Ich stelle glaube ich mal ein Beispiel zusammen, damit das klarer wird 😉

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6532

Ich habe mir schon fast gedacht, dass mehr dahinter steckt bzw. das bei KDE einiges anders sein könnte.

Ich benutze z.B. folgende Zeile in einer Desktop-Datei:

Icon=/usr/share/pixmaps/tview.png

Das funktioniert bei Ubuntu-Mate, Xubuntu und Debian-Xfce. Mich wundert, das bei Dir keine Dateiendung auftaucht. Könnte es sein, das KDE das anders interpretiert? Das wäre dann ein etwas komplizierterer Mechanismus, wenn dazu noch die Kenntnis des Layouts notwendig ist.

ChickenLipsRfun2eat Team-Icon

(Themenstarter)

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Die beiden „großen“ Frameworks Qt und GTK bieten zum Ermitteln der Icons eigene Methoden. Im Falle von Qt wäre das QIcon::fromTheme, GTK bietet GTKIconTheme (Da braucht es gtk-icon-theme-lookup-icon, gtk_icon_info_load_icon und gtk_icon_theme_load_icon). Da ich aber gerne unabhängig von GTK/Qt wäre, bzw. QIcon zudem die o.g. Einschränkungen hat, suche ich etwas schnelleres.

Mal grob in Pseudo-Code für ein einzelnes Icon:

1
2
3
4
5
6
7
8
string icon_name = extractIconFromDesktopFile( "example.desktop" );
if( icon_name[0] != '/' ) { // kein absoluter Pfad → suchen
  for( Directory dir : getIconLocations() ) {  // ~/.local/share/icons, ~/.icons, /usr/local/share/icons, /usr/share/icons, usw.
    Icon i = getIconSetFromTheme( getCurrentTheme() );  // Auswertung aktuelles Theme, darin das Icon suchen — oder wenn nichts gefunden wird, in allen Themes suchen
    if( i.isValid() )  // wenn schliesslich ein Icon-Set gefunden wurde:
      return getMatchingIconSize( i, currentView.getResolution() ); // aus den vorhandenen Größen die brauchbarste wählen (meistens scalable oder 64x64)
  }
}

Mein Problem dabei ist, dass es furchtbar langsam ist, wenn ich bei jedem Programmstart erstmal ein paarhundert Icon-Einträge gegen ein paarhundert Icons in verschiedenen Größen testen muss, nebst Auswertung der XML-Daten aus den index.themes. Klar, wenn man von jeder Bild-Datei erst die Größe ermitteln muss und dann die passendste auswählt, das zudem noch für verschiedenste Icons. Daher suche ich einen anderen Weg. Die Benennung von Icons ist leider nicht einheitlich und es können auch verschiedenste Formate vorliegen. Bei KDE weiß ich, dass die das aufgrund ihres riesigen Frameworks umschiffen, indem sie einen icon-cache anlegen. Den könnte ich natürlich verwenden (wenn ich das Ablageformat rausfinde, ist ein binary-file), aber dann hänge ich wieder an dieser Abhängigkeit fest und ich weiß auch gar nicht, ob der ohne weitere KDE-Klassen nutzbar ist.

ChickenLipsRfun2eat Team-Icon

(Themenstarter)

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Dakuan schrieb:

Ich habe mir schon fast gedacht, dass mehr dahinter steckt bzw. das bei KDE einiges anders sein könnte.

Das ist ein freedesktop-Standard, an den sich KDE und GNOME halten.

Ich benutze z.B. folgende Zeile in einer Desktop-Datei:

Ja, das mache ich bei selbst gewählten icons auch. Aber schau bspw. mal in die desktop-Dateien unter /usr/share/applications. Da kommen auch noch so schöne Sachen wie Actions vor 😉

Mich wundert, das bei Dir keine Dateiendung auftaucht

Richtig. Das wird nach einer Hierarchie ausgewertet. Wenn da bspw. system-file-manager steht, wird erst nach .pxi, dann nach svg, jpg, png geguckt (nagel mich nicht auf die letzten beiden fest). Das ist aber noch nicht alles. In den icon-themes (oder generell GTK/KDE-Themes) gibt es jeweils eine index.theme, da stehen Zuordnungen drin wie

…
[48x48/categories]
Context=Categories
Size=48
Type=Fixed
…
[64x64/actions]
Context=Actions
Size=64
Type=Fixed
…
[512x512/mimetypes]
Context=MimeTypes
Size=512
MinSize=56
MaxSize=512
Type=Scalable
…

Aber eben auch nicht fest definiert, sondern nur das, was auch da ist. Ein nahezu vollständiges Theme ist bspw. Adwaita (daraus sind die Abschnitte). Und je nachdem, welches Framework dein Programm benutzt, kann das auch anders sein. Es lebe die Vielfalt 😀

ChickenLipsRfun2eat Team-Icon

(Themenstarter)

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Ich werde es mir nun wohl einfach machen. Ich lese alle Dateinamen des Themes ein, wenn es kein svg gibt, sortiere ich sie nach Größe und nehme das jeweils Größte als Icon; das wird dann eben bei Bedarf runterskaliert. Kostet zwar auch Leistung, aber das ist nicht spürbar. Das „teure Einlesen“ schon. Ich muss mir das Leben ja nicht unnötig schwer machen 😉

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6532

Mir fällt da auch nichts besseres ein. Aber wenn es mehrere Größen von einem Icon gibt, solltest du mal prüfen, ob das größere mehr Details zeigt. Es könnte ja sein, dass der Designer das nicht nur einfach verkleinert hat, sondern auch Details weggelassen hat um das nicht zu matschig werden zu lassen.

Andererseits hast Du bei der größten Version mehr Sicherheit, denn ein zu kleines Icon vergrößern zu müssen, ist noch schlimmer.

ChickenLipsRfun2eat Team-Icon

(Themenstarter)

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Ja, ich bastle mir gerade eine Klasse auf Basis der freedesktop-Spezifikation. Wenn ich soweit fertig bin, stelle ich die hier mal rein. Dauert aber ein wenig, ist doch mehr als ich dachte 😉

Antworten |