diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-09-07 19:42:15 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-09-07 19:42:15 +0000 |
commit | 9cc1e2c1aa2629d499e7555acd4906d6cc989cf9 (patch) | |
tree | 2a737f47bb029688c2f5ebef76869903cf4b4eec /kwin/events.cpp | |
parent | eaa51fec106463800192924168eaf9f03f188655 (diff) | |
download | tdebase-9cc1e2c1aa2629d499e7555acd4906d6cc989cf9.tar.gz tdebase-9cc1e2c1aa2629d499e7555acd4906d6cc989cf9.zip |
Merged in remaining kdebase bugfixes from the Chakra project
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1172677 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kwin/events.cpp')
-rw-r--r-- | kwin/events.cpp | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/kwin/events.cpp b/kwin/events.cpp index ba6321a7c..a30e915e1 100644 --- a/kwin/events.cpp +++ b/kwin/events.cpp @@ -1078,6 +1078,217 @@ int qtToX11State( Qt::ButtonState state ) // for the decoration window cannot be (easily) intercepted as X11 events bool Client::eventFilter( TQObject* o, TQEvent* e ) { + if (o == shadowWidget) + { + if (e->type() == TQEvent::MouseButtonRelease) + { + int buttonMask, buttonPressed, x, y, x_root, y_root; + unsigned int mask; + TQMouseEvent *qe = (TQMouseEvent *)e; + Window inner_window, parent_window, pointer_window, root_window; + XButtonEvent xe; + + removeShadow(); + switch (qe->button()) + { + case Qt::MidButton: + buttonMask = Button2Mask; + buttonPressed = Button2; + break; + case Qt::RightButton: + buttonMask = Button3Mask; + buttonPressed = Button3; + break; + default: + buttonMask = Button1Mask; + buttonPressed = Button1; + break; + } + + // find the window under the cursor that should receive the + // simulated events + root_window = qt_xrootwin(); + XQueryPointer(qt_xdisplay(), root_window, &root_window, + &pointer_window, &x_root, &y_root, &x, &y, &mask); + + if (pointer_window != None) + { + // Save the child window immediately under the window + // decoration, if any. This is so that we can send an event to + // the immediate descendant of a window's window decoration, + // which causes KWin to refocus windows properly + parent_window = pointer_window; + XQueryPointer(qt_xdisplay(), parent_window, &root_window, + &pointer_window, &x_root, &y_root, &x, &y, &mask); + inner_window = pointer_window; + + while (pointer_window != None) + { + // Recursively query for the child window under the pointer, + // using the returned child window as the parent window for + // the subsequent query. When no child window is left, we've + // found the child that will receive the simulated event + parent_window = pointer_window; + XQueryPointer(qt_xdisplay(), parent_window, &root_window, + &pointer_window, &x_root, &y_root, &x, &y, &mask); + } + pointer_window = parent_window; + } + else + inner_window = None; + + // simulate a mouse button press + xe.type = ButtonPress; + xe.display = qt_xdisplay(); + xe.root = qt_xrootwin(); + xe.subwindow = None; + xe.time = CurrentTime; + xe.x = x; + xe.y = y; + xe.x_root = x_root; + xe.y_root = y_root; + xe.state = 0; + xe.button = buttonPressed; + xe.same_screen = True; + if (inner_window != None && inner_window != pointer_window) + { + xe.window = inner_window; + XSendEvent(qt_xdisplay(), inner_window, True, ButtonPressMask, + (XEvent *)&xe); + } + xe.window = pointer_window; + XSendEvent(qt_xdisplay(), pointer_window, True, ButtonPressMask, + (XEvent *)&xe); + + // simulate a mouse button release + xe.type = ButtonRelease; + xe.display = qt_xdisplay(); + xe.root = qt_xrootwin(); + xe.subwindow = None; + xe.time = CurrentTime; + xe.x = x; + xe.y = y; + xe.x_root = x_root; + xe.y_root = y_root; + xe.state = buttonMask; + xe.button = buttonPressed; + xe.same_screen = True; + if (inner_window != None && inner_window != pointer_window) + { + xe.window = inner_window; + XSendEvent(qt_xdisplay(), inner_window, True, ButtonReleaseMask, + (XEvent *)&xe); + } + xe.window = pointer_window; + XSendEvent(qt_xdisplay(), pointer_window, True, ButtonReleaseMask, + (XEvent *)&xe); + + drawDelayedShadow(); + + return true; + } + else if (e->type() == TQEvent::Wheel) + { + int x, y, x_root, y_root; + unsigned int buttonMask, buttonPressed, mask; + TQWheelEvent *wheelEvent = (TQWheelEvent *)e; + Window inner_window, parent_window, pointer_window, + root_window; + XButtonEvent xe; + + removeShadow(); + + // state and button parameters passed to XSendEvent depend on the + // direction in which the mouse wheel was rolled + buttonMask = wheelEvent->delta() > 0 ? Button4Mask : Button5Mask; + buttonPressed = wheelEvent->delta() > 0 ? Button4 : Button5; + + // find the window under the cursor that should receive the + // simulated events + root_window = qt_xrootwin(); + XQueryPointer(qt_xdisplay(), root_window, &root_window, + &pointer_window, &x_root, &y_root, &x, &y, &mask); + + if (pointer_window != None) + { + // Save the child window immediately under the window + // decoration, if any. This is so that we can send an event to + // the immediate descendant of a window's window decoration, + // which causes KWin to refocus windows properly + parent_window = pointer_window; + XQueryPointer(qt_xdisplay(), parent_window, &root_window, + &pointer_window, &x_root, &y_root, &x, &y, &mask); + inner_window = pointer_window; + + while (pointer_window != None) + { + // Recursively query for the child window under the pointer, + // using the returned child window as the parent window for + // the subsequent query. When no child window is left, we've + // found the child that will receive the simulated event + parent_window = pointer_window; + XQueryPointer(qt_xdisplay(), parent_window, &root_window, + &pointer_window, &x_root, &y_root, &x, &y, &mask); + } + pointer_window = parent_window; + } + else + inner_window = None; + + // simulate a mouse button press + xe.type = ButtonPress; + xe.display = qt_xdisplay(); + xe.root = qt_xrootwin(); + xe.subwindow = None; + xe.time = CurrentTime; + xe.x = x; + xe.y = y; + xe.x_root = x_root; + xe.y_root = y_root; + xe.state = 0; + xe.same_screen = True; + if (inner_window != None && inner_window != pointer_window) + { + xe.button = buttonPressed; + xe.window = inner_window; + XSendEvent(qt_xdisplay(), inner_window, True, ButtonPressMask, + (XEvent *)&xe); + } + xe.button = buttonPressed; + xe.window = pointer_window; + XSendEvent(qt_xdisplay(), pointer_window, True, ButtonPressMask, + (XEvent *)&xe); + + // simulate a mouse button release + xe.type = ButtonRelease; + xe.display = qt_xdisplay(); + xe.root = qt_xrootwin(); + xe.subwindow = None; + xe.time = CurrentTime; + xe.x = x; + xe.y = y; + xe.x_root = x_root; + xe.y_root = y_root; + xe.same_screen = True; + if (inner_window != None && inner_window != pointer_window) + { + xe.window = inner_window; + xe.state = buttonMask; + xe.button = buttonPressed; + XSendEvent(qt_xdisplay(), inner_window, True, ButtonReleaseMask, + (XEvent *)&xe); + } + xe.state = buttonMask; + xe.button = buttonPressed; + xe.window = pointer_window; + XSendEvent(qt_xdisplay(), pointer_window, True, ButtonReleaseMask, + (XEvent *)&xe); + + drawDelayedShadow(); + + return true; + } + } if( decoration == NULL || o != decoration->widget()) return false; |