]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-application.c
[dualscreen] fix crash on ctrl+w and fix control window closing
[evince.git] / shell / ev-application.c
index 91555b9708d8c8392006acd62cbc68658300b115..600880a1e6ad86dd2d8eff036493fcfcc07505da 100644 (file)
@@ -221,17 +221,6 @@ ev_display_open_if_needed (const gchar *name)
        return display != NULL ? display : gdk_display_open (name);
 }
 
-static void
-child_setup (gpointer user_data)
-{
-       gchar *startup_id;
-
-       startup_id = g_strdup_printf ("_TIME%lu",
-                                     (unsigned long)GPOINTER_TO_INT (user_data));
-       g_setenv ("DESKTOP_STARTUP_ID", startup_id, TRUE);
-       g_free (startup_id);
-}
-
 static void
 ev_spawn (const char     *uri,
          GdkScreen      *screen,
@@ -240,69 +229,91 @@ ev_spawn (const char     *uri,
          const gchar    *search_string,
          guint           timestamp)
 {
-       gchar   *argv[6];
-       guint    arg = 0;
-       gint     i;
-       gboolean res;
+       GString *cmd;
+       gchar *path, *cmdline;
+       GAppInfo *app;
+       GdkAppLaunchContext *ctx;
        GError  *error = NULL;
 
+       cmd = g_string_new (NULL);
+
 #ifdef G_OS_WIN32
 {
        gchar *dir;
 
        dir = g_win32_get_package_installation_directory_of_module (NULL);
-       argv[arg++] = g_build_filename (dir, "bin", "evince", NULL);
+       path = g_build_filename (dir, "bin", "evince", NULL);
+
        g_free (dir);
 }
 #else
-       argv[arg++] = g_build_filename (BINDIR, "evince", NULL);
+       path = g_build_filename (BINDIR, "evince", NULL);
 #endif
 
+       g_string_append_printf (cmd, " %s", path);
+       g_free (path);
+       
        /* Page label */
        if (dest) {
                const gchar *page_label;
 
                page_label = ev_link_dest_get_page_label (dest);
+
                if (page_label)
-                       argv[arg++] = g_strdup_printf ("--page-label=%s", page_label);
+                       g_string_append_printf (cmd, " --page-label=%s", page_label);
                else
-                       argv[arg++] = g_strdup_printf ("--page-label=%d",
-                                                      ev_link_dest_get_page (dest));
+                       g_string_append_printf (cmd, " --page-label=%d",
+                                               ev_link_dest_get_page (dest));
        }
 
        /* Find string */
        if (search_string) {
-               argv[arg++] = g_strdup_printf ("--find=%s", search_string);
+               g_string_append_printf (cmd, " --find=%s", search_string);
        }
 
        /* Mode */
        switch (mode) {
        case EV_WINDOW_MODE_FULLSCREEN:
-               argv[arg++] = g_strdup ("-f");
+               g_string_append (cmd, " -f");
                break;
        case EV_WINDOW_MODE_PRESENTATION:
-               argv[arg++] = g_strdup ("-s");
+               g_string_append (cmd, " -s");
                break;
        default:
                break;
        }
 
-       argv[arg++] = (gchar *)uri;
-       argv[arg] = NULL;
+       cmdline = g_string_free (cmd, FALSE);
+       app = g_app_info_create_from_commandline (cmdline, NULL, 0, &error);
+
+       if (app != NULL) {
+                GList uri_list;
+
+               ctx = gdk_display_get_app_launch_context (gdk_screen_get_display (screen));
+               gdk_app_launch_context_set_screen (ctx, screen);
+               gdk_app_launch_context_set_timestamp (ctx, timestamp);
+
+                /* Some URIs can be changed when passed through a GFile
+                 * (for instance unsupported uris with strange formats like mailto:),
+                 * so if you have a textual uri you want to pass in as argument,
+                 * consider using g_app_info_launch_uris() instead.
+                 * See https://bugzilla.gnome.org/show_bug.cgi?id=644604
+                 */
+                uri_list.data = (gchar *)uri;
+                uri_list.prev = uri_list.next = NULL;
+               g_app_info_launch_uris (app, &uri_list,
+                                        G_APP_LAUNCH_CONTEXT (ctx), &error);
+
+               g_object_unref (app);
+               g_object_unref (ctx);
+       }
 
-       res = gdk_spawn_on_screen (screen, NULL /* wd */, argv, NULL /* env */,
-                                  0,
-                                  child_setup,
-                                  GINT_TO_POINTER(timestamp),
-                                  NULL, &error);
-       if (!res) {
+       if (error != NULL) {
                g_warning ("Error launching evince %s: %s\n", uri, error->message);
                g_error_free (error);
        }
 
-       for (i = 0; i < arg - 1; i++) {
-               g_free (argv[i]);
-       }
+       g_free (cmdline);
 }
 
 static GList *
@@ -389,6 +400,10 @@ on_reload_cb (GObject      *source_object,
        }
        g_variant_unref (value);
 
+       /* We did not open a window, so manually clear the startup
+        * notification. */
+       gdk_notify_startup_complete ();
+
        ev_application_shutdown (EV_APP);
 }
 
@@ -454,9 +469,17 @@ on_register_uri_cb (GObject      *source_object,
                                "screen",
                                g_variant_new_int32 (gdk_screen_get_number (data->screen)));
        if (data->dest) {
-                g_variant_builder_add (&builder, "{sv}",
-                                       "page-label",
-                                       g_variant_new_string (ev_link_dest_get_page_label (data->dest)));
+                const gchar *page_label = ev_link_dest_get_page_label (data->dest);
+
+                if (page_label) {
+                        g_variant_builder_add (&builder, "{sv}",
+                                               "page-label",
+                                               g_variant_new_string (page_label));
+                } else {
+                        g_variant_builder_add (&builder, "{sv}",
+                                               "page-index",
+                                               g_variant_new_uint32 (ev_link_dest_get_page (data->dest)));
+                }
        }
        if (data->search_string) {
                 g_variant_builder_add (&builder, "{sv}",
@@ -755,12 +778,14 @@ method_call_cb (GDBusConnection       *connection,
                while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
                        if (strcmp (key, "display") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
                                display = ev_display_open_if_needed (g_variant_get_string (value, NULL));
-                       } else if (strcmp (key, "screen") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
+                       } else if (strcmp (key, "screen") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_INT32) {
                                screen_number = g_variant_get_int32 (value);
                        } else if (strcmp (key, "mode") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
-                       mode = g_variant_get_uint32 (value);
+                                mode = g_variant_get_uint32 (value);
                        } else if (strcmp (key, "page-label") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
                                dest = ev_link_dest_new_page_label (g_variant_get_string (value, NULL));
+                        } else if (strcmp (key, "page-index") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
+                                dest = ev_link_dest_new_page (g_variant_get_uint32 (value));
                        } else if (strcmp (key, "find-string") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
                                search_string = g_variant_get_string (value, NULL);
                        }