5

How do I give my application's custom document a custom icon? Additionally, how do I make the file manager open these documents when a user double clicks on them?

I have to do this on the command line because the solution will be used inside an installation script.

2
  • Have you tried using assogiate? It's a graphical MIME-type editor that automates a lot of the more tedious steps. – Glutanimate Jun 15 '14 at 22:22
  • I wish I could use it. But it appears it won't work headless. This has to be done via a script. – user293406 Jun 16 '14 at 0:03
3

The correct solution can be found --> here <-- , but a foo version is provided below to directly answer the question.

Please pay very close attention to the use of application-x-foo, x-foo, and foo as they change throughout.

Note: When updating the Ubuntu tutorial, it's probably better in an example to distinguish between the foo application, foo the extension and foo mimetype to avoid confusion moving forward. i.e. lmms uses *.mmpz and x-lmms-project, which helped a lot in figuring this out.

  • Get a scalable SVG icon (example provided)
  • wget http://soqr.fr/testsvg/zebra.svg -O ~/Desktop/application-x-foo.svg
    

  • Create a mime-ingest file in XML format:
  • <?xml version="1.0" encoding="UTF-8"?>
    <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
    <mime-type type="application/x-foo">  
    <comment>Foo File</comment>
    <glob pattern="*.foo"/>
    </mime-type>
    </mime-info>
    

  • Save this to ~/Desktop/x-foo.xml
  • If not already, create a desktop file:
  • [Desktop Entry]
    Version=1.0.0
    Encoding=UTF-8
    Name=FooGazi
    GenericName=Foo Application
    Comment=This is my Foo Application
    Exec=/usr/bin/foo
    # Please change, system-shutdown.svg used only as example
    Icon=/usr/share/icons/Humanity/actions/48/system-shutdown.svg
    StartupNotify=true
    Type=Application
    MimeType=application/x-foo;
    

  • Save this to ~/Desktop/foo.desktop

  • Deploy the mime description
  • sudo xdg-mime install --mode system ~/Desktop/x-foo.xml
    

  • Deploy the application launcher
  • sudo cp ~/Desktop/foo.desktop /usr/share/applications
    

  • Deploy the SVG icon
  • sudo cp ~/Desktop/application-x-foo.svg /usr/share/icons/gnome/scalable/mimetypes/
    

  • Register the application launcher with the registered mimetype
  • sudo xdg-mime default foo.desktop application/x-foo
    

  • Update the mime cache
  • sudo update-mime-database /usr/share/mime
    

  • Update the icon cache
  • sudo gtk-update-icon-cache /usr/share/icons/gnome/ -f
    

  • As a habit, I also add the appropriate line to /etc/mime.types but please confirm whether or not this is still needed and edit this post to reflect that.
  • Log off and then back in. Both the icon and the association should work.
  • 2
    • One note, talking to people at irc freedesktoporg, the x convention has be dropped and vender name is supposed to being used. x was there to stop collisions, but apparently that created collisions too? I don't really understand that, but I was told something in regard to that. Correct me if I have misunderstood something. – user293406 Jun 16 '14 at 20:31
    • Thanks for this information this is good to know. I suspect it will take a while for the individual applications to catch up to the removal of "x-foo". If you can link any official documentation on this decision now or down the road, it would be beneficial to this thread. :) – user1466873 Jun 17 '14 at 16:10
    1

    Never, ever, edit existing files in /etc from you install script! That is a terribly bad idea. besides you don't need to edit /etc/mime.types

    your xml file is still wrong, and in the wrong location it should be /usr/share/mime/text/x-foo.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <mime-type xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="text/x-foo">
        <comment>Example file type </comment>
        <glob pattern="*.foo"/>
    </mime-type>
    

    3rd party Icons are normally installed to: /usr/share/icons/hicolor/scalable/mimetypes

    1
    • 1
      This did not work. (1) Placing the foo.xml in said location is removed when I call: sudo update-mime-database /usr/share/mime. The files then do not launch /usr/bin/foo. (2) Placing the foo.svg in /usr/share/icons/highcolor/scalable/mimetypes does not bring up the icon under any them. – user293406 Jun 16 '14 at 16:40
    0

    I was not able to get things working with the other answers, but I was able to get things working the following way.

    This has been tested and works on these live disks:

    Ubuntu 14.04
    Lubuntu 14.04
    Ubuntu-Gnome 14.04
    

    Make Foo Wrapper App

    For this example, I'm creating a wrapper for gedit called foo for the purposes of a complete working example.

    (1) As sudo, create a file with this content:

    gedit %f

    (2) Save it as:

    /usr/bin/foo

    (3) Make it executable:

    sudo chmod +x /usr/bin/foo

    Getting Foo Application To Show Up In The Menu And It's Icon

    (1) Create the application image. Gimp or Inkscape are both excellent programs for this. After creating the image, export it as a png or svg.

    (2) Name your image. The image name should be the same name you use to launch your application on the command line. The app in this example is called: foo. So the correct name would be foo.png or foo.svg.

    (3) Copy image to:

    /usr/share/icons/foo.svg
    

    (4) Create Desktop Entry. Open up gedit, leafpad or your IDE. Create a new document with this data:

    [Desktop Entry]
    Exec=foo %f
    Icon=foo
    Terminal=false
    Type=Application
    Categories=Office;
    StartupNotify=true
    MimeType=text/foo
    Name=Foo
    GenericName=Foo
    Comment=Compose, Edit, and View Foo Documents
    

    Take note of Exec, Icon and MimeType keys:

    Exec: %f is added after the executable name. That must be there so when a user double clicks on a foo document, the system will execute foo application and send that foo document path to the application via the %f argument.

    Icon: Only the name is needed. I did not get good results when using absolute paths.

    MimeType: text/foo. text is the called the 'content type'. foo of course is the application name. This mapping convention must be adhered to in the other steps. For example you don't want to use application/foo in another step. By doing that you are not keeping the content type consistent for foo and things will fail.

    (5) Save this file as:

    foo.desktop
    

    The name of the file is the name of you application launch name and it must have the extension desktop. Now, it must be copied to:

    /usr/share/applications
    

    At this point, you will see you application under the category Office in the menu and your icon will be viewable as well.

    Giving Your Application Documents Their Own Icon

    (1) Create a mime xml file with this content:

    <?xml version="1.0" encoding="UTF-8"?>
    <mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="text/foo">
       <mime-type type="text/foo">
          <magic>
             <match type="string" offset="2" value="0foomagic"/>
          </magic>
       </mime-type>
    </mime-info>
    

    Take note of the content type mapping: both are text/foo.

    You have two choices when you want a custom document to get it's icon. (1), the system will look for it's extensions and give it an icon based upon the extension. (2) the system will look for a magic string at a particular offset in the file. I'm choosing magic, because I don't prefer to view extensions on my file names in the file manager.

    In order to use magic, I save all my documents as json files. It's a universal storage protocol, so it works well for me. When I save the file, I sort the keys alphabetically, which causes the magic key to appear as the first key in the file. This happens because I put a zero as the first character of "0foomagic", and I make sure no other key will ever be made in my documents that mess this up.

    Referring to this line in the xml above,

    <match type="string" offset="2" value="0foomagic"/>
    

    a json file has two characters before it hits my magic key called 0foomagic. So I set the offset to 2.

    If you prefer to use an extension instead, just take out the magic entry, and replace it with:

    <glob pattern="*.foo"/>
    

    where .foo is your application document extension.

    (2) Update Mime Database with this command:

    sudo update-mime-database /usr/share/mime
    

    (3) The icons that will show up for custom documents have to be named a special way for them to work. They must be mapped with the content type. Create a document icon and name it with the mapped the content type convention mentioned earlier (expect dash is used instead of forward slash):

    text-foo.svg
    

    text is the content type and foo is your application name, same as before.

    You will need to copy this icon to any theme you will be using. Any theme it is not copied to will not display your foo document with text-foo.svg.

    Themes are set up two different ways, you will end up with more work with some themes, for example:

    For Gnome Theme, you will only need to copy text-foo.svg to one place: /usr/share/icons/gnome/scalable/mimetypes/

    Switch to gnome theme and then you are done with this step.

    But, for example if you use hicolor theme, you have more work to do. You must create an icon size for each of these directories the theme demands, for example:

    /usr/share/icons/hicolor/16x16/mimetypes/
    /usr/share/icons/hicolor/22x22/mimetypes/
    ...
    

    etc., etc.

    Now that you've copied the icons over, the icon data base must be updated. I've noticed two commands for this (gtk-update-icon-cache and gtk-update-icon-cache3.0), I just call both and I haven't noticed a problem. They must be called on any theme directory you've added icons to.

    If you added to gnome theme, then:

    sudo gtk-update-icon-cache /usr/share/icons/gnome/
    

    If you added to hicolor theme, then:

    sudo gtk-update-icon-cache /usr/share/icons/hicolor
    

    Now, just one more thing to do, and you should see things working without even logging in and out. Update the desktop data base:

    sudo update-desktop-database

    Test Foo

    Since it would overburden this answer to create ask you to create json file, just use foo, the gedit wrapper, to trick it into making a foo doc with the 0foomagic inside it.

    (1) Type foo on the command line, and you should see gedit launch.

    (2) In the empty text file in gedit, add two characters, then the magic string:

    xx0foomagic
    

    (3) Save and close gedit. Now look inside the file manager and you will see your new document has the text-foo.svg icon. Double click on it, and foo will open it. Presto! That's freedesktoporg magic!

    There are many other things you can learn about this process, but this will at the very least will get you going with your own app-launching document icons on Ubuntu.

    Please contribute to this answer or create a new answer if you have the best practice way to do it.

    1
    • If you use the desktop-file-validate application on your .desktop file there, you'll get the following warning: file.desktop: error: value "text/foo" for string list key "MimeType" in group "Desktop Entry" does not have a semicolon (';') as trailing character (Sorry, trying to get the above to show as a code block, but newlines don't work in comments I guess?) – Jordan Dec 2 '16 at 4:32

    Your Answer

    By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

    Not the answer you're looking for? Browse other questions tagged or ask your own question.