Пример #1
0
/**
 * xfdashboard_create_app_context:
 * @inWorkspace: The workspace where to place application windows on or %NULL
 *
 * Returns a #GAppLaunchContext suitable for launching applications on the
 * given display and workspace by GIO.
 *
 * If @inWorkspace is specified it sets workspace on which applications will
 * be launched when using this context when running under a window manager
 * that supports multiple workspaces.
 *
 * When the workspace is not specified it is up to the window manager to pick
 * one, typically it will be the current workspace.
 *
 * Return value: (transfer full): the newly created #GAppLaunchContext or %NULL
 *   in case of an error. Use g_object_unref() to free return value.
 */
GAppLaunchContext* xfdashboard_create_app_context(XfdashboardWindowTrackerWorkspace *inWorkspace)
{
	GdkAppLaunchContext			*context;
	const ClutterEvent			*event;
	XfdashboardWindowTracker	*tracker;

	g_return_val_if_fail(inWorkspace==NULL || XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE(inWorkspace), NULL);

	/* Get last event for timestamp */
	event=clutter_get_current_event();

	/* Get active workspace if not specified */
	if(!inWorkspace)
	{
		tracker=xfdashboard_window_tracker_get_default();
		inWorkspace=xfdashboard_window_tracker_get_active_workspace(tracker);
		g_object_unref(tracker);
	}

	/* Create and set up application context to use either the workspace specified
	 * or otherwise current active workspace. We will even set the current active
	 * explicitly to launch the application on current workspace even if user changes
	 * workspace in the time between launching application and showing first window.
	 */
	context=gdk_display_get_app_launch_context(gdk_display_get_default());
	if(event) gdk_app_launch_context_set_timestamp(context, clutter_event_get_time(event));
	gdk_app_launch_context_set_desktop(context, xfdashboard_window_tracker_workspace_get_number(inWorkspace));

	/* Return application context */
	return(G_APP_LAUNCH_CONTEXT(context));
}
Пример #2
0
/**
 * cinnamon_app_launch:
 * @timestamp: Event timestamp, or 0 for current event timestamp
 * @uris: (element-type utf8): List of uris to pass to application
 * @workspace: Start on this workspace, or -1 for default
 * @startup_id: (out): Returned startup notification ID, or %NULL if none
 * @error: A #GError
 */
gboolean
cinnamon_app_launch (CinnamonApp     *app,
                  guint         timestamp,
                  GList        *uris,
                  int           workspace,
                  char        **startup_id,
                  GError      **error)
{
  GDesktopAppInfo *gapp;
  GdkAppLaunchContext *context;
  gboolean ret;
  CinnamonGlobal *global;
  MetaScreen *screen;
  GdkDisplay *gdisplay;

  if (startup_id)
    *startup_id = NULL;

  if (app->entry == NULL)
    {
      MetaWindow *window = window_backed_app_get_window (app);
      /* We can't pass URIs into a window; shouldn't hit this
       * code path.  If we do, fix the caller to disallow it.
       */
      g_return_val_if_fail (uris == NULL, TRUE);

      meta_window_activate (window, timestamp);
      return TRUE;
    }

  global = cinnamon_global_get ();
  screen = cinnamon_global_get_screen (global);
  gdisplay = gdk_screen_get_display (cinnamon_global_get_gdk_screen (global));

  if (timestamp == 0)
    timestamp = cinnamon_global_get_current_time (global);

  if (workspace < 0)
    workspace = meta_screen_get_active_workspace_index (screen);

  context = gdk_display_get_app_launch_context (gdisplay);
  gdk_app_launch_context_set_timestamp (context, timestamp);
  gdk_app_launch_context_set_desktop (context, workspace);

  gapp = gmenu_tree_entry_get_app_info (app->entry);
  ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris,
                                                   G_APP_LAUNCH_CONTEXT (context),
                                                   G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL  | G_SPAWN_STDERR_TO_DEV_NULL,
                                                   NULL, NULL,
                                                   _gather_pid_callback, app,
                                                   error);
  g_object_unref (context);

  return ret;
}
Пример #3
0
/**
 * shell_global_get_app_launch_context:
 * @global: A #ShellGlobal
 *
 * Create a #GAppLaunchContext set up with the correct timestamp, and
 * targeted to activate on the current workspace.
 *
 * Return value: A new #GAppLaunchContext
 */
GAppLaunchContext *
shell_global_create_app_launch_context (ShellGlobal *global)
{
  GdkAppLaunchContext *context;

  context = gdk_app_launch_context_new ();
  gdk_app_launch_context_set_timestamp (context, shell_global_get_current_time (global));

  // Make sure that the app is opened on the current workspace even if
  // the user switches before it starts
  gdk_app_launch_context_set_desktop (context, meta_screen_get_active_workspace_index (shell_global_get_screen (global)));

  return (GAppLaunchContext *)context;
}
/**
 * shell_doc_system_open:
 * @system: A #ShellDocSystem
 * @info: A #GtkRecentInfo
 * @workspace: Open on this workspace, or -1 for default
 *
 * Launch the default application associated with the mime type of
 * @info, using its uri.
 */
void
shell_doc_system_open (ShellDocSystem *system,
                       GtkRecentInfo  *info,
                       int             workspace)
{
  GFile *file;
  GAppInfo *app_info;
  gboolean needs_uri;
  GAppLaunchContext *context;

  context = shell_global_create_app_launch_context (shell_global_get ());
  if (workspace != -1)
    gdk_app_launch_context_set_desktop ((GdkAppLaunchContext *)context, workspace);

  file = g_file_new_for_uri (gtk_recent_info_get_uri (info));
  needs_uri = g_file_get_path (file) == NULL;
  g_object_unref (file);

  app_info = g_app_info_get_default_for_type (gtk_recent_info_get_mime_type (info), needs_uri);
  if (app_info != NULL)
    {
      GList *uris;
      uris = g_list_prepend (NULL, (gpointer)gtk_recent_info_get_uri (info));
      g_app_info_launch_uris (app_info, uris, context, NULL);
      g_list_free (uris);
    }
  else
    {
      char *app_name;
      const char *app_exec;
      char *app_exec_quoted;
      guint count;
      time_t time;

      app_name = gtk_recent_info_last_application (info);
      if (gtk_recent_info_get_application_info (info, app_name, &app_exec, &count, &time))
        {
          GRegex *regex;

          /* TODO: Change this once better support for creating
             GAppInfo is added to GtkRecentInfo, as right now
             this relies on the fact that the file uri is
             already a part of appExec, so we don't supply any
             files to app_info.launch().

             The 'command line' passed to
             create_from_command_line is allowed to contain
             '%<something>' macros that are expanded to file
             name / icon name, etc, so we need to escape % as %%
           */

          regex = g_regex_new ("%", 0, 0, NULL);
          app_exec_quoted = g_regex_replace (regex, app_exec, -1, 0, "%%", 0, NULL);
          g_regex_unref (regex);

          app_info = g_app_info_create_from_commandline (app_exec_quoted, NULL, 0, NULL);
          g_free (app_exec_quoted);

          /* The point of passing an app launch context to
             launch() is mostly to get startup notification and
             associated benefits like the app appearing on the
             right desktop; but it doesn't really work for now
             because with the way we create the appInfo we
             aren't reading the application's desktop file, and
             thus don't find the StartupNotify=true in it. So,
             despite passing the app launch context, no startup
             notification occurs.
           */
          g_app_info_launch (app_info, NULL, context, NULL);
        }

      g_free (app_name);
    }

  g_object_unref (context);
}
/**
 * shell_app_info_launch_full:
 * @timestamp: Event timestamp, or 0 for current event timestamp
 * @uris: List of uris to pass to application
 * @workspace: Start on this workspace, or -1 for default
 * @startup_id: (out): Returned startup notification ID, or %NULL if none
 * @error: A #GError
 */
gboolean
shell_app_info_launch_full (ShellAppInfo *info,
                            guint         timestamp,
                            GList        *uris,
                            int           workspace,
                            char        **startup_id,
                            GError      **error)
{
  ShellApp *shell_app;
  GDesktopAppInfo *gapp;
  GdkAppLaunchContext *context;
  gboolean ret;
  ShellGlobal *global;
  MetaScreen *screen;

  if (startup_id)
    *startup_id = NULL;

  if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
    {
      /* We can't pass URIs into a window; shouldn't hit this
       * code path.  If we do, fix the caller to disallow it.
       */
      g_return_val_if_fail (uris == NULL, TRUE);

      meta_window_activate (info->window, timestamp);
      return TRUE;
    }
  else if (info->type == SHELL_APP_INFO_TYPE_ENTRY)
    {
      /* Can't use g_desktop_app_info_new, see bug 614879 */
      const char *filename = gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry *)info->entry);
      gapp = g_desktop_app_info_new_from_filename (filename);
    }
  else
    {
      char *filename = shell_app_info_get_desktop_file_path (info);
      gapp = g_desktop_app_info_new_from_filename (filename);
      g_free (filename);
    }

  if (!gapp)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Not found");
      return FALSE;
    }

  global = shell_global_get ();
  screen = shell_global_get_screen (global);

  if (timestamp == 0)
    timestamp = clutter_get_current_event_time ();

  if (workspace < 0)
    workspace = meta_screen_get_active_workspace_index (screen);

  context = gdk_app_launch_context_new ();
  gdk_app_launch_context_set_timestamp (context, timestamp);
  gdk_app_launch_context_set_desktop (context, workspace);

  shell_app = shell_app_system_get_app (shell_app_system_get_default (),
                                        shell_app_info_get_id (info));

  /* In the case where we know an app, we handle reaping the child internally,
   * in the window tracker.
   */
  if (shell_app != NULL)
    ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris,
                                                     G_APP_LAUNCH_CONTEXT (context),
                                                     G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
                                                     NULL, NULL,
                                                     _gather_pid_callback, shell_app,
                                                     error);
  else
    ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris,
                                                     G_APP_LAUNCH_CONTEXT (context),
                                                     G_SPAWN_SEARCH_PATH,
                                                     NULL, NULL,
                                                     NULL, NULL,
                                                     error);

  g_object_unref (G_OBJECT (gapp));

  return ret;
}
Пример #6
0
/**
 * shell_app_info_launch_full:
 * @timestamp: Event timestamp, or 0 for current event timestamp
 * @uris: List of uris to pass to application
 * @workspace: Start on this workspace, or -1 for default
 * @startup_id: (out): Returned startup notification ID, or %NULL if none
 * @error: A #GError
 */
gboolean
shell_app_info_launch_full (ShellAppInfo *info,
                            guint         timestamp,
                            GList        *uris,
                            int           workspace,
                            char        **startup_id,
                            GError      **error)
{
  GDesktopAppInfo *gapp;
  char *filename;
  GdkAppLaunchContext *context;
  gboolean ret;
  ShellGlobal *global;
  MetaScreen *screen;
  MetaDisplay *display;

  if (startup_id)
    *startup_id = NULL;

  if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
    {
      /* We can't pass URIs into a window; shouldn't hit this
       * code path.  If we do, fix the caller to disallow it.
       */
      g_return_val_if_fail (uris == NULL, TRUE);

      meta_window_activate (info->window, timestamp);
      return TRUE;
    }
  else if (info->type == SHELL_APP_INFO_TYPE_ENTRY)
    {
      gapp = g_desktop_app_info_new (shell_app_info_get_id (info));
    }
  else
    {
      filename = shell_app_info_get_desktop_file_path (info);
      gapp = g_desktop_app_info_new_from_filename (filename);
      g_free (filename);
    }

  if (!gapp)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Not found");
      return FALSE;
    }

  global = shell_global_get ();
  screen = shell_global_get_screen (global);
  display = meta_screen_get_display (screen);

  if (timestamp == 0)
    timestamp = clutter_get_current_event_time ();

  if (workspace < 0)
    workspace = meta_screen_get_active_workspace_index (screen);

  context = gdk_app_launch_context_new ();
  gdk_app_launch_context_set_timestamp (context, timestamp);
  gdk_app_launch_context_set_desktop (context, workspace);

  ret = g_app_info_launch (G_APP_INFO (gapp), uris, (GAppLaunchContext*) context, error);

  g_object_unref (G_OBJECT (gapp));

  return ret;
}