Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(482)

Side by Side Diff: ui/base/x/x11_window_event_manager.cc

Issue 2313033002: Refactor X11ForeignWindowManager (Reland) (Closed)
Patch Set: Rename to XWindowEventmanager Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 #include "ui/base/x/x11_window_event_manager.h"
6
7 #include <stddef.h>
8 #include <X11/Xlib.h>
9 #include <X11/Xlib-xcb.h>
10 #include <xcb/xcb.h>
11
12 #include "base/compiler_specific.h"
13 #include "base/memory/singleton.h"
14
15 namespace ui {
16
17 // static
18 XWindowEventManager* XWindowEventManager::GetInstance() {
19 return base::Singleton<XWindowEventManager>::get();
20 }
21
22 void XWindowEventManager::SelectEvents(XID xid, uint32_t event_mask) {
23 BeforeMaskChanged(xid);
24 MultiMask& mask = mask_map_[xid];
25 mask.AddMask(event_mask);
26 AfterMaskChanged(xid);
27 }
28
29 void XWindowEventManager::DeselectEvents(XID xid, uint32_t event_mask) {
30 DCHECK(mask_map_.find(xid) != mask_map_.end());
31 BeforeMaskChanged(xid);
32 MultiMask& mask = mask_map_[xid];
33 mask.RemoveMask(event_mask);
34 AfterMaskChanged(xid);
35 }
36
37 XWindowEventManager::XWindowEventManager() {}
38 XWindowEventManager::~XWindowEventManager() {}
39
40 void XWindowEventManager::BeforeMaskChanged(XID xid) {
41 old_mask_ = mask_map_[xid].ToMask();
Daniel Erat 2016/09/07 00:37:33 caching this in a single member feels a bit scary.
Tom (Use chromium acct) 2016/09/07 18:02:22 Done.
42 }
43
44 void XWindowEventManager::AfterMaskChanged(XID xid) {
45 uint32_t new_mask = mask_map_[xid].ToMask();
46 if (new_mask == old_mask_)
47 return;
48
49 XDisplay* display = gfx::GetXDisplay();
50 xcb_connection_t* connection = XGetXCBConnection(display);
51 auto cookie = xcb_change_window_attributes(connection, xid, XCB_CW_EVENT_MASK,
52 &new_mask);
53 // Window |xid| may already be destroyed at this point, so the
54 // change_attributes request may give a BadWindow error. In this case, just
55 // ignore the error.
56 xcb_discard_reply(connection, cookie.sequence);
57
58 if (new_mask == NoEventMask)
59 mask_map_.erase(xid);
60 }
61
62 XWindowEventManager::ScopedEventSelector::ScopedEventSelector(
63 XID xid,
64 uint32_t event_mask)
65 : xid_(xid), event_mask_(event_mask) {
66 XWindowEventManager::GetInstance()->SelectEvents(xid_, event_mask_);
67 }
68
69 XWindowEventManager::ScopedEventSelector::~ScopedEventSelector() {
70 XWindowEventManager::GetInstance()->DeselectEvents(xid_, event_mask_);
71 }
72
73 XWindowEventManager::MultiMask::MultiMask() {
74 for (int i = 0; i < kMaskSize; i++)
75 mask_bits[i] = 0;
76 }
77
78 XWindowEventManager::MultiMask::~MultiMask() {}
79
80 void XWindowEventManager::MultiMask::AddMask(uint32_t mask) {
81 for (int i = 0; i < kMaskSize; i++) {
82 if (mask & (1 << i))
83 mask_bits[i]++;
84 }
85 }
86
87 void XWindowEventManager::MultiMask::RemoveMask(uint32_t mask) {
88 for (int i = 0; i < kMaskSize; i++) {
89 if (mask & (1 << i))
90 DCHECK(mask_bits[i]);
91 mask_bits[i]--;
92 }
93 }
94
95 uint32_t XWindowEventManager::MultiMask::ToMask() const {
96 uint32_t mask = NoEventMask;
97 for (int i = 0; i < kMaskSize; i++) {
98 if (mask_bits[i])
99 mask |= (1 << i);
100 }
101 return mask;
102 }
103
104 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698