Merge lp:~attente/compiz/plugin-actions into lp:compiz/0.9.11
- plugin-actions
- Merge into 0.9.11
Status: | Merged |
---|---|
Approved by: | Christopher Townsend |
Approved revision: | 3823 |
Merged at revision: | 3817 |
Proposed branch: | lp:~attente/compiz/plugin-actions |
Merge into: | lp:compiz/0.9.11 |
Diff against target: |
832 lines (+309/-144) 8 files modified
include/core/abiversion.h (+1/-1) include/core/action.h (+27/-12) include/core/plugin.h (+24/-0) src/action.cpp (+53/-10) src/event.cpp (+183/-116) src/plugin.cpp (+6/-0) src/plugin/tests/test-plugin.cpp (+0/-5) src/privatescreen.h (+15/-0) |
To merge this branch: | bzr merge lp:~attente/compiz/plugin-actions |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Christopher Townsend | Approve | ||
Marco Trevisan (Treviño) | Approve | ||
Review via email: mp+200307@code.launchpad.net |
Commit message
Add an interface for plugins to provide non-option key actions that can be triggered.
Description of the change
Add an interface for plugins to provide non-option key actions that can be triggered.
PS Jenkins bot (ps-jenkins) wrote : | # |
Christopher Townsend (townsend) wrote : | # |
Gmock already has a class named CompAction that is interfering with your newly created CompAction class. This is causing build failures when building the compiz_plugin_test.
Please rename your new class to something like CompizAction to avoid this.
Thanks!
Christopher Townsend (townsend) wrote : | # |
Also, I don't quite understand what this change is for and how to test it. What am I expecting it to do?
William Hua (attente) wrote : | # |
Thanks, Christopher, I'll fix the CompAction problem, as well as another bug I'm currently encountering with the branch.
Right now, (afaict) the only way for a key CompAction to be triggered is if it's set as the value of a CompOption returned by a Compiz plugin's getOptions () method. So this branch should allow plugins to return a list of key actions which are not necessarily plugin options, and those actions will be appropriately triggered by the event handling code.
I needed this because I've been trying to implement the GNOME key grabber in Unity, which will allow us to stop using passive key grabs in gnome-settings-
Christopher Townsend (townsend) wrote : | # |
Ok, thanks for the explanation. I have heard here and there about these changes but I'm not well versed on it. So it seems it really can't be tested until all the pieces are in place.
Once you update the branch, we'll review the code and make sure it builds, runs, etc.
- 3820. By William Hua
-
Fix test errors.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3820
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 3821. By William Hua
-
Merge trunk.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3821
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
40 + class Class {
41 + public:
42 + virtual ~Class() {}
43 + virtual Vector & getActions () = 0;
44 + };
No better name? Also, wouldn't make sense to return a const& instead?
William Hua (attente) wrote : | # |
I just realized, adding those const qualifiers to the CompAction public API may break Compiz consumers... is this something we're ok with doing? Anyone who uses those CompAction member functions will be safe, however we would break anyone who tried to re-implement those functions in a subclass...
- 3822. By William Hua
-
Rename CompAction::Class -> CompAction:
:Container
William Hua (attente) wrote : | # |
Hi Marco, I tried to const-correct that, but it seems not possible to make getActions return a const Vector &. The reason is because the initiate and terminate callbacks of CompAction require a non-const pointer to the CompAction object, and there are places in Unity which call non-const member functions on that pointer.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3822
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Ok, that's fine then.
Christopher Townsend (townsend) wrote : | # |
Hi William,
This is indeed an ABI break. We'll need to update the ABI version in Compiz to reflect this. To do this:
1. Open include/
2. Replace the value of CORE_ABIVERSION to today's date in form of yyyymmdd.
Other than that, this looks good. Once you get the ABI version change in, we'll top approve.
Thanks!
- 3823. By William Hua
-
Bump ABI version.
William Hua (attente) wrote : | # |
Great, thanks guys! If we need any last minute changes, just let me know!
Christopher Townsend (townsend) wrote : | # |
Ok, looks good to me as well.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3823
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'include/core/abiversion.h' |
2 | --- include/core/abiversion.h 2013-11-05 18:51:36 +0000 |
3 | +++ include/core/abiversion.h 2014-01-23 16:45:20 +0000 |
4 | @@ -5,6 +5,6 @@ |
5 | # error Conflicting definitions of CORE_ABIVERSION |
6 | #endif |
7 | |
8 | -#define CORE_ABIVERSION 20131105 |
9 | +#define CORE_ABIVERSION 20140123 |
10 | |
11 | #endif // COMPIZ_ABIVERSION_H |
12 | |
13 | === modified file 'include/core/action.h' |
14 | --- include/core/action.h 2012-10-11 10:12:05 +0000 |
15 | +++ include/core/action.h 2014-01-23 16:45:20 +0000 |
16 | @@ -32,8 +32,6 @@ |
17 | |
18 | #include <boost/function.hpp> |
19 | |
20 | -#include <X11/Xlib-xcb.h> |
21 | - |
22 | namespace compiz |
23 | { |
24 | namespace actions |
25 | @@ -109,6 +107,9 @@ |
26 | bool fromString (const CompString &str); |
27 | CompString toString () const; |
28 | |
29 | + bool operator== (const KeyBinding &k) const; |
30 | + bool operator!= (const KeyBinding &k) const; |
31 | + |
32 | private: |
33 | unsigned int mModifiers; |
34 | int mKeycode; |
35 | @@ -126,6 +127,9 @@ |
36 | bool fromString (const CompString &str); |
37 | CompString toString () const; |
38 | |
39 | + bool operator== (const ButtonBinding &b) const; |
40 | + bool operator!= (const ButtonBinding &b) const; |
41 | + |
42 | private: |
43 | unsigned int mModifiers; |
44 | int mButton; |
45 | @@ -133,32 +137,41 @@ |
46 | |
47 | typedef unsigned int State; |
48 | typedef unsigned int BindingType; |
49 | + typedef std::vector<CompAction> Vector; |
50 | typedef boost::function <bool (CompAction *, State, CompOption::Vector &)> CallBack; |
51 | |
52 | + class Container { |
53 | + public: |
54 | + virtual ~Container() {} |
55 | + virtual Vector & getActions () = 0; |
56 | + }; |
57 | + |
58 | public: |
59 | CompAction (); |
60 | CompAction (const CompAction &); |
61 | ~CompAction (); |
62 | |
63 | - CallBack initiate (); |
64 | - CallBack terminate (); |
65 | + CallBack initiate () const; |
66 | + CallBack terminate () const; |
67 | |
68 | void setInitiate (const CallBack &initiate); |
69 | void setTerminate (const CallBack &terminate); |
70 | |
71 | - State state (); |
72 | - BindingType type (); |
73 | + State state () const; |
74 | + BindingType type () const; |
75 | |
76 | KeyBinding & key (); |
77 | + const KeyBinding & key () const; |
78 | void setKey (const KeyBinding &key); |
79 | |
80 | ButtonBinding & button (); |
81 | + const ButtonBinding & button () const; |
82 | void setButton (const ButtonBinding &button); |
83 | |
84 | - unsigned int edgeMask (); |
85 | + unsigned int edgeMask () const; |
86 | void setEdgeMask (unsigned int edge); |
87 | |
88 | - bool bell (); |
89 | + bool bell () const; |
90 | void setBell (bool bell); |
91 | |
92 | void setState (State state); |
93 | @@ -172,13 +185,13 @@ |
94 | bool buttonFromString (const CompString &str); |
95 | bool edgeMaskFromString (const CompString &str); |
96 | |
97 | - CompString keyToString (); |
98 | - CompString buttonToString (); |
99 | - CompString edgeMaskToString (); |
100 | + CompString keyToString () const; |
101 | + CompString buttonToString () const; |
102 | + CompString edgeMaskToString () const; |
103 | |
104 | static CompString edgeToString (unsigned int edge); |
105 | |
106 | - bool active (); |
107 | + bool active () const; |
108 | |
109 | /* CompAction should be a pure virtual class so |
110 | * that we can pass the interface required to for setActionActiveState |
111 | @@ -191,4 +204,6 @@ |
112 | PrivateAction *priv; |
113 | }; |
114 | |
115 | +CompAction::Vector & noActions (); |
116 | + |
117 | #endif |
118 | |
119 | === modified file 'include/core/plugin.h' |
120 | --- include/core/plugin.h 2013-04-17 06:58:36 +0000 |
121 | +++ include/core/plugin.h 2014-01-23 16:45:20 +0000 |
122 | @@ -27,6 +27,7 @@ |
123 | #define _COMPIZ_PLUGIN_H |
124 | |
125 | #include <core/string.h> |
126 | +#include <core/action.h> |
127 | #include <core/option.h> |
128 | #include <core/privateunion.h> |
129 | #include <core/pluginclasshandler.h> |
130 | @@ -146,6 +147,8 @@ |
131 | |
132 | virtual bool setOption (const CompString &name, |
133 | CompOption::Value &value); |
134 | + |
135 | + virtual CompAction::Vector & getActions (); |
136 | private: |
137 | CompString mName; |
138 | VTable **mSelf; |
139 | @@ -167,6 +170,7 @@ |
140 | CompOption::Vector & getOptions (); |
141 | bool setOption (const CompString &name, |
142 | CompOption::Value &value); |
143 | + CompAction::Vector & getActions (); |
144 | |
145 | private: |
146 | |
147 | @@ -190,6 +194,7 @@ |
148 | void finiScreen (CompScreen *s); |
149 | CompOption::Vector & getOptions (); |
150 | bool setOption (const CompString &name, CompOption::Value &value); |
151 | + CompAction::Vector & getActions (); |
152 | |
153 | private: |
154 | |
155 | @@ -364,6 +369,15 @@ |
156 | return oc->setOption (name, value); |
157 | } |
158 | |
159 | +template <typename T, typename T2, int ABI> |
160 | +CompAction::Vector & CompPlugin::VTableForScreenAndWindow<T, T2, ABI>::getActions () |
161 | +{ |
162 | + CompAction::Container *ac = dynamic_cast<CompAction::Container *> (T::get (screen)); |
163 | + if (!ac) |
164 | + return noActions (); |
165 | + return ac->getActions (); |
166 | +} |
167 | + |
168 | /** |
169 | * Mark the plugin class handlers as ready to be initialized |
170 | */ |
171 | @@ -435,6 +449,16 @@ |
172 | return oc->setOption (name, value); |
173 | } |
174 | |
175 | +template <typename T, int ABI> |
176 | +CompAction::Vector & |
177 | +CompPlugin::VTableForScreen<T, ABI>::getActions () |
178 | +{ |
179 | + CompAction::Container *ac = dynamic_cast<CompAction::Container *> (T::get (screen)); |
180 | + if (!ac) |
181 | + return noActions (); |
182 | + return ac->getActions (); |
183 | +} |
184 | + |
185 | typedef CompPlugin::VTable *(*PluginGetInfoProc) (void); |
186 | |
187 | #endif |
188 | |
189 | === modified file 'src/action.cpp' |
190 | --- src/action.cpp 2013-11-25 20:54:05 +0000 |
191 | +++ src/action.cpp 2014-01-23 16:45:20 +0000 |
192 | @@ -242,6 +242,18 @@ |
193 | return binding; |
194 | } |
195 | |
196 | +bool |
197 | +CompAction::KeyBinding::operator== (const KeyBinding &k) const |
198 | +{ |
199 | + return mKeycode == k.mKeycode && mModifiers == k.mModifiers; |
200 | +} |
201 | + |
202 | +bool |
203 | +CompAction::KeyBinding::operator!= (const KeyBinding &k) const |
204 | +{ |
205 | + return !(*this == k); |
206 | +} |
207 | + |
208 | CompAction::ButtonBinding::ButtonBinding () : |
209 | mModifiers (0), |
210 | mButton (0) |
211 | @@ -314,6 +326,18 @@ |
212 | return binding; |
213 | } |
214 | |
215 | +bool |
216 | +CompAction::ButtonBinding::operator== (const ButtonBinding &b) const |
217 | +{ |
218 | + return mButton == b.mButton && mModifiers == b.mModifiers; |
219 | +} |
220 | + |
221 | +bool |
222 | +CompAction::ButtonBinding::operator!= (const ButtonBinding &b) const |
223 | +{ |
224 | + return !(*this == b); |
225 | +} |
226 | + |
227 | CompAction::CompAction () : |
228 | priv (new PrivateAction ()) |
229 | { |
230 | @@ -330,13 +354,13 @@ |
231 | } |
232 | |
233 | CompAction::CallBack |
234 | -CompAction::initiate () |
235 | +CompAction::initiate () const |
236 | { |
237 | return priv->initiate; |
238 | } |
239 | |
240 | CompAction::CallBack |
241 | -CompAction::terminate () |
242 | +CompAction::terminate () const |
243 | { |
244 | return priv->terminate; |
245 | } |
246 | @@ -354,13 +378,13 @@ |
247 | } |
248 | |
249 | CompAction::State |
250 | -CompAction::state () |
251 | +CompAction::state () const |
252 | { |
253 | return priv->state; |
254 | } |
255 | |
256 | CompAction::BindingType |
257 | -CompAction::type () |
258 | +CompAction::type () const |
259 | { |
260 | return priv->type; |
261 | } |
262 | @@ -371,6 +395,12 @@ |
263 | return priv->key; |
264 | } |
265 | |
266 | +const CompAction::KeyBinding & |
267 | +CompAction::key () const |
268 | +{ |
269 | + return priv->key; |
270 | +} |
271 | + |
272 | void |
273 | CompAction::setKey (const CompAction::KeyBinding &key) |
274 | { |
275 | @@ -388,6 +418,12 @@ |
276 | return priv->button; |
277 | } |
278 | |
279 | +const CompAction::ButtonBinding & |
280 | +CompAction::button () const |
281 | +{ |
282 | + return priv->button; |
283 | +} |
284 | + |
285 | void |
286 | CompAction::setButton (const CompAction::ButtonBinding &button) |
287 | { |
288 | @@ -405,7 +441,7 @@ |
289 | } |
290 | |
291 | unsigned int |
292 | -CompAction::edgeMask () |
293 | +CompAction::edgeMask () const |
294 | { |
295 | return priv->edgeMask; |
296 | } |
297 | @@ -426,7 +462,7 @@ |
298 | } |
299 | |
300 | bool |
301 | -CompAction::bell () |
302 | +CompAction::bell () const |
303 | { |
304 | return priv->bell; |
305 | } |
306 | @@ -558,7 +594,7 @@ |
307 | } |
308 | |
309 | CompString |
310 | -CompAction::keyToString () |
311 | +CompAction::keyToString () const |
312 | { |
313 | CompString binding = priv->key.toString (); |
314 | |
315 | @@ -569,7 +605,7 @@ |
316 | } |
317 | |
318 | CompString |
319 | -CompAction::buttonToString () |
320 | +CompAction::buttonToString () const |
321 | { |
322 | CompString edge; |
323 | |
324 | @@ -584,7 +620,7 @@ |
325 | } |
326 | |
327 | CompString |
328 | -CompAction::edgeMaskToString () |
329 | +CompAction::edgeMaskToString () const |
330 | { |
331 | CompString edge; |
332 | |
333 | @@ -609,7 +645,7 @@ |
334 | } |
335 | |
336 | bool |
337 | -CompAction::active () |
338 | +CompAction::active () const |
339 | { |
340 | return priv->active; |
341 | } |
342 | @@ -654,3 +690,10 @@ |
343 | { |
344 | memcpy (&priv, &a.priv, sizeof (CompPrivate)); |
345 | } |
346 | + |
347 | +CompAction::Vector & |
348 | +noActions () |
349 | +{ |
350 | + static CompAction::Vector v; |
351 | + return v; |
352 | +} |
353 | |
354 | === modified file 'src/event.cpp' |
355 | --- src/event.cpp 2013-11-22 15:11:24 +0000 |
356 | +++ src/event.cpp 2014-01-23 16:45:20 +0000 |
357 | @@ -98,6 +98,23 @@ |
358 | Mod3Mask | Mod4Mask | Mod5Mask | CompNoMask) |
359 | |
360 | static bool |
361 | +isCallBackBinding (CompAction &action, |
362 | + CompAction::BindingType type, |
363 | + CompAction::State state) |
364 | +{ |
365 | + if (!(action.type () & type)) |
366 | + return false; |
367 | + |
368 | + if (!(action.state () & state)) |
369 | + return false; |
370 | + |
371 | + if (!action.active ()) |
372 | + return false; |
373 | + |
374 | + return true; |
375 | +} |
376 | + |
377 | +static bool |
378 | isCallBackBinding (CompOption &option, |
379 | CompAction::BindingType type, |
380 | CompAction::State state) |
381 | @@ -105,16 +122,7 @@ |
382 | if (!option.isAction ()) |
383 | return false; |
384 | |
385 | - if (!(option.value ().action ().type () & type)) |
386 | - return false; |
387 | - |
388 | - if (!(option.value ().action ().state () & state)) |
389 | - return false; |
390 | - |
391 | - if (!option.value ().action ().active ()) |
392 | - return false; |
393 | - |
394 | - return true; |
395 | + return isCallBackBinding (option.value ().action (), type, state); |
396 | } |
397 | |
398 | static bool |
399 | @@ -135,6 +143,14 @@ |
400 | } |
401 | |
402 | static bool |
403 | +isBound (CompAction &action, |
404 | + CompAction::BindingType type, |
405 | + CompAction::State state) |
406 | +{ |
407 | + return isCallBackBinding (action, type, state); |
408 | +} |
409 | + |
410 | +static bool |
411 | isBound (CompOption &option, |
412 | CompAction::BindingType type, |
413 | CompAction::State state, |
414 | @@ -379,19 +395,53 @@ |
415 | } |
416 | |
417 | bool |
418 | +PrivateScreen::shouldTriggerKeyPressAction (CompAction *action, |
419 | + XKeyEvent *event) |
420 | +{ |
421 | + unsigned int modMask = REAL_MOD_MASK & ~modHandler->ignoredModMask (); |
422 | + unsigned int bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); |
423 | + int bindCode = action->key ().keycode (); |
424 | + unsigned int bindCodeMod = bindCode ? modHandler->keycodeToModifiers (bindCode) : 0; |
425 | + unsigned int eventMods = event->state & modMask; |
426 | + |
427 | + if (bindCode == (int) event->keycode) |
428 | + return (bindMods & modMask) == eventMods; |
429 | + else if (!xkbEvent.get() && bindCode == 0) |
430 | + return bindMods == eventMods; |
431 | + else if (bindCodeMod != 0) |
432 | + { |
433 | + for (int mod = 0; mod < 8; mod++) |
434 | + { |
435 | + int mask = 1 << mod; |
436 | + |
437 | + if ((bindMods & mask) == 0) |
438 | + continue; |
439 | + |
440 | + for (int k = mod * modHandler->modMap ()->max_keypermod; |
441 | + k < (mod + 1) * modHandler->modMap ()->max_keypermod; |
442 | + k++) |
443 | + { |
444 | + if (modHandler->modMap ()->modifiermap[k] == event->keycode) |
445 | + { |
446 | + if ((((bindMods & ~mask) | bindCodeMod) & modMask) == eventMods) |
447 | + return true; |
448 | + |
449 | + break; |
450 | + } |
451 | + } |
452 | + } |
453 | + } |
454 | + |
455 | + return false; |
456 | +} |
457 | + |
458 | +bool |
459 | PrivateScreen::triggerKeyPressBindings (CompOption::Vector &options, |
460 | + CompAction::Vector &actions, |
461 | XKeyEvent *event, |
462 | CompOption::Vector &arguments) |
463 | { |
464 | CompAction::State state = 0; |
465 | - CompAction *action; |
466 | - unsigned int modMask = REAL_MOD_MASK & ~modHandler->ignoredModMask (); |
467 | - unsigned int modifierForBindCode; |
468 | - unsigned int bindMods; |
469 | - int bindCode; |
470 | - int mask; |
471 | - int mod; |
472 | - int k; |
473 | |
474 | if (event->keycode == escapeKeyCode) |
475 | state = CompAction::StateCancel; |
476 | @@ -410,6 +460,12 @@ |
477 | } |
478 | } |
479 | |
480 | + foreach (CompAction &a, actions) |
481 | + { |
482 | + if (!a.terminate ().empty ()) |
483 | + a.terminate () (&a, state, noOptions ()); |
484 | + } |
485 | + |
486 | if (state == CompAction::StateCancel) |
487 | return false; |
488 | } |
489 | @@ -417,103 +473,114 @@ |
490 | state = CompAction::StateInitKey; |
491 | foreach (CompOption &option, options) |
492 | { |
493 | - if (isBound (option, CompAction::BindingTypeKey, state, &action)) |
494 | - { |
495 | - bindCode = action->key ().keycode (); |
496 | - bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); |
497 | - |
498 | - if (bindCode == 0) |
499 | - modifierForBindCode = 0; |
500 | - else |
501 | - modifierForBindCode = modHandler->keycodeToModifiers (bindCode); |
502 | - |
503 | - bool match = false; |
504 | - if (bindCode == (int) event->keycode) |
505 | - match = ((bindMods & modMask) == (event->state & modMask)); |
506 | - else if (!xkbEvent.get() && bindCode == 0) |
507 | - match = (bindMods == (event->state & modMask)); |
508 | - else if (modifierForBindCode != 0) |
509 | - { |
510 | - for (mod = 0; mod < 8; mod++) |
511 | - { |
512 | - mask = 1 << mod; |
513 | - |
514 | - if ((bindMods & mask) == 0) |
515 | - continue; |
516 | - |
517 | - for (k = mod * modHandler->modMap ()->max_keypermod; |
518 | - k < (mod + 1) * modHandler->modMap ()->max_keypermod; |
519 | - k++) |
520 | - { |
521 | - if (modHandler->modMap ()->modifiermap[k] == event->keycode) |
522 | - { |
523 | - match = ((((bindMods & ~mask) | modifierForBindCode) & modMask) == (event->state & modMask)); |
524 | - break; |
525 | - } |
526 | - } |
527 | - |
528 | - if (match) |
529 | - break; |
530 | - } |
531 | - } |
532 | - |
533 | - if (match && eventManager.triggerPress (action, state, arguments)) |
534 | - return true; |
535 | - } |
536 | + CompAction *action; |
537 | + |
538 | + if (isBound (option, CompAction::BindingTypeKey, state, &action) && |
539 | + shouldTriggerKeyPressAction (action, event) && |
540 | + eventManager.triggerPress (action, state, arguments)) |
541 | + return true; |
542 | + } |
543 | + |
544 | + foreach (CompAction &action, actions) |
545 | + { |
546 | + if (isBound (action, CompAction::BindingTypeKey, state) && |
547 | + shouldTriggerKeyPressAction (&action, event) && |
548 | + eventManager.triggerPress (&action, state, arguments)) |
549 | + return true; |
550 | } |
551 | |
552 | return false; |
553 | } |
554 | |
555 | bool |
556 | +PrivateScreen::shouldTriggerKeyReleaseAction (CompAction *action, |
557 | + XKeyEvent *event) |
558 | +{ |
559 | + unsigned int modMask = REAL_MOD_MASK & ~modHandler->ignoredModMask (); |
560 | + unsigned int bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); |
561 | + |
562 | + if ((bindMods & modMask) == 0) |
563 | + return (unsigned int) action->key ().keycode () == event->keycode; |
564 | + |
565 | + unsigned int mods = modHandler->keycodeToModifiers (event->keycode); |
566 | + return !xkbEvent.get() && ((mods & modMask & bindMods) != bindMods); |
567 | +} |
568 | + |
569 | +bool |
570 | PrivateScreen::triggerKeyReleaseBindings (CompOption::Vector &options, |
571 | + CompAction::Vector &actions, |
572 | XKeyEvent *event, |
573 | CompOption::Vector &arguments) |
574 | { |
575 | CompAction::State state = CompAction::StateTermKey; |
576 | - CompAction *action; |
577 | - unsigned int ignored = modHandler->ignoredModMask (); |
578 | - unsigned int modMask = REAL_MOD_MASK & ~ignored; |
579 | - unsigned int bindMods; |
580 | - unsigned int mods; |
581 | |
582 | - mods = modHandler->keycodeToModifiers (event->keycode); |
583 | - if (!xkbEvent.get() && !mods) |
584 | + if (!xkbEvent.get() && !modHandler->keycodeToModifiers (event->keycode)) |
585 | return false; |
586 | |
587 | bool handled = false; |
588 | |
589 | foreach (CompOption &option, options) |
590 | { |
591 | - if (isBound (option, CompAction::BindingTypeKey, state, &action)) |
592 | - { |
593 | - bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); |
594 | - |
595 | - bool match = false; |
596 | - if ((bindMods & modMask) == 0) |
597 | - match = ((unsigned int) action->key ().keycode () == |
598 | - (unsigned int) event->keycode); |
599 | - else if (!xkbEvent.get() && ((mods & modMask & bindMods) != bindMods)) |
600 | - match = true; |
601 | - |
602 | - handled |= match && eventManager.triggerRelease (action, state, arguments); |
603 | - } |
604 | + CompAction *action; |
605 | + |
606 | + if (isBound (option, CompAction::BindingTypeKey, state, &action) && |
607 | + shouldTriggerKeyReleaseAction (action, event)) |
608 | + handled |= eventManager.triggerRelease (action, state, arguments); |
609 | + } |
610 | + |
611 | + foreach (CompAction &action, actions) |
612 | + { |
613 | + if (isBound (action, CompAction::BindingTypeKey, state) && |
614 | + shouldTriggerKeyReleaseAction (&action, event)) |
615 | + handled |= eventManager.triggerRelease (&action, state, arguments); |
616 | } |
617 | |
618 | return handled; |
619 | } |
620 | |
621 | bool |
622 | +PrivateScreen::shouldTriggerModifierPressAction (CompAction *action, |
623 | + XkbStateNotifyEvent *event) |
624 | +{ |
625 | + if (action->key ().keycode ()) |
626 | + return false; |
627 | + |
628 | + unsigned int modMask = REAL_MOD_MASK & ~modHandler->ignoredModMask (); |
629 | + unsigned int bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); |
630 | + unsigned int eventMods = event->mods & modMask; |
631 | + |
632 | + return eventMods == bindMods; |
633 | +} |
634 | + |
635 | +bool |
636 | +PrivateScreen::shouldTriggerModifierReleaseAction (CompAction *action, |
637 | + XkbStateNotifyEvent *event) |
638 | +{ |
639 | + unsigned int modMask = REAL_MOD_MASK & ~modHandler->ignoredModMask (); |
640 | + unsigned int bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); |
641 | + |
642 | + if (event->mods && ((event->mods & modMask) != bindMods)) |
643 | + return true; |
644 | + |
645 | + unsigned int eventCodeMod = modHandler->keycodeToModifiers (event->keycode); |
646 | + |
647 | + if (!event->mods && (eventCodeMod == bindMods)) |
648 | + return true; |
649 | + |
650 | + int bindCode = action->key ().keycode (); |
651 | + unsigned int bindCodeMod = bindCode ? modHandler->keycodeToModifiers (bindCode) : 0; |
652 | + |
653 | + return bindCodeMod && event->keycode == bindCode && |
654 | + ((bindMods | bindCodeMod) == ((event->mods & modMask) | eventCodeMod)); |
655 | +} |
656 | + |
657 | +bool |
658 | PrivateScreen::triggerStateNotifyBindings (CompOption::Vector &options, |
659 | + CompAction::Vector &actions, |
660 | XkbStateNotifyEvent *event, |
661 | CompOption::Vector &arguments) |
662 | { |
663 | CompAction::State state; |
664 | - CompAction *action; |
665 | - unsigned int ignored = modHandler->ignoredModMask (); |
666 | - unsigned int modMask = REAL_MOD_MASK & ~ignored; |
667 | - unsigned int bindMods; |
668 | - int bindCode; |
669 | |
670 | if (event->event_type == KeyPress) |
671 | { |
672 | @@ -521,20 +588,20 @@ |
673 | |
674 | foreach (CompOption &option, options) |
675 | { |
676 | - if (isBound (option, CompAction::BindingTypeKey, state, &action)) |
677 | - { |
678 | - if (action->key ().keycode () == 0) |
679 | - { |
680 | - bindMods = |
681 | - modHandler->virtualToRealModMask (action->key ().modifiers ()); |
682 | - |
683 | - if ((event->mods & modMask) == bindMods) |
684 | - { |
685 | - if (eventManager.triggerPress (action, state, arguments)) |
686 | - return true; |
687 | - } |
688 | - } |
689 | - } |
690 | + CompAction *action; |
691 | + |
692 | + if (isBound (option, CompAction::BindingTypeKey, state, &action) && |
693 | + shouldTriggerModifierPressAction (action, event) && |
694 | + eventManager.triggerPress (action, state, arguments)) |
695 | + return true; |
696 | + } |
697 | + |
698 | + foreach (CompAction &action, actions) |
699 | + { |
700 | + if (isBound (action, CompAction::BindingTypeKey, state) && |
701 | + shouldTriggerModifierPressAction (&action, event) && |
702 | + eventManager.triggerPress (&action, state, arguments)) |
703 | + return true; |
704 | } |
705 | } |
706 | else if (event->event_type == KeyRelease) |
707 | @@ -544,21 +611,18 @@ |
708 | |
709 | foreach (CompOption &option, options) |
710 | { |
711 | - if (isBound (option, CompAction::BindingTypeKey, state, &action)) |
712 | - { |
713 | - bindCode = action->key ().keycode (); |
714 | - bindMods = modHandler->virtualToRealModMask (action->key ().modifiers ()); |
715 | - unsigned int modifierForBindCode = bindCode ? modHandler->keycodeToModifiers (bindCode) : 0; |
716 | - unsigned int modifierForEventCode = modHandler->keycodeToModifiers (event->keycode); |
717 | + CompAction *action; |
718 | |
719 | - if ((event->mods && ((event->mods & modMask) != bindMods)) || |
720 | - (!event->mods && (modifierForEventCode == bindMods)) || |
721 | - (modifierForBindCode && event->keycode == bindCode && |
722 | - ((bindMods | modifierForBindCode) == ((event->mods & modMask) | modifierForEventCode)))) |
723 | - { |
724 | + if (isBound (option, CompAction::BindingTypeKey, state, &action) && |
725 | + shouldTriggerModifierReleaseAction (action, event)) |
726 | handled |= eventManager.triggerRelease (action, state, arguments); |
727 | - } |
728 | - } |
729 | + } |
730 | + |
731 | + foreach (CompAction &action, actions) |
732 | + { |
733 | + if (isBound (action, CompAction::BindingTypeKey, state) && |
734 | + shouldTriggerModifierReleaseAction (&action, event)) |
735 | + handled |= eventManager.triggerRelease (&action, state, arguments); |
736 | } |
737 | |
738 | if (handled) |
739 | @@ -880,7 +944,8 @@ |
740 | foreach (CompPlugin *p, CompPlugin::getPlugins ()) |
741 | { |
742 | CompOption::Vector &options = p->vTable->getOptions (); |
743 | - if (triggerKeyPressBindings (options, &event->xkey, o)) |
744 | + CompAction::Vector &actions = p->vTable->getActions (); |
745 | + if (triggerKeyPressBindings (options, actions, &event->xkey, o)) |
746 | return true; |
747 | } |
748 | break; |
749 | @@ -904,7 +969,8 @@ |
750 | foreach (CompPlugin *p, CompPlugin::getPlugins ()) |
751 | { |
752 | CompOption::Vector &options = p->vTable->getOptions (); |
753 | - handled |= triggerKeyReleaseBindings (options, &event->xkey, o); |
754 | + CompAction::Vector &actions = p->vTable->getActions (); |
755 | + handled |= triggerKeyReleaseBindings (options, actions, &event->xkey, o); |
756 | } |
757 | |
758 | if (handled) |
759 | @@ -1110,7 +1176,8 @@ |
760 | foreach (CompPlugin *p, CompPlugin::getPlugins ()) |
761 | { |
762 | CompOption::Vector &options = p->vTable->getOptions (); |
763 | - handled |= triggerStateNotifyBindings (options, stateEvent, arg); |
764 | + CompAction::Vector &actions = p->vTable->getActions (); |
765 | + handled |= triggerStateNotifyBindings (options, actions, stateEvent, arg); |
766 | } |
767 | |
768 | if (handled) |
769 | |
770 | === modified file 'src/plugin.cpp' |
771 | --- src/plugin.cpp 2013-06-28 01:10:57 +0000 |
772 | +++ src/plugin.cpp 2014-01-23 16:45:20 +0000 |
773 | @@ -638,3 +638,9 @@ |
774 | { |
775 | return false; |
776 | } |
777 | + |
778 | +CompAction::Vector & |
779 | +CompPlugin::VTable::getActions () |
780 | +{ |
781 | + return noActions (); |
782 | +} |
783 | |
784 | === modified file 'src/plugin/tests/test-plugin.cpp' |
785 | --- src/plugin/tests/test-plugin.cpp 2013-06-28 01:10:57 +0000 |
786 | +++ src/plugin/tests/test-plugin.cpp 2014-01-23 16:45:20 +0000 |
787 | @@ -13,11 +13,6 @@ |
788 | #include <gtest_shared_tmpenv.h> |
789 | #include <gtest_shared_autodestroy.h> |
790 | |
791 | -/* This is a link-seam so that we don't have to include screen.h */ |
792 | -class CompAction |
793 | -{ |
794 | -}; |
795 | - |
796 | class CompMatch |
797 | { |
798 | }; |
799 | |
800 | === modified file 'src/privatescreen.h' |
801 | --- src/privatescreen.h 2013-10-31 15:59:14 +0000 |
802 | +++ src/privatescreen.h 2014-01-23 16:45:20 +0000 |
803 | @@ -624,15 +624,30 @@ |
804 | XButtonEvent *event, |
805 | CompOption::Vector &arguments); |
806 | |
807 | + bool shouldTriggerKeyPressAction (CompAction *action, |
808 | + XKeyEvent *event); |
809 | + |
810 | + bool shouldTriggerKeyReleaseAction (CompAction *action, |
811 | + XKeyEvent *event); |
812 | + |
813 | + bool shouldTriggerModifierPressAction (CompAction *action, |
814 | + XkbStateNotifyEvent *event); |
815 | + |
816 | + bool shouldTriggerModifierReleaseAction (CompAction *action, |
817 | + XkbStateNotifyEvent *event); |
818 | + |
819 | bool triggerKeyPressBindings (CompOption::Vector &options, |
820 | + CompAction::Vector &actions, |
821 | XKeyEvent *event, |
822 | CompOption::Vector &arguments); |
823 | |
824 | bool triggerKeyReleaseBindings (CompOption::Vector &options, |
825 | + CompAction::Vector &actions, |
826 | XKeyEvent *event, |
827 | CompOption::Vector &arguments); |
828 | |
829 | bool triggerStateNotifyBindings (CompOption::Vector &options, |
830 | + CompAction::Vector &actions, |
831 | XkbStateNotifyEvent *event, |
832 | CompOption::Vector &arguments); |
833 |
FAILED: Continuous integration, rev:3819 jenkins. qa.ubuntu. com/job/ compiz- 0.9.11- ci/15/ jenkins. qa.ubuntu. com/job/ compiz- 0.9.11- trusty- amd64-ci/ 15/console jenkins. qa.ubuntu. com/job/ compiz- 0.9.11- trusty- armhf-ci/ 15/console jenkins. qa.ubuntu. com/job/ compiz- 0.9.11- trusty- i386-ci/ 15/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/compiz- 0.9.11- ci/15/rebuild
http://