示例#1
0
void
meta_stack_tracker_record_lower (MetaStackTracker *tracker,
				 Window            window,
				 gulong            serial)
{
  meta_stack_tracker_record_raise_above (tracker, window, None, serial);
}
示例#2
0
文件: stack.c 项目: collinss/muffin
/*
 * This function is used to avoid raising a window above popup
 * menus and other such things.
 *
 * The key to the operation of this function is that we are expecting
 * at most one window to be added at a time. If xwindow is newly added,
 * then its own stack position will be too high (the frame window
 * is created at the top of the stack), but if we ignore xwindow,
 * then the *next* managed window in the stack will be a window that
 * we've already stacked.
 *
 * We could generalize this and remove the assumption that windows
 * are added one at a time by keeping an explicit ->stacked flag in
 * MetaWindow.
 *
 * An alternate approach would be to reverse the stacking algorithm to
 * work by placing each window above the others, and start by lowering
 * a window to the bottom (instead of the current way, which works by
 * placing each window below another and starting with a raise)
 */
static void
raise_window_relative_to_managed_windows (MetaScreen *screen,
                                          Window      xwindow)
{

  Window *children;
  int n_children;
  int i;

  meta_stack_tracker_get_stack (screen->stack_tracker,
                                &children, &n_children);

  /* Children are in order from bottom to top. We want to
   * find the topmost managed child, then configure
   * our window to be above it.
   */
  i = n_children - 1;
  while (i >= 0)
    {
      if (children[i] == xwindow)
        {
          /* Do nothing. This means we're already the topmost managed
           * window, but it DOES NOT mean we are already just above
           * the topmost managed window. This is important because if
           * an override redirect window is up, and we map a new
           * managed window, the new window is probably above the old
           * popup by default, and we want to push it below that
           * popup. So keep looking for a sibling managed window
           * to be moved below.
           */
        }
      else
        {
          MetaWindow *other = meta_display_lookup_x_window (screen->display,
                                                            children[i]);
          if (other != NULL && !other->override_redirect && !other->unmanaging)
            {
              XWindowChanges changes;

              /* children[i] is the topmost managed child */
              meta_topic (META_DEBUG_STACK,
                          "Moving 0x%lx above topmost managed child window 0x%lx\n",
                          xwindow, children[i]);

              changes.sibling = children[i];
              changes.stack_mode = Above;

              meta_error_trap_push (screen->display);
              meta_stack_tracker_record_raise_above (screen->stack_tracker,
                                                     xwindow,
                                                     children[i],
                                                     XNextRequest (screen->display->xdisplay));
              XConfigureWindow (screen->display->xdisplay,
                                xwindow,
                                CWSibling | CWStackMode,
                                &changes);
              meta_error_trap_pop (screen->display);

              break;
            }
        }

      --i;
    }

  if (i < 0)
    {
      /* No sibling to use, just lower ourselves to the bottom
       * to be sure we're below any override redirect windows.
       */
      meta_error_trap_push (screen->display);
      meta_stack_tracker_record_lower (screen->stack_tracker,
                                       xwindow,
                                       XNextRequest (screen->display->xdisplay));
      XLowerWindow (screen->display->xdisplay,
                    xwindow);
      meta_error_trap_pop (screen->display);
    }
}