Merge lp:~samuel-thibault/unity/shortcuts into lp:unity

Proposed by Samuel thibault on 2017-12-14
Status: Needs review
Proposed branch: lp:~samuel-thibault/unity/shortcuts
Merge into: lp:unity
Diff against target: 130 lines (+62/-5)
1 file modified
unity-shared/InputMonitor.cpp (+62/-5)
To merge this branch: bzr merge lp:~samuel-thibault/unity/shortcuts
Reviewer Review Type Date Requested Status
Samuel thibault (community) Resubmit on 2017-12-21
Unity Team 2017-12-14 Pending
Review via email: mp+335231@code.launchpad.net
To post a comment you must log in.
Marco Trevisan (Treviño) (3v1n0) wrote :

Thanks for this, looks sane... Check the comments please.

lp:~samuel-thibault/unity/shortcuts updated on 2017-12-14
4267. By Samuel thibault on 2017-12-14

xi2: Rework according to review

Samuel thibault (samuel-thibault) wrote :

I pushed fixes to address the comments.

review: Resubmit
Marco Trevisan (Treviño) (3v1n0) wrote :

Just an update... I've tried this, but there are some problems... For example the Alt+Mouse-down to Move doesn't work and same for right click on Unity window switcher to select windows.

I've been debugging this a bit, and also I've prepared some cleanup for the compiz branch, I'll submit them asap.

Unmerged revisions

4267. By Samuel thibault on 2017-12-14

xi2: Rework according to review

4266. By Samuel thibault on 2017-12-14

xi2: Use compiz-provided masks as a base for ours

This is needed for the fix for https://launchpad.net/bugs/1653072 , which makes
compiz use xi2.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'unity-shared/InputMonitor.cpp'
--- unity-shared/InputMonitor.cpp 2017-02-28 17:16:14 +0000
+++ unity-shared/InputMonitor.cpp 2017-12-14 19:22:54 +0000
@@ -135,8 +135,11 @@
135 : xi_opcode_(0)135 : xi_opcode_(0)
136 , event_filter_set_(false)136 , event_filter_set_(false)
137 , invoking_callbacks_(false)137 , invoking_callbacks_(false)
138 , basemasks_(nullptr)
139 , num_basemasks_(0)
138 {140 {
139 Display *dpy = gdk_x11_get_default_xdisplay();141 Display *dpy = gdk_x11_get_default_xdisplay();
142 Window root = DefaultRootWindow(dpy);
140 int event_base, error_base;143 int event_base, error_base;
141144
142 if (XQueryExtension(dpy, "XInputExtension", &xi_opcode_, &event_base, &error_base))145 if (XQueryExtension(dpy, "XInputExtension", &xi_opcode_, &event_base, &error_base))
@@ -149,6 +152,10 @@
149 LOG_ERROR(logger) << "Need XInput version "<< maj << "." << min << ", "152 LOG_ERROR(logger) << "Need XInput version "<< maj << "." << min << ", "
150 << "impossible, to setup an InputMonitor";153 << "impossible, to setup an InputMonitor";
151 }154 }
155 else
156 {
157 basemasks_ = XIGetSelectedEvents(dpy, root, &num_basemasks_);
158 }
152 }159 }
153 else160 else
154 {161 {
@@ -165,6 +172,7 @@
165 barrier_callbacks_.clear();172 barrier_callbacks_.clear();
166 UpdateEventMonitor();173 UpdateEventMonitor();
167 }174 }
175 XFree(basemasks_);
168 }176 }
169177
170 bool RegisterClient(Events type, EventCallback const& cb)178 bool RegisterClient(Events type, EventCallback const& cb)
@@ -223,14 +231,51 @@
223 return events;231 return events;
224 }232 }
225233
234 // Prepare a mask based on the Compiz-configured mask
235 void InitializeMask(int deviceid, XIEventMask* ourmask)
236 {
237 int wanted_mask_len = XIMaskLen(XI_LASTEVENT);
238 int mask_len = -1;
239 unsigned char* mask;
240
241 for (int i = 0; i < num_basemasks_; i++)
242 {
243 if (basemasks_[i].deviceid == deviceid)
244 {
245 // Compiz is already listening for some events on this device, use this as a base
246
247 mask_len = basemasks_[i].mask_len;
248 if (mask_len < wanted_mask_len)
249 mask_len = wanted_mask_len;
250
251 mask = (unsigned char*) malloc(mask_len);
252 memcpy(mask, basemasks_[i].mask, basemasks_[i].mask_len);
253 memset(mask + basemasks_[i].mask_len, 0,
254 mask_len - basemasks_[i].mask_len);
255 break;
256 }
257 }
258
259 if (mask_len < 0)
260 {
261 mask_len = wanted_mask_len;
262 mask = (unsigned char*) calloc(mask_len, 1);
263 }
264
265 ourmask->deviceid = deviceid;
266 ourmask->mask_len = mask_len;
267 ourmask->mask = mask;
268 }
269
226 void UpdateEventMonitor()270 void UpdateEventMonitor()
227 {271 {
228 auto* nux_dpy = nux::GetGraphicsDisplay();272 auto* nux_dpy = nux::GetGraphicsDisplay();
229 auto* dpy = nux_dpy ? nux_dpy->GetX11Display() : gdk_x11_get_default_xdisplay();273 auto* dpy = nux_dpy ? nux_dpy->GetX11Display() : gdk_x11_get_default_xdisplay();
230 Window root = DefaultRootWindow(dpy);274 Window root = DefaultRootWindow(dpy);
231275
232 unsigned char master_dev_bits[XIMaskLen(XI_LASTEVENT)] = { 0 };276 XIEventMask master_dev;
233 XIEventMask master_dev = { XIAllMasterDevices, sizeof(master_dev_bits), master_dev_bits };277
278 InitializeMask(XIAllMasterDevices, &master_dev);
234279
235 if (!barrier_callbacks_.empty())280 if (!barrier_callbacks_.empty())
236 {281 {
@@ -238,8 +283,9 @@
238 XISetMask(master_dev.mask, XI_BarrierLeave);283 XISetMask(master_dev.mask, XI_BarrierLeave);
239 }284 }
240285
241 unsigned char all_devs_bits[XIMaskLen(XI_LASTEVENT)] = { 0 };286 XIEventMask all_devs;
242 XIEventMask all_devs = { XIAllDevices, sizeof(all_devs_bits), all_devs_bits };287
288 InitializeMask(XIAllDevices, &all_devs);
243289
244 if (!pointer_callbacks_.empty())290 if (!pointer_callbacks_.empty())
245 {291 {
@@ -254,10 +300,19 @@
254 XISetMask(all_devs.mask, XI_KeyRelease);300 XISetMask(all_devs.mask, XI_KeyRelease);
255 }301 }
256302
257 XIEventMask selected[] = {master_dev, all_devs};303 // Note: XISelectEvents can take several masks with the same deviceid,
304 // and only the last mask will be effective, here the merged ones
305 XIEventMask selected[num_basemasks_ + 2];
306 memcpy(selected, basemasks_, num_basemasks_ * sizeof(basemasks_[0]));
307 selected[num_basemasks_] = master_dev;
308 selected[num_basemasks_+1] = all_devs;
309
258 XISelectEvents(dpy, root, selected, G_N_ELEMENTS(selected));310 XISelectEvents(dpy, root, selected, G_N_ELEMENTS(selected));
259 XSync(dpy, False);311 XSync(dpy, False);
260312
313 free(master_dev.mask);
314 free(all_devs.mask);
315
261 LOG_DEBUG(logger) << "Pointer clients: " << pointer_callbacks_.size() << ", "316 LOG_DEBUG(logger) << "Pointer clients: " << pointer_callbacks_.size() << ", "
262 << "Key clients: " << key_callbacks_.size() << ", "317 << "Key clients: " << key_callbacks_.size() << ", "
263 << "Barrier clients: " << barrier_callbacks_.size();318 << "Barrier clients: " << barrier_callbacks_.size();
@@ -374,6 +429,8 @@
374 EventCallbackSet key_callbacks_;429 EventCallbackSet key_callbacks_;
375 EventCallbackSet barrier_callbacks_;430 EventCallbackSet barrier_callbacks_;
376 EventCallbackSet removal_queue_;431 EventCallbackSet removal_queue_;
432 XIEventMask* basemasks_;
433 int num_basemasks_;
377};434};
378435
379Monitor::Monitor()436Monitor::Monitor()