blob: a7bd4a2c954c8e4efa10fe712601621a789fa21c [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WINDOW_MANAGER_STACKING_MANAGER_H_
#define WINDOW_MANAGER_STACKING_MANAGER_H_
#include <map>
#include <tr1/memory>
#include <gtest/gtest_prod.h> // for FRIEND_TEST() macro
#include "window_manager/compositor/compositor.h"
#include "window_manager/x11/x_types.h"
namespace window_manager {
class AtomCache;
class Window;
class XConnection;
// Used to stack X11 client windows and compositor actors. StackingManager
// creates a window and an actor to use as reference points for each
// logical stacking layer and provides methods to move windows and actors
// between layers.
class StackingManager {
public:
// Layers into which windows can be stacked, in top-to-bottom order.
// Layers above LAYER_TOP_CLIENT_WINDOW don't have X windows, since we want
// them to always appear above client windows.
enum Layer {
// Debugging objects that should be stacked above everything else.
LAYER_DEBUGGING = 0,
// Snapshots of the screen animated while locking or shutting down.
LAYER_SCREEN_LOCKER_SNAPSHOT,
// Actors belonging to client windows are initially stacked at this layer.
// They shouldn't be raised above it (but note that an override-redirect
// window can stack itself above this layer's X window -- the layers above
// this one have no X windows, so their actors should always be stacked
// above client windows' actors).
LAYER_TOP_CLIENT_WINDOW,
// Chrome screen locker window.
LAYER_SCREEN_LOCKER,
// A fullscreen window (maybe a browser window; maybe a panel content
// window).
LAYER_FULLSCREEN_WINDOW,
// A panel as it's being dragged. This is a separate layer so that the
// panel's shadow will be cast over stationary panels.
LAYER_DRAGGED_PANEL,
// A transient window belonging to the currently-active toplevel
// window. Transients are stacked here when in active mode so that
// they'll obscure panels. (In overview mode, they're stacked directly
// above their owners.)
LAYER_ACTIVE_TRANSIENT_WINDOW,
// Panel bar's input windows.
LAYER_PANEL_BAR_INPUT_WINDOW,
// A stationary, packed (that is, in the main group on the right) panel
// in the panel bar.
LAYER_PACKED_PANEL_IN_BAR,
// A stationary, floating ("independently positioned") panel in the
// panel bar.
LAYER_FLOATING_PANEL_IN_BAR,
// A stationary panel in a panel dock.
LAYER_PACKED_PANEL_IN_DOCK,
// Panel docks along the sides of the screen (specifically, their
// backgrounds).
LAYER_PANEL_DOCK,
// The currently active (i.e. stacked-on-top) browser window.
LAYER_ACTIVE_BROWSER_WINDOW,
// An inactive browser window.
LAYER_INACTIVE_BROWSER_WINDOW,
// "Other" non-login windows (e.g. transient dialogs) managed by
// LoginController.
LAYER_LOGIN_OTHER_WINDOW,
// Chrome login windows used by LoginController.
LAYER_LOGIN_WINDOW,
// The background image.
LAYER_BACKGROUND,
kNumLayers,
};
// Policies for stacking something relative to a supplied sibling.
enum SiblingPolicy {
// Stack the object directly above the sibling.
ABOVE_SIBLING = 0,
// Stack the object directly below the sibling.
BELOW_SIBLING,
};
// Policies for stacking a window's shadow.
enum ShadowPolicy {
// Stack the shadow at the bottom of layer specified by the |shadow_layer|
// parameter. This can be useful for preventing a window's shadow from
// falling on its siblings -- imagine the case of two panels in the same
// layer that are located a pixel apart.
SHADOW_AT_BOTTOM_OF_SHADOW_LAYER = 0,
// Stack the shadow directly below |win|'s actor.
SHADOW_DIRECTLY_BELOW_ACTOR,
};
// The layer reference points will be created at the top of the current stack
// of X windows (for LAYER_TOP_CLIENT_WINDOW and below) and children of the
// default compositor stage.
StackingManager(XConnection* xconn,
Compositor* compositor,
AtomCache* atom_cache);
~StackingManager();
// Is the passed-in X window one of our internal windows?
bool IsInternalWindow(XWindow xid) {
return (xid_to_layer_.find(xid) != xid_to_layer_.end());
}
// Stack a window (both its X window and its compositor actor) at the top
// of the passed-in layer, which must be LAYER_TOP_CLIENT_WINDOW or below.
// |shadow_layer| is only honored if |shadow_policy| is
// SHADOW_AT_BOTTOM_OF_SHADOW_LAYER.
void StackWindowAtTopOfLayer(
Window* win,
Layer layer,
ShadowPolicy shadow_policy,
Layer shadow_layer);
// Stack an X window at the top of the passed-in layer, which must be
// LAYER_TOP_CLIENT_WINDOW or below. This is useful for X windows that don't
// have Window objects associated with them (e.g. input windows).
void StackXidAtTopOfLayer(XWindow xid, Layer layer);
// Stack a compositor actor at the top of the passed-in layer.
void StackActorAtTopOfLayer(Compositor::Actor* actor, Layer layer);
// Stack a window's client and composited windows directly above or below
// another window.
void StackWindowRelativeToOtherWindow(
Window* win,
Window* sibling,
SiblingPolicy sibling_policy,
ShadowPolicy shadow_policy,
Layer shadow_layer);
// Stack a compositor actor above or below another actor.
void StackActorRelativeToOtherActor(
Compositor::Actor* actor,
Compositor::Actor* sibling,
SiblingPolicy sibling_policy);
// If |xid| is being used as a layer's stacking reference point, return
// the actor corresponding to the layer. Returns NULL otherwise.
Compositor::Actor* GetActorIfLayerXid(XWindow xid);
private:
friend class BasicWindowManagerTest; // uses Get*ForLayer()
FRIEND_TEST(LayoutManagerTest, InitialWindowStacking); // uses |layer_to_*|
FRIEND_TEST(WindowManagerTest, StackOverrideRedirectWindowsAboveLayers);
// Get a layer's name.
static const char* LayerToName(Layer layer);
// Get the actor or XID for a particular layer. These crash if the layer
// is invalid.
Compositor::Actor* GetActorForLayer(Layer layer);
XWindow GetXidForLayer(Layer layer);
XConnection* xconn_; // not owned
// Maps from layers to the corresponding X or Compositor reference points.
// The reference points are stacked at the top of their corresponding
// layer (in other words, the Stack*AtTopOfLayer() methods will stack
// windows and actors directly beneath the corresponding reference
// points).
std::map<Layer, XWindow> layer_to_xid_;
std::map<Layer, std::tr1::shared_ptr<Compositor::Actor> >
layer_to_actor_;
// Map we can use for quick lookup of whether an X window belongs to us,
// and to find the layer corresponding to an X window.
std::map<XWindow, Layer> xid_to_layer_;
};
} // namespace window_manager
#endif // WINDOW_MANAGER_STACKING_MANAGER_H_