Merge lp:~attente/compiz/plugin-actions into lp:compiz/0.9.11

Proposed by William Hua
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
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.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
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!

review: Needs Fixing
Revision history for this message
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?

Revision history for this message
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-daemon which conflict with Compiz. I have an initial implementation (there's still a couple of issues I'm trying to fix): https://launchpad.net/~attente/+archive/gnome-key-grabber.

Revision history for this message
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.

lp:~attente/compiz/plugin-actions updated
3820. By William Hua

Fix test errors.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~attente/compiz/plugin-actions updated
3821. By William Hua

Merge trunk.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
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?

Revision history for this message
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...

lp:~attente/compiz/plugin-actions updated
3822. By William Hua

Rename CompAction::Class -> CompAction::Container

Revision history for this message
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.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Ok, that's fine then.

review: Approve
Revision history for this message
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/core/abiversion.h
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!

lp:~attente/compiz/plugin-actions updated
3823. By William Hua

Bump ABI version.

Revision history for this message
William Hua (attente) wrote :

Great, thanks guys! If we need any last minute changes, just let me know!

Revision history for this message
Christopher Townsend (townsend) wrote :

Ok, looks good to me as well.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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

Subscribers

People subscribed via source and target branches