Skip to content

Commit

Permalink
Adds a generic window management interface to mus.
Browse files Browse the repository at this point in the history
This patch replaces the last direct usage in chrome code of
//ash/wm/tablet_mode_controller.cc by adding a generic interface to mus
for window manager specific actions.

Bug: 766759
Change-Id: Ifd38c6b94d27e6cdcd7f130a44802e020c824610
Reviewed-on: https://chromium-review.googlesource.com/726971
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Elliot Glaysher <erg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#511336}
  • Loading branch information
eglaysher authored and Commit Bot committed Oct 25, 2017
1 parent d255982 commit 247b763
Show file tree
Hide file tree
Showing 30 changed files with 196 additions and 4 deletions.
8 changes: 8 additions & 0 deletions ash/mus/window_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "ash/public/cpp/window_pin_type.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/public/cpp/window_state_type.h"
#include "ash/public/interfaces/window_actions.mojom.h"
#include "ash/public/interfaces/window_pin_type.mojom.h"
#include "ash/public/interfaces/window_state_type.mojom.h"
#include "ash/root_window_controller.h"
Expand All @@ -35,6 +36,7 @@
#include "ash/shell_init_params.h"
#include "ash/wayland/wayland_server_controller.h"
#include "ash/wm/ash_focus_rules.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_state.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/common/accelerator_util.h"
Expand Down Expand Up @@ -501,6 +503,12 @@ void WindowManager::OnWmDeactivateWindow(aura::Window* window) {
Shell::Get()->activation_client()->DeactivateWindow(window);
}

void WindowManager::OnWmPerformAction(aura::Window* window,
const std::string& action) {
if (action == mojom::kAddWindowToTabletMode)
ash::Shell::Get()->tablet_mode_controller()->AddWindow(window);
}

void WindowManager::OnEventBlockedByModalWindow(aura::Window* window) {
AnimateWindow(window, ::wm::WINDOW_ANIMATION_TYPE_BOUNCE);
}
Expand Down
2 changes: 2 additions & 0 deletions ash/mus/window_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class WindowManager : public aura::WindowManagerDelegate,
const std::vector<gfx::Rect>& additional_client_areas) override;
bool IsWindowActive(aura::Window* window) override;
void OnWmDeactivateWindow(aura::Window* window) override;
void OnWmPerformAction(aura::Window* window,
const std::string& action) override;
void OnEventBlockedByModalWindow(aura::Window* window) override;

service_manager::Connector* connector_;
Expand Down
1 change: 1 addition & 0 deletions ash/public/interfaces/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ mojom("interfaces_internal") {
"volume.mojom",
"vpn_list.mojom",
"wallpaper.mojom",
"window_actions.mojom",
"window_pin_type.mojom",
"window_state_type.mojom",
"window_style.mojom",
Expand Down
10 changes: 10 additions & 0 deletions ash/public/interfaces/window_actions.mojom
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module ash.mojom;

// The multiprofile mode in chromeos performs tricks with window visibility
// which require manually notifying the tablet mode controller that a window
// should be considered visible.
const string kAddWindowToTabletMode = "ash:add-window-to-tablet-mode";
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@

#include "ash/multi_profile_uma.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/public/interfaces/window_actions.mojom.h"
#include "ash/shell.h" // mash-ok
#include "ash/wm/tablet_mode/tablet_mode_controller.h" // mash-ok
#include "ash/wm/window_state.h"
#include "base/auto_reset.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/ash_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/ash/media_client.h"
Expand All @@ -33,6 +35,7 @@
#include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
Expand Down Expand Up @@ -710,8 +713,16 @@ void MultiUserWindowManagerChromeOS::SetWindowVisible(
// are not user activatable. Since invisible windows are not being tracked,
// we tell it to maximize / track this window now before it gets shown, to
// reduce animation jank from multiple resizes.
if (visible)
ash::Shell::Get()->tablet_mode_controller()->AddWindow(window);
if (visible) {
// TODO(erg): When we get rid of the classic ash, get rid of the direct
// linkage on tablet_mode_controller() here.
if (chromeos::GetAshConfig() == ash::Config::MASH) {
aura::WindowTreeHostMus::ForWindow(window)->PerformWmAction(
ash::mojom::kAddWindowToTabletMode);
} else {
ash::Shell::Get()->tablet_mode_controller()->AddWindow(window);
}
}

AnimationSetter animation_setter(
window, GetAdjustedAnimationTimeInMS(animation_time_in_ms));
Expand Down
3 changes: 3 additions & 0 deletions mash/simple_wm/simple_wm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,9 @@ bool SimpleWM::IsWindowActive(aura::Window* window) { return false; }

void SimpleWM::OnWmDeactivateWindow(aura::Window* window) {}

void SimpleWM::OnWmPerformAction(aura::Window* window,
const std::string& action) {}

////////////////////////////////////////////////////////////////////////////////
// SimpleWM, wm::BaseFocusRules implementation:

Expand Down
2 changes: 2 additions & 0 deletions mash/simple_wm/simple_wm.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ class SimpleWM : public service_manager::Service,
const std::vector<gfx::Rect>& additional_client_areas) override;
bool IsWindowActive(aura::Window* window) override;
void OnWmDeactivateWindow(aura::Window* window) override;
void OnWmPerformAction(aura::Window* window,
const std::string& action) override;

// wm::BaseFocusRules:
bool SupportsChildActivation(aura::Window* window) const override;
Expand Down
3 changes: 3 additions & 0 deletions services/ui/public/interfaces/window_manager.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ interface WindowManager {
// window manager owned parent.
WmStackAtTop(uint32 change_id, uint32 window_id);

// Asks the WindowManager to perform |action| on |window_id|.
WmPerformWmAction(uint32 window_id, string action);

// An accelerator registered via AddAccelerator() has been triggered. If
// |ack_id| is non-zero the accelerator matches a PRE_TARGET and must be
// acknowledged by WindowManagerClient::OnAcceleratorAck().
Expand Down
3 changes: 3 additions & 0 deletions services/ui/public/interfaces/window_tree.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ interface WindowTree {
// Stacks the window above all sibling windows.
StackAtTop(uint32 change_id, uint32 window_id);

// Tells the window manager to perform |string_action| for |window_id|.
PerformWmAction(uint32 window_id, string action);

// See description of WindowManager for details.
GetWindowManagerClient(associated WindowManagerClient& internal);

Expand Down
1 change: 1 addition & 0 deletions services/ui/ws/access_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class AccessPolicy {
virtual bool CanStackAbove(const ServerWindow* above,
const ServerWindow* below) const = 0;
virtual bool CanStackAtTop(const ServerWindow* window) const = 0;
virtual bool CanPerformWmAction(const ServerWindow* window) const = 0;
// Used for all client controllable cursor properties; which cursor should be
// displayed, visibility, locking, etc.
virtual bool CanSetCursorProperties(const ServerWindow* window) const = 0;
Expand Down
5 changes: 5 additions & 0 deletions services/ui/ws/default_access_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ bool DefaultAccessPolicy::CanStackAtTop(const ServerWindow* window) const {
delegate_->IsWindowCreatedByWindowManager(window);
}

bool DefaultAccessPolicy::CanPerformWmAction(const ServerWindow* window) const {
return WasCreatedByThisClient(window) ||
delegate_->HasRootForAccessPolicy(window);
}

bool DefaultAccessPolicy::CanSetCursorProperties(
const ServerWindow* window) const {
return WasCreatedByThisClient(window) ||
Expand Down
1 change: 1 addition & 0 deletions services/ui/ws/default_access_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class DefaultAccessPolicy : public AccessPolicy {
bool CanStackAbove(const ServerWindow* above,
const ServerWindow* below) const override;
bool CanStackAtTop(const ServerWindow* window) const override;
bool CanPerformWmAction(const ServerWindow* window) const override;
bool CanSetCursorProperties(const ServerWindow* window) const override;
bool CanInitiateDragLoop(const ServerWindow* window) const override;
bool CanInitiateMoveLoop(const ServerWindow* window) const override;
Expand Down
5 changes: 5 additions & 0 deletions services/ui/ws/test_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,11 @@ void TestWindowManager::WmStackAbove(uint32_t change_id,

void TestWindowManager::WmStackAtTop(uint32_t change_id, uint32_t window_id) {}

void TestWindowManager::WmPerformWmAction(uint32_t window_id,
const std::string& action) {
last_wm_action_ = action;
}

void TestWindowManager::OnAccelerator(uint32_t ack_id,
uint32_t accelerator_id,
std::unique_ptr<ui::Event> event) {
Expand Down
5 changes: 5 additions & 0 deletions services/ui/ws/test_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ class TestWindowManager : public mojom::WindowManager {
on_accelerator_called_ = false;
}

const std::string& last_wm_action() const { return last_wm_action_; }
bool on_perform_move_loop_called() { return on_perform_move_loop_called_; }
bool on_accelerator_called() { return on_accelerator_called_; }
uint32_t on_accelerator_id() { return on_accelerator_id_; }
Expand Down Expand Up @@ -431,12 +432,16 @@ class TestWindowManager : public mojom::WindowManager {
void WmStackAbove(uint32_t change_id, uint32_t above_id,
uint32_t below_id) override;
void WmStackAtTop(uint32_t change_id, uint32_t window_id) override;
void WmPerformWmAction(uint32_t window_id,
const std::string& action) override;
void OnAccelerator(uint32_t ack_id,
uint32_t accelerator_id,
std::unique_ptr<ui::Event> event) override;
void OnCursorTouchVisibleChanged(bool enabled) override;
void OnEventBlockedByModalWindow(uint32_t window_id) override;

std::string last_wm_action_;

bool on_perform_move_loop_called_ = false;
bool on_set_modal_type_called_ = false;

Expand Down
7 changes: 7 additions & 0 deletions services/ui/ws/window_manager_access_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ bool WindowManagerAccessPolicy::CanStackAtTop(
return false;
}

bool WindowManagerAccessPolicy::CanPerformWmAction(
const ServerWindow* window) const {
// This API is for clients. Window managers don't need to tell themselves to
// do things.
return false;
}

bool WindowManagerAccessPolicy::CanSetCursorProperties(
const ServerWindow* window) const {
return WasCreatedByThisClient(window) ||
Expand Down
1 change: 1 addition & 0 deletions services/ui/ws/window_manager_access_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class WindowManagerAccessPolicy : public AccessPolicy {
bool CanStackAbove(const ServerWindow* above,
const ServerWindow* below) const override;
bool CanStackAtTop(const ServerWindow* window) const override;
bool CanPerformWmAction(const ServerWindow* window) const override;
bool CanSetCursorProperties(const ServerWindow* window) const override;
bool CanInitiateDragLoop(const ServerWindow* window) const override;
bool CanInitiateMoveLoop(const ServerWindow* window) const override;
Expand Down
23 changes: 23 additions & 0 deletions services/ui/ws/window_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2191,6 +2191,29 @@ void WindowTree::StackAtTop(uint32_t change_id, Id window_id) {
wm_change_id, wm_tree->TransportIdForWindow(window));
}

void WindowTree::PerformWmAction(Id window_id, const std::string& action) {
ServerWindow* window = GetWindowByClientId(MakeClientWindowId(window_id));
if (!window) {
DVLOG(1) << "PerformWmAction(" << action << ") failed (invalid id)";
return;
}

if (!access_policy_->CanPerformWmAction(window)) {
DVLOG(1) << "PerformWmAction(" << action << ") failed (access denied)";
return;
}

WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window);
if (!display_root) {
DVLOG(1) << "PerformWmAction(" << action << ") failed (no display root)";
return;
}

WindowTree* wm_tree = display_root->window_manager_state()->window_tree();
wm_tree->window_manager_internal_->WmPerformWmAction(
wm_tree->TransportIdForWindow(window), action);
}

void WindowTree::GetWindowManagerClient(
mojo::AssociatedInterfaceRequest<mojom::WindowManagerClient> internal) {
if (!access_policy_->CanSetWindowManager() || !window_manager_internal_ ||
Expand Down
1 change: 1 addition & 0 deletions services/ui/ws/window_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ class WindowTree : public mojom::WindowTree,
const base::Optional<gfx::Rect>& mask) override;
void StackAbove(uint32_t change_id, Id above_id, Id below_id) override;
void StackAtTop(uint32_t change_id, Id window_id) override;
void PerformWmAction(Id window_id, const std::string& action) override;
void GetWindowManagerClient(
mojo::AssociatedInterfaceRequest<mojom::WindowManagerClient> internal)
override;
Expand Down
4 changes: 4 additions & 0 deletions services/ui/ws/window_tree_client_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,10 @@ class TestWindowTreeClient : public mojom::WindowTreeClient,
void WmStackAtTop(uint32_t change_id, uint32_t window_id) override {
NOTIMPLEMENTED();
}
void WmPerformWmAction(uint32_t window_id,
const std::string& action) override {
NOTIMPLEMENTED();
}
void OnAccelerator(uint32_t ack_id,
uint32_t accelerator_id,
std::unique_ptr<ui::Event> event) override {
Expand Down
37 changes: 37 additions & 0 deletions services/ui/ws/window_tree_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2054,6 +2054,43 @@ TEST_F(WindowTreeTest, EmbedFlagEmbedderControlsVisibility) {
EXPECT_TRUE(tree1->SetWindowVisibility(child_window_id, true));
}

TEST_F(WindowTreeTest, PerformWmAction) {
TestWindowManager wm_internal;
set_window_manager_internal(wm_tree(), &wm_internal);

TestWindowTreeBinding* child_binding = nullptr;
WindowTree* child_tree = CreateNewTree(wm_tree()->user_id(), &child_binding);

// Create a new top level window.
std::unordered_map<std::string, std::vector<uint8_t>> properties;
const uint32_t initial_change_id = 17;
// Explicitly use an id that does not contain the client id.
const ClientWindowId embed_window_id2_in_child(child_tree->id(), 27);
static_cast<mojom::WindowTree*>(child_tree)
->NewTopLevelWindow(
initial_change_id,
child_tree->ClientWindowIdToTransportId(embed_window_id2_in_child),
properties);

// Create the window for |embed_window_id2_in_child|.
const ClientWindowId embed_window_id2 = BuildClientWindowId(wm_tree(), 2);
EXPECT_TRUE(
wm_tree()->NewWindow(embed_window_id2, ServerWindow::Properties()));
EXPECT_TRUE(wm_tree()->SetWindowVisibility(embed_window_id2, true));
EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id2));

// Ack the change, which should resume the binding.
static_cast<mojom::WindowManagerClient*>(wm_tree())
->OnWmCreatedTopLevelWindow(
0u, wm_tree()->ClientWindowIdToTransportId(embed_window_id2));

static_cast<mojom::WindowTree*>(child_tree)
->PerformWmAction(
child_tree->ClientWindowIdToTransportId(embed_window_id2_in_child),
"test-action");
EXPECT_EQ("test-action", wm_internal.last_wm_action());
}

} // namespace test
} // namespace ws
} // namespace ui
3 changes: 3 additions & 0 deletions ui/aura/mus/window_manager_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ ui::mojom::EventResult WindowManagerDelegate::OnAccelerator(
return ui::mojom::EventResult::UNHANDLED;
}

void WindowManagerDelegate::OnWmPerformAction(Window* window,
const std::string& action) {}

void WindowManagerDelegate::OnEventBlockedByModalWindow(Window* window) {}

} // namespace aura
4 changes: 4 additions & 0 deletions ui/aura/mus/window_manager_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ class AURA_EXPORT WindowManagerDelegate {
// window.
virtual void OnWmDeactivateWindow(Window* window) = 0;

// Called when a client requests that a generic action be performed. |window|
// can never be null.
virtual void OnWmPerformAction(Window* window, const std::string& action);

// Called when an event is blocked by a modal window. |window| is the modal
// window that blocked the event.
virtual void OnEventBlockedByModalWindow(Window* window);
Expand Down
17 changes: 17 additions & 0 deletions ui/aura/mus/window_tree_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,16 @@ void WindowTreeClient::WmStackAtTop(uint32_t wm_change_id, uint32_t window_id) {
window_manager_client_->WmResponse(wm_change_id, true);
}

void WindowTreeClient::WmPerformWmAction(Id window_id,
const std::string& action) {
if (!window_manager_delegate_)
return;

WindowMus* window = GetWindowByServerId(window_id);
if (window)
window_manager_delegate_->OnWmPerformAction(window->GetWindow(), action);
}

void WindowTreeClient::OnAccelerator(uint32_t ack_id,
uint32_t accelerator_id,
std::unique_ptr<ui::Event> event) {
Expand Down Expand Up @@ -2218,6 +2228,13 @@ void WindowTreeClient::OnWindowTreeHostStackAtTop(
tree_->StackAtTop(change_id, window->server_id());
}

void WindowTreeClient::OnWindowTreeHostPerformWmAction(
WindowTreeHostMus* window_tree_host,
const std::string& action) {
WindowMus* window = WindowMus::Get(window_tree_host->window());
tree_->PerformWmAction(window->server_id(), action);
}

void WindowTreeClient::OnWindowTreeHostPerformWindowMove(
WindowTreeHostMus* window_tree_host,
ui::mojom::MoveLoopSource source,
Expand Down
3 changes: 3 additions & 0 deletions ui/aura/mus/window_tree_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ class AURA_EXPORT WindowTreeClient
void WmDeactivateWindow(Id window_id) override;
void WmStackAbove(uint32_t change_id, Id above_id, Id below_id) override;
void WmStackAtTop(uint32_t change_id, uint32_t window_id) override;
void WmPerformWmAction(Id window_id, const std::string& action) override;
void OnAccelerator(uint32_t ack_id,
uint32_t accelerator_id,
std::unique_ptr<ui::Event> event) override;
Expand Down Expand Up @@ -548,6 +549,8 @@ class AURA_EXPORT WindowTreeClient
void OnWindowTreeHostStackAbove(WindowTreeHostMus* window_tree_host,
Window* window) override;
void OnWindowTreeHostStackAtTop(WindowTreeHostMus* window_tree_host) override;
void OnWindowTreeHostPerformWmAction(WindowTreeHostMus* window_tree_host,
const std::string& action) override;
void OnWindowTreeHostPerformWindowMove(
WindowTreeHostMus* window_tree_host,
ui::mojom::MoveLoopSource mus_source,
Expand Down
Loading

0 comments on commit 247b763

Please sign in to comment.