improved mouse emulation
svn path=/trunk/kdebase/kwin/; revision=53892
This commit is contained in:
parent
601d183852
commit
c0e1ae2879
2 changed files with 168 additions and 56 deletions
175
workspace.cpp
175
workspace.cpp
|
@ -1925,6 +1925,8 @@ void Workspace::slotMouseEmulation()
|
|||
GrabModeAsync, GrabModeAsync,
|
||||
kwin_time) == GrabSuccess ) {
|
||||
mouse_emulation = TRUE;
|
||||
mouse_emulation_state = 0;
|
||||
mouse_emulation_window = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2175,6 +2177,105 @@ QPoint Workspace::adjustClientPosition( Client* c, QPoint pos )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
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 = qt_xrootwin();
|
||||
int root_x, root_y, lx, ly;
|
||||
uint state;
|
||||
Window w;
|
||||
Client * c = 0;
|
||||
do {
|
||||
w = child;
|
||||
if (!c)
|
||||
c = findClientWidthId( w );
|
||||
XQueryPointer( qt_xdisplay(), 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( QPoint pos, WId w, MouseEmulation type, int button, unsigned int state )
|
||||
{
|
||||
if ( !w )
|
||||
return state;
|
||||
QWidget* widget = QWidget::find( w );
|
||||
if ( (!widget || widget->inherits("QToolButton") ) && !findClient( w ) ) {
|
||||
int x, y;
|
||||
Window xw;
|
||||
XTranslateCoordinates( qt_xdisplay(), qt_xrootwin(), w, pos.x(), pos.y(), &x, &y, &xw );
|
||||
if ( type == EmuMove ) { // motion notify events
|
||||
XMotionEvent e;
|
||||
e.type = MotionNotify;
|
||||
e.window = w;
|
||||
e.root = qt_xrootwin();
|
||||
e.subwindow = w;
|
||||
e.time = kwin_time;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.x_root = pos.x();
|
||||
e.y_root = pos.y();
|
||||
e.state = state;
|
||||
e.is_hint = NotifyNormal;
|
||||
XSendEvent( qt_xdisplay(), w, TRUE, ButtonMotionMask, (XEvent*)&e );
|
||||
} else {
|
||||
XButtonEvent e;
|
||||
e.type = type == EmuRelease ? ButtonRelease : ButtonPress;
|
||||
e.window = w;
|
||||
e.root = qt_xrootwin();
|
||||
e.subwindow = w;
|
||||
e.time = kwin_time;
|
||||
e.x = x;
|
||||
e.y = y;
|
||||
e.x_root = pos.x();
|
||||
e.y_root = pos.y();
|
||||
e.state = state;
|
||||
e.button = button;
|
||||
XSendEvent( qt_xdisplay(), w, TRUE, ButtonPressMask, (XEvent*)&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
|
||||
*/
|
||||
|
@ -2187,6 +2288,7 @@ bool Workspace::keyPressMouseEmulation( XKeyEvent key )
|
|||
|
||||
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 = QCursor::pos();
|
||||
|
||||
|
@ -2207,46 +2309,47 @@ bool Workspace::keyPressMouseEmulation( XKeyEvent key )
|
|||
case XK_KP_Down:
|
||||
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:
|
||||
{
|
||||
Window root;
|
||||
Window child = qt_xrootwin();
|
||||
int root_x, root_y, lx, ly;
|
||||
uint state;
|
||||
Window w;
|
||||
Client * c = 0;
|
||||
do {
|
||||
w = child;
|
||||
if (!c)
|
||||
c = findClientWidthId( w );
|
||||
XQueryPointer( qt_xdisplay(), w, &root, &child,
|
||||
&root_x, &root_y, &lx, &ly, &state );
|
||||
} while ( child != None && child != w );
|
||||
|
||||
if ( c && !c->isActive() )
|
||||
activateClient( c );
|
||||
|
||||
QWidget* widget = QWidget::find( w );
|
||||
if ( (!widget || widget->inherits("QToolButton") ) && !findClient( w ) ) {
|
||||
XButtonEvent e;
|
||||
e.type = ButtonPress;
|
||||
e.window = w;
|
||||
e.root = qt_xrootwin();
|
||||
e.subwindow = w;
|
||||
e.time = kwin_time;
|
||||
e.x = lx;
|
||||
e.y = ly;
|
||||
e.x_root = root_x;
|
||||
e.y_root = root_y;
|
||||
e.state = key.state;
|
||||
e.button = Button1;
|
||||
XSendEvent( qt_xdisplay(), w, TRUE, ButtonPressMask, (XEvent*)&e );
|
||||
e.type = ButtonRelease;
|
||||
e.state = key.state & Button1Mask;
|
||||
XSendEvent( qt_xdisplay(), w, TRUE, ButtonReleaseMask, (XEvent*)&e );
|
||||
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
|
||||
|
@ -2259,6 +2362,8 @@ bool Workspace::keyPressMouseEmulation( XKeyEvent key )
|
|||
}
|
||||
|
||||
QCursor::setPos( pos );
|
||||
if ( mouse_emulation_state )
|
||||
mouse_emulation_state = sendFakedMouseEvent( pos, mouse_emulation_window, EmuMove, 0, mouse_emulation_state );
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
|
|
@ -259,6 +259,11 @@ private:
|
|||
int row;
|
||||
};
|
||||
|
||||
// mouse emulation
|
||||
WId getMouseEmulationWindow();
|
||||
enum MouseEmulation { EmuPress, EmuRelease, EmuMove };
|
||||
unsigned int sendFakedMouseEvent( QPoint pos, WId win, MouseEmulation type, int button, unsigned int state ); // returns the new state
|
||||
|
||||
// ------------------
|
||||
|
||||
DockWindowList dockwins;
|
||||
|
@ -286,6 +291,8 @@ private:
|
|||
bool control_grab;
|
||||
bool tab_grab;
|
||||
bool mouse_emulation;
|
||||
unsigned int mouse_emulation_state;
|
||||
WId mouse_emulation_window;
|
||||
bool focus_change;
|
||||
|
||||
TabBox* tab_box;
|
||||
|
|
Loading…
Reference in a new issue