blob: a70fcf1d622de3fdfb17d11fe046fc1463def873 [file] [log] [blame]
// Copyright (c) 2011 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.
#include <map>
#include <gflags/gflags.h>
#include <gtest/gtest.h>
#include "base/logging.h"
#include "window_manager/test_lib.h"
#include "window_manager/transient_window_collection.h"
#include "window_manager/stacking_manager.h"
#include "window_manager/window.h"
#include "window_manager/window_manager.h"
DEFINE_bool(logtostderr, false,
"Print debugging messages to stderr (suppressed otherwise)");
using std::map;
namespace window_manager {
class TransientWindowCollectionTest : public BasicWindowManagerTest {};
TEST_F(TransientWindowCollectionTest, Stacking) {
// Create an owner window and stack it in the fullscreen layer.
XWindow owner_xid = CreateSimpleWindow();
XConnection::WindowGeometry geometry;
ASSERT_TRUE(xconn_->GetWindowGeometry(owner_xid, &geometry));
Window owner_win(wm_.get(), owner_xid, false, geometry);
wm_->stacking_manager()->StackWindowAtTopOfLayer(
&owner_win,
StackingManager::LAYER_FULLSCREEN_WINDOW,
StackingManager::SHADOW_AT_BOTTOM_OF_SHADOW_LAYER,
StackingManager::LAYER_FULLSCREEN_WINDOW);
TestEventConsumer event_consumer;
TransientWindowCollection transients(
&owner_win,
TransientWindowCollection::STACK_ABOVE_OWNER,
TransientWindowCollection::CENTER_OVER_OWNER,
TransientWindowCollection::KEEP_ONSCREEN_ALWAYS,
&event_consumer);
// Create a window to treat as transient.
XWindow transient_xid = CreateSimpleWindow();
ASSERT_TRUE(xconn_->GetWindowGeometry(transient_xid, &geometry));
Window transient_win(wm_.get(), transient_xid, false, geometry);
// After the window is added to the collection, it should be stacked above its
// owner.
transients.AddWindow(&transient_win);
EXPECT_TRUE(WindowIsInLayer(&transient_win,
StackingManager::LAYER_FULLSCREEN_WINDOW));
MockCompositor::StageActor* stage = compositor_->GetDefaultStage();
EXPECT_LT(stage->GetStackingIndex(transient_win.GetBottomActor()),
stage->GetStackingIndex(owner_win.GetTopActor()));
// Now change the stacking policy and check that the transient is restacked.
transients.set_stacking_policy(TransientWindowCollection::STACK_IN_LAYER);
transients.ApplyStackingForAllWindows();
EXPECT_TRUE(WindowIsInLayer(&transient_win,
StackingManager::LAYER_ACTIVE_TRANSIENT_WINDOW));
// Add a second transient. It should get stacked on top.
XWindow transient_xid2 = CreateSimpleWindow();
ASSERT_TRUE(xconn_->GetWindowGeometry(transient_xid2, &geometry));
Window transient_win2(wm_.get(), transient_xid2, false, geometry);
transients.AddWindow(&transient_win2);
EXPECT_LT(stage->GetStackingIndex(transient_win2.GetBottomActor()),
stage->GetStackingIndex(transient_win.GetTopActor()));
// Make the second transient modal.
map<XAtom, bool> wm_state;
wm_state[xconn_->GetAtomOrDie("_NET_WM_STATE_MODAL")] = true;
transient_win2.ChangeWmState(wm_state);
ASSERT_TRUE(transient_win2.wm_state_modal());
// Now add a third, non-modal transient and check that it gets stacked below
// the second transient.
XWindow transient_xid3 = CreateSimpleWindow();
ASSERT_TRUE(xconn_->GetWindowGeometry(transient_xid3, &geometry));
Window transient_win3(wm_.get(), transient_xid3, false, geometry);
transients.AddWindow(&transient_win3);
EXPECT_LT(stage->GetStackingIndex(transient_win2.GetBottomActor()),
stage->GetStackingIndex(transient_win3.GetTopActor()));
EXPECT_LT(stage->GetStackingIndex(transient_win3.GetBottomActor()),
stage->GetStackingIndex(transient_win.GetTopActor()));
// If all of the windows are modal, then a fourth, non-modal transient should
// get stacked on the bottom.
transient_win.ChangeWmState(wm_state);
transient_win3.ChangeWmState(wm_state);
XWindow transient_xid4 = CreateSimpleWindow();
ASSERT_TRUE(xconn_->GetWindowGeometry(transient_xid4, &geometry));
Window transient_win4(wm_.get(), transient_xid4, false, geometry);
transients.AddWindow(&transient_win4);
EXPECT_LT(stage->GetStackingIndex(transient_win2.GetBottomActor()),
stage->GetStackingIndex(transient_win3.GetTopActor()));
EXPECT_LT(stage->GetStackingIndex(transient_win3.GetBottomActor()),
stage->GetStackingIndex(transient_win.GetTopActor()));
EXPECT_LT(stage->GetStackingIndex(transient_win.GetBottomActor()),
stage->GetStackingIndex(transient_win4.GetTopActor()));
transients.RemoveWindow(&transient_win);
transients.RemoveWindow(&transient_win2);
transients.RemoveWindow(&transient_win3);
transients.RemoveWindow(&transient_win4);
}
} // namespace window_manager
int main(int argc, char** argv) {
return window_manager::InitAndRunTests(&argc, argv, &FLAGS_logtostderr);
}