Exemplo n.º 1
0
static void
shell_app_usage_init (ShellAppUsage *self)
{
  ShellGlobal *global;
  char *shell_userdata_dir, *path;
  GDBusConnection *session_bus;
  ShellWindowTracker *tracker;
  ShellAppSystem *app_system;

  global = shell_global_get ();

  self->app_usages_for_context = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_destroy);

  tracker = shell_window_tracker_get_default ();
  g_signal_connect (tracker, "notify::focus-app", G_CALLBACK (on_focus_app_changed), self);

  app_system = shell_app_system_get_default ();
  g_signal_connect (app_system, "app-state-changed", G_CALLBACK (on_app_state_changed), self);

  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  self->session_proxy = g_dbus_proxy_new_sync (session_bus,
                                               G_DBUS_PROXY_FLAGS_NONE,
                                               NULL, /* interface info */
                                               "org.gnome.SessionManager",
                                               "/org/gnome/SessionManager/Presence",
                                               "org.gnome.SessionManager",
                                               NULL, /* cancellable */
                                               NULL /* error */);
  g_signal_connect (self->session_proxy, "g-signal", G_CALLBACK (session_proxy_signal), self);
  g_object_unref (session_bus);

  self->last_idle = 0;
  self->currently_idle = FALSE;
  self->enable_monitoring = FALSE;

  g_object_get (shell_global_get(), "userdatadir", &shell_userdata_dir, NULL),
  path = g_build_filename (shell_userdata_dir, DATA_FILENAME, NULL);
  g_free (shell_userdata_dir);
  self->configfile = g_file_new_for_path (path);
  g_free (path);
  restore_from_file (self);


  self->privacy_settings = g_settings_new(PRIVACY_SCHEMA);
  g_signal_connect (self->privacy_settings,
                    "changed::" ENABLE_MONITORING_KEY,
                    G_CALLBACK (on_enable_monitoring_key_changed),
                    self);
  update_enable_monitoring (self);
}
Exemplo n.º 2
0
static void
on_startup_sequence_changed (MetaScreen            *screen,
                             SnStartupSequence     *sequence,
                             ShellWindowTracker    *self)
{
  ShellApp *app;

  app = shell_startup_sequence_get_app ((ShellStartupSequence*)sequence);
  if (app)
    {
      gboolean starting = !sn_startup_sequence_get_completed (sequence);

      /* The Shell design calls for on application launch, the app title
       * appears at top, and no X window is focused.  So when we get
       * a startup-notification for this app, transition it to STARTING
       * if it's currently stopped, set it as our application focus,
       * but focus the no_focus window.
       */
      if (starting && shell_app_get_state (app) == SHELL_APP_STATE_STOPPED)
        {
          MetaScreen *screen = shell_global_get_screen (shell_global_get ());
          MetaDisplay *display = meta_screen_get_display (screen);
          long tv_sec, tv_usec;

          sn_startup_sequence_get_initiated_time (sequence, &tv_sec, &tv_usec);

          _shell_app_set_starting (app, starting);
          set_focus_app (self, app);
          meta_display_focus_the_no_focus_window (display, screen, tv_sec);
        }
    }

  g_signal_emit (G_OBJECT (self), signals[STARTUP_SEQUENCE_CHANGED], 0, sequence);
}
/**
 * shell_startup_sequence_create_icon:
 * @sequence:
 * @size: Size in pixels of icon
 *
 * Returns: (transfer none): A new #ClutterTexture containing an icon for the sequence
 */
ClutterActor *
shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size)
{
  GIcon *themed;
  const char *icon_name;
  ClutterActor *texture;
  gint scale;
  ShellGlobal *global;
  StThemeContext *context;

  global = shell_global_get ();
  context = st_theme_context_get_for_stage (shell_global_get_stage (global));
  g_object_get (context, "scale-factor", &scale, NULL);

  icon_name = sn_startup_sequence_get_icon_name ((SnStartupSequence*)sequence);
  if (!icon_name)
    {
      texture = clutter_texture_new ();
      clutter_actor_set_size (texture, size * scale, size * scale);
      return texture;
    }

  themed = g_themed_icon_new (icon_name);
  texture = st_texture_cache_load_gicon (st_texture_cache_get_default (),
                                         NULL, themed, size, scale);
  g_object_unref (G_OBJECT (themed));
  return texture;
}
Exemplo n.º 4
0
/* Enable or disable the timers, depending on the value of ENABLE_MONITORING_KEY
 * and taking care of the previous state.  If selfing is disabled, we still
 * report apps usage based on (possibly) saved data, but don't collect data.
 */
static void
update_enable_monitoring (ShellAppUsage *self)
{
  ShellGlobal *global;
  gboolean enable;

  global = shell_global_get ();
  enable = g_settings_get_boolean (shell_global_get_settings (global),
                                   ENABLE_MONITORING_KEY);

  /* Be sure not to start the timers if they were already set */
  if (enable && !self->enable_monitoring)
    {
      on_focus_app_changed (shell_window_tracker_get_default (), NULL, self);
    }
  /* ...and don't try to stop them if they were not running */
  else if (!enable && self->enable_monitoring)
    {
      if (self->watched_app)
        g_object_unref (self->watched_app);
      self->watched_app = NULL;
      if (self->save_id)
        {
          g_source_remove (self->save_id);
          self->save_id = 0;
        }
    }

  self->enable_monitoring = enable;
}
Exemplo n.º 5
0
/**
 * shell_app_system_get_from_pid:
 * @self; A #ShellAppSystem
 * @pid: A Unix process identifier
 *
 * Look up the application corresponding to a process.
 *
 * Returns: (transfer full): A #ShellApp, or %NULL if none
 */
ShellApp *
shell_window_tracker_get_app_from_pid (ShellWindowTracker *self, 
                                       int                 pid)
{
  ShellGlobal *global = shell_global_get ();
  GList *windows, *iter;
  
  windows = shell_global_get_windows (global);
  for (iter = windows; iter; iter = iter->next)
    {
      MutterWindow *win = iter->data;
      MetaWindow *metawin;
      int windowpid;
      ShellApp *app;
      
      metawin = mutter_window_get_meta_window (win);
      windowpid = meta_window_get_pid (metawin);
      if (windowpid != pid)
        continue;
      
      app = shell_window_tracker_get_window_app (self, metawin);
      if (app)
        return app;
    }
  return NULL;
}
Exemplo n.º 6
0
static void
update_focus_app (ShellWindowTracker *self)
{
  MetaWindow *new_focus_win;
  ShellApp *new_focus_app;

  new_focus_win = meta_display_get_focus_window (shell_global_get_display (shell_global_get ()));

  /* we only consider an app focused if the focus window can be clearly
   * associated with a running app; this is the case if the focus window
   * or one of its parents is visible in the taskbar, e.g.
   *   - 'nautilus' should appear focused when its about dialog has focus
   *   - 'nautilus' should not appear focused when the DESKTOP has focus
   */
  while (new_focus_win && meta_window_is_skip_taskbar (new_focus_win))
    new_focus_win = meta_window_get_transient_for (new_focus_win);

  new_focus_app = new_focus_win ? shell_window_tracker_get_window_app (self, new_focus_win) : NULL;

  if (new_focus_app)
    {
      shell_app_update_window_actions (new_focus_app, new_focus_win);
      shell_app_update_app_menu (new_focus_app, new_focus_win);
    }

  set_focus_app (self, new_focus_app);
}
Exemplo n.º 7
0
/**
 * shell_recorder_close:
 * @recorder: the #ShellRecorder
 *
 * Stops recording. It's possible to call shell_recorder_record()
 * again to reopen a new recording stream, but unless change the
 * recording filename, this may result in the old recording being
 * overwritten.
 */
void
shell_recorder_close (ShellRecorder *recorder)
{
  g_return_if_fail (SHELL_IS_RECORDER (recorder));
  g_return_if_fail (recorder->state != RECORDER_STATE_CLOSED);

  /* We want to record one more frame since some time may have
   * elapsed since the last frame
   */
  recorder_record_frame (recorder, TRUE);

  recorder_remove_update_pointer_timeout (recorder);
  recorder_close_pipeline (recorder);

  /* Queue a redraw to remove the recording indicator */
  clutter_actor_queue_redraw (CLUTTER_ACTOR (recorder->stage));

  if (recorder->repaint_hook_id != 0)
    {
      clutter_threads_remove_repaint_func (recorder->repaint_hook_id);
      recorder->repaint_hook_id = 0;
    }

  recorder->state = RECORDER_STATE_CLOSED;

  /* Reenable after the recording */
  meta_enable_unredirect_for_screen (shell_global_get_screen (shell_global_get ()));

  /* Release the refcount we took when we started recording */
  g_object_unref (recorder);
}
Exemplo n.º 8
0
/**
 * shell_window_tracker_get_startup_sequences:
 * @self:
 *
 * Returns: (transfer none) (element-type ShellStartupSequence): Currently active startup sequences
 */
GSList *
shell_window_tracker_get_startup_sequences (ShellWindowTracker *self)
{
  ShellGlobal *global = shell_global_get ();
  MetaScreen *screen = shell_global_get_screen (global);
  return meta_screen_get_startup_sequences (screen);
}
Exemplo n.º 9
0
static gboolean
list_modes (const char  *option_name,
            const char  *value,
            gpointer     data,
            GError     **error)
{
  ShellGlobal *global;
  GjsContext *context;
  const char *script;
  int status;

  /* Many of our imports require global to be set, so rather than
   * tayloring our imports carefully here to avoid that dependency,
   * we just set it.
   * ShellGlobal has some GTK+ dependencies, so initialize GTK+; we
   * don't really care if it fails though (e.g. when running from a tty),
   * so we mute all warnings */
  g_log_set_default_handler (shut_up, NULL);
  gtk_init_check (NULL, NULL);

  _shell_global_init (NULL);
  global = shell_global_get ();
  context = _shell_global_get_gjs_context (global);

  shell_introspection_init ();

  script = "imports.ui.environment.init();"
           "imports.ui.sessionMode.listModes();";
  if (!gjs_context_eval (context, script, -1, "<main>", &status, NULL))
      g_message ("Retrieving list of available modes failed.");

  exit (status);
}
Exemplo n.º 10
0
static void
shell_alt_tab_handler_constructed (GObject *object)
{
  ShellGlobal *global = shell_global_get ();
  ShellWM *wm;

  g_object_get (G_OBJECT (global), "window-manager", &wm, NULL);
  _shell_wm_begin_alt_tab (wm, SHELL_ALT_TAB_HANDLER (object));
  g_object_unref (wm);
}
Exemplo n.º 11
0
static void
init_window_tracking (ShellWindowTracker *self)
{
  MetaDisplay *display;
  MetaScreen *screen = shell_global_get_screen (shell_global_get ());

  g_signal_connect (screen, "notify::n-workspaces",
                    G_CALLBACK (shell_window_tracker_on_n_workspaces_changed), self);
  display = meta_screen_get_display (screen);
  g_signal_connect (display, "notify::focus-window",
                    G_CALLBACK (on_focus_window_changed), self);

  shell_window_tracker_on_n_workspaces_changed (screen, NULL, self);
}
Exemplo n.º 12
0
static void
on_focus_window_changed (MetaDisplay        *display,
                         GParamSpec         *spec,
                         ShellWindowTracker *tracker)
{
  MetaScreen *screen;
  MetaWindow *new_focus_win;
  ShellApp *new_focus_app;

  screen = shell_global_get_screen (shell_global_get ());

  new_focus_win = meta_display_get_focus_window (display);
  new_focus_app = new_focus_win ? g_hash_table_lookup (tracker->window_to_app, new_focus_win) : NULL;

  set_focus_app (tracker, new_focus_app);
}
Exemplo n.º 13
0
static void
update_focus_app (ShellWindowTracker *self)
{
  MetaWindow *new_focus_win;
  ShellApp *new_focus_app;

  new_focus_win = meta_display_get_focus_window (shell_global_get_display (shell_global_get ()));
  new_focus_app = new_focus_win ? shell_window_tracker_get_window_app (self, new_focus_win) : NULL;

  if (new_focus_app)
    {
      shell_app_update_window_actions (new_focus_app, new_focus_win);
      shell_app_update_app_menu (new_focus_app, new_focus_win);
    }

  set_focus_app (self, new_focus_app);
}
Exemplo n.º 14
0
static void
shell_window_tracker_init (ShellWindowTracker *self)
{
  MetaScreen *screen;

  self->window_to_app = g_hash_table_new_full (g_direct_hash, g_direct_equal,
                                               NULL, (GDestroyNotify) g_object_unref);

  self->running_apps = g_hash_table_new (g_str_hash, g_str_equal);

  screen = shell_global_get_screen (shell_global_get ());

  g_signal_connect (G_OBJECT (screen), "startup-sequence-changed",
                    G_CALLBACK (on_startup_sequence_changed), self);

  load_initial_windows (self);
  init_window_tracking (self);
}
Exemplo n.º 15
0
static void
shell_prefs_init (void)
{
  ShellGlobal *global = shell_global_get ();
  GSettings *settings = shell_global_get_overrides_settings (global);
  char **keys, **k, *schema_id;

  if (!settings)
    return;

  g_object_get (G_OBJECT (settings), "schema-id", &schema_id, NULL);

  keys = g_settings_list_keys (settings);
  for (keys = k = g_settings_list_keys (settings); *k; k++)
    meta_prefs_override_preference_schema (*k, schema_id);

  g_strfreev (keys);
  g_free (schema_id);
}
Exemplo n.º 16
0
static void
shell_app_usage_finalize (GObject *object)
{
  ShellGlobal *global;
  ShellAppUsage *self = SHELL_APP_USAGE (object);

  if (self->save_id > 0)
    g_source_remove (self->save_id);

  global = shell_global_get ();
  g_signal_handler_disconnect (shell_global_get_settings (global),
                               self->settings_notify);

  g_object_unref (self->configfile);

  g_object_unref (self->session_proxy);

  G_OBJECT_CLASS (shell_app_usage_parent_class)->finalize(object);
}
Exemplo n.º 17
0
static void
shell_prefs_init (void)
{
    ShellGlobal *global = shell_global_get ();
    GSettings *settings = shell_global_get_overrides_settings (global);
    GSettingsSchema *schema;
    char **keys, **k;

    if (!settings)
        return;

    g_object_get (G_OBJECT (settings), "settings-schema", &schema, NULL);

    for (keys = k = g_settings_schema_list_keys (schema); *k; k++)
        meta_prefs_override_preference_schema (*k, g_settings_schema_get_id (schema));

    g_strfreev (keys);
    g_settings_schema_unref (schema);
}
Exemplo n.º 18
0
/**
 * shell_status_menu_toggle:
 * @menu: a #ShellStatusMenu
 *
 * If the menu is not currently up, pops it up. Otherwise, hides it.
 * Popping up may fail if another grab is already active; check with
 * shell_status_menu_is_active().
 */
void
shell_status_menu_toggle (ShellStatusMenu *status, ClutterEvent *event)
{
  ShellStatusMenuPrivate *priv = status->priv;

  if (GTK_WIDGET_VISIBLE (priv->menu))
    {
      gtk_menu_popdown (GTK_MENU (priv->menu));
    }
  else
    {
      /* We don't want to overgrab a Mutter grab with the grab that GTK+
       * uses on menus.
       */
      ShellGlobal *global = shell_global_get ();
      if (shell_global_display_is_grabbed (global))
        return;

      gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, position_menu,
                      status, 1, event->button.time);
    }
}
Exemplo n.º 19
0
static void
load_initial_windows (ShellWindowTracker *monitor)
{
  GList *workspaces, *iter;
  MetaScreen *screen = shell_global_get_screen (shell_global_get ());
  workspaces = meta_screen_get_workspaces (screen);

  for (iter = workspaces; iter; iter = iter->next)
    {
      MetaWorkspace *workspace = iter->data;
      GList *windows = meta_workspace_list_windows (workspace);
      GList *window_iter;

      for (window_iter = windows; window_iter; window_iter = window_iter->next)
        {
          MetaWindow *window = window_iter->data;
          track_window (monitor, window);
        }

      g_list_free (windows);
    }
}
Exemplo n.º 20
0
/**
 * shell_recorder_record:
 * @recorder: the #ShellRecorder
 * @filename_used: (out) (optional): actual filename used for recording
 *
 * Starts recording, Starting the recording may fail if the output file
 * cannot be opened, or if the output stream cannot be created
 * for other reasons. In that case a warning is printed to
 * stderr. There is no way currently to get details on how
 * recording failed to start.
 *
 * An extra reference count is added to the recorder if recording
 * is succesfully started; the recording object will not be freed
 * until recording is stopped even if the creator no longer holds
 * a reference. Recording is automatically stopped if the stage
 * is destroyed.
 *
 * Return value: %TRUE if recording was succesfully started
 */
gboolean
shell_recorder_record (ShellRecorder  *recorder,
                       char          **filename_used)
{
  g_return_val_if_fail (SHELL_IS_RECORDER (recorder), FALSE);
  g_return_val_if_fail (recorder->stage != NULL, FALSE);
  g_return_val_if_fail (recorder->state != RECORDER_STATE_RECORDING, FALSE);

  if (!recorder_open_pipeline (recorder))
    return FALSE;

  if (filename_used)
    *filename_used = g_strdup (recorder->current_pipeline->filename);

  recorder_connect_stage_callbacks (recorder);

  recorder->last_frame_time = GST_CLOCK_TIME_NONE;

  recorder->state = RECORDER_STATE_RECORDING;
  recorder_update_pointer (recorder);
  recorder_add_update_pointer_timeout (recorder);

  /* Disable unredirection while we are recoring */
  meta_disable_unredirect_for_screen (shell_global_get_screen (shell_global_get ()));

  /* Set up repaint hook */
  recorder->repaint_hook_id = clutter_threads_add_repaint_func(recorder_repaint_hook, recorder->stage, NULL);

  /* Record an initial frame and also redraw with the indicator */
  clutter_actor_queue_redraw (CLUTTER_ACTOR (recorder->stage));

  /* We keep a ref while recording to let a caller start a recording then
   * drop their reference to the recorder
   */
  g_object_ref (recorder);

  return TRUE;
}
/**
 * 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);
}
Exemplo n.º 22
0
static void
shell_screenshot_init (ShellScreenshot *screenshot)
{
  screenshot->global = shell_global_get ();
}
static void
update_focus_app (ShellWindowTracker *self)
{
  MetaWindow *new_focus_win;
  ShellApp *new_focus_app;

  new_focus_win = meta_display_get_focus_window (meta_screen_get_display (shell_global_get_screen (shell_global_get ())));
  new_focus_app = new_focus_win ? shell_window_tracker_get_window_app (self, new_focus_win) : NULL;

  set_focus_app (self, new_focus_app);
}
Exemplo n.º 24
0
int
main(int argc, char **argv)
{
  GOptionContext *context;
  GError *error = NULL;
  ShellGlobal *global;
  GjsContext *js_context;
  char *script;
  const char *filename;
  char *title;
  gsize len;
  int code;

  gtk_init (&argc, &argv);

  clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
  clutter_x11_disable_event_retrieval ();

  if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
    return 1;

  gdk_window_add_filter (NULL, event_filter, NULL);

  context = g_option_context_new (NULL);

  /* pass unknown through to the JS script */
  g_option_context_set_ignore_unknown_options (context, TRUE);

  g_option_context_add_main_entries (context, entries, NULL);
  if (!g_option_context_parse (context, &argc, &argv, &error))
    g_error ("option parsing failed: %s", error->message);

  setlocale (LC_ALL, "");
  g_type_init ();

  _shell_global_init (NULL);
  global = shell_global_get ();
  js_context = _shell_global_get_gjs_context (global);

  /* prepare command line arguments */
  if (!gjs_context_define_string_array (js_context, "ARGV",
                                        argc - 2, (const char**)argv + 2,
                                        &error)) {
    g_printerr ("Failed to defined ARGV: %s", error->message);
    exit (1);
  }

  if (command != NULL) {
    script = command;
    len = strlen (script);
    filename = "<command line>";
  } else if (argc <= 1) {
    script = g_strdup ("const Console = imports.console; Console.interact();");
    len = strlen (script);
    filename = "<stdin>";
  } else /*if (argc >= 2)*/ {
    error = NULL;
    if (!g_file_get_contents (argv[1], &script, &len, &error)) {
      g_printerr ("%s\n", error->message);
      exit (1);
    }
    filename = argv[1];
  }

  title = g_filename_display_basename (filename);
  g_set_prgname (title);
  g_free (title);

#if HAVE_BLUETOOTH
  /* The module imports are all so intertwined that if the test
   * imports anything in js/ui, it will probably eventually end up
   * pulling in ui/status/bluetooth.js. So we need this.
   */
  g_irepository_prepend_search_path (BLUETOOTH_DIR);
#endif

  /* evaluate the script */
  error = NULL;
  if (!gjs_context_eval (js_context, script, len,
                         filename, &code, &error)) {
    g_free (script);
    g_printerr ("%s\n", error->message);
    exit (1);
  }

  g_free (script);
  exit (code);
}
Exemplo n.º 25
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;
}
/**
 * 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;
}
Exemplo n.º 27
0
int
main (int argc, char **argv)
{
  GOptionContext *ctx;
  GError *error = NULL;
  int ecode;
  TpDebugSender *sender;

  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);

  session_mode = (char *) g_getenv ("GNOME_SHELL_SESSION_MODE");

  ctx = meta_get_option_context ();
  g_option_context_add_main_entries (ctx, gnome_shell_options, GETTEXT_PACKAGE);
  g_option_context_add_group (ctx, g_irepository_get_option_group ());
  if (!g_option_context_parse (ctx, &argc, &argv, &error))
    {
      g_printerr ("%s: %s\n", argv[0], error->message);
      exit (1);
    }

  g_option_context_free (ctx);

  meta_plugin_manager_set_plugin_type (gnome_shell_plugin_get_type ());

  meta_set_wm_name (WM_NAME);
  meta_set_gnome_wm_keybindings (GNOME_WM_KEYBINDINGS);

  meta_init ();

  /* FIXME: Add gjs API to set this stuff and don't depend on the
   * environment.  These propagate to child processes.
   */
  g_setenv ("GJS_DEBUG_OUTPUT", "stderr", TRUE);
  g_setenv ("GJS_DEBUG_TOPICS", "JS ERROR;JS LOG", TRUE);

  shell_init_debug (g_getenv ("SHELL_DEBUG"));

  shell_dbus_init (meta_get_replace_current_wm ());
  shell_a11y_init ();
  shell_perf_log_init ();
  shell_introspection_init ();
  shell_fonts_init ();

  /* Turn on telepathy-glib debugging but filter it out in
   * default_log_handler. This handler also exposes all the logs over D-Bus
   * using TpDebugSender. */
  tp_debug_set_flags ("all");

  sender = tp_debug_sender_dup ();

  g_log_set_default_handler (default_log_handler, sender);

  /* Initialize the global object */
  if (session_mode == NULL)
    session_mode = is_gdm_mode ? "gdm" : "user";

  _shell_global_init ("session-mode", session_mode, NULL);

  shell_prefs_init ();

  ecode = meta_run ();

  if (g_getenv ("GNOME_SHELL_ENABLE_CLEANUP"))
    {
      g_printerr ("Doing final cleanup...\n");
      g_object_unref (shell_global_get ());
    }

  g_object_unref (sender);

  return ecode;
}