Skip to content

Commit 409fced

Browse files
committed
nemo-application: Fix FileManager1.ShowItems().
In commit c9cbba6, we had nemo-desktop start handling FileManager1, in order to ensure dbus-activations used the preferred file manager according to user mime-handler settings. Unfortunately, by when launching nemo to perform the desired action, we lost the file selection feature in ShowItems - nemo doesn't allow selecting a file from the commandline. Add that option (--select), and use it to select the file when one of a list of known-supported file managers is preferred. In the case of multiple filenames being passed, if they reside in the same location, a single window will spawn with all items selected. Otherwise, a new window will spawn for each unique parent location. Fixes #3776.
1 parent 9b16b30 commit 409fced

5 files changed

Lines changed: 246 additions & 36 deletions

File tree

src/nemo-application.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,18 @@ nemo_application_open_location (NemoApplication *application,
454454
open_in_tabs);
455455
}
456456

457+
void
458+
nemo_application_show_items (NemoApplication *application,
459+
GFile **uris,
460+
gint n_uris,
461+
const char *startup_id)
462+
{
463+
NEMO_APPLICATION_CLASS (G_OBJECT_GET_CLASS (application))->show_items (application,
464+
uris,
465+
n_uris,
466+
startup_id);
467+
}
468+
457469
NemoWindow *
458470
nemo_application_create_window (NemoApplication *application,
459471
GdkScreen *screen)

src/nemo-application.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ struct NemoApplicationClass {
6262
const char *startup_id,
6363
const gboolean open_in_tabs);
6464

65+
void (* show_items) (NemoApplication *application,
66+
GFile **uris,
67+
gint n_uris,
68+
const char *startup_id);
69+
6570
NemoWindow * (* create_window) (NemoApplication *application,
6671
GdkScreen *screen);
6772

@@ -88,6 +93,10 @@ void nemo_application_open_location (NemoApplication *application,
8893
GFile *selection,
8994
const char *startup_id,
9095
const gboolean open_in_tabs);
96+
void nemo_application_show_items (NemoApplication *application,
97+
GFile **uris,
98+
gint n_uris,
99+
const char *startup_id);
91100
void nemo_application_close_all_windows (NemoApplication *self);
92101

93102
void nemo_application_notify_unmount_show (NemoApplication *application,

src/nemo-desktop-application.c

Lines changed: 112 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -384,42 +384,137 @@ nemo_desktop_application_open (GApplication *app,
384384
/* FIXME: how to do this? */
385385
}
386386

387+
/* File managers known to accept --select with the same "open parent, select
388+
* URI" semantics as nemo. */
389+
static const gchar * const select_capable_handlers[] = {
390+
"nemo",
391+
"nautilus",
392+
"caja",
393+
"dolphin",
394+
NULL
395+
};
396+
397+
static gboolean
398+
handler_supports_select (const gchar *exe)
399+
{
400+
gchar *basename;
401+
gboolean found = FALSE;
402+
gint i;
403+
404+
if (exe == NULL) {
405+
return FALSE;
406+
}
407+
408+
basename = g_path_get_basename (exe);
409+
410+
for (i = 0; select_capable_handlers[i] != NULL; i++) {
411+
if (g_strcmp0 (basename, select_capable_handlers[i]) == 0) {
412+
found = TRUE;
413+
break;
414+
}
415+
}
416+
417+
g_free (basename);
418+
return found;
419+
}
420+
387421
static void
388422
nemo_desktop_application_open_location (NemoApplication *application,
389423
GFile *location,
390424
GFile *selection,
391425
const char *startup_id,
392426
const gboolean open_in_tabs)
427+
{
428+
/* Route through show_items so all "open with selection" paths share
429+
* the same launch logic. When there's no selection, fall back to
430+
* g_app_info_launch with the location so we don't lose plain-folder
431+
* opens (this path isn't currently exercised by the freedesktop dbus
432+
* handlers but is part of the open_location contract). */
433+
if (selection != NULL) {
434+
GFile *one = selection;
435+
nemo_application_show_items (application, &one, 1, startup_id);
436+
return;
437+
}
438+
439+
if (location != NULL) {
440+
GAppInfo *appinfo;
441+
GError *error = NULL;
442+
GList *uri_list;
443+
444+
appinfo = g_app_info_get_default_for_type ("inode/directory", TRUE);
445+
if (!appinfo) {
446+
g_warning ("Cannot launch file browser, no mimetype handler for inode/directory");
447+
return;
448+
}
449+
450+
uri_list = g_list_prepend (NULL, location);
451+
if (!g_app_info_launch (appinfo, uri_list, NULL, &error)) {
452+
gchar *uri = g_file_get_uri (location);
453+
g_warning ("Could not launch file browser to display file: %s", uri);
454+
g_free (uri);
455+
g_clear_error (&error);
456+
}
457+
458+
g_list_free (uri_list);
459+
g_clear_object (&appinfo);
460+
}
461+
}
462+
463+
static void
464+
nemo_desktop_application_show_items (NemoApplication *application,
465+
GFile **uris,
466+
gint n_uris,
467+
const char *startup_id)
393468
{
394469
GAppInfo *appinfo;
395470
GError *error = NULL;
396-
GList *sel_list = NULL;
471+
const gchar *exe;
472+
gint i;
397473

398-
appinfo = g_app_info_get_default_for_type ("inode/directory", TRUE);
474+
if (uris == NULL || n_uris == 0) {
475+
return;
476+
}
399477

478+
appinfo = g_app_info_get_default_for_type ("inode/directory", TRUE);
400479
if (!appinfo) {
401480
g_warning ("Cannot launch file browser, no mimetype handler for inode/directory");
402481
return;
403482
}
404483

405-
if (selection != NULL) {
406-
sel_list = g_list_prepend (sel_list, selection);
407-
} else if (location != NULL) {
408-
sel_list = g_list_prepend (sel_list, location);
409-
}
484+
exe = g_app_info_get_executable (appinfo);
410485

411-
if (!g_app_info_launch (appinfo, sel_list, NULL, &error)) {
412-
gchar *uri;
486+
if (handler_supports_select (exe)) {
487+
GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
413488

414-
uri = g_file_get_uri (selection);
415-
g_warning ("Could not launch file browser to display file: %s\n", uri);
489+
g_ptr_array_add (argv, g_strdup (exe));
490+
g_ptr_array_add (argv, g_strdup ("--select"));
491+
for (i = 0; i < n_uris; i++) {
492+
g_ptr_array_add (argv, g_file_get_uri (uris[i]));
493+
}
494+
g_ptr_array_add (argv, NULL);
416495

417-
g_free (uri);
418-
g_clear_error (&error);
419-
}
496+
if (!g_spawn_async (NULL, (gchar **) argv->pdata, NULL,
497+
G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) {
498+
g_warning ("Could not launch file browser %s: %s", exe,
499+
error ? error->message : "(unknown)");
500+
g_clear_error (&error);
501+
}
502+
503+
g_ptr_array_unref (argv);
504+
} else {
505+
GList *uri_list = NULL;
506+
507+
for (i = n_uris - 1; i >= 0; i--) {
508+
uri_list = g_list_prepend (uri_list, uris[i]);
509+
}
510+
511+
if (!g_app_info_launch (appinfo, uri_list, NULL, &error)) {
512+
g_warning ("Could not launch file browser: %s",
513+
error ? error->message : "(unknown)");
514+
g_clear_error (&error);
515+
}
420516

421-
if (sel_list != NULL) {
422-
g_list_free (sel_list);
517+
g_list_free (uri_list);
423518
}
424519

425520
g_clear_object (&appinfo);
@@ -451,6 +546,7 @@ nemo_desktop_application_class_init (NemoDesktopApplicationClass *class)
451546
nemo_app_class->create_window = nemo_desktop_application_create_window;
452547
nemo_app_class->continue_quit = nemo_desktop_application_continue_quit;
453548
nemo_app_class->open_location = nemo_desktop_application_open_location;
549+
nemo_app_class->show_items = nemo_desktop_application_show_items;
454550

455551
g_type_class_add_private (class, sizeof (NemoDesktopApplicationPriv));
456552
}

src/nemo-freedesktop-dbus.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,27 +59,23 @@ skeleton_handle_show_items_cb (NemoFreedesktopFileManager1 *object,
5959
const gchar *startup_id,
6060
gpointer data)
6161
{
62-
NemoApplication *application;
62+
NemoApplication *application;
63+
GPtrArray *files;
6364
int i;
6465

65-
application = NEMO_APPLICATION (g_application_get_default ());
66+
application = NEMO_APPLICATION (g_application_get_default ());
6667

68+
files = g_ptr_array_new_with_free_func (g_object_unref);
6769
for (i = 0; uris[i] != NULL; i++) {
68-
GFile *file;
69-
GFile *parent;
70-
71-
file = g_file_new_for_uri (uris[i]);
72-
parent = g_file_get_parent (file);
70+
g_ptr_array_add (files, g_file_new_for_uri (uris[i]));
71+
}
7372

74-
if (parent != NULL) {
75-
nemo_application_open_location (application, parent, file, startup_id, FALSE);
76-
g_object_unref (parent);
77-
} else {
78-
nemo_application_open_location (application, file, NULL, startup_id, FALSE);
79-
}
73+
nemo_application_show_items (application,
74+
(GFile **) files->pdata,
75+
files->len,
76+
startup_id);
8077

81-
g_object_unref (file);
82-
}
78+
g_ptr_array_unref (files);
8379

8480
nemo_freedesktop_file_manager1_complete_show_items (object, invocation);
8581
return TRUE;

0 commit comments

Comments
 (0)