From e4ab19a936cefdbc32bd903d3e1a29ce48d8634f Mon Sep 17 00:00:00 2001 From: Lucas Murray Date: Mon, 16 Nov 2009 13:31:02 +0000 Subject: [PATCH] Allow automatic grouping of unrelated windows by matching them with a window rule ID. svn path=/trunk/KDE/kdebase/workspace/; revision=1050040 --- kcmkwin/kwinrules/ruleswidget.cpp | 5 +++ kcmkwin/kwinrules/ruleswidget.h | 1 + kcmkwin/kwinrules/ruleswidgetbase.ui | 56 +++++++++++++++++++++++----- manage.cpp | 11 ++++-- rules.cpp | 8 ++++ rules.h | 4 ++ workspace.cpp | 44 +++++++++++++++++----- 7 files changed, 106 insertions(+), 23 deletions(-) diff --git a/kcmkwin/kwinrules/ruleswidget.cpp b/kcmkwin/kwinrules/ruleswidget.cpp index fc33265621..ce7d2d023d 100644 --- a/kcmkwin/kwinrules/ruleswidget.cpp +++ b/kcmkwin/kwinrules/ruleswidget.cpp @@ -99,6 +99,7 @@ RulesWidget::RulesWidget( QWidget* parent ) SETUP( acceptfocus, force ); SETUP( closeable, force ); SETUP( autogroup, force ); + SETUP( autogroupid, force ); SETUP( opacityactive, force ); SETUP( opacityinactive, force ); SETUP( shortcut, force ); @@ -147,6 +148,7 @@ UPDATE_ENABLE_SLOT( skippager ) UPDATE_ENABLE_SLOT( acceptfocus ) UPDATE_ENABLE_SLOT( closeable ) UPDATE_ENABLE_SLOT( autogroup ) +UPDATE_ENABLE_SLOT( autogroupid ) UPDATE_ENABLE_SLOT( opacityactive ) UPDATE_ENABLE_SLOT( opacityinactive ) void RulesWidget::updateEnableshortcut() @@ -423,6 +425,7 @@ void RulesWidget::setRules( Rules* rules ) CHECKBOX_FORCE_RULE( acceptfocus, ); CHECKBOX_FORCE_RULE( closeable, ); CHECKBOX_FORCE_RULE( autogroup, ); + LINEEDIT_FORCE_RULE( autogroupid, ); LINEEDIT_FORCE_RULE( opacityactive, intToStr ); LINEEDIT_FORCE_RULE( opacityinactive, intToStr ); LINEEDIT_SET_RULE( shortcut, ); @@ -514,6 +517,7 @@ Rules* RulesWidget::rules() const CHECKBOX_FORCE_RULE( acceptfocus, ); CHECKBOX_FORCE_RULE( closeable, ); CHECKBOX_FORCE_RULE( autogroup, ); + LINEEDIT_FORCE_RULE( autogroupid, ); LINEEDIT_FORCE_RULE( opacityactive, strToInt ); LINEEDIT_FORCE_RULE( opacityinactive, strToInt ); LINEEDIT_SET_RULE( shortcut, ); @@ -632,6 +636,7 @@ void RulesWidget::prefillUnusedValues( const KWindowInfo& info ) //CHECKBOX_PREFILL( acceptfocus, ); //CHECKBOX_PREFILL( closeable, ); //CHECKBOX_PREFILL( autogroup, ); + //LINEEDIT_PREFILL( autogroupid, ); LINEEDIT_PREFILL( opacityactive, intToStr, 100 /*get the actual opacity somehow*/); LINEEDIT_PREFILL( opacityinactive, intToStr, 100 /*get the actual opacity somehow*/); //LINEEDIT_PREFILL( shortcut, ); diff --git a/kcmkwin/kwinrules/ruleswidget.h b/kcmkwin/kwinrules/ruleswidget.h index 3de4963b8b..fd65ce4bda 100644 --- a/kcmkwin/kwinrules/ruleswidget.h +++ b/kcmkwin/kwinrules/ruleswidget.h @@ -73,6 +73,7 @@ class RulesWidget void updateEnableacceptfocus(); void updateEnablecloseable(); void updateEnableautogroup(); + void updateEnableautogroupid(); void updateEnableopacityactive(); void updateEnableopacityinactive(); // workarounds tab diff --git a/kcmkwin/kwinrules/ruleswidgetbase.ui b/kcmkwin/kwinrules/ruleswidgetbase.ui index 4171e62fd5..3f617d3a30 100644 --- a/kcmkwin/kwinrules/ruleswidgetbase.ui +++ b/kcmkwin/kwinrules/ruleswidgetbase.ui @@ -1157,13 +1157,20 @@ + + + Autogroup by I&D + + + + A&ctive opacity in % - + false @@ -1185,7 +1192,7 @@ - + false @@ -1275,6 +1282,35 @@ + + + + false + + + + + + + false + + + + Do Not Affect + + + + + Force + + + + + Force Temporarily + + + + @@ -1526,7 +1562,7 @@ - + Qt::Vertical @@ -1542,7 +1578,7 @@ - + false @@ -1564,7 +1600,7 @@ - + false @@ -1574,14 +1610,14 @@ - + I&nactive opacity in % - + Shortcut @@ -1591,7 +1627,7 @@ - + false @@ -1628,14 +1664,14 @@ - + Edit... - + false diff --git a/manage.cpp b/manage.cpp index f89fbfa772..e21a392b76 100644 --- a/manage.cpp +++ b/manage.cpp @@ -297,6 +297,7 @@ bool Client::manage( Window w, bool isMapped ) move( geom.x(), geom.y() ); // Before gravitating // Create client group if the window will have a decoration + bool dontKeepInArea = false; if( !noBorder() ) { client_group = NULL; @@ -312,14 +313,16 @@ bool Client::manage( Window w, bool isMapped ) group->add( this, -1, true ); break; } - if( !client_group && !isMapped && !session && - rules()->checkAutogrouping( options->autogroupSimilarWindows )) + if( !client_group && !isMapped && !session ) { // Attempt to automatically group similar windows const Client* similar = workspace()->findSimilarClient( this ); if( similar && similar->clientGroup() && !similar->noBorder() ) { similar->clientGroup()->add( this, -1, true ); - placementDone = true; // Don't move entire group + // Don't move entire group + geom = QRect( similar->pos() + similar->clientPos(), similar->clientSize() ); + placementDone = true; + dontKeepInArea = true; } } if( !client_group ) @@ -345,7 +348,7 @@ bool Client::manage( Window w, bool isMapped ) placementDone = true; } - if(( !isSpecialWindow() || isToolbar() ) && isMovable() ) + if(( !isSpecialWindow() || isToolbar() ) && isMovable() && !dontKeepInArea ) keepInArea( area, partial_keep_in_area ); updateShape(); diff --git a/rules.cpp b/rules.cpp index bbf33da1e3..37d9b71f65 100644 --- a/rules.cpp +++ b/rules.cpp @@ -69,6 +69,7 @@ Rules::Rules() , moveresizemoderule( UnusedForceRule ) , closeablerule( UnusedForceRule ) , autogrouprule( UnusedForceRule ) + , autogroupidrule( UnusedForceRule ) , strictgeometryrule( UnusedForceRule ) , shortcutrule( UnusedSetRule ) , disableglobalshortcutsrule( UnusedForceRule ) @@ -170,6 +171,7 @@ void Rules::readFromCfg( const KConfigGroup& cfg ) READ_FORCE_RULE( moveresizemode,Options::stringToMoveResizeMode, QString()); READ_FORCE_RULE( closeable, , false); READ_FORCE_RULE( autogroup,, false); + READ_FORCE_RULE( autogroupid,, QString()); READ_FORCE_RULE( strictgeometry, , false); READ_SET_RULE( shortcut, ,QString() ); READ_FORCE_RULE( disableglobalshortcuts, , false); @@ -255,6 +257,7 @@ void Rules::write( KConfigGroup& cfg ) const WRITE_FORCE_RULE( moveresizemode, Options::moveResizeModeToString ); WRITE_FORCE_RULE( closeable, ); WRITE_FORCE_RULE( autogroup, ); + WRITE_FORCE_RULE( autogroupid, ); WRITE_FORCE_RULE( strictgeometry, ); WRITE_SET_RULE( shortcut, ); WRITE_FORCE_RULE( disableglobalshortcuts, ); @@ -292,6 +295,7 @@ bool Rules::isEmpty() const && moveresizemoderule == UnusedForceRule && closeablerule == UnusedForceRule && autogrouprule == UnusedForceRule + && autogroupidrule == UnusedForceRule && strictgeometryrule == UnusedForceRule && shortcutrule == UnusedSetRule && disableglobalshortcutsrule == UnusedForceRule ); @@ -617,6 +621,7 @@ APPLY_FORCE_RULE( acceptfocus, AcceptFocus, bool ) APPLY_FORCE_RULE( moveresizemode, MoveResizeMode, Options::MoveResizeMode ) APPLY_FORCE_RULE( closeable, Closeable, bool ) APPLY_FORCE_RULE( autogroup, Autogrouping, bool ) +APPLY_FORCE_RULE( autogroupid, AutogroupById, QString ) APPLY_FORCE_RULE( strictgeometry, StrictGeometry, bool ) APPLY_RULE( shortcut, Shortcut, QString ) APPLY_FORCE_RULE( disableglobalshortcuts, DisableGlobalShortcuts, bool ) @@ -680,6 +685,7 @@ void Rules::discardUsed( bool withdrawn ) DISCARD_USED_FORCE_RULE( moveresizemode ); DISCARD_USED_FORCE_RULE( closeable ); DISCARD_USED_FORCE_RULE( autogroup ); + DISCARD_USED_FORCE_RULE( autogroupid ); DISCARD_USED_FORCE_RULE( strictgeometry ); DISCARD_USED_SET_RULE( shortcut ); DISCARD_USED_FORCE_RULE( disableglobalshortcuts ); @@ -801,6 +807,7 @@ CHECK_FORCE_RULE( AcceptFocus, bool ) CHECK_FORCE_RULE( MoveResizeMode, Options::MoveResizeMode ) CHECK_FORCE_RULE( Closeable, bool ) CHECK_FORCE_RULE( Autogrouping, bool ) +CHECK_FORCE_RULE( AutogroupById, QString ) CHECK_FORCE_RULE( StrictGeometry, bool ) CHECK_RULE( Shortcut, QString ) CHECK_FORCE_RULE( DisableGlobalShortcuts, bool ) @@ -857,6 +864,7 @@ void Client::applyWindowRules() if( s != size()) resizeWithChecks( s ); // Autogrouping : Only checked on window manage + // AutogroupById : Only checked on window manage // StrictGeometry setShortcut( rules()->checkShortcut( shortcut().toString())); // see also Client::setActive() diff --git a/rules.h b/rules.h index 28f9575c0a..55e1a75f90 100644 --- a/rules.h +++ b/rules.h @@ -78,6 +78,7 @@ class WindowRules Options::MoveResizeMode checkMoveResizeMode( Options::MoveResizeMode mode ) const; bool checkCloseable( bool closeable ) const; bool checkAutogrouping( bool autogroup ) const; + QString checkAutogroupById( QString id ) const; bool checkStrictGeometry( bool strict ) const; QString checkShortcut( QString s, bool init = false ) const; bool checkDisableGlobalShortcuts( bool disable ) const; @@ -131,6 +132,7 @@ class Rules bool applyMoveResizeMode( Options::MoveResizeMode& mode ) const; bool applyCloseable( bool& closeable ) const; bool applyAutogrouping( bool& autogroup ) const; + bool applyAutogroupById( QString& id ) const; bool applyStrictGeometry( bool& strict ) const; bool applyShortcut( QString& shortcut, bool init ) const; bool applyDisableGlobalShortcuts( bool& disable ) const; @@ -246,6 +248,8 @@ class Rules ForceRule closeablerule; bool autogroup; ForceRule autogrouprule; + QString autogroupid; + ForceRule autogroupidrule; bool strictgeometry; ForceRule strictgeometryrule; QString shortcut; diff --git a/workspace.cpp b/workspace.cpp index 4c353fe8a8..eaf9e6a44a 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -2892,19 +2892,45 @@ Client* Workspace::findSimilarClient( Client* c ) { // Attempt to find a similar window to the input. If we find multiple possibilities that are in // different groups then ignore all of them. This function is for automatic window grouping. Client* found = NULL; - QByteArray wRole = truncatedWindowRole( c->windowRole() ); - foreach( Client* cl, clients ) + + // See if the window has a group ID to match with + QString wGId = c->rules()->checkAutogroupById( QString() ); + if( !wGId.isEmpty() ) { - QByteArray wRoleB = truncatedWindowRole( cl->windowRole() ); - if( c->resourceClass() == cl->resourceClass() && // Same resource class - wRole == wRoleB && // Same window role - cl->isNormalWindow() ) // Normal window TODO: Can modal windows be "normal"? + foreach( Client* cl, clients ) { - if( found && found->clientGroup() != cl->clientGroup() ) // We've found two, ignore both - return NULL; - found = cl; + if( wGId == cl->rules()->checkAutogroupById( QString() )) + { + if( found && found->clientGroup() != cl->clientGroup() ) // We've found two, ignore both + { + found = NULL; + break; // Continue to the next test + } + found = cl; + } + } + if( found ) + return found; + } + + // If we don't have an ID take a guess + if( c->rules()->checkAutogrouping( options->autogroupSimilarWindows )) + { + QByteArray wRole = truncatedWindowRole( c->windowRole() ); + foreach( Client* cl, clients ) + { + QByteArray wRoleB = truncatedWindowRole( cl->windowRole() ); + if( c->resourceClass() == cl->resourceClass() && // Same resource class + wRole == wRoleB && // Same window role + cl->isNormalWindow() ) // Normal window TODO: Can modal windows be "normal"? + { + if( found && found->clientGroup() != cl->clientGroup() ) // We've found two, ignore both + return NULL; + found = cl; + } } } + return found; }