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

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

Issue 2313033002: Refactor X11ForeignWindowManager (Reland) (Closed)
Patch Set: Fix bug 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 class XWindowEventManager::MultiMask {
23 public:
24 MultiMask() {
25 for (int i = 0; i < kMaskSize; i++)
26 mask_bits_[i] = 0;
27 }
28
29 ~MultiMask() {}
30
31 void AddMask(uint32_t mask) {
32 for (int i = 0; i < kMaskSize; i++) {
33 if (mask & (1 << i))
34 mask_bits_[i]++;
35 }
36 }
37
38 void RemoveMask(uint32_t mask) {
39 for (int i = 0; i < kMaskSize; i++) {
40 if (mask & (1 << i))
41 DCHECK(mask_bits_[i]);
42 mask_bits_[i]--;
43 }
44 }
45
46 uint32_t ToMask() const {
47 uint32_t mask = NoEventMask;
48 for (int i = 0; i < kMaskSize; i++) {
49 if (mask_bits_[i])
50 mask |= (1 << i);
51 }
52 return mask;
53 }
54
55 private:
56 static constexpr auto kMaskSize = 25;
57
58 int mask_bits_[kMaskSize];
59
60 DISALLOW_COPY_AND_ASSIGN(MultiMask);
61 };
62
63 void XWindowEventManager::SelectEvents(XID xid, uint32_t event_mask) {
64 std::unique_ptr<MultiMask>& mask = mask_map_[xid];
65 if (!mask)
66 mask.reset(new MultiMask());
67 uint32_t old_mask = mask_map_[xid]->ToMask();
68 mask->AddMask(event_mask);
69 AfterMaskChanged(xid, old_mask);
70 }
71
72 void XWindowEventManager::DeselectEvents(XID xid, uint32_t event_mask) {
73 DCHECK(mask_map_.find(xid) != mask_map_.end());
74 uint32_t old_mask = mask_map_[xid]->ToMask();
75 std::unique_ptr<MultiMask>& mask = mask_map_[xid];
Daniel Erat 2016/09/07 20:00:07 nit: move this up one line and use it to get old_m
Tom (Use chromium acct) 2016/09/07 21:32:21 Done.
76 mask->RemoveMask(event_mask);
77 AfterMaskChanged(xid, old_mask);
78 }
79
80 XWindowEventManager::XWindowEventManager() {}
81 XWindowEventManager::~XWindowEventManager() {}
82
83 void XWindowEventManager::AfterMaskChanged(XID xid, uint32_t old_mask) {
84 uint32_t new_mask = mask_map_[xid]->ToMask();
85 if (new_mask == old_mask)
86 return;
87
88 XDisplay* display = gfx::GetXDisplay();
89 xcb_connection_t* connection = XGetXCBConnection(display);
90 auto cookie = xcb_change_window_attributes(connection, xid, XCB_CW_EVENT_MASK,
91 &new_mask);
92 // Window |xid| may already be destroyed at this point, so the
93 // change_attributes request may give a BadWindow error. In this case, just
94 // ignore the error.
95 xcb_discard_reply(connection, cookie.sequence);
96
97 if (new_mask == NoEventMask)
98 mask_map_.erase(xid);
99 }
100
101 XScopedEventSelector::XScopedEventSelector(XID xid, uint32_t event_mask)
Daniel Erat 2016/09/07 20:00:07 nit: move these to the top of the file to match th
Tom (Use chromium acct) 2016/09/07 21:32:21 Done.
102 : xid_(xid), event_mask_(event_mask) {
103 XWindowEventManager::GetInstance()->SelectEvents(xid_, event_mask_);
104 }
105
106 XScopedEventSelector::~XScopedEventSelector() {
107 XWindowEventManager::GetInstance()->DeselectEvents(xid_, event_mask_);
108 }
109
110 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698