Closed KELiON closed 2 years ago
I investigated this a bit, the algorithm looks like this:
Found a simple way here:
Execute in shell: gvfs-info -a standard::icon /full/path/to/file.txt
Output:
uri: file:///full/path/to/file.txt
attributes:
standard::icon: text-plain, text-x-generic
The last line defines matching MIME types, in the order of priority.
The search would be /usr/share/icons/**/text-plain.*
, if not found then /usr/share/icons/**/text-x-generic.*
(popular ones are png
and svg
files). If nothing matches, then just choose some default a use it. On my machine nothing matches for text-plain
, but there are a few results for text-x-generic
, in different theme folders. How to know which theme to use?
~Found this command here:~
~gsettings get org.gnome.desktop.interface gtk-theme~
@bil-elmoussaoui suggests a better command:
gsettings get org.gnome.desktop.interface icon-theme
Plus this will only work on Gnome and derivatives, so for example on Cinnamon the command would be:
gsettings get org.cinnamon.desktop.interface icon-theme
It is unclear yet what are the commands that will work on other desktop environments.
It outputs a theme name for me: Adwaita
Therefore the search should be prioritized for /usr/share/icons/Adwaita/**/text-x-generic.*
, if not found then consider all the other folders.
Same rules as with icon resolutions for the apps.
Therefore, for my example with a text file, the correct icon to use is located at:
/usr/share/icons/Adwaita/256x256/mimetypes/text-x-generic.png
I wish it was simpler.
We could also use this algorithm to show default application icons, in case we didn't find any icon for the application itself. Default icon is better than no icon.
@maximbaz you shouldn't be looking at gtk-theme but icon-theme instead. + This will only work on a gnome desktop or a derivate of it, it won't work on cinnamon for example as they use org.cinnamon.desktop.interface instead.
Thanks! updated the message.
@KELiON Hey! How can I get in touch with you about this issue? I'm currently trying to implement a simple way to find an icon on the theme. For now, the whole code is Sync (i will implement an Async version once everything works as expected).
The whole package is just one file and pretty easy to use. It has one function which is getIcon()
It takes three parameters: The icon name, the icon size, and the context of the icon (mime types here in your issue). What is good about what I've done till now, is that the code handles themes inherited without any issue. If you're using theme X and it's inherited theme Y, if you look for a Z icon and it's not found on X, the code will look on Y after that.
But as I'm not that good JS dev, I don't know how should i handle the case where the iconPath (found by the getIcon) is an SVG icon instead of a png one?
For now, I'm thinking of converting the SVG icon to a png one and returning the buffer, this way it can be easily used using nativeImage.createFromBuffer. But i couldn't find any great package to handle svg to png conversions.
I tried my solution with a simple electron app with a tray icon, and the code I wrote works well and get the correct icon to work.
If you would like, we can get this done together (just a few tips and code review/improvements from you) and this can be used across all other electron applications. Either for using a themeable tray icon (which is requested in every icon theme out there) or for some cases like your application! Thanks and keep up the great work!
Is it not possible to render SVG icon? Why do you want to convert it to PNG? I'm asking because we use SVG icons for app icons, for example, without any conversion.
@maximbaz sadly, tray icons on electron can not use SVG icons.... The reason why i wanted to convert it to png's is to be able to return a base64 encoded png to be used with nativeImage.createfromBuffer. Anyway, I've already figured out how to handle all of that! You can now either get the Buffer or the absolute path of the image:+1:
Here you go : https://github.com/bil-elmoussaoui/linux-icons
Nice job @bil-elmoussaoui! Am I right to assume that your project can be used not only for file icons, but also for application icons (https://github.com/KELiON/cerebro/issues/97) ?
@maximbaz The difference between app icons and mime types is the context (the third parameter you use). If you want to get an application icon you would do
const icons = require('linux-icons')
icons.getIcon('myicon-name', 22, icons.Context.APPLICATION, iconPath => {
console.log(iconPath)
})
Here's the list of supported Contexts (the free desktop standards https://github.com/bil-elmoussaoui/linux-icons/blob/master/index.js#L26) which will work on every Linux distro out there!
Cool! That would be a great improvement to use your new library for both app and file icons 👍
Consider getting this integrated in Cerebro, many people will be thankful 😜 I can help out with testing or reviewing the code.
Just keep in mind, the functionality was recently extracted in separate plugins: cerebro-basic-apps and cerebro-files-nav
@maximbaz That would be awesome, as a JS noob my code isn't perfect and it can be improved a lot. Especially the fact that I'm using svg2png to convert SVG icons to png's, this library uses PhantomJS which is not that good (huge library as dependency...);
Try to use this https://gist.github.com/PurpleBabar/b7ab56435a172b743a8f5f3b255c4cb3
@PurpleBabar
Please try:
#!/usr/bin/env gjs
const { Gio } = imports.gi;
let file = Gio.File.new_for_path(ARGV[0]);
let fileInfo = file.query_info('*', Gio.FileQueryInfoFlags.NONE, null);
let icons = fileInfo.get_icon().get_names();
print(icons[0]);
You have to send the file path in double quote as argument to this script.
Find a way to read file icon on Linux