Esempio n. 1
0
static MetaWindow*
get_default_focus_window (MetaStack     *stack,
                          MetaWorkspace *workspace,
                          MetaWindow    *not_this_one,
                          gboolean       must_be_at_point,
                          int            root_x,
                          int            root_y)
{
  /* Find the topmost, focusable, mapped, window.
   * not_this_one is being unfocused or going away, so exclude it.
   * Also, prefer to focus transient parent of not_this_one,
   * or top window in same group as not_this_one.
   */

  MetaWindow *transient_parent;
  MetaWindow *topmost_in_group;
  MetaWindow *topmost_overall;
  MetaGroup *not_this_one_group;
  GList *l;

  transient_parent = NULL;
  topmost_in_group = NULL;
  topmost_overall = NULL;
  if (not_this_one)
    not_this_one_group = meta_window_get_group (not_this_one);
  else
    not_this_one_group = NULL;

  stack_ensure_sorted (stack);

  /* top of this layer is at the front of the list */
  for (l = stack->sorted; l != NULL; l = l->next)
    {
      MetaWindow *window = l->data;

      if (!window)
        continue;

      if (window == not_this_one)
        continue;

      if (window->unmaps_pending > 0)
        continue;

      if (window->minimized)
        continue;

      if (window->unmanaging)
        continue;

      if (!(window->input || window->take_focus))
        continue;

      if (workspace != NULL && !meta_window_located_on_workspace (window, workspace))
        continue;

      if (must_be_at_point && !window_contains_point (window, root_x, root_y))
        continue;

      if (not_this_one != NULL)
        {
          if (transient_parent == NULL &&
              meta_window_get_transient_for (not_this_one) == window)
            transient_parent = window;

          if (topmost_in_group == NULL &&
              not_this_one_group != NULL &&
              not_this_one_group == meta_window_get_group (window))
            topmost_in_group = window;
        }

      if (topmost_overall == NULL && window->type != META_WINDOW_DOCK)
        topmost_overall = window;

      /* We could try to bail out early here for efficiency in
       * some cases, but it's just not worth the code.
       */
    }

  if (transient_parent)
    return transient_parent;
  else if (topmost_in_group)
    return topmost_in_group;
  else if (topmost_overall)
    return topmost_overall;
  else
    return NULL;
}
Esempio n. 2
0
static MetaWindow*
get_default_focus_window (MetaStack     *stack,
                          MetaWorkspace *workspace,
                          MetaWindow    *not_this_one,
                          gboolean       must_be_at_point,
                          int            root_x,
                          int            root_y)
{
  /* Find the topmost, focusable, mapped, window.
   * not_this_one is being unfocused or going away, so exclude it.
   * Also, prefer to focus transient parent of not_this_one,
   * or top window in same group as not_this_one.
   */

  MetaWindow *topmost_dock;
  MetaWindow *transient_parent;
  MetaWindow *topmost_in_group;
  MetaWindow *topmost_overall;
  MetaGroup *not_this_one_group;
  GList *link;
  
  topmost_dock = NULL;
  transient_parent = NULL;
  topmost_in_group = NULL;
  topmost_overall = NULL;
  if (not_this_one)
    not_this_one_group = meta_window_get_group (not_this_one);
  else
    not_this_one_group = NULL;

  stack_ensure_sorted (stack);

  /* top of this layer is at the front of the list */
  link = stack->sorted;
      
  while (link)
    {
      MetaWindow *window = link->data;

      if (window &&
          window != not_this_one &&
          (window->unmaps_pending == 0) &&
          !window->minimized &&
          (window->input || window->take_focus) &&
          (workspace == NULL ||
           meta_window_located_on_workspace (window, workspace)))
        {
          if (topmost_dock == NULL &&
              window->type == META_WINDOW_DOCK)
            topmost_dock = window;

          if (not_this_one != NULL)
            {
              if (transient_parent == NULL &&
                  not_this_one->xtransient_for != None &&
                  not_this_one->xtransient_for == window->xwindow &&
                  (!must_be_at_point ||
                   window_contains_point (window, root_x, root_y)))
                transient_parent = window;

              if (topmost_in_group == NULL &&
                  not_this_one_group != NULL &&
                  not_this_one_group == meta_window_get_group (window) &&
                  (!must_be_at_point ||
                   window_contains_point (window, root_x, root_y)))
                topmost_in_group = window;
            }

          /* Note that DESKTOP windows can be topmost_overall so
           * we prefer focusing desktop or other windows over
           * focusing dock, even though docks are stacked higher.
           */
          if (topmost_overall == NULL &&
              window->type != META_WINDOW_DOCK &&
              (!must_be_at_point ||
               window_contains_point (window, root_x, root_y)))
            topmost_overall = window;

          /* We could try to bail out early here for efficiency in
           * some cases, but it's just not worth the code.
           */
        }

      link = link->next;
    }

  if (transient_parent)
    return transient_parent;
  else if (topmost_in_group)
    return topmost_in_group;
  else if (topmost_overall)
    return topmost_overall;
  else
    return topmost_dock;
}