You are not logged in.

#1 2011-01-26 17:38:10

Gullible Jones
Member
Registered: 2004-12-29
Posts: 4,863

How to launch applications via .desktop files?

Some file managers (e.g. Rox) can launch an application when you click on its .desktop file in /usr/share/applications. Many don't. Is there a command line utility that can parse .desktop files and launch the correct application, which I can associate with .desktop files in file managers like mc or xfe?

Offline

#2 2011-01-26 17:39:03

Inxsible
Forum Fellow
From: Chicago
Registered: 2008-06-09
Posts: 9,130

Re: How to launch applications via .desktop files?

The ones that don't work, do they have the following in them

Exec=/path/to/command

Forum Rules

There's no such thing as a stupid question, but there sure are a lot of inquisitive idiots !

Offline

#3 2011-01-26 17:55:19

Gullible Jones
Member
Registered: 2004-12-29
Posts: 4,863

Re: How to launch applications via .desktop files?

It's not the .desktop files that don't work, it's the file managers. For instance Xfe will just open .desktop files as text, whereas Rox will open the application they belong to by default. I'd like to have that latter behavior in Xfe, and was wondering if there was any command line utility for executing an application based on a .desktop file.

Offline

#4 2011-01-26 18:11:51

anonymous_user
Member
Registered: 2009-08-28
Posts: 3,058

Re: How to launch applications via .desktop files?

You could do "xdg-open whatever.desktop".

Offline

#5 2011-01-26 18:32:10

Xyne
Moderator/TU
Registered: 2008-08-03
Posts: 6,441
Website

Re: How to launch applications via .desktop files?

anonymous_user wrote:

You could do "xdg-open whatever.desktop".

That opens the desktop file based on file-type associations, which is what the file browsers are already doing.


@Gullible Jones
Here's a script that will open the application of the Exec key in the desktop file. Pass it the path to the desktop file as the first argument. Additional arguments will be passed through to the application.

The code has been ripped from mimeo and tweaked a bit. I've only done some quick testing but the Exec command parser should be fully compliant with the Desktop specification, so it should work with everything.

If you find any bugs, let me know, as they may affect mimeo as well.

#!/usr/bin/env python2
# Author: Xyne

import os, os.path, re, subprocess, sys
from pipes import quote



def launch(args):
  subprocess.Popen(args, shell=True, close_fds=True)



def parseDesktop(fpath):
  desktop = {}
  if os.path.exists(fpath):
    try:
      f = open(fpath)
    except IOError:
      print "error: unable to open", fpath
    else:
      for line in f.readlines():
        m = re.search(r'^\s*(.+?)\s*=\s*(.+?)\s*$', line)
        if m:
          desktop[m.group(1)] = m.group(2)
  return desktop



def which(cmd):
  def isExecutable(fpath):
    return os.path.exists(fpath) and os.access(fpath, os.X_OK)
  fpath, fname = os.path.split(cmd)
  if fpath:
    cmd = os.path.abspath(cmd)
    if isExecutable(cmd):
      return cmd
  else:
    for p in os.environ["PATH"].split(os.pathsep):
      fpath = os.path.join(p, fname)
      if isExecutable(fpath):
        return fpath
  return None



# http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
def parse_exec_key(key, user_args):
  #reserved = " \t\n\"\'\\><~|&;$*?#()`"
  quoted = False
  escaped = False
  percent = False
  # Track field codes which may only occur once and alone.
  seen = False
  # Track where to insert replacements for %f and %u.
  insertion_point = None
  # Track skipped variables to prevent empty arguments, e.g. '%x' -> ''.
  skipped = False
  args = []
  a = ""

  for c in key:
    if escaped:
      escaped = False

    elif percent:
      percent = False
      if c == '%':
        pass
      else:
        # skip some fields that appear more than once
        if 'fFuU'.find(c) > -1:
          if seen:
            skipped = True
            continue
          else:
            seen = True

        if c == 'f' or c == 'u':
          insertion_point = (len(args), len(a))

        elif c == 'F' or c == 'U':
          a += '%' + c

        # TODO: implement remaining
        elif c == 'i' or c == 'c' or c == 'k':
          skipped = True

        continue

    elif quoted:
      if c == '\\':
        escaped = True
        continue
      elif c == '%':
        percent = True
        continue
      elif c == '"':
        quoted = False
        continue

    elif c == '"':
      quoted = True
      continue

    elif c == '%':
      percent = True
      continue

    elif c == ' ':
      if a or not skipped:
        args.append(a)
      a = ""
      skipped = False
      continue

    a += c

  if a or not skipped:
    args.append(a)
  cmd = args[0]

  cpath = which(cmd)
  if not cpath:
    die("invalid executable (%s)" % cmd)
  else:
    args[0] = cpath

  if not user_args:
    return [cpath]

  if insertion_point:
    i, j = insertion_point
    a = args[i]
    cmds = []
    for user_arg in user_args:
      b = a[:j] + user_arg + a[j:]
      args[i] = b
      cmds.append(quote_command(args))
    return cmds


  else:
    cmd = []
    complete = False
    for a in args:
      if a == "%F" or a == "%U":
        cmd.extend(user_args)
        complete = True
      else:
        cmd.append(a)

    if not complete:
      cmd.extend(user_args)

    return [quote_command(cmd)]


def quote_command(args):
  return ' '.join( map(quote, args) )


def die(msg):
  sys.stderr.write("error: %s\n" % msg)
  sys.exit(1)



def main():
  try:
    fpath = sys.argv[1]
  except IndexError:
    die("no desktop file specified")

  args = sys.argv[2:]


  desktop = parseDesktop(fpath)

  if not desktop:
    die("%s does not exist" % fpath)

  elif desktop.has_key('Exec'):
    execCmd = desktop['Exec']
    for cmd in parse_exec_key(execCmd, args):
      launch(cmd)

  else:
    die("%s does not contain an \"Exec\" field" % fpath)



if __name__ == "__main__":
    main()

Last edited by Xyne (2011-01-26 18:36:06)


My Arch Linux StuffForum EtiquetteCommunity Ethos - Arch is not for everyone

Offline

#6 2011-01-26 18:37:33

Gullible Jones
Member
Registered: 2004-12-29
Posts: 4,863

Re: How to launch applications via .desktop files?

Err... Thank you. Thank you very much. big_smile

Offline

Board footer

Powered by FluxBB