/*
 * get_app_from_window_pid:
 * @tracker: a #ShellWindowTracker
 * @window: a #MetaWindow
 *
 * Check if the pid associated with @window corresponds to an
 * application.
 *
 * Return value: (transfer full): A newly-referenced #ShellApp, or %NULL
 */
static ShellApp *
get_app_from_window_pid (ShellWindowTracker  *tracker,
                         MetaWindow          *window)
{
  ShellApp *result;
  int pid;

  if (meta_window_is_remote (window))
    return NULL;

  pid = meta_window_get_pid (window);

  if (pid == -1)
    return NULL;

  result = shell_window_tracker_get_app_from_pid (tracker, pid);

  if (result == NULL)
    result = g_hash_table_lookup (tracker->launched_pid_to_app, GINT_TO_POINTER (pid));

  if (result != NULL)
    g_object_ref (result);

  return result;
}
Example #2
0
void
meta_window_kill (MetaWindow *window)
{
  meta_topic (META_DEBUG_WINDOW_OPS,
              "Killing %s brutally\n",
              window->desc);

  if (!meta_window_is_remote (window) &&
      window->net_wm_pid > 0)
    {
      meta_topic (META_DEBUG_WINDOW_OPS,
                  "Killing %s with kill()\n",
                  window->desc);

      if (kill (window->net_wm_pid, 9) < 0)
        meta_topic (META_DEBUG_WINDOW_OPS,
                    "Failed to signal %s: %s\n",
                    window->desc, strerror (errno));
    }

  meta_topic (META_DEBUG_WINDOW_OPS,
              "Disconnecting %s with XKillClient()\n",
              window->desc);
  meta_error_trap_push (window->display);
  XKillClient (window->display->xdisplay, window->xwindow);
  meta_error_trap_pop (window->display);
}
/**
 * get_app_for_window:
 *
 * Determines the application associated with a window, using
 * all available information such as the window's MetaGroup,
 * and what we know about other windows.
 *
 * Returns: (transfer full): a #CinnamonApp, or NULL if none is found
 */
static CinnamonApp *
get_app_for_window (CinnamonWindowTracker    *tracker,
                    MetaWindow            *window)
{
  CinnamonApp *result = NULL;
  const char *startup_id;

  /* First, we check whether we already know about this window,
   * if so, just return that.
   */
  if (meta_window_get_window_type (window) == META_WINDOW_NORMAL
      || meta_window_is_remote (window))
    {
      result = g_hash_table_lookup (tracker->window_to_app, window);
      if (result != NULL)
        {
          g_object_ref (result);
          return result;
        }
    }

  if (meta_window_is_remote (window))
    return _cinnamon_app_new_for_window (window);

  /* Check if the window has a GApplication ID attached; this is
   * canonical if it does
   */
  result = get_app_from_gapplication_id (window);
  if (result != NULL)
    return result;

  /* Check if the app's WM_CLASS specifies an app; this is
   * canonical if it does.
   */
  result = get_app_from_window_wmclass (window);
  if (result != NULL)
    return result;

  result = get_app_from_window_pid (tracker, window);
  if (result != NULL)
    return result;

  /* Now we check whether we have a match through startup-notification */
  startup_id = meta_window_get_startup_id (window);
  if (startup_id)
    {
      GSList *iter, *sequences;

      sequences = cinnamon_window_tracker_get_startup_sequences (tracker);
      for (iter = sequences; iter; iter = iter->next)
        {
          CinnamonStartupSequence *sequence = iter->data;
          const char *id = cinnamon_startup_sequence_get_id (sequence);
          if (strcmp (id, startup_id) != 0)
            continue;

          result = cinnamon_startup_sequence_get_app (sequence);
          if (result)
            {
              result = g_object_ref (result);
              break;
            }
        }
    }

  /* If we didn't get a startup-notification match, see if we matched
   * any other windows in the group.
   */
  if (result == NULL)
    result = get_app_from_window_group (tracker, window);

  /* Our last resort - we create a fake app from the window */
  if (result == NULL)
    result = _cinnamon_app_new_for_window (window);

  return result;
}