~malizor/compiz-core/fix-942890

« back to all changes in this revision

Viewing changes to src/event.cpp

  • Committer: Daniel van Vugt
  • Date: 2012-02-22 07:15:32 UTC
  • mfrom: (3013.2.2 fix-934058)
  • Revision ID: vanvugt@gmail.com-20120222071532-2oijktoaomi25iim
Fix keyboard lockup, which occurred when a plugin was devious enough to
override handleEvent and not allow keyboard events to reach core.
(LP: #934058)

Arguably we should fix the offending plugin (unityshell). But I figured it's
better to make core more robust so that the same bug can never occur with
any plugin in future.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1040
1040
}
1041
1041
 
1042
1042
void
 
1043
CompScreenImpl::alwaysHandleEvent (XEvent *event)
 
1044
{
 
1045
    priv->eventHandled = true;  // if we return inside WRAPABLE_HND_FUNCTN
 
1046
 
 
1047
    handleEvent (event);
 
1048
 
 
1049
    /*
 
1050
     * Critical event handling that cannot be overridden by plugins
 
1051
     */
 
1052
 
 
1053
    if (priv->tapGrab &&
 
1054
        (event->type == KeyPress || event->type == KeyRelease))
 
1055
    {
 
1056
        int mode = priv->eventHandled ? AsyncKeyboard : ReplayKeyboard;
 
1057
        XAllowEvents (priv->dpy, mode, event->xkey.time);
 
1058
    }
 
1059
 
 
1060
    if (priv->grabs.empty () && event->type == KeyRelease)
 
1061
    {
 
1062
        XUngrabKeyboard (priv->dpy, event->xkey.time);
 
1063
        priv->tapGrab = false;
 
1064
    }
 
1065
}
 
1066
 
 
1067
void
1043
1068
CompScreenImpl::_handleEvent (XEvent *event)
1044
1069
{
 
1070
    /*
 
1071
     * Non-critical event handling that might be overridden by plugins
 
1072
     */
 
1073
 
1045
1074
    CompWindow *w = NULL;
1046
1075
    XWindowAttributes wa;
1047
 
    bool              actionEventHandled = false;
1048
1076
 
1049
1077
    switch (event->type) {
1050
1078
    case ButtonPress:
1068
1096
        break;
1069
1097
    }
1070
1098
 
1071
 
    if (priv->handleActionEvent (event))
 
1099
    priv->eventHandled = priv->handleActionEvent (event);
 
1100
    if (priv->eventHandled)
1072
1101
    {
1073
1102
        if (priv->grabs.empty ())
1074
1103
            XAllowEvents (priv->dpy, AsyncPointer, event->xbutton.time);
1075
 
 
1076
 
        actionEventHandled = true;
1077
 
    }
1078
 
 
1079
 
    if (priv->tapGrab &&
1080
 
        (event->type == KeyPress || event->type == KeyRelease))
1081
 
    {
1082
 
        int mode = actionEventHandled ? AsyncKeyboard : ReplayKeyboard;
1083
 
        XAllowEvents (priv->dpy, mode, event->xkey.time);
1084
 
    }
1085
 
 
1086
 
    if (priv->grabs.empty () && event->type == KeyRelease)
1087
 
    {
1088
 
        XUngrabKeyboard (priv->dpy, event->xkey.time);
1089
 
        priv->tapGrab = false;
1090
 
    }
1091
 
 
1092
 
    if (actionEventHandled)
1093
1104
        return;
 
1105
    }
1094
1106
 
1095
1107
    switch (event->type) {
1096
1108
    case SelectionRequest: