| 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..bc2d1c8a182b44f8909a11036bb5968098aee4d5
|
| --- /dev/null
|
| +++ b/ui/base/x/x11_window_cache.h
|
| @@ -0,0 +1,179 @@
|
| +// 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.
|
| + 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;
|
| +
|
| + private:
|
| + friend class XWindowCacheTest;
|
| +
|
| + struct Request {
|
| + virtual void OnReply(void* reply, XWindowCache* cache) = 0;
|
| + uint16_t sequence() { return sequence_; }
|
| +
|
| + protected:
|
| + Request(xcb_window_t id);
|
| + // 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_;
|
| + // All requests are (currently) associated with a window.
|
| + const xcb_window_t id_;
|
| + };
|
| +
|
| + struct GetWindowAttributesRequest : public XWindowCache::Request {
|
| + GetWindowAttributesRequest(xcb_window_t window, XWindowCache* cache);
|
| + void OnReply(void* reply, XWindowCache* cache) override;
|
| + };
|
| +
|
| + struct GetGeometryRequest : public XWindowCache::Request {
|
| + GetGeometryRequest(xcb_window_t window, XWindowCache* cache);
|
| + void OnReply(void* reply, XWindowCache* cache) override;
|
| + };
|
| +
|
| + struct ListPropertiesRequest : public XWindowCache::Request {
|
| + ListPropertiesRequest(xcb_window_t window, XWindowCache* cache);
|
| + void OnReply(void* reply, XWindowCache* cache) override;
|
| + };
|
| +
|
| + struct QueryTreeRequest : public XWindowCache::Request {
|
| + QueryTreeRequest(xcb_window_t window, XWindowCache* cache);
|
| + void OnReply(void* reply, XWindowCache* cache) override;
|
| + };
|
| +
|
| + struct GetPropertyRequest : public XWindowCache::Request {
|
| + GetPropertyRequest(xcb_window_t window,
|
| + xcb_atom_t atom,
|
| + XWindowCache* cache);
|
| + void OnReply(void* reply, XWindowCache* cache) override;
|
| + protected:
|
| + xcb_atom_t atom_;
|
| + };
|
| +
|
| + // Creates and adds a new property to |window|.
|
| + void CacheProperty(Window* window, xcb_atom_t atom);
|
| + // Takes ownership of |window|.
|
| + 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();
|
| +
|
| + // Outstanding requests that should be serviced.
|
| + std::queue<std::unique_ptr<Request>> requests_;
|
| +
|
| + xcb_connection_t* connection_;
|
| + Window* root_;
|
| + // The last sequence number received by the server.
|
| + uint16_t sequence_;
|
| +
|
| + 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_
|
|
|