Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 85337 | Differences between
and this patch

Collapse All | Expand All

(-)configure.ac (+12 lines)
Lines 52-57 Link Here
52
LIBGNOMEVFS_REQUIRED=2.9.2
52
LIBGNOMEVFS_REQUIRED=2.9.2
53
LIBGNOMEUI_REQUIRED=2.6.0
53
LIBGNOMEUI_REQUIRED=2.6.0
54
GNOME_DESKTOP_REQUIRED=2.9.91
54
GNOME_DESKTOP_REQUIRED=2.9.91
55
LIBSTARTUP_NOTIFICATION_REQUIRED=0.5
55
56
56
AC_ENABLE_SHARED([yes])
57
AC_ENABLE_SHARED([yes])
57
AC_ENABLE_STATIC([no])
58
AC_ENABLE_STATIC([no])
Lines 71-76 Link Here
71
GNOME_COMPILE_WARNINGS([maximum])
72
GNOME_COMPILE_WARNINGS([maximum])
72
dnl GNOME_CXX_WARNINGS
73
dnl GNOME_CXX_WARNINGS
73
74
75
AC_PATH_PROG([PKG_CONFIG], [pkg-config], [no])
76
if $PKG_CONFIG --atleast-version $LIBSTARTUP_NOTIFICATION_REQUIRED libstartup-notification-1.0; then
77
	echo "Building with libstartup-notification"
78
	AC_DEFINE([HAVE_STARTUP_NOTIFICATION],[1],[Define to enable startup notification support])
79
	STARTUP_NOTIFICATION_PACKAGE=libstartup-notification-1.0
80
else
81
	echo "***** WARNING: Building without libstartup-notification"
82
	STARTUP_NOTIFICATION_PACKAGE=
83
fi
84
74
PKG_CHECK_MODULES([EPIPHANY_DEPENDENCY], [\
85
PKG_CHECK_MODULES([EPIPHANY_DEPENDENCY], [\
75
		  glib-2.0 >= $GLIB_REQUIRED \
86
		  glib-2.0 >= $GLIB_REQUIRED \
76
		  pango >= $PANGO_REQUIRED \
87
		  pango >= $PANGO_REQUIRED \
Lines 86-91 Link Here
86
		  gnome-vfs-module-2.0 \
97
		  gnome-vfs-module-2.0 \
87
		  gconf-2.0 \
98
		  gconf-2.0 \
88
		  gnome-desktop-2.0 >= $GNOME_DESKTOP_REQUIRED \
99
		  gnome-desktop-2.0 >= $GNOME_DESKTOP_REQUIRED \
100
		  $STARTUP_NOTIFICATION_PACKAGE \
89
		  ])
101
		  ])
90
AC_SUBST([EPIPHANY_DEPENDENCY_CFLAGS])
102
AC_SUBST([EPIPHANY_DEPENDENCY_CFLAGS])
91
AC_SUBST([EPIPHANY_DEPENDENCY_LIBS])
103
AC_SUBST([EPIPHANY_DEPENDENCY_LIBS])
(-)lib/ephy-file-helpers.c (-31 / +332 lines)
Lines 44-49 Link Here
44
#undef GNOME_DISABLE_DEPRECATED
44
#undef GNOME_DISABLE_DEPRECATED
45
#include <libgnome/gnome-desktop-item.h>
45
#include <libgnome/gnome-desktop-item.h>
46
46
47
#ifdef HAVE_STARTUP_NOTIFICATION
48
#define SN_API_NOT_YET_FROZEN
49
#include <libsn/sn.h>
50
#include <gdk/gdk.h>
51
#include <gdk/gdkx.h>
52
#endif
53
47
static GHashTable *files = NULL;
54
static GHashTable *files = NULL;
48
static GHashTable *mime_table = NULL;
55
static GHashTable *mime_table = NULL;
49
56
Lines 458-463 Link Here
458
	return permission;
465
	return permission;
459
}
466
}
460
467
468
/* Copied from nautilus-program-choosing.c */
469
470
extern char **environ;
471
472
/* Cut and paste from gdkspawn-x11.c */
473
static gchar **
474
my_gdk_spawn_make_environment_for_screen (GdkScreen  *screen,
475
					  gchar     **envp)
476
{
477
  gchar **retval = NULL;
478
  gchar  *display_name;
479
  gint    display_index = -1;
480
  gint    i, env_len;
481
482
  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
483
484
  if (envp == NULL)
485
    envp = environ;
486
487
  for (env_len = 0; envp[env_len]; env_len++)
488
    if (strncmp (envp[env_len], "DISPLAY", strlen ("DISPLAY")) == 0)
489
      display_index = env_len;
490
491
  retval = g_new (char *, env_len + 1);
492
  retval[env_len] = NULL;
493
494
  display_name = gdk_screen_make_display_name (screen);
495
496
  for (i = 0; i < env_len; i++)
497
    if (i == display_index)
498
      retval[i] = g_strconcat ("DISPLAY=", display_name, NULL);
499
    else
500
      retval[i] = g_strdup (envp[i]);
501
502
  g_assert (i == env_len);
503
504
  g_free (display_name);
505
506
  return retval;
507
}
508
509
#ifdef HAVE_STARTUP_NOTIFICATION
510
static void
511
sn_error_trap_push (SnDisplay *display,
512
		    Display   *xdisplay)
513
{
514
	gdk_error_trap_push ();
515
}
516
517
static void
518
sn_error_trap_pop (SnDisplay *display,
519
		   Display   *xdisplay)
520
{
521
	gdk_error_trap_pop ();
522
}
523
524
static char **
525
make_spawn_environment_for_sn_context (SnLauncherContext *sn_context,
526
				       char             **envp)
527
{
528
	char **retval;
529
	int    i, j;
530
531
	retval = NULL;
532
	
533
	if (envp == NULL) {
534
		envp = environ;
535
	}
536
	
537
	for (i = 0; envp[i]; i++) {
538
		/* Count length */
539
	}
540
541
	retval = g_new (char *, i + 2);
542
543
	for (i = 0, j = 0; envp[i]; i++) {
544
		if (!g_str_has_prefix (envp[i], "DESKTOP_STARTUP_ID=")) {
545
			retval[j] = g_strdup (envp[i]);
546
			++j;
547
	        }
548
	}
549
550
	retval[j] = g_strdup_printf ("DESKTOP_STARTUP_ID=%s",
551
				     sn_launcher_context_get_startup_id (sn_context));
552
	++j;
553
	retval[j] = NULL;
554
555
	return retval;
556
}
557
558
/* This should be fairly long, as it's confusing to users if a startup
559
 * ends when it shouldn't (it appears that the startup failed, and
560
 * they have to relaunch the app). Also the timeout only matters when
561
 * there are bugs and apps don't end their own startup sequence.
562
 *
563
 * This timeout is a "last resort" timeout that ignores whether the
564
 * startup sequence has shown activity or not.  Metacity and the
565
 * tasklist have smarter, and correspondingly able-to-be-shorter
566
 * timeouts. The reason our timeout is dumb is that we don't monitor
567
 * the sequence (don't use an SnMonitorContext)
568
 */
569
#define STARTUP_TIMEOUT_LENGTH (30 /* seconds */ * 1000)
570
571
typedef struct
572
{
573
	GdkScreen *screen;
574
	GSList *contexts;
575
	guint timeout_id;
576
} StartupTimeoutData;
577
578
static void
579
free_startup_timeout (void *data)
580
{
581
	StartupTimeoutData *std;
582
583
	std = data;
584
585
	g_slist_foreach (std->contexts,
586
			 (GFunc) sn_launcher_context_unref,
587
			 NULL);
588
	g_slist_free (std->contexts);
589
590
	if (std->timeout_id != 0) {
591
		g_source_remove (std->timeout_id);
592
		std->timeout_id = 0;
593
	}
594
595
	g_free (std);
596
}
597
598
static gboolean
599
startup_timeout (void *data)
600
{
601
	StartupTimeoutData *std;
602
	GSList *tmp;
603
	GTimeVal now;
604
	int min_timeout;
605
606
	std = data;
607
608
	min_timeout = STARTUP_TIMEOUT_LENGTH;
609
	
610
	g_get_current_time (&now);
611
	
612
	tmp = std->contexts;
613
	while (tmp != NULL) {
614
		SnLauncherContext *sn_context;
615
		GSList *next;
616
		long tv_sec, tv_usec;
617
		double elapsed;
618
		
619
		sn_context = tmp->data;
620
		next = tmp->next;
621
		
622
		sn_launcher_context_get_last_active_time (sn_context,
623
							  &tv_sec, &tv_usec);
624
625
		elapsed =
626
			((((double)now.tv_sec - tv_sec) * G_USEC_PER_SEC +
627
			  (now.tv_usec - tv_usec))) / 1000.0;
628
629
		if (elapsed >= STARTUP_TIMEOUT_LENGTH) {
630
			std->contexts = g_slist_remove (std->contexts,
631
							sn_context);
632
			sn_launcher_context_complete (sn_context);
633
			sn_launcher_context_unref (sn_context);
634
		} else {
635
			min_timeout = MIN (min_timeout, (STARTUP_TIMEOUT_LENGTH - elapsed));
636
		}
637
		
638
		tmp = next;
639
	}
640
641
	if (std->contexts == NULL) {
642
		std->timeout_id = 0;
643
	} else {
644
		std->timeout_id = g_timeout_add (min_timeout,
645
						 startup_timeout,
646
						 std);
647
	}
648
649
	/* always remove this one, but we may have reinstalled another one. */
650
	return FALSE;
651
}
652
653
static void
654
add_startup_timeout (GdkScreen         *screen,
655
		     SnLauncherContext *sn_context)
656
{
657
	StartupTimeoutData *data;
658
659
	data = g_object_get_data (G_OBJECT (screen), "nautilus-startup-data");
660
	if (data == NULL) {
661
		data = g_new (StartupTimeoutData, 1);
662
		data->screen = screen;
663
		data->contexts = NULL;
664
		data->timeout_id = 0;
665
		
666
		g_object_set_data_full (G_OBJECT (screen), "nautilus-startup-data",
667
					data, free_startup_timeout);		
668
	}
669
670
	sn_launcher_context_ref (sn_context);
671
	data->contexts = g_slist_prepend (data->contexts, sn_context);
672
	
673
	if (data->timeout_id == 0) {
674
		data->timeout_id = g_timeout_add (STARTUP_TIMEOUT_LENGTH,
675
						  startup_timeout,
676
						  data);		
677
	}
678
}
679
680
#endif /* HAVE_STARTUP_NOTIFICATION */
681
682
gboolean
683
ephy_file_launch_application (GnomeVFSMimeApplication *application,
684
			      const char *parameter,
685
			      guint32 user_time)
686
{
687
	GdkScreen       *screen;
688
	GList           *uris = NULL;
689
	char            *uri;
690
	char           **envp;
691
	GnomeVFSResult   result;
692
#ifdef HAVE_STARTUP_NOTIFICATION
693
	SnLauncherContext *sn_context;
694
	SnDisplay *sn_display;
695
#endif
696
697
	g_return_val_if_fail (application != NULL, FALSE);
698
	g_return_val_if_fail (parameter != NULL, FALSE);
699
700
	uri = gnome_vfs_make_uri_canonical (parameter);
701
	if (uri == NULL) return FALSE;
702
703
	uris = g_list_prepend (NULL, uri);
704
	
705
	screen = gdk_screen_get_default ();
706
	envp = my_gdk_spawn_make_environment_for_screen (screen, NULL);
707
	
708
#ifdef HAVE_STARTUP_NOTIFICATION
709
	sn_display = sn_display_new (gdk_display,
710
				     sn_error_trap_push,
711
				     sn_error_trap_pop);
712
713
	
714
	/* Only initiate notification if application supports it. */
715
	if (gnome_vfs_mime_application_supports_startup_notification (application))
716
	{
717
		char *name;
718
719
		sn_context = sn_launcher_context_new (sn_display,
720
						      screen ? gdk_screen_get_number (screen) :
721
						      DefaultScreen (gdk_display));
722
		
723
		name = g_filename_display_basename (uri);
724
		if (name != NULL) {
725
			char *description;
726
			
727
			sn_launcher_context_set_name (sn_context, name);
728
729
			/* FIXME: i18n after string freeze! */
730
			description = g_strdup_printf ("Opening %s", name);
731
			
732
			sn_launcher_context_set_description (sn_context, description);
733
734
			g_free (name);
735
			g_free (description);
736
		}
737
		
738
		if (!sn_launcher_context_get_initiated (sn_context)) {
739
			const char *binary_name;
740
			char **old_envp;
741
742
			binary_name = gnome_vfs_mime_application_get_binary_name (application);
743
		
744
			sn_launcher_context_set_binary_name (sn_context,
745
							     binary_name);
746
			
747
			sn_launcher_context_initiate (sn_context,
748
						      g_get_prgname () ? g_get_prgname () : "unknown",
749
						      binary_name,
750
						      (Time) user_time);
751
752
			old_envp = envp;
753
			envp = make_spawn_environment_for_sn_context (sn_context, envp);
754
			g_strfreev (old_envp);
755
		}
756
	} else {
757
		sn_context = NULL;
758
	}
759
#endif /* HAVE_STARTUP_NOTIFICATION */
760
	
761
	result = gnome_vfs_mime_application_launch_with_env (application, uris, envp);
762
763
#ifdef HAVE_STARTUP_NOTIFICATION
764
	if (sn_context != NULL) {
765
		if (result != GNOME_VFS_OK) {
766
			sn_launcher_context_complete (sn_context); /* end sequence */
767
		} else {
768
			add_startup_timeout (screen ? screen :
769
					     gdk_display_get_default_screen (gdk_display_get_default ()),
770
					     sn_context);
771
		}
772
		sn_launcher_context_unref (sn_context);
773
	}
774
	
775
	sn_display_unref (sn_display);
776
#endif /* HAVE_STARTUP_NOTIFICATION */
777
778
	g_strfreev (envp);
779
	g_list_foreach (uris, (GFunc) g_free,NULL);
780
	g_list_free (uris);
781
782
	if (result != GNOME_VFS_OK)
783
	{
784
		g_warning ("Cannot launch application '%s'\n",
785
			   gnome_vfs_mime_application_get_name (application));
786
	}
787
788
	return result == GNOME_VFS_OK;
789
}
790
791
/* End cut-paste-adapt from nautilus */
792
461
static int
793
static int
462
launch_desktop_item (const char *desktop_file,
794
launch_desktop_item (const char *desktop_file,
463
		     const char *parameter,
795
		     const char *parameter,
Lines 529-565 Link Here
529
}
861
}
530
862
531
gboolean
863
gboolean
532
ephy_file_launch_application (GnomeVFSMimeApplication *application,
533
			      const char *parameter,
534
			      guint32 user_time)
535
{
536
	GError *error = NULL;
537
	const char *desktop_file;
538
	int ret = -1;
539
540
	g_return_val_if_fail (application != NULL, FALSE);
541
	g_return_val_if_fail (parameter != NULL, FALSE);
542
543
	desktop_file = gnome_vfs_mime_application_get_desktop_file_path (application);
544
	if (desktop_file != NULL)
545
	{
546
		ret = launch_desktop_item (desktop_file, parameter, user_time, &error);
547
	}
548
549
	if (ret == -1 || error != NULL)
550
	{
551
		/* FIXME We should really warn the user here */
552
553
		g_warning ("Cannot launch application '%s': %s\n",
554
			   gnome_vfs_mime_application_get_name (application),
555
			   error ? error->message : "(unknown error)");
556
		g_clear_error (&error);
557
	}
558
559
	return ret >= 0;
560
}
561
562
gboolean
563
ephy_file_launch_handler (const char *mime_type,
864
ephy_file_launch_handler (const char *mime_type,
564
			  const char *address,
865
			  const char *address,
565
			  guint32 user_time)
866
			  guint32 user_time)

Return to bug 85337