Chromium Code Reviews| Index: ui/base/x/x11_window_cache.h |
| diff --git a/ui/base/x/x11_window_cache.h b/ui/base/x/x11_window_cache.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..096ac945e5b8d2cd08d4286ee53982be640d2e57 |
| --- /dev/null |
| +++ b/ui/base/x/x11_window_cache.h |
| @@ -0,0 +1,178 @@ |
| +// Copyright 2016 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 UI_BASE_X_X11_WINDOW_CACHE_H_ |
| +#define UI_BASE_X_X11_WINDOW_CACHE_H_ |
| + |
| +#include <xcb/xcb.h> |
| + |
| +#include <list> |
| +#include <map> |
| +#include <queue> |
| + |
| +#include "ui/base/x/ui_base_x_export.h" |
| +#include "ui/gfx/x/x11_types.h" |
| + |
| +namespace ui { |
| + |
| +// Keep tabs on the window tree starting from a root window. |
| +class UI_BASE_X_EXPORT XWindowCache { |
| + public: |
| + // Clients should not modify any members of Property. |
| + struct Property { |
| + Property(xcb_atom_t name); |
| + ~Property(); |
| + |
| + xcb_atom_t name; |
| + |
| + bool cached_property; |
| + xcb_atom_t type; |
| + // Format can be 8, 16, or 32, indicating how |data| should be interpreted. |
| + uint8_t data_format; |
| + int data_length; |
| + union { |
| + uint8_t* bits_8; |
| + uint16_t* bits_16; |
| + uint32_t* bits_32; |
| + } data; |
| + }; |
| + |
| + // Clients should not modify any members of Window. |
|
Tom (Use chromium acct)
2016/07/26 20:17:43
Not sure what the best API design is here.
XWindo
Tom (Use chromium acct)
2016/08/06 00:38:17
Still need help on this
|
| + struct Window { |
| + Window(xcb_window_t id, Window* parent); |
| + ~Window(); |
| + |
| + xcb_window_t id; |
| + Window* parent; |
| + |
| + bool cached_attributes; |
| + bool override_redirect; |
| + // |is_mapped| is different from the map_state that is returned by |
| + // XGetWindowAttributes. map_state can be one of IsUnmapped, IsUnviewable, |
| + // or IsViewable. map_state is set to IsUnviewable when the window is |
| + // mapped but some ancestor window is unmapped. If you need to check for |
| + // this case, you must do so manually. |
| + bool is_mapped; |
| + |
| + bool cached_geometry; |
| + int16_t x, y; |
| + uint16_t width, height; |
| + uint16_t border_width; |
| + |
| + bool cached_properties; |
| + std::map<xcb_atom_t, std::unique_ptr<Property>> properties; |
| + |
| + bool cached_children; |
| + std::list<Window*> children; |
| + |
| + const Property* GetProperty(XID atom) const; |
| + }; |
| + |
| + XWindowCache(XDisplay* display, XID root); |
| + ~XWindowCache(); |
| + |
| + bool ConnectionHasError() const; |
| + int ConnectionFd() const; |
| + |
| + // Reads any events and responses that are available, and makes new requests |
| + // if necessary. |
| + void OnConnectionReadable(); |
| + |
| + // Ensures we have the state of the entire window tree. May block. Returns |
| + // false iff there was a connection error or a timeout. Mainly used in |
| + // testing. |
| + bool BlockUntilTreeIsCached(); |
| + // Ensures we have processed all events sent server-side before Synchronize |
| + // was called client-side. We may be forced to wait for more events to come |
| + // that are not yet in the queue. You most likely want to |
| + // BlockUntilWindowTreeIsCached before and after calling Synchronize. Blocks. |
| + // Returns false iff there was a connection error or a timeout. Mainly used in |
| + // testing. |
| + bool Synchronize(); |
| + // Similar to Synchronize, except synchronizes this cache to a different |
| + // client. As an example, a client might change a property, and wants to be |
| + // sure the cache is up-to-date with the property change. |
| + bool SynchronizeWith(XDisplay* display); |
| + |
| + // Returns null when window |id| is not cached. |
| + const Window* GetWindow(XID id) const; |
| + |
| + void PrintWindowTreeForTesting() const; |
| + |
| + private: |
| + struct Request { |
| + Request(); |
| + virtual ~Request(); |
| + |
| + virtual void OnReply(void* reply, XWindowCache* cache) = 0; |
| + |
| + // The sequence number is logically an arbitrary-sized integer. However, |
| + // the X11 protocol only tracks the lower 16 bits, so that's all we need to |
| + // keep. |
| + uint16_t sequence; |
| + }; |
| + |
| + struct GetWindowAttributesRequest : public XWindowCache::Request { |
| + GetWindowAttributesRequest(xcb_window_t window, XWindowCache* cache); |
| + void OnReply(void* reply, XWindowCache* cache) override; |
| + xcb_window_t id; |
| + }; |
| + |
| + struct GetGeometryRequest : public XWindowCache::Request { |
| + GetGeometryRequest(xcb_window_t window, XWindowCache* cache); |
| + void OnReply(void* reply, XWindowCache* cache) override; |
| + xcb_window_t id; |
| + }; |
| + |
| + struct ListPropertiesRequest : public XWindowCache::Request { |
| + ListPropertiesRequest(xcb_window_t window, XWindowCache* cache); |
| + void OnReply(void* reply, XWindowCache* cache) override; |
| + xcb_window_t id; |
| + }; |
| + |
| + struct QueryTreeRequest : public XWindowCache::Request { |
| + QueryTreeRequest(xcb_window_t window, XWindowCache* cache); |
| + void OnReply(void* reply, XWindowCache* cache) override; |
| + xcb_window_t id; |
| + }; |
| + |
| + struct GetPropertyRequest : public XWindowCache::Request { |
| + GetPropertyRequest(xcb_window_t window, |
| + xcb_atom_t atom, |
| + XWindowCache* cache); |
| + void OnReply(void* reply, XWindowCache* cache) override; |
| + xcb_window_t id; |
| + xcb_atom_t atom; |
| + }; |
| + |
| + void CacheProperty(Window* window, xcb_atom_t atom); |
| + void CacheWindow(Window* window); |
| + |
| + void DeleteSubtree(Window* window); |
| + |
| + void ProcessEvent(xcb_generic_event_t* event); |
| + |
| + Window* GetWindow(xcb_window_t id) const; |
| + |
| + // Returns false iff there was a connection error or a timeout. |
| + bool BlockUntilConnectionIsReadable(); |
| + |
| + void PrintWindowTreeForTestingAux(Window* window, int indent) const; |
| + |
| + // Outstanding requests that should be serviced. |
| + std::queue<std::unique_ptr<Request>> requests_; |
| + |
| + xcb_connection_t* connection_; |
| + Window* root_; |
| + std::map<xcb_window_t, std::unique_ptr<Window>> windows_; |
| + |
| + // Don't cache icon properties because they take up too much space and we |
| + // currently never use them. |
| + xcb_intern_atom_cookie_t net_wm_icon_cookie_; |
| + xcb_atom_t net_wm_icon_; |
| +}; |
| + |
| +} // namespace ui |
| + |
| +#endif // UI_BASE_X_X11_WINDOW_CACHE_H_ |