// Copyright 2014 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. #ifndef SERVICES_UI_WS_IDS_H_ #define SERVICES_UI_WS_IDS_H_ #include #include #include #include "base/containers/hash_tables.h" #include "base/hash.h" #include "base/strings/stringprintf.h" #include "services/ui/common/types.h" #include "services/ui/common/util.h" namespace ui { namespace ws { // A client id used to indicate no client. That is, no WindowTree ever gets this // id. const ClientSpecificId kInvalidClientId = 0; // Every window has a unique id associated with it (WindowId). The id is a // combination of the id assigned to the client (the high order bits) and // a unique id for the window. Each client (WindowTree) refers to the window // by an id assigned by the client (ClientWindowId). To facilitate this // WindowTree maintains a mapping between WindowId and ClientWindowId. // // This model works when the client initiates creation of windows, which is // the typical use case. Embed roots and the WindowManager are special, they // get access to windows created by other clients. These clients see the // id assigned on the server. Such clients have to take care that they only // create windows using their client id. To do otherwise could result in // multiple windows having the same ClientWindowId. WindowTree enforces // that embed roots use the client id in creating the window id to avoid // possible conflicts. struct WindowId { constexpr WindowId(ClientSpecificId client_id, ClientSpecificId window_id) : client_id(client_id), window_id(window_id) {} constexpr WindowId() : client_id(0), window_id(0) {} bool operator==(const WindowId& other) const { return other.client_id == client_id && other.window_id == window_id; } bool operator!=(const WindowId& other) const { return !(*this == other); } bool operator<(const WindowId& other) const { return std::tie(client_id, window_id) < std::tie(other.client_id, other.window_id); } std::string ToString() const { return base::StringPrintf("%u:%u", client_id, window_id); } ClientSpecificId client_id; ClientSpecificId window_id; }; // Used for ids assigned by the client. struct ClientWindowId { explicit ClientWindowId(Id id) : id(id) {} ClientWindowId() : id(0u) {} bool operator==(const ClientWindowId& other) const { return other.id == id; } bool operator!=(const ClientWindowId& other) const { return !(*this == other); } bool operator<(const ClientWindowId& other) const { return id < other.id; } Id id; }; inline WindowId WindowIdFromTransportId(Id id) { return WindowId(HiWord(id), LoWord(id)); } inline Id WindowIdToTransportId(const WindowId& id) { return (id.client_id << 16) | id.window_id; } // Returns a WindowId that is reserved to indicate no window. That is, no window // will ever be created with this id. inline WindowId InvalidWindowId() { return WindowId(kInvalidClientId, 0); } // Returns a root window id with a given index offset. inline WindowId RootWindowId(uint16_t index) { return WindowId(kInvalidClientId, 2 + index); } struct ClientWindowIdHash { size_t operator()(const ClientWindowId& id) const { return id.id; } }; struct WindowIdHash { size_t operator()(const WindowId& id) const { return WindowIdToTransportId(id); } }; } // namespace ws } // namespace ui #endif // SERVICES_UI_WS_IDS_H_