From 494edbe76f10133fbb1d70e11758cbbe048608f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sat, 21 May 2011 08:50:59 +0200 Subject: [PATCH] Remove Mouse Emulation from KWin Mouse Emulation is provided in a better way by KAccess. This provides a global systemsettings switch to enable mouse emulation instead of a shortcut and Xkb to enable mouse control with keyboard instead of sending out fake mouse events. So no need for duplicated functionality in KWin. REVIEW: 101406 --- events.cpp | 12 --- kwinbindings.cpp | 1 - workspace.cpp | 241 ----------------------------------------------- workspace.h | 10 -- 4 files changed, 264 deletions(-) diff --git a/events.cpp b/events.cpp index 66a94197fe..668b6423d7 100644 --- a/events.cpp +++ b/events.cpp @@ -221,10 +221,6 @@ void RootInfo::changeShowingDesktop(bool showing) */ bool Workspace::workspaceEvent(XEvent * e) { - if (mouse_emulation && (e->type == ButtonPress || e->type == ButtonRelease)) { - mouse_emulation = false; - ungrabXKeyboard(); - } if (effects && static_cast< EffectsHandlerImpl* >(effects)->hasKeyboardGrab() && (e->type == KeyPress || e->type == KeyRelease)) return false; // let Qt process it, it'll be intercepted again in eventFilter() @@ -410,14 +406,6 @@ bool Workspace::workspaceEvent(XEvent * e) } break; } - case KeyPress: - if (mouse_emulation) - return keyPressMouseEmulation(e->xkey); - break; - case KeyRelease: - if (mouse_emulation) - return false; - break; case FocusIn: if (e->xfocus.window == rootWindow() && (e->xfocus.detail == NotifyDetailNone || e->xfocus.detail == NotifyPointerRoot)) { diff --git a/kwinbindings.cpp b/kwinbindings.cpp index 06ed2e8ec4..980031b885 100644 --- a/kwinbindings.cpp +++ b/kwinbindings.cpp @@ -192,7 +192,6 @@ DEF(I18N_NOOP("Switch to Next Screen"), 0, slotSwitchToNextScreen()); a = actionCollection->addAction("Group:Miscellaneous"); a->setText(i18n("Miscellaneous")); -DEF(I18N_NOOP("Mouse Emulation"), Qt::ALT + Qt::Key_F12, slotMouseEmulation()); DEF(I18N_NOOP("Kill Window"), Qt::CTRL + Qt::ALT + Qt::Key_Escape, slotKillWindow()); DEF(I18N_NOOP("Block Global Shortcuts"), 0, slotDisableGlobalShortcuts()); DEF(I18N_NOOP("Suspend Compositing"), Qt::SHIFT + Qt::ALT + Qt::Key_F12, slotToggleCompositing()); diff --git a/workspace.cpp b/workspace.cpp index a773700fe8..ccca0376f5 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -122,7 +122,6 @@ Workspace::Workspace(bool restore) , session_saving(false) , control_grab(false) , tab_grab(false) - , mouse_emulation(false) , block_focus(0) , tab_box(0) , desktop_change_osd(0) @@ -1866,246 +1865,6 @@ void Workspace::sendTakeActivity(Client* c, Time timestamp, long flags) pending_take_activity = c; } -/** - * Invokes keyboard mouse emulation - */ -void Workspace::slotMouseEmulation() -{ - if (mouse_emulation) { - ungrabXKeyboard(); - mouse_emulation = false; - return; - } - - if (grabXKeyboard()) { - mouse_emulation = true; - mouse_emulation_state = 0; - mouse_emulation_window = 0; - } -} - -/** - * Returns the child window under the mouse and activates the - * respective client if necessary. - * - * Auxiliary function for the mouse emulation system. - */ -WId Workspace::getMouseEmulationWindow() -{ - Window root; - Window child = rootWindow(); - int root_x, root_y, lx, ly; - uint state; - Window w; - Client * c = 0; - do { - w = child; - if (!c) - c = findClient(FrameIdMatchPredicate(w)); - XQueryPointer(display(), w, &root, &child, &root_x, &root_y, &lx, &ly, &state); - } while (child != None && child != w); - - if (c && !c->isActive()) - activateClient(c); - return WId(w); -} - -/** - * Sends a faked mouse event to the specified window. Returns the new button state. - */ -unsigned int Workspace::sendFakedMouseEvent(const QPoint& pos, WId w, MouseEmulation type, - int button, unsigned int state) -{ - if (!w) - return state; - QWidget* widget = QWidget::find(w); - if ((!widget || qobject_cast(widget)) && !findClient(WindowMatchPredicate(w))) { - int x, y; - Window xw; - XTranslateCoordinates(display(), rootWindow(), w, pos.x(), pos.y(), &x, &y, &xw); - if (type == EmuMove) { - // Motion notify events - XEvent e; - e.type = MotionNotify; - e.xmotion.window = w; - e.xmotion.root = rootWindow(); - e.xmotion.subwindow = w; - e.xmotion.time = xTime(); - e.xmotion.x = x; - e.xmotion.y = y; - e.xmotion.x_root = pos.x(); - e.xmotion.y_root = pos.y(); - e.xmotion.state = state; - e.xmotion.is_hint = NotifyNormal; - XSendEvent(display(), w, true, ButtonMotionMask, &e); - } else { - XEvent e; - e.type = type == EmuRelease ? ButtonRelease : ButtonPress; - e.xbutton.window = w; - e.xbutton.root = rootWindow(); - e.xbutton.subwindow = w; - e.xbutton.time = xTime(); - e.xbutton.x = x; - e.xbutton.y = y; - e.xbutton.x_root = pos.x(); - e.xbutton.y_root = pos.y(); - e.xbutton.state = state; - e.xbutton.button = button; - XSendEvent(display(), w, true, ButtonPressMask, &e); - - if (type == EmuPress) { - switch(button) { - case 2: - state |= Button2Mask; - break; - case 3: - state |= Button3Mask; - break; - default: // 1 - state |= Button1Mask; - break; - } - } else { - switch(button) { - case 2: - state &= ~Button2Mask; - break; - case 3: - state &= ~Button3Mask; - break; - default: // 1 - state &= ~Button1Mask; - break; - } - } - } - } - - return state; -} - -/** - * Handles keypress event during mouse emulation - */ -bool Workspace::keyPressMouseEmulation(XKeyEvent& ev) -{ - int kc = XKeycodeToKeysym(display(), ev.keycode, 0); - int km = ev.state & (ControlMask | Mod1Mask | ShiftMask); - - bool is_control = km & ControlMask; - bool is_alt = km & Mod1Mask; - bool is_shift = km & ShiftMask; - int delta = is_control ? 1 : (is_alt ? 32 : 8); - QPoint pos = cursorPos(); - - switch(kc) { - case XK_Left: - case XK_KP_Left: - pos.rx() -= delta; - break; - case XK_Right: - case XK_KP_Right: - pos.rx() += delta; - break; - case XK_Up: - case XK_KP_Up: - pos.ry() -= delta; - break; - case XK_Down: - case XK_KP_Down: - pos.ry() += delta; - break; - case XK_Home: - case XK_KP_Home: - pos.rx() -= delta; - pos.ry() -= delta; - break; - case XK_Page_Up: - case XK_KP_Page_Up: - pos.rx() += delta; - pos.ry() -= delta; - break; - case XK_Page_Down: - case XK_KP_Page_Down: - pos.rx() += delta; - pos.ry() += delta; - break; - case XK_End: - case XK_KP_End: - pos.rx() -= delta; - pos.ry() += delta; - break; - case XK_F1: - if (!mouse_emulation_state) - mouse_emulation_window = getMouseEmulationWindow(); - if ((mouse_emulation_state & Button1Mask) == 0) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuPress, Button1, mouse_emulation_state); - if (!is_shift) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuRelease, Button1, mouse_emulation_state); - break; - case XK_F2: - if (!mouse_emulation_state) - mouse_emulation_window = getMouseEmulationWindow(); - if ((mouse_emulation_state & Button2Mask) == 0) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuPress, Button2, mouse_emulation_state); - if (!is_shift) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuRelease, Button2, mouse_emulation_state); - break; - case XK_F3: - if (!mouse_emulation_state) - mouse_emulation_window = getMouseEmulationWindow(); - if ((mouse_emulation_state & Button3Mask) == 0) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuPress, Button3, mouse_emulation_state); - if (!is_shift) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuRelease, Button3, mouse_emulation_state); - break; - case XK_Return: - case XK_space: - case XK_KP_Enter: - case XK_KP_Space: { - if (!mouse_emulation_state) { - // Nothing was pressed, fake a LMB click - mouse_emulation_window = getMouseEmulationWindow(); - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuPress, Button1, mouse_emulation_state); - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuRelease, Button1, mouse_emulation_state); - } else { - // Release all - if (mouse_emulation_state & Button1Mask) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuRelease, Button1, mouse_emulation_state); - if (mouse_emulation_state & Button2Mask) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuRelease, Button2, mouse_emulation_state); - if (mouse_emulation_state & Button3Mask) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuRelease, Button3, mouse_emulation_state); - } - } - // Fall through - case XK_Escape: - ungrabXKeyboard(); - mouse_emulation = false; - return true; - default: - return false; - } - - QCursor::setPos(pos); - if (mouse_emulation_state) - mouse_emulation_state = sendFakedMouseEvent(pos, mouse_emulation_window, - EmuMove, 0, mouse_emulation_state); - - return true; -} - /** * Delayed focus functions */ diff --git a/workspace.h b/workspace.h index 837e557523..2be4c3505d 100644 --- a/workspace.h +++ b/workspace.h @@ -645,7 +645,6 @@ public slots: void slotWindowToDesktopUp(); void slotWindowToDesktopDown(); - void slotMouseEmulation(); void slotDisableGlobalShortcuts(); void slotSettingsChanged(int category); @@ -730,7 +729,6 @@ private slots: void reallyStopActivity(const QString &id); //dbus deadlocks suck protected: - bool keyPressMouseEmulation(XKeyEvent& ev); void timerEvent(QTimerEvent *te); Q_SIGNALS: @@ -814,11 +812,6 @@ private: void loadDesktopSettings(); void saveDesktopSettings(); - // Mouse emulation - WId getMouseEmulationWindow(); - enum MouseEmulation { EmuPress, EmuRelease, EmuMove }; - unsigned int sendFakedMouseEvent(const QPoint& pos, WId win, MouseEmulation type, int button, unsigned int state); // returns the new state - void tabBoxKeyPress(int key); void tabBoxKeyRelease(const XKeyEvent& ev); @@ -919,9 +912,6 @@ private: KShortcut cutWalkThroughWindows, cutWalkThroughWindowsReverse; KShortcut cutWalkThroughGroupWindows, cutWalkThroughGroupWindowsReverse; KShortcut cutWalkThroughWindowsAlternative, cutWalkThroughWindowsAlternativeReverse; - bool mouse_emulation; - unsigned int mouse_emulation_state; - WId mouse_emulation_window; int block_focus; TabBox::TabBox* tab_box;