From ca87a4bae2e44dfc5a80c1f9e283d1e6397cbaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Fri, 24 Aug 2007 09:46:56 +0000 Subject: [PATCH] In mouse focus policies, change active window only when the mouse actually moves, not as a result of window changes (#92290). svn path=/trunk/KDE/kdebase/workspace/; revision=704202 --- activation.cpp | 1 + events.cpp | 22 ++++++++++++++++------ workspace.h | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/activation.cpp b/activation.cpp index f51c105a1..844c908c0 100644 --- a/activation.cpp +++ b/activation.cpp @@ -220,6 +220,7 @@ void Workspace::setActiveClient( Client* c, allowed_t ) closeActivePopup(); StackingUpdatesBlocker blocker( this ); ++set_active_client_recursion; + updateFocusMousePosition( QCursor::pos()); if( active_client != NULL ) { // note that this may call setActiveClient( NULL ), therefore the recursion counter active_client->setActive( false ); diff --git a/events.cpp b/events.cpp index 3ceb03670..cae2ae4ee 100644 --- a/events.cpp +++ b/events.cpp @@ -637,6 +637,7 @@ bool Client::windowEvent( XEvent* e ) case MotionNotify: motionNotifyEvent( e->xmotion.window, e->xmotion.state, e->xmotion.x, e->xmotion.y, e->xmotion.x_root, e->xmotion.y_root ); + workspace()->updateFocusMousePosition( QPoint( e->xmotion.x_root, e->xmotion.y_root )); break; case EnterNotify: enterNotifyEvent( &e->xcrossing ); @@ -647,11 +648,14 @@ bool Client::windowEvent( XEvent* e ) // events simpler (Qt does that too). motionNotifyEvent( e->xcrossing.window, e->xcrossing.state, e->xcrossing.x, e->xcrossing.y, e->xcrossing.x_root, e->xcrossing.y_root ); + workspace()->updateFocusMousePosition( QPoint( e->xcrossing.x_root, e->xcrossing.y_root )); break; case LeaveNotify: motionNotifyEvent( e->xcrossing.window, e->xcrossing.state, e->xcrossing.x, e->xcrossing.y, e->xcrossing.x_root, e->xcrossing.y_root ); leaveNotifyEvent( &e->xcrossing ); + // not here, it'd break following enter notify handling + // workspace()->updateFocusMousePosition( QPoint( e->xcrossing.x_root, e->xcrossing.y_root )); break; case FocusIn: focusInEvent( &e->xfocus ); @@ -951,13 +955,19 @@ void Client::enterNotifyEvent( XCrossingEvent* e ) autoRaiseTimer->start( options->autoRaiseInterval ); } - if ( options->focusPolicy != Options::FocusStrictlyUnderMouse && ( isDesktop() || isDock() || isTopMenu() ) ) + QPoint currentPos( e->x_root, e->y_root ); + if ( options->focusPolicy != Options::FocusStrictlyUnderMouse && ( isDesktop() || isDock() || isTopMenu() ) ) return; - if ( options->delayFocus ) - workspace()->requestDelayFocus( this ); - else - workspace()->requestFocus( this ); - + // for FocusFollowsMouse, change focus only if the mouse has actually been moved, not if the focus + // change came because of window changes (e.g. closing a window) - #92290 + if( options->focusPolicy != Options::FocusFollowsMouse + || currentPos != workspace()->focusMousePosition()) + { + if ( options->delayFocus ) + workspace()->requestDelayFocus( this ); + else + workspace()->requestFocus( this ); + } return; } } diff --git a/workspace.h b/workspace.h index 3f2a2987a..b54ac3096 100644 --- a/workspace.h +++ b/workspace.h @@ -292,6 +292,8 @@ class Workspace : public QObject, public KDecorationDefines void cancelDelayFocus(); void requestDelayFocus( Client* ); + void updateFocusMousePosition( const QPoint& pos ); + QPoint focusMousePosition() const; void toggleTopDockShadows(bool on); @@ -581,6 +583,7 @@ class Workspace : public QObject, public KDecorationDefines // delay(ed) window focus timer and client QTimer* delayFocusTimer; Client* delayfocus_client; + QPoint focusMousePos; ClientList clients; ClientList desktops; @@ -870,6 +873,18 @@ void Workspace::forceRestacking() StackingUpdatesBlocker blocker( this ); // do restacking if not blocked } +inline +void Workspace::updateFocusMousePosition( const QPoint& pos ) + { + focusMousePos = pos; + } + +inline +QPoint Workspace::focusMousePosition() const + { + return focusMousePos; + } + template< typename T > inline Client* Workspace::findClient( T predicate ) {