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:
Luboš Luňák 2004-02-10 09:24:57 +00:00
parent 9e9a93fe62
commit 5f079f5e3d
5 changed files with 61 additions and 26 deletions

View file

@ -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();

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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 )
{