Exemple #1
0
static void menu_item_activate(GtkMenuItem *menuitem, gpointer user_data) 
{
    GAppInfo *app = (GAppInfo *)user_data;

    if (app)
        g_spawn_command_line_async(g_app_info_get_commandline(app), NULL);
}
Exemple #2
0
static MxAction *
_action_new_from_desktop_file (const gchar *desktop_file_id)
{
  GDesktopAppInfo *dai;

  dai = g_desktop_app_info_new (desktop_file_id);

  if (dai)
    {
      MxAction *action;
      GAppInfo *ai;
      GIcon *icon;

      ai = G_APP_INFO (dai);

      action = mx_action_new_full (g_app_info_get_name (ai),
                                   g_app_info_get_display_name (ai),
                                   G_CALLBACK (_app_launcher_cb),
                                   (gpointer)g_app_info_get_commandline (ai));

     icon = g_app_info_get_icon (ai);
     if (icon)
       {
         gchar *icon_name;
         icon_name =  g_icon_to_string (icon);

         mx_action_set_icon (action, icon_name);

         g_free (icon_name);
       }

      return action;
    }
  return NULL;
}
Exemple #3
0
GAppInfo *
problem_create_app_from_cmdline (const char *cmdline)
{
    GAppInfo *app;
    GList *apps, *l;
    GList *shortlist;
    char *binary;
    char **cmdargs;

    binary = problem_get_argv0(cmdline);

    apps = g_app_info_get_all ();
    shortlist = NULL;
    app = NULL;
    for (l = apps; l != NULL; l = l->next)
    {
        GAppInfo *a = l->data;

        if (!g_app_info_should_show(a))
            continue;

        if (!compare_binaries (binary, g_app_info_get_executable (a)))
            continue;

        shortlist = g_list_prepend (shortlist, a);
    }

    if (shortlist == NULL)
    {
        g_list_free_full (apps, g_object_unref);
        return NULL;
    }

    cmdargs = g_strsplit (cmdline, " ", -1);
    remove_quotes (cmdargs);

    for (l = shortlist; l != NULL; l = l->next)
    {
        GAppInfo *a = l->data;
        char **dcmdargs;

        const char *commandline = g_app_info_get_commandline (a);
        if (commandline == NULL)
            continue;

        dcmdargs = g_strsplit (commandline, " ", -1);
        remove_quotes (dcmdargs);

        if (compare_args (cmdargs, dcmdargs))
            app = g_object_ref (a);

        g_strfreev (dcmdargs);
        if (app != NULL)
            break;
    }

    g_list_free (shortlist);
    g_list_free_full (apps, g_object_unref);
    return app;
}
static void
_settings_launcher_button_clicked_cb (MxButton *button,
                                      gpointer  userdata)
{
  MnbPeoplePanelPrivate *priv = GET_PRIVATE (userdata);
  GDesktopAppInfo *app_info;
  GError *error = NULL;
  const gchar *args[2] = { NULL, };

  app_info = g_desktop_app_info_new ("empathy-accounts.desktop");
  args[0] = g_app_info_get_commandline (G_APP_INFO (app_info));
  args[1] = NULL;

  if (!g_spawn_async (NULL,
                      (gchar **)args,
                      NULL,
                      G_SPAWN_SEARCH_PATH,
                      NULL,
                      NULL,
                      NULL,
                      &error))
  {
    g_warning (G_STRLOC ": Error starting empathy-accounts: %s",
               error->message);
    g_clear_error (&error);
  } else {
    if (priv->panel_client)
      mpl_panel_client_hide (priv->panel_client);
  }

  g_object_unref (app_info);
}
Exemple #5
0
QString App_info::command() const {
  if (!object) {
    qWarning("unitialized App_info used");
    return QString();
  }
  const char* b = g_app_info_get_commandline(object);
  return QString::fromLocal8Bit(b);
}
Exemple #6
0
EphyWebApplication *
ephy_web_application_for_profile_directory (const char *profile_dir)
{
  EphyWebApplication *app;
  char *desktop_file_path;
  const char *id;
  GDesktopAppInfo *desktop_info;
  const char *exec;
  int argc;
  char **argv;
  GFile *file;
  GFileInfo *file_info;
  guint64 created;
  GDate *date;

  id = get_app_id_from_profile_directory (profile_dir);
  if (!id)
    return NULL;

  app = g_new0 (EphyWebApplication, 1);
  app->id = g_strdup (id);

  app->desktop_file = get_app_desktop_filename (id);
  desktop_file_path = g_build_filename (profile_dir, app->desktop_file, NULL);
  desktop_info = g_desktop_app_info_new_from_filename (desktop_file_path);
  if (!desktop_info) {
    ephy_web_application_free (app);
    g_free (desktop_file_path);
    return NULL;
  }

  app->name = g_strdup (g_app_info_get_name (G_APP_INFO (desktop_info)));
  app->icon_url = g_desktop_app_info_get_string (desktop_info, "Icon");
  exec = g_app_info_get_commandline (G_APP_INFO (desktop_info));
  if (g_shell_parse_argv (exec, &argc, &argv, NULL)) {
    app->url = g_strdup (argv[argc - 1]);
    g_strfreev (argv);
  }

  g_object_unref (desktop_info);

  file = g_file_new_for_path (desktop_file_path);

  /* FIXME: this should use TIME_CREATED but it does not seem to be working. */
  file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_MODIFIED, 0, NULL, NULL);
  created = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);

  date = g_date_new ();
  g_date_set_time_t (date, (time_t)created);
  g_date_strftime (app->install_date, 127, "%x", date);

  g_date_free (date);
  g_object_unref (file);
  g_object_unref (file_info);
  g_free (desktop_file_path);

  return app;
}
NS_IMETHODIMP
nsGIOMimeApp::GetCommand(nsACString& aCommand)
{
  const char *cmd = g_app_info_get_commandline(mApp);
  if (!cmd)
    return NS_ERROR_FAILURE;
  aCommand.Assign(cmd);
  return NS_OK;
}
Exemple #8
0
static gboolean
init_mailer (NautilusSendto *nst)
{
	GAppInfo *app_info;
	char *needle;

	nst->type = MAILER_UNKNOWN;

	app_info = g_app_info_get_default_for_uri_scheme ("mailto");
	if (app_info) {
		nst->mail_cmd = g_strdup (g_app_info_get_commandline (app_info));
		g_object_unref (app_info);
	} else {
		nst->mail_cmd = NULL;
	}

	if (nst->mail_cmd == NULL || *nst->mail_cmd == '\0') {
		g_free (nst->mail_cmd);
		nst->mail_cmd = get_evo_cmd ();
		nst->type = MAILER_EVO;
	} else {
		/* Find what the default mailer is */
		if (strstr (nst->mail_cmd, "balsa"))
			nst->type = MAILER_BALSA;
		else if (strstr (nst->mail_cmd, "thunder") || strstr (nst->mail_cmd, "seamonkey") || strstr (nst->mail_cmd, "icedove")) {
			char **strv;

			nst->type = MAILER_THUNDERBIRD;

			/* Thunderbird sucks, see
			 * https://bugzilla.gnome.org/show_bug.cgi?id=614222 */
			strv = g_strsplit (nst->mail_cmd, " ", -1);
			g_free (nst->mail_cmd);
			nst->mail_cmd = g_strdup_printf ("%s %%s", strv[0]);
			g_strfreev (strv);
		} else if (strstr (nst->mail_cmd, "sylpheed") || strstr (nst->mail_cmd, "claws"))
			nst->type = MAILER_SYLPHEED;
		else if (strstr (nst->mail_cmd, "anjal"))
			nst->type = MAILER_EVO;
	}

	if (nst->mail_cmd == NULL)
		return FALSE;

	/* Replace %U by %s */
	while ((needle = g_strrstr (nst->mail_cmd, "%U")) != NULL)
		needle[1] = 's';
	while ((needle = g_strrstr (nst->mail_cmd, "%u")) != NULL)
		needle[1] = 's';

	return TRUE;
}
Exemple #9
0
gboolean
empathy_launch_external_app (const gchar *desktop_file,
    const gchar *args,
    GError **error)
{
  GDesktopAppInfo *desktop_info;
  gboolean result;
  GError *err = NULL;

  desktop_info = g_desktop_app_info_new (desktop_file);
  if (desktop_info == NULL)
    {
      DEBUG ("%s not found", desktop_file);

      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
          "%s not found", desktop_file);
      return FALSE;
    }

  if (args == NULL)
    {
      result = launch_app_info (G_APP_INFO (desktop_info), error);
    }
  else
    {
      gchar *cmd;
      GAppInfo *app_info;

      /* glib doesn't have API to start a desktop file with args... (#637875) */
      cmd = g_strdup_printf ("%s %s", g_app_info_get_commandline (
            (GAppInfo *) desktop_info), args);

      app_info = g_app_info_create_from_commandline (cmd, NULL, 0, &err);
      if (app_info == NULL)
        {
          DEBUG ("Failed to launch '%s': %s", cmd, err->message);
          g_free (cmd);
          g_object_unref (desktop_info);
          g_propagate_error (error, err);
          return FALSE;
        }

      result = launch_app_info (app_info, error);

      g_object_unref (app_info);
      g_free (cmd);
    }

  g_object_unref (desktop_info);
  return result;
}
static void
_launch_app (OlPlayerChooser *window,
             GAppInfo *app_info)
{
  GError *err = NULL;
  if (!g_app_info_launch (app_info, NULL, NULL, &err))
  {
    ol_errorf ("Cannot launch %s: %s",
               g_app_info_get_commandline (app_info),
               err->message);
    gchar *title = g_strdup_printf (_("Failed to launch %s"),
                                    g_app_info_get_name (app_info));
    ol_player_chooser_set_info (window, title, err->message);
    ol_player_chooser_set_image_by_name (window, GTK_STOCK_DIALOG_ERROR);
    g_free (title);
    g_error_free (err);
  }
  else
  {
    _set_launch_app (window, app_info);
    gchar *title = g_strdup_printf (_("Launching %s"),
                                    g_app_info_get_name (app_info));
    gchar *desc = g_strdup_printf (_("OSD Lyrics is trying to launch and connect to %s. Please wait for a second."),
                                   g_app_info_get_name (app_info));
    ol_player_chooser_set_info (window, title, desc);
    g_free (title);
    g_free (desc);
    ol_player_chooser_set_image_by_gicon (window, g_app_info_get_icon (app_info));
    _set_sensitive (window, FALSE);
    if (OL_IS_PLAYER_CHOOSER (window))
    {
      _remember_cmd_if_needed (window, g_app_info_get_commandline (app_info));
      gtk_dialog_response (GTK_DIALOG (window), OL_PLAYER_CHOOSER_RESPONSE_LAUNCH);
    }
  }
}
static void on_browse_btn_clicked(GtkButton* btn, AppChooserData* data)
{
    FmPath* file;
    GtkFileFilter* filter = gtk_file_filter_new();
    char* binary;
    gtk_file_filter_add_custom(filter,
        GTK_FILE_FILTER_FILENAME|GTK_FILE_FILTER_MIME_TYPE, exec_filter_func, NULL, NULL);
    /* gtk_file_filter_set_name(filter, _("Executable files")); */
    file = fm_select_file(GTK_WINDOW(data->dlg), NULL, "/usr/bin", TRUE, FALSE, filter, NULL);

    if (file == NULL)
        return;
    binary = fm_path_to_str(file);
    if (g_str_has_suffix(fm_path_get_basename(file), ".desktop"))
    {
        GKeyFile *kf = g_key_file_new();
        GDesktopAppInfo *info;
        if (g_key_file_load_from_file(kf, binary, 0, NULL) &&
            (info = g_desktop_app_info_new_from_keyfile(kf)) != NULL)
            /* it is a valid desktop entry */
        {
            /* FIXME: it will duplicate the file, how to avoid that? */
            gtk_entry_set_text(data->cmdline,
                               g_app_info_get_commandline(G_APP_INFO(info)));
            gtk_entry_set_text(data->app_name,
                               g_app_info_get_name(G_APP_INFO(info)));
            gtk_toggle_button_set_active(data->use_terminal,
                                         g_key_file_get_boolean(kf, G_KEY_FILE_DESKTOP_GROUP,
                                                                G_KEY_FILE_DESKTOP_KEY_TERMINAL,
                                                                NULL));
            gtk_toggle_button_set_active(data->keep_open,
                                         g_key_file_get_boolean(kf, G_KEY_FILE_DESKTOP_GROUP,
                                                                "X-KeepTerminal",
                                                                NULL));
            g_object_unref(info);
            g_key_file_free(kf);
            fm_path_unref(file);
            return;
        }
        g_key_file_free(kf);
    }
    gtk_entry_set_text(data->cmdline, binary);
    g_free(binary);
    fm_path_unref(file);
}
Exemple #12
0
void
nautilus_recent_add_file (NautilusFile *file,
			  GAppInfo *application)
{
	GtkRecentData recent_data;
	char *uri;

	uri = nautilus_file_get_activation_uri (file);
	if (uri == NULL) {
		uri = nautilus_file_get_uri (file);
	}

	/* do not add trash:// etc */
	if (eel_uri_is_trash (uri)  ||
	    eel_uri_is_search (uri) ||
	    eel_uri_is_recent (uri) ||
	    eel_uri_is_desktop (uri)) {
		g_free (uri);
		return;
	}

	recent_data.display_name = NULL;
	recent_data.description = NULL;

	recent_data.mime_type = nautilus_file_get_mime_type (file);
	recent_data.app_name = g_strdup (g_get_application_name ());

	if (application != NULL)
		recent_data.app_exec = g_strdup (g_app_info_get_commandline (application));
	else
		recent_data.app_exec = g_strdup (DEFAULT_APP_EXEC);

	recent_data.groups = NULL;
	recent_data.is_private = FALSE;

	gtk_recent_manager_add_full (nautilus_recent_get_manager (),
				     uri, &recent_data);

	g_free (recent_data.mime_type);
	g_free (recent_data.app_name);
	g_free (recent_data.app_exec);
	
	g_free (uri);
}
static void
new_index_changed_cb (MxComboBox     *combo,
                      GParamSpec     *pspec,
                      MnbPeoplePanel *self)
{
  MnbPeoplePanelPrivate *priv = GET_PRIVATE (self);
  gint index = mx_combo_box_get_index (combo);
  GDesktopAppInfo *app_info;
  GError *error = NULL;
  const gchar *args[4] = { NULL, };
  const gchar *option;

  if (index == 0)
    option = "--new-contact";
  else if (index == 1)
    option = "--join-chatroom";
  else
    return;

  app_info = g_desktop_app_info_new ("empathy.desktop");
  args[0] = g_app_info_get_commandline (G_APP_INFO (app_info));
  args[1] = "--start-hidden";
  args[2] = option;
  args[3] = NULL;

  if (!g_spawn_async (NULL,
                      (gchar **)args,
                      NULL,
                      G_SPAWN_SEARCH_PATH,
                      NULL,
                      NULL,
                      NULL,
                      &error))
  {
    g_warning (G_STRLOC ": Error starting empathy: %s", error->message);
    g_clear_error (&error);
  } else
  {
    if (priv->panel_client)
      mpl_panel_client_hide (priv->panel_client);
  }

  g_object_unref (app_info);
}
Exemple #14
0
gboolean
dawati_netbook_launch_application_from_desktop_file (const  gchar *desktop,
                                                     GList        *files,
                                                     gint          workspace,
                                                     gboolean      no_chooser)
{
  GAppInfo *app;
  GAppLaunchContext *ctx;
  GError *error = NULL;
  gboolean retval = TRUE;

  g_return_val_if_fail (desktop, FALSE);

  app = G_APP_INFO (g_desktop_app_info_new_from_filename (desktop));

  if (!app)
    {
      g_warning ("Failed to create GAppInfo for file %s", desktop);
      return FALSE;
    }

  ctx = G_APP_LAUNCH_CONTEXT (gdk_app_launch_context_new ());

  retval = g_app_info_launch (app, files, ctx, &error);

  if (error)
    {
      g_warning ("Failed to lauch %s (%s)",
#if GLIB_CHECK_VERSION(2,20,0)
                 g_app_info_get_commandline (app),
#else
                 g_app_info_get_name (app),
#endif
                 error->message);

      g_error_free (error);
    }

  g_object_unref (ctx);
  g_object_unref (app);

  return retval;
}
Exemple #15
0
/**
 * Open default file manager via mime type
 * Some file managers custom the directory by user
 **/
int
main(int argc, char *argv[])
{
    GAppInfo *app_info = g_app_info_get_default_for_type(FILE_MANAGER_MIME_TYPE, FALSE);
    if (!app_info) {
        g_error("Failed to get default app for %s", FILE_MANAGER_MIME_TYPE);
        return -1;
    }
    g_debug("Executable: %s\n", g_app_info_get_executable(app_info));
    g_debug("Commandline: %s\n", g_app_info_get_commandline(app_info));

    GError *error = NULL;
    gboolean ret = g_app_info_launch(app_info, NULL, NULL, &error);
    if (error) {
        g_error("Failed to launch %s, error: %s", g_app_info_get_name(app_info), error->message);
        g_error_free(error);
        goto EXIT;
    }

EXIT:
    g_object_unref(app_info);
    return ret?0:-1;
}
Exemple #16
0
/**
 * fm_app_chooser_dlg_dup_selected_app
 * @dlg: a widget
 * @set_default: location to get value that was used for fm_app_chooser_dlg_new()
 *
 * Retrieves a currently selected application from @dlg.
 *
 * Before 1.0.0 this call had name fm_app_chooser_dlg_get_selected_app.
 *
 * Returns: (transfer full): selected application.
 *
 * Since: 0.1.0
 */
GAppInfo* fm_app_chooser_dlg_dup_selected_app(GtkDialog* dlg, gboolean* set_default)
{
    GAppInfo* app = NULL;
    AppChooserData* data = (AppChooserData*)g_object_get_qdata(G_OBJECT(dlg), fm_qdata_id);
    switch( gtk_notebook_get_current_page(data->notebook) )
    {
    case 0: /* all applications */
        app = fm_app_menu_view_dup_selected_app(data->apps_view);
        break;
    case 1: /* custom cmd line */
        {
            const char* cmdline = gtk_entry_get_text(data->cmdline);
            const char* app_name = gtk_entry_get_text(data->app_name);
            if(cmdline && cmdline[0])
            {
                char* _cmdline = NULL;
                gboolean arg_found = FALSE;
                char* bin1 = get_binary(cmdline, &arg_found);
                g_debug("bin1 = %s", bin1);
                /* see if command line contains %f, %F, %u, or %U. */
                if(!arg_found)  /* append %f if no %f, %F, %u, or %U was found. */
                    cmdline = _cmdline = g_strconcat(cmdline, " %f", NULL);

                /* FIXME: is there any better way to do this? */
                /* We need to ensure that no duplicated items are added */
                if(data->mime_type)
                {
                    MenuCache* menu_cache;
                    /* see if the command is already in the list of known apps for this mime-type */
                    GList* apps = g_app_info_get_all_for_type(fm_mime_type_get_type(data->mime_type));
                    GList* l;
                    for(l=apps;l;l=l->next)
                    {
                        GAppInfo* app2 = G_APP_INFO(l->data);
                        const char* cmd = g_app_info_get_commandline(app2);
                        char* bin2 = get_binary(cmd, NULL);
                        if(g_strcmp0(bin1, bin2) == 0)
                        {
                            app = G_APP_INFO(g_object_ref(app2));
                            g_debug("found in app list");
                            g_free(bin2);
                            break;
                        }
                        g_free(bin2);
                    }
                    g_list_foreach(apps, (GFunc)g_object_unref, NULL);
                    g_list_free(apps);
                    if(app)
                        goto _out;

                    /* see if this command can be found in menu cache */
                    menu_cache = menu_cache_lookup("applications.menu");
                    if(menu_cache)
                    {
#if MENU_CACHE_CHECK_VERSION(0, 4, 0)
                        MenuCacheDir *root_dir = menu_cache_dup_root_dir(menu_cache);
                        if(root_dir)
#else
                        if(menu_cache_get_root_dir(menu_cache))
#endif
                        {
                            GSList* all_apps = menu_cache_list_all_apps(menu_cache);
                            GSList* l;
                            for(l=all_apps;l;l=l->next)
                            {
                                MenuCacheApp* ma = MENU_CACHE_APP(l->data);
                                const char *exec = menu_cache_app_get_exec(ma);
                                char* bin2;
                                if (exec == NULL)
                                {
                                    g_warning("application %s has no Exec statement", menu_cache_item_get_id(MENU_CACHE_ITEM(ma)));
                                    continue;
                                }
                                bin2 = get_binary(exec, NULL);
                                if(g_strcmp0(bin1, bin2) == 0)
                                {
                                    app = G_APP_INFO(g_desktop_app_info_new(menu_cache_item_get_id(MENU_CACHE_ITEM(ma))));
                                    g_debug("found in menu cache");
                                    menu_cache_item_unref(MENU_CACHE_ITEM(ma));
                                    g_free(bin2);
                                    break;
                                }
                                menu_cache_item_unref(MENU_CACHE_ITEM(ma));
                                g_free(bin2);
                            }
                            g_slist_free(all_apps);
#if MENU_CACHE_CHECK_VERSION(0, 4, 0)
                            menu_cache_item_unref(MENU_CACHE_ITEM(root_dir));
#endif
                        }
                        menu_cache_unref(menu_cache);
                    }
                    if(app)
                        goto _out;
                }

                /* FIXME: g_app_info_create_from_commandline force the use of %f or %u, so this is not we need */
                app = app_info_create_from_commandline(cmdline,
                            app_name ? app_name : "", bin1,
                            data->mime_type ? fm_mime_type_get_type(data->mime_type) : NULL,
                            gtk_toggle_button_get_active(data->use_terminal),
                            data->keep_open && gtk_toggle_button_get_active(data->keep_open));
            _out:
                g_free(bin1);
                g_free(_cmdline);
            }
        }
        break;
    }

    if(set_default)
        *set_default = gtk_toggle_button_get_active(data->set_default);
    return app;
}
static void
create_custom_desktop_file (NemoMimeApplicationChooser *chooser, gboolean def)
{
    GKeyFile *keyfile = g_key_file_new ();

    g_key_file_set_string (keyfile,
                           G_KEY_FILE_DESKTOP_GROUP,
                           G_KEY_FILE_DESKTOP_KEY_EXEC,
                           g_app_info_get_commandline (chooser->details->custom_info));

    g_key_file_set_string (keyfile,
                           G_KEY_FILE_DESKTOP_GROUP,
                           G_KEY_FILE_DESKTOP_KEY_NAME,
                           g_app_info_get_display_name (chooser->details->custom_info));

    g_key_file_set_string (keyfile,
                           G_KEY_FILE_DESKTOP_GROUP,
                           G_KEY_FILE_DESKTOP_KEY_MIME_TYPE,
                           chooser->details->content_type);

    g_key_file_set_string (keyfile,
                           G_KEY_FILE_DESKTOP_GROUP,
                           G_KEY_FILE_DESKTOP_KEY_TYPE,
                           G_KEY_FILE_DESKTOP_TYPE_APPLICATION);

    gsize size;
    gchar *buffer = g_key_file_to_data (keyfile, &size, NULL);

    gint32 rn = g_random_int_range (0, G_MAXINT32 - 1);
    gchar *fn = g_strdup_printf ("nemo_%s_%d.desktop",
                                 g_app_info_get_display_name (chooser->details->custom_info),
                                 rn);

    gchar *path = g_build_filename (g_get_user_data_dir (), "applications", fn, NULL);

    GFile *outfile = g_file_new_for_path (path);

    g_free (path);

    GFileOutputStream *out;
    gboolean res;

    out = g_file_create (outfile,
                         G_FILE_CREATE_NONE,
                         NULL,
                         NULL);
    if (out) {
        res = g_output_stream_write_all (G_OUTPUT_STREAM (out),
                                         buffer, size,
                                         NULL,
                                         NULL,
                                         NULL);
        if (res) {
            res = g_output_stream_close (G_OUTPUT_STREAM (out),
                                         NULL,
                                         NULL);
            update_mimelist (chooser, fn, def);
        }
        g_object_unref (out);
    }

    g_object_unref (outfile);
    g_free (fn);
    g_free (buffer);
}
Exemple #18
0
static VALUE
appinfo_get_commandline(VALUE self)
{
        return CSTR2RVAL(g_app_info_get_commandline(_SELF(self)));
}
Exemple #19
0
static char* expand_exec_macros(GAppInfo* app, const char* full_desktop_path, GKeyFile* kf, GList* gfiles)
{
    GString* cmd;
    const char* exec = g_app_info_get_commandline(app);
    const char* p;
    gboolean files_added = FALSE;

    cmd = g_string_sized_new(1024);
    for(p = exec; *p; ++p)
    {
        if(*p == '%')
        {
            ++p;
            if(!*p)
                break;
            switch(*p)
            {
            case 'f':
                if(gfiles)
                    append_file_to_cmd(G_FILE(gfiles->data), cmd);
                files_added = TRUE;
                break;
            case 'F':
                g_list_foreach(gfiles, (GFunc)append_file_to_cmd, cmd);
                files_added = TRUE;
                break;
            case 'u':
                if(gfiles)
                    append_uri_to_cmd(G_FILE(gfiles->data), cmd);
                files_added = TRUE;
                break;
            case 'U':
                g_list_foreach(gfiles, (GFunc)append_uri_to_cmd, cmd);
                files_added = TRUE;
                break;
            case '%':
                g_string_append_c(cmd, '%');
                break;
            case 'i':
                {
                    char* icon_name = g_key_file_get_locale_string(kf, "Desktop Entry",
                                                                   "Icon", NULL, NULL);
                    if(icon_name)
                    {
                        g_string_append(cmd, "--icon ");
                        g_string_append(cmd, icon_name);
                        g_free(icon_name);
                    }
                    break;
                }
            case 'c':
                {
                    const char* name = g_app_info_get_name(app);
                    if(name)
                        g_string_append(cmd, name);
                    break;
                }
            case 'k':
                /* append the file path of the desktop file */
                if(full_desktop_path)
                {
                    /* FIXME: how about quoting here? */
                    char* desktop_location = g_path_get_dirname(full_desktop_path);
                    g_string_append(cmd, desktop_location);
                    g_free(desktop_location);
                }
                break;
            }
        }
        else
            g_string_append_c(cmd, *p);
    }

    /* if files are provided but the Exec key doesn't contain %f, %F, %u, or %U */
    if(gfiles && !files_added)
    {
        /* treat as %f */
        g_string_append_c(cmd, ' ');
        append_file_to_cmd(G_FILE(gfiles->data), cmd);
    }

    return g_string_free(cmd, FALSE);
}