<div><div style="font-family:'trebuchet ms',sans-serif">Wow! First of all, I would like to say thank you for so much attention to my small contribution!</div><div style="font-family:'trebuchet ms',sans-serif">
Really I didn't expect that, thanks! I'm glad that my work to someone in good stead.</div><div style="font-family:'trebuchet ms',sans-serif"><br></div><div style="font-family:'trebuchet ms',sans-serif">
<span style="font-family:arial">> Sorry for not replying to your earlier private email about this.</span><br style="font-family:arial"><div><span style="font-family:arial">It's ok :)</span></div></div><div><br></div>
> I have one major issue with the implementation you're suggesting though.<br>> Unlike the mimetype stuff which is based on a mmap'ed cached (mime.cache), it<br>> seems to parse all the .desktop files in-process. This means, if you start 10<br>
> apps and they all need at some point to use xdg_mime_*_apps_lookup, they will<br>> each suffer the runtime penalty (slowness and memory usage) of parsing all the<br><div style="font-family:'trebuchet ms',sans-serif">
> .desktop files on the system.</div><div><div><font face="'trebuchet ms', sans-serif">You are absolutely right! I'm thinking about some mechanism to cache all that staff</font></div><div><font face="'trebuchet ms', sans-serif">like other parts of xdgmime does. But specification does not describe where </font><font face="'trebuchet ms', sans-serif">it could</font></div>
<div><font face="'trebuchet ms', sans-serif">be </font><font face="'trebuchet ms', sans-serif">stored, so </font><span style="font-family:'trebuchet ms',sans-serif">I decided to not to do it right now. But, maybe this is the time :)</span></div>
<div style="font-family:'trebuchet ms',sans-serif"><br></div></div><div style="font-family:'trebuchet ms',sans-serif">
> <span style="font-family:arial">So for application .desktop files, we could have another helper binary, say</span><br style="font-family:arial">> <span style="font-family:arial">update-app-database (part of shared-mime-info maybe, so that we don't need to</span><br style="font-family:arial">
> <span style="font-family:arial">depend on xdgmime, which we don't use in KDE and I think gnome might not</span><br style="font-family:arial">> <span style="font-family:arial">either, or in a new module), which updates a new cache, say</span><br style="font-family:arial">
> <span style="font-family:arial">"application.cache" in a given directory. RPMs and other packages would run</span><br style="font-family:arial">> <span style="font-family:arial">that script when installing .desktop files, and then xdgmime could just mmap</span><br style="font-family:arial">
> <span style="font-family:arial">that and look things up directly, without the need to parse any .desktop files</span><br style="font-family:arial">> <span style="font-family:arial">during the application runtime. Now if you implemented that, it would</span><br style="font-family:arial">
> <span style="font-family:arial">definitely be the best Christmas ever, in my eyes :-)</span></div><div style="font-family:'trebuchet ms',sans-serif">I think this is a great idea! I will begin the implementation of mmap'ed cache</div>
<div style="font-family:'trebuchet ms',sans-serif">on the weekend.</div><div style="font-family:'trebuchet ms',sans-serif"><br></div><div style="font-family:'trebuchet ms',sans-serif">> <span style>So overall, I'm not sure what this would be fixing, apart from the</span><br style>
> <span style>lack of an icon spec implementation at that level of the stack. There's</span><br style>> <span style>already one in KDE, one in Qt, and surely a few in the gnome/glib/gtk world,</span><br style>> <span style>but I suppose none of this fits your bill otherwise you wouldn't have written</span><br style>
> <span style>it :-)</span><br style></div><div><div><font color="#222222" face="arial, sans-serif">This implementations do not suits me because, well they are in a huge libraries :)</font></div><div><font color="#222222" face="arial, sans-serif"><div>
I'm adherent of small modules each of which is implementing strictly defined task</div><div>with strictly defined interface.</div></font></div></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif"><br>
</span></div><div style="font-family:'trebuchet ms',sans-serif"><span style>> I agree the contents of the theme file itself is probably not as urgent to</span><br style><span style>> </span><span style>cache.</span><br style>
</div><div><span style>I agree with you, but maybe the thing is that I'm an </span><font color="#222222" face="arial, sans-serif">perfectionist :) and I think</font></div><div><font color="#222222" face="arial, sans-serif">if I can make an improvement I should do it.</font></div>
<div style="font-family:'trebuchet ms',sans-serif"><span style><br></span></div><div style="font-family:'trebuchet ms',sans-serif"><span style><br></span></div><div><div><span style="font-family:'trebuchet ms',sans-serif">Let me briefly explain how current implementation works, I hope it will clarify</span></div>
<div><font face="'trebuchet ms', sans-serif">some things and help to understand what to do next.</font></div><div style="font-family:'trebuchet ms',sans-serif"><br></div></div><div style="font-family:'trebuchet ms',sans-serif">
There are two entry points, first one in</div><div style="font-family:'trebuchet ms',sans-serif">"xdgmime.c:143: xdg_mime_init_from_directory(...)". There is a call to private</div><div style="font-family:'trebuchet ms',sans-serif">
method "_xdg_mime_applications_read_from_directory(...)". This entry point is</div><div style="font-family:'trebuchet ms',sans-serif">for "Desktop Entry Specification" (xdgmimeapp{.h, .c, _p.h}).</div>
<div style="font-family:'trebuchet ms',sans-serif"><br></div><div style="font-family:'trebuchet ms',sans-serif">"_xdg_mime_applications_read_from_directory(...)" does parsing of all "*.desktop"</div>
<div style="font-family:'trebuchet ms',sans-serif">and "*.list" files found according to "The Desktop Base Directory Specification"</div><div style="font-family:'trebuchet ms',sans-serif">
then stores all "*.desktop" files into AVL tree using the file name as key (I've taken</div><div style="font-family:'trebuchet ms',sans-serif">into consideration that there could be subdirs which means prefix for the file name</div>
<div style="font-family:'trebuchet ms',sans-serif">in global scope, like "kde4-"). As a value of key-value pair for AVL tree another</div><div style="font-family:'trebuchet ms',sans-serif">AVL tree is used with contents of "*.desktop" file. This makes access to any field</div>
<div style="font-family:'trebuchet ms',sans-serif">of any "*.desktop" file in the system very fast, I would say as fast as possible (this</div><div style="font-family:'trebuchet ms',sans-serif">was the major task for me). Contents of all "*.list" files is stored in one AVL tree.</div>
<div style="font-family:'trebuchet ms',sans-serif">Also, all associations of mime type with "*.desktop" files (from "*.desktop" files)</div><div style="font-family:'trebuchet ms',sans-serif">
are stored in another AVL tree.</div>
<div style="font-family:'trebuchet ms',sans-serif"><br></div><div style="font-family:'trebuchet ms',sans-serif">So, it was about internals. Let me describe public interface of the</div><div style="font-family:'trebuchet ms',sans-serif">
"Desktop Entry Specification" (file: "xdgmimeapp.h"). As already mentioned</div><div style="font-family:'trebuchet ms',sans-serif">by David, the are three interesting methods:</div></div><font color="#000000"><font><font face="trebuchet ms,sans-serif"><div>
<div><br></div><div> - "xdg_mime_default_apps_lookup(...)" - this method searches for all applications</div><div>associated with the given mime type in section "Default Applications" of all found</div>
<div>"*.list" files (do you remember, contents of all "*.list" files is stored in one</div><div>AVL tree - it's like we merged all "*.list" files into one);</div>
</div><div><br></div><div><div><div> - "xdg_mime_user_apps_lookup(...)" - this method searches for all applications</div><div>associated with the given mime type in section "Added Associations" of all found</div>
<div>"*.list" files. As mentioned by David, it is not quite correct because there is</div><div>"Removed Associations" section about which I didn't know (or missed it);</div></div></div><div><br></div>
<div><div><div><div> - "xdg_mime_known_apps_lookup(...)" - this method searches for all applications</div><div>associated with the given mime type using third AVL tree I have described at</div><div>very beggining (where all associations of mime type with "*.desktop" files);</div>
</div></div></div><div><br></div><div> - "xdg_mime_app_icon_lookup(..)" - well, it depends on "Icon theme specification"</div><div>and will be described later;</div>
<div><br></div><div> - "xdg_mime_app_group_lookup(...)" - this method can return a group</div><div>from "*.desktop" file (like "Desktop Entry");</div><div><br></div><div> - "xdg_mime_app_entry_lookup(...)" - this method can return array of entry values</div>
<div>from group of "*.desktop" file (like "Name");</div>
<div><br></div><div> - "xdg_mime_array_app_item_at(...)" - this method is needed for traversing through</div><div>array of XdgApp ("*.desktop" files).</div><div><br></div><div><div>Note: I'm thinking about localized fields... I think it should be merged with parent field</div>
<div>(for example Name[de] with Name). Provide convinient interface for reading of</div><div>localized values of the same field.</div></div><div><br></div><div>We got to the second entry point which is in "xdgmime.c:449: xdg_mime_init(...)".</div>
<div>There is a call to private method "_xdg_mime_themes_read_from_directory(...)".</div><div>This entry point is for "Icon Theme Specification" (xdgmimetheme{.h, .c, _p.h}).</div><div>This implementation has a "special" entry point (not in "convinient" place) because it</div>
<div>relies on diffrent layout of directories than "The Desktop Base Directory Specification"</div><div>describes (includes "~/.icons/" and "/usr/share/pixmaps/").</div><div><br></div><div><div>
Initialization of this mechanism works similar to previous one with one difference - it</div><div>reads "index.theme" files. "_xdg_mime_themes_read_from_directory(...)" does parsing of</div><div>all "index.theme" files found according to directory layout from "Icon Theme Specification"</div>
<div>then stores all "index.theme" files into AVL tree using theme directory name as key.</div><div>As a value of key-value pair for AVL tree another AVL tree is used with contents of</div><div>"index.theme" file. This approach eliminates need of scanning whole theme directory and</div>
<div>directory of parent theme (and parent of parent, etc) to find icon.</div></div>
<div><div><br></div><div><div>In general, for algorithm of filesystem scanning we have absolute path to directories</div><div>where icon could be. The only thing we have to do is to check existence of the icon file</div>
<div>in this directories. If its not there take the parent theme and so on.</div></div></div><div><br></div><div>Here is the public interface of the "Icon Theme Specification" (file: "xdgmimetheme.h"):</div>
<div><br></div><div> - "xdg_mime_type_icon_lookup(...)" - this method can return absolute path to icon file</div><div>for given mime type, icon size and theme name. It converts mime type to icon name</div><div>by replacing "/" to "-" then searches for theme by given theme name (for example "hicolor")</div>
<div>and looks for icon in directories listed in the theme file ("index.theme");</div>
<div><br></div><div> - "xdg_mime_icon_lookup(...)" - this method can return absolute path to icon file for</div><div>given icon name, icon size, context and theme name. It searches for theme by given</div><div>
theme name (for example "oxygen") and then looks for icon in directories listed in</div><div>the theme file ("index.theme");</div><div><br></div><div><div> - "xdg_mime_app_icon_lookup(..)" - It was mentioned in "Desktop Entry Specification"</div>
<div>interface. This method takes icon name from "*.desktop" file and searches for it in a given</div><div>theme.</div><div><div><br></div><div>Note: I think this implementation could be improved by adding an AVL tree for indexing</div>
<div>(by size and/or context) directories inside of theme file. But I'm not assured would it</div><div>be really improvement or not.</div></div></div><div><br></div><div>P.S.: sorry for by bad english.</div></font></font></font><div style="line-height:12px;font-family:Arial,Helvetica,'Nimbus Sans L',sans-serif">
<h3 style="font-family:inherit;font-style:inherit;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;outline-width:0px;outline-style:initial;outline-color:initial;font-weight:inherit;vertical-align:baseline;color:rgb(51,51,51)">
<font>--------------------------------</font></h3></div><div style="line-height:12px;font-family:Arial,Helvetica,'Nimbus Sans L',sans-serif"><h3 style="font-family:inherit;font-style:inherit;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;border-style:initial;border-color:initial;outline-width:0px;outline-style:initial;outline-color:initial;font-weight:inherit;vertical-align:baseline;color:rgb(51,51,51)">
<font>Best regards, Dmitriy.</font></h3></div><br>
<br><br><div class="gmail_quote">24 января 2012 г. 2:20 пользователь David Faure <span dir="ltr"><<a href="mailto:faure@kde.org" target="_blank">faure@kde.org</a>></span> написал:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>On Sunday 15 January 2012 17:40:27 DAV wrote:<br>
> I added missing features:<br>
> - C-implementation of AVL trees;<br>
> - indexed (by using of AVL trees) access to all ".desktop" files and its<br>
> contents (implementation of "Desktop Entry Specification");<br>
<br>
</div>Hello Dmitriy,<br>
<br>
Sorry for not replying to your earlier private email about this. But let's<br>
discuss this here, it's a better idea indeed.<br>
<br>
I'm very excited by the idea of having a cross-desktop solution to the very<br>
common issue of getting the list of apps associated with a given mimetype,<br>
I've been thinking that we need that, for quite some time (when I saw your<br>
mail, I thought "wow, it's Christmas!").<br>
<br>
(We use ksycoca in kde4 for this purpose, but I'd like to get rid of it for<br>
kde5, so the timing is perfect.)<br>
<br>
I have one major issue with the implementation you're suggesting though.<br>
Unlike the mimetype stuff which is based on a mmap'ed cached (mime.cache), it<br>
seems to parse all the .desktop files in-process. This means, if you start 10<br>
apps and they all need at some point to use xdg_mime_*_apps_lookup, they will<br>
each suffer the runtime penalty (slowness and memory usage) of parsing all the<br>
.desktop files on the system.<br>
<br>
We don't do that with mimetypes: shared-mime-info has a binary called "update-<br>
mime-database" which does the collecting and parsing of the (mime) files, and<br>
generates a binary file called mime.cache, whose on-disk layout is such that it<br>
can be used via mmap. This way, the applications are fast.<br>
<br>
So for application .desktop files, we could have another helper binary, say<br>
update-app-database (part of shared-mime-info maybe, so that we don't need to<br>
depend on xdgmime, which we don't use in KDE and I think gnome might not<br>
either, or in a new module), which updates a new cache, say<br>
"application.cache" in a given directory. RPMs and other packages would run<br>
that script when installing .desktop files, and then xdgmime could just mmap<br>
that and look things up directly, without the need to parse any .desktop files<br>
during the application runtime. Now if you implemented that, it would<br>
definitely be the best Christmas ever, in my eyes :-)<br>
<br>
Alex, Bastien: do you agree about the approach? Would gnome/gtk/glib use it,<br>
if it was done that way? (Otherwise half the RPMs/DEBs in the world will<br>
forget to run the update-app-database... so to me this solution will only work<br>
out in practice if it's used by everyone.)<br>
<br>
> const XdgArray *xdg_mime_default_apps_lookup(const char *mimeType);<br>
> const XdgArray *xdg_mime_user_apps_lookup(const char *mimeType);<br>
> const XdgArray *xdg_mime_known_apps_lookup(const char *mimeType);<br>
<br>
A bit of documentation wouldn't hurt ;-) What's each of those doing exactly?<br>
It seems user_apps looks at the contents of mimeapps.list (but allows any<br>
*.list file? Is that in the spec?), but it only looks at [Added Associations],<br>
so this is missing support for [Removed Associations]. I think "user apps"<br>
should return the final set: default apps plus those added by the user, minus<br>
those removed by user. That's what client code cares mostly about.<br>
<br>
There's also the issue that the defaults should be desktop-dependent, but<br>
that's an entire new topic. The current situation is that KDE uses<br>
InitialPreference in the desktop files while Gnome uses a defaults.list file<br>
(iirc). One could say it sucks that this is non-standard, but on the other<br>
hand it gives "defaults are desktop-dependent" de facto.<br>
If we were to use a common way (which would definitely please distros and<br>
ISVs), then we would still need a way to make the defaults desktop-dependent,<br>
I would think, somehow (maybe a *.list file per desktop). (Although I definitely<br>
prefer the more modular KDE solution where an app can be installed later on<br>
and not have to hack into a global file to take precedence).<br>
I'm sure we've had this discussion already on this list, but I forgot the<br>
outcome of it :-}<br>
<div><br>
> - indexed (by using of AVL trees) access to icon themes and its contents<br>
> (implemetation of "<br>
</div>> <a href="http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html" target="_blank">http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html</a><br>
> " and<br>
> "<br>
> <a href="http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.ht" target="_blank">http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.ht</a><br>
> ml ").<br>
<br>
My first reaction was: this, too, only seems interesting to me if it's based on<br>
a mmap'ed binary cache. Otherwise apps can just look things up directly on<br>
disk, as they already do currently. But either it only caches the contents of<br>
the theme files, and then it seems not so useful (there are only very few of<br>
them, typically, right?), or it also caches the names of all available icons,<br>
but that might not be a big saving compared to looking up in the file system<br>
directly. So overall, I'm not sure what this would be fixing, apart from the<br>
lack of an icon spec implementation at that level of the stack. There's<br>
already one in KDE, one in Qt, and surely a few in the gnome/glib/gtk world,<br>
but I suppose none of this fits your bill otherwise you wouldn't have written<br>
it :-)<br>
Anyhow, no real objection from me, but the target audience probably needs to<br>
be defined, and like xdgmime itself (AFAIK), I think it wouldn't be much used.<br>
<span><font color="#888888"><br>
--<br>
David Faure, <a href="mailto:faure@kde.org" target="_blank">faure@kde.org</a>, <a href="http://www.davidfaure.fr" target="_blank">http://www.davidfaure.fr</a><br>
Sponsored by Nokia to work on KDE, incl. KDE Frameworks 5<br>
<br>
</font></span></blockquote></div><br>