Fix for #67416 by Martin Koller + my grab code changes to get mouse
clicks even for the active window. svn path=/trunk/kdebase/kwin/; revision=286702
This commit is contained in:
parent
9e9a93fe62
commit
5f079f5e3d
5 changed files with 61 additions and 26 deletions
2
client.h
2
client.h
|
@ -238,6 +238,7 @@ class Client : public QObject, public KDecorationDefines
|
|||
QString caption() const;
|
||||
|
||||
void keyPressEvent( uint key_code ); // FRAME ??
|
||||
void updateMouseGrab();
|
||||
|
||||
const QPoint calculateGravitation( bool invert, int gravity = 0 ) const; // FRAME public?
|
||||
|
||||
|
@ -351,7 +352,6 @@ class Client : public QObject, public KDecorationDefines
|
|||
void checkUnrestrictedMoveResize();
|
||||
void handleMoveResize( int x, int y, int x_root, int y_root );
|
||||
void positionGeometryTip();
|
||||
void updateMouseGrab();
|
||||
void grabButton( int mod );
|
||||
void ungrabButton( int mod );
|
||||
void resetMaximize();
|
||||
|
|
|
@ -952,8 +952,8 @@ void Client::ungrabButton( int modifier )
|
|||
(Motif, AWT, Tk, ...)
|
||||
*/
|
||||
void Client::updateMouseGrab()
|
||||
{
|
||||
if( isActive() )
|
||||
{ // see Workspace::establishTabBoxGrab()
|
||||
if( isActive() && !workspace()->forcedGlobalMouseGrab())
|
||||
{
|
||||
// remove the grab for no modifiers only if the window
|
||||
// is unobscured or if the user doesn't want click raise
|
||||
|
|
67
tabbox.cpp
67
tabbox.cpp
|
@ -1,4 +1,4 @@
|
|||
/*****************************************************************
|
||||
/********x*********************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
|
@ -541,7 +541,10 @@ void TabBox::handleMouseEvent( XEvent* e )
|
|||
return;
|
||||
QPoint pos( e->xbutton.x_root, e->xbutton.y_root );
|
||||
if( !geometry().contains( pos ))
|
||||
{
|
||||
workspace()->closeTabBox(); // click outside closes tab
|
||||
return;
|
||||
}
|
||||
pos.rx() -= x(); // pos is now inside tabbox
|
||||
pos.ry() -= y();
|
||||
int num = (pos.y()-frameWidth()) / lineHeight;
|
||||
|
@ -798,13 +801,8 @@ void Workspace::slotWalkBackThroughDesktopList()
|
|||
|
||||
bool Workspace::startKDEWalkThroughWindows()
|
||||
{
|
||||
if ( XGrabKeyboard(qt_xdisplay(),
|
||||
root, FALSE,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
qt_x_time) != GrabSuccess )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if( !establishTabBoxGrab())
|
||||
return false;
|
||||
tab_grab = TRUE;
|
||||
keys->setEnabled( false );
|
||||
tab_box->setMode( TabBox::WindowsMode );
|
||||
|
@ -814,13 +812,8 @@ bool Workspace::startKDEWalkThroughWindows()
|
|||
|
||||
bool Workspace::startWalkThroughDesktops( int mode )
|
||||
{
|
||||
if ( XGrabKeyboard(qt_xdisplay(),
|
||||
root, FALSE,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
qt_x_time) != GrabSuccess )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if( !establishTabBoxGrab())
|
||||
return false;
|
||||
control_grab = TRUE;
|
||||
keys->setEnabled( false );
|
||||
tab_box->setMode( (TabBox::Mode) mode );
|
||||
|
@ -964,15 +957,20 @@ void Workspace::tabBoxKeyPress( const KKeyNative& keyX )
|
|||
if ( ((keyQt & 0xffff) == Qt::Key_Escape)
|
||||
&& !(forward || backward) )
|
||||
{ // if Escape is part of the shortcut, don't cancel
|
||||
XUngrabKeyboard(qt_xdisplay(), qt_x_time);
|
||||
tab_box->hide();
|
||||
keys->setEnabled( true );
|
||||
tab_grab = FALSE;
|
||||
control_grab = FALSE;
|
||||
closeTabBox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::closeTabBox()
|
||||
{
|
||||
removeTabBoxGrab();
|
||||
tab_box->hide();
|
||||
keys->setEnabled( true );
|
||||
tab_grab = FALSE;
|
||||
control_grab = FALSE;
|
||||
}
|
||||
|
||||
/*!
|
||||
Handles alt-tab / control-tab releasing
|
||||
*/
|
||||
|
@ -1013,7 +1011,7 @@ void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
|
|||
return;
|
||||
if (tab_grab)
|
||||
{
|
||||
XUngrabKeyboard(qt_xdisplay(), qt_x_time);
|
||||
removeTabBoxGrab();
|
||||
tab_box->hide();
|
||||
keys->setEnabled( true );
|
||||
tab_grab = false;
|
||||
|
@ -1026,7 +1024,7 @@ void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
|
|||
}
|
||||
if (control_grab)
|
||||
{
|
||||
XUngrabKeyboard(qt_xdisplay(), qt_x_time);
|
||||
removeTabBoxGrab();
|
||||
tab_box->hide();
|
||||
keys->setEnabled( true );
|
||||
control_grab = False;
|
||||
|
@ -1128,6 +1126,31 @@ Client* Workspace::previousStaticClient( Client* c ) const
|
|||
return *it;
|
||||
}
|
||||
|
||||
bool Workspace::establishTabBoxGrab()
|
||||
{
|
||||
if( XGrabKeyboard( qt_xdisplay(), root, FALSE,
|
||||
GrabModeAsync, GrabModeAsync, qt_x_time) != GrabSuccess )
|
||||
return false;
|
||||
// Don't try to establish a global mouse grab using XGrabPointer, as that would prevent
|
||||
// using Alt+Tab while DND (#44972). However force passive grabs on all windows
|
||||
// in order to catch MouseRelease events and close the tabbox (#67416).
|
||||
// All clients already have passive grabs in their wrapper windows, so check only
|
||||
// the active client, which may not have it.
|
||||
assert( !forced_global_mouse_grab );
|
||||
forced_global_mouse_grab = true;
|
||||
if( active_client != NULL )
|
||||
active_client->updateMouseGrab();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Workspace::removeTabBoxGrab()
|
||||
{
|
||||
XUngrabKeyboard(qt_xdisplay(), qt_x_time);
|
||||
assert( forced_global_mouse_grab );
|
||||
forced_global_mouse_grab = false;
|
||||
if( active_client != NULL )
|
||||
active_client->updateMouseGrab();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -95,7 +95,8 @@ Workspace::Workspace( bool restore )
|
|||
layoutY(2),
|
||||
workarea(NULL),
|
||||
set_active_client_recursion( 0 ),
|
||||
block_stacking_updates( 0 )
|
||||
block_stacking_updates( 0 ),
|
||||
forced_global_mouse_grab( false )
|
||||
{
|
||||
_self = this;
|
||||
mgr = new PluginMgr;
|
||||
|
|
11
workspace.h
11
workspace.h
|
@ -164,6 +164,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
|
|||
Client* previousStaticClient(Client*) const;
|
||||
int nextDesktopFocusChain( int iDesktop ) const;
|
||||
int previousDesktopFocusChain( int iDesktop ) const;
|
||||
void closeTabBox();
|
||||
|
||||
/**
|
||||
* Returns the list of clients sorted in stacking order, with topmost client
|
||||
|
@ -220,6 +221,8 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
|
|||
bool checkStartupNotification( const Client* c, KStartupInfoData& data );
|
||||
|
||||
void focusToNull(); // SELI public?
|
||||
|
||||
bool forcedGlobalMouseGrab() const;
|
||||
|
||||
void sessionSaveStarted();
|
||||
void sessionSaveDone();
|
||||
|
@ -332,6 +335,8 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
|
|||
void oneStepThroughDesktops( bool forward, int mode ); // TabBox::Mode::DesktopMode | DesktopListMode
|
||||
void oneStepThroughDesktops( bool forward );
|
||||
void oneStepThroughDesktopList( bool forward );
|
||||
bool establishTabBoxGrab();
|
||||
void removeTabBoxGrab();
|
||||
|
||||
void updateStackingOrder( bool propagate_new_clients = false );
|
||||
void propagateClients( bool propagate_new_clients ); // called only from updateStackingOrder
|
||||
|
@ -513,6 +518,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
|
|||
int block_stacking_updates; // when >0, stacking updates are temporarily disabled
|
||||
bool blocked_propagating_new_clients; // propagate also new clients after enabling stacking updates?
|
||||
Window null_focus_window;
|
||||
bool forced_global_mouse_grab;
|
||||
friend class StackingUpdatesBlocker;
|
||||
};
|
||||
|
||||
|
@ -628,6 +634,11 @@ inline bool Workspace::sessionSaving() const
|
|||
return session_saving;
|
||||
}
|
||||
|
||||
inline bool Workspace::forcedGlobalMouseGrab() const
|
||||
{
|
||||
return forced_global_mouse_grab;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline Client* Workspace::findClient( T predicate )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue