diff --git a/clientgroup.cpp b/clientgroup.cpp index b8a6e62172..d7e1d14b06 100644 --- a/clientgroup.cpp +++ b/clientgroup.cpp @@ -85,7 +85,6 @@ void ClientGroup::add( Client* c, int before, bool becomeVisible ) updateMinMaxSize(); updateStates( clients_[visible_], c ); - c->setGeometry( clients_[visible_]->geometry() ); if( becomeVisible ) // Set visible after settings geometry setVisible( c ); diff --git a/kcmkwin/kwinoptions/windows.cpp b/kcmkwin/kwinoptions/windows.cpp index 966c89ea15..f4d76e46e5 100644 --- a/kcmkwin/kwinoptions/windows.cpp +++ b/kcmkwin/kwinoptions/windows.cpp @@ -61,6 +61,7 @@ #define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval" #define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel" #define KWIN_HIDE_UTILITY "HideUtilityWindowsForInactive" +#define KWIN_AUTOGROUP_SIMILAR "AutogroupSimilarWindows" #define KWIN_SEPARATE_SCREEN_FOCUS "SeparateScreenFocus" #define KWIN_ACTIVE_MOUSE_SCREEN "ActiveMouseScreen" @@ -592,6 +593,12 @@ KAdvancedConfig::KAdvancedConfig (bool _standAlone, KConfig *_config, const KCom connect(hideUtilityWindowsForInactive, SIGNAL(toggled(bool)), SLOT(changed())); vLay->addWidget( hideUtilityWindowsForInactive, 1, 0, 1, 2 ); + autogroupSimilarWindows = new QCheckBox( i18n( "Automatically group identical windows" ), this ); + autogroupSimilarWindows->setWhatsThis( + i18n( "When turned on attempt to automatically detect when a newly opened window is related" + " to an existing one and place them in the same window group." )); + connect(autogroupSimilarWindows, SIGNAL(toggled(bool)), SLOT(changed())); + vLay->addWidget( autogroupSimilarWindows, 2, 0, 1, 2 ); lay->addStretch(); load(); @@ -663,6 +670,7 @@ void KAdvancedConfig::load( void ) // } setHideUtilityWindowsForInactive( cg.readEntry( KWIN_HIDE_UTILITY, true)); + setAutogroupSimilarWindows( cg.readEntry( KWIN_AUTOGROUP_SIMILAR, false)); emit KCModule::changed(false); } @@ -701,6 +709,7 @@ void KAdvancedConfig::save( void ) cg.writeEntry(KWIN_PLACEMENT, "Smart"); cg.writeEntry(KWIN_HIDE_UTILITY, hideUtilityWindowsForInactive->isChecked()); + cg.writeEntry(KWIN_AUTOGROUP_SIMILAR, autogroupSimilarWindows->isChecked()); if (standAlone) { @@ -720,6 +729,7 @@ void KAdvancedConfig::defaults() setShadeHoverInterval(250); setPlacement(SMART_PLACEMENT); setHideUtilityWindowsForInactive( true ); + setAutogroupSimilarWindows( false ); emit KCModule::changed(true); } @@ -739,6 +749,10 @@ void KAdvancedConfig::setHideUtilityWindowsForInactive(bool s) { hideUtilityWindowsForInactive->setChecked( s ); } +void KAdvancedConfig::setAutogroupSimilarWindows(bool s) { + autogroupSimilarWindows->setChecked( s ); +} + KMovingConfig::~KMovingConfig () { if (standAlone) diff --git a/kcmkwin/kwinoptions/windows.h b/kcmkwin/kwinoptions/windows.h index 665c2a560d..24562df8d3 100644 --- a/kcmkwin/kwinoptions/windows.h +++ b/kcmkwin/kwinoptions/windows.h @@ -204,6 +204,9 @@ private: void setHideUtilityWindowsForInactive( bool ); QCheckBox* hideUtilityWindowsForInactive; + void setAutogroupSimilarWindows( bool ); + QCheckBox* autogroupSimilarWindows; + int getPlacement( void ); //CT void setPlacement(int); //CT KComboBox *placementCombo; diff --git a/manage.cpp b/manage.cpp index 78b23f3f83..c47d5de8f4 100644 --- a/manage.cpp +++ b/manage.cpp @@ -312,6 +312,15 @@ bool Client::manage( Window w, bool isMapped ) group->add( this, -1, true ); break; } + if( !client_group && !isMapped && !session && options->autogroupSimilarWindows ) + { // 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 + } + } if( !client_group ) client_group = new ClientGroup( this ); } diff --git a/options.cpp b/options.cpp index 888be03a41..138aeae23a 100644 --- a/options.cpp +++ b/options.cpp @@ -169,6 +169,7 @@ unsigned long Options::updateSettings() killPingTimeout = config.readEntry( "KillPingTimeout", 5000 ); hideUtilityWindowsForInactive = config.readEntry( "HideUtilityWindowsForInactive", true); + autogroupSimilarWindows = config.readEntry( "AutogroupSimilarWindows", false ); showDesktopIsMinimizeAll = config.readEntry( "ShowDesktopIsMinimizeAll", false ); borderless_maximized_windows = config.readEntry( "BorderlessMaximizedWindows", false ); diff --git a/options.h b/options.h index f61d37ce40..657107004d 100644 --- a/options.h +++ b/options.h @@ -321,6 +321,8 @@ class Options : public KDecorationOptions // Whether to hide utility windows for inactive applications. bool hideUtilityWindowsForInactive; + bool autogroupSimilarWindows; + // Compositing settings bool useCompositing; CompositingType compositingMode; diff --git a/workspace.cpp b/workspace.cpp index ab392464b9..4c353fe8a8 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -2877,6 +2877,37 @@ void Workspace::moveItemToClientGroup( ClientGroup* oldGroup, int oldIndex, group->add( c, index, true ); } +// To accept "mainwindow#1" to "mainwindow#2" +static QByteArray truncatedWindowRole( QByteArray a ) + { + int i = a.indexOf('#'); + if( i == -1 ) + return a; + QByteArray b( a ); + b.truncate( i ); + return b; + } + +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 ) + { + 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; + } + } // namespace #include "workspace.moc" diff --git a/workspace.h b/workspace.h index c411ed901a..759833ff60 100644 --- a/workspace.h +++ b/workspace.h @@ -322,6 +322,7 @@ class Workspace : public QObject, public KDecorationDefines int indexOfClientGroup( ClientGroup* group ); /// Change the client c_id to the group with index g_id void moveItemToClientGroup( ClientGroup* oldGroup, int oldIndex, ClientGroup* group, int index = -1 ); + Client* findSimilarClient( Client* c ); QList clientGroups; // List of existing clients groups with no special order /**