Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef UI_BASE_X_X11_WINDOW_CACHE_H_ | |
| 6 #define UI_BASE_X_X11_WINDOW_CACHE_H_ | |
| 7 | |
| 8 #include <xcb/xcb.h> | |
| 9 | |
| 10 #include <list> | |
| 11 #include <map> | |
| 12 #include <queue> | |
| 13 | |
| 14 #include "ui/base/x/ui_base_x_export.h" | |
| 15 #include "ui/gfx/x/x11_types.h" | |
| 16 | |
| 17 namespace ui { | |
| 18 | |
| 19 // Keep tabs on the window tree starting from a root window. | |
| 20 class UI_BASE_X_EXPORT XWindowCache { | |
| 21 public: | |
| 22 // Clients should not modify any members of Property. | |
| 23 struct Property { | |
| 24 Property(xcb_atom_t name); | |
| 25 ~Property(); | |
| 26 | |
| 27 xcb_atom_t name; | |
| 28 | |
| 29 bool cached_property; | |
| 30 xcb_atom_t type; | |
| 31 // Format can be 8, 16, or 32, indicating how |data| should be interpreted. | |
| 32 uint8_t data_format; | |
| 33 int data_length; | |
| 34 union { | |
| 35 uint8_t* bits_8; | |
| 36 uint16_t* bits_16; | |
| 37 uint32_t* bits_32; | |
| 38 } data; | |
| 39 }; | |
| 40 | |
| 41 // Clients should not modify any members of Window. | |
| 42 struct Window { | |
| 43 Window(xcb_window_t id, Window* parent); | |
| 44 ~Window(); | |
| 45 | |
| 46 xcb_window_t id; | |
| 47 Window* parent; | |
| 48 | |
| 49 bool cached_attributes; | |
| 50 bool override_redirect; | |
| 51 // |is_mapped| is different from the map_state that is returned by | |
| 52 // XGetWindowAttributes. map_state can be one of IsUnmapped, IsUnviewable, | |
| 53 // or IsViewable. map_state is set to IsUnviewable when the window is | |
| 54 // mapped but some ancestor window is unmapped. If you need to check for | |
| 55 // this case, you must do so manually. | |
| 56 bool is_mapped; | |
| 57 | |
| 58 bool cached_geometry; | |
| 59 int16_t x, y; | |
| 60 uint16_t width, height; | |
| 61 uint16_t border_width; | |
| 62 | |
| 63 bool cached_properties; | |
| 64 std::map<xcb_atom_t, std::unique_ptr<Property>> properties; | |
| 65 | |
| 66 bool cached_children; | |
| 67 std::list<Window*> children; | |
| 68 | |
| 69 const Property* GetProperty(XID atom) const; | |
| 70 }; | |
| 71 | |
| 72 XWindowCache(XDisplay* display, XID root); | |
| 73 ~XWindowCache(); | |
| 74 | |
| 75 bool ConnectionHasError() const; | |
| 76 int ConnectionFd() const; | |
| 77 | |
| 78 // Reads any events and responses that are available, and makes new requests | |
| 79 // if necessary. | |
| 80 void OnConnectionReadable(); | |
| 81 | |
| 82 // Ensures we have the state of the entire window tree. May block. Returns | |
| 83 // false iff there was a connection error or a timeout. Mainly used in | |
| 84 // testing. | |
| 85 bool BlockUntilTreeIsCached(); | |
| 86 // Ensures we have processed all events sent server-side before Synchronize | |
| 87 // was called client-side. We may be forced to wait for more events to come | |
| 88 // that are not yet in the queue. You most likely want to | |
| 89 // BlockUntilWindowTreeIsCached before and after calling Synchronize. Blocks. | |
| 90 // Returns false iff there was a connection error or a timeout. Mainly used in | |
| 91 // testing. | |
| 92 bool Synchronize(); | |
| 93 // Similar to Synchronize, except synchronizes this cache to a different | |
| 94 // client. As an example, a client might change a property, and wants to be | |
| 95 // sure the cache is up-to-date with the property change. | |
| 96 bool SynchronizeWith(XDisplay* display); | |
| 97 | |
| 98 // Returns null when window |id| is not cached. | |
| 99 const Window* GetWindow(XID id) const; | |
| 100 | |
| 101 private: | |
| 102 friend class XWindowCacheTest; | |
| 103 | |
| 104 struct Request { | |
|
Elliot Glaysher
2016/08/08 18:17:28
Forward declare Request and move it and all its su
Tom (Use chromium acct)
2016/08/08 23:23:38
Done.
| |
| 105 virtual void OnReply(void* reply, XWindowCache* cache) = 0; | |
|
Elliot Glaysher
2016/08/08 18:17:28
IIRC, you should be passing an xcb_generic_reply_t
Tom (Use chromium acct)
2016/08/08 23:23:38
Done.
| |
| 106 uint16_t sequence() { return sequence_; } | |
| 107 | |
| 108 protected: | |
| 109 Request(xcb_window_t id); | |
| 110 // The sequence number is logically an arbitrary-sized integer. However, | |
| 111 // the X11 protocol only tracks the lower 16 bits, so that's all we need to | |
| 112 // keep. | |
| 113 uint16_t sequence_; | |
| 114 // All requests are (currently) associated with a window. | |
| 115 const xcb_window_t id_; | |
| 116 }; | |
| 117 | |
| 118 struct GetWindowAttributesRequest : public XWindowCache::Request { | |
| 119 GetWindowAttributesRequest(xcb_window_t window, XWindowCache* cache); | |
| 120 void OnReply(void* reply, XWindowCache* cache) override; | |
| 121 }; | |
| 122 | |
| 123 struct GetGeometryRequest : public XWindowCache::Request { | |
| 124 GetGeometryRequest(xcb_window_t window, XWindowCache* cache); | |
| 125 void OnReply(void* reply, XWindowCache* cache) override; | |
| 126 }; | |
| 127 | |
| 128 struct ListPropertiesRequest : public XWindowCache::Request { | |
| 129 ListPropertiesRequest(xcb_window_t window, XWindowCache* cache); | |
| 130 void OnReply(void* reply, XWindowCache* cache) override; | |
| 131 }; | |
| 132 | |
| 133 struct QueryTreeRequest : public XWindowCache::Request { | |
| 134 QueryTreeRequest(xcb_window_t window, XWindowCache* cache); | |
| 135 void OnReply(void* reply, XWindowCache* cache) override; | |
| 136 }; | |
| 137 | |
| 138 struct GetPropertyRequest : public XWindowCache::Request { | |
| 139 GetPropertyRequest(xcb_window_t window, | |
| 140 xcb_atom_t atom, | |
| 141 XWindowCache* cache); | |
| 142 void OnReply(void* reply, XWindowCache* cache) override; | |
| 143 protected: | |
| 144 xcb_atom_t atom_; | |
| 145 }; | |
| 146 | |
| 147 // Creates and adds a new property to |window|. | |
| 148 void CacheProperty(Window* window, xcb_atom_t atom); | |
| 149 // Takes ownership of |window|. | |
| 150 void CacheWindow(Window* window); | |
| 151 | |
| 152 void DeleteSubtree(Window* window); | |
| 153 | |
| 154 void ProcessEvent(xcb_generic_event_t* event); | |
| 155 | |
| 156 Window* GetWindow(xcb_window_t id) const; | |
| 157 | |
| 158 // Returns false iff there was a connection error or a timeout. | |
| 159 bool BlockUntilConnectionIsReadable(); | |
| 160 | |
| 161 // Outstanding requests that should be serviced. | |
| 162 std::queue<std::unique_ptr<Request>> requests_; | |
| 163 | |
| 164 xcb_connection_t* connection_; | |
| 165 Window* root_; | |
| 166 // The last sequence number received by the server. | |
| 167 uint16_t sequence_; | |
| 168 | |
| 169 std::map<xcb_window_t, std::unique_ptr<Window>> windows_; | |
| 170 | |
| 171 // Don't cache icon properties because they take up too much space and we | |
| 172 // currently never use them. | |
| 173 xcb_intern_atom_cookie_t net_wm_icon_cookie_; | |
| 174 xcb_atom_t net_wm_icon_; | |
| 175 }; | |
| 176 | |
| 177 } // namespace ui | |
| 178 | |
| 179 #endif // UI_BASE_X_X11_WINDOW_CACHE_H_ | |
| OLD | NEW |