From 5f079f5e3d7fa4bd04cfa18740cf3dde12dba2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Tue, 10 Feb 2004 09:24:57 +0000 Subject: [PATCH] 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 --- client.h | 2 +- events.cpp | 4 +-- tabbox.cpp | 67 ++++++++++++++++++++++++++++++++++----------------- workspace.cpp | 3 ++- workspace.h | 11 +++++++++ 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/client.h b/client.h index fc1ae26a12..b8864f3245 100644 --- a/client.h +++ b/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(); diff --git a/events.cpp b/events.cpp index f18ab3de4d..903fd8ebf2 100644 --- a/events.cpp +++ b/events.cpp @@ -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 diff --git a/tabbox.cpp b/tabbox.cpp index e5603d9787..1d5fa5f0b8 100644 --- a/tabbox.cpp +++ b/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 diff --git a/workspace.cpp b/workspace.cpp index 6d3639fb5a..832acce967 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -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; diff --git a/workspace.h b/workspace.h index 1fb08c9fd5..64088766ae 100644 --- a/workspace.h +++ b/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 ) {