diff --git a/client.cpp b/client.cpp index a22d2f6e46..7e89c18238 100644 --- a/client.cpp +++ b/client.cpp @@ -1007,7 +1007,7 @@ void Client::killProcess( bool ask, Time timestamp ) if( process_killer != NULL ) return; Q_ASSERT( !ask || timestamp != CurrentTime ); - QCString machine = wmClientMachine(); + QCString machine = wmClientMachine( true ); pid_t pid = info->pid(); if( pid <= 0 || machine.isEmpty()) // needed properties missing return; @@ -1388,29 +1388,12 @@ QCString Client::staticWmCommand(WId w) /*! Returns WM_CLIENT_MACHINE property for a given window. - Local machine is always returned as "localhost". */ QCString Client::staticWmClientMachine(WId w) { QCString result = getStringProperty(w, XA_WM_CLIENT_MACHINE); if (result.isEmpty()) - { result = "localhost"; - } - else - { - // special name for the local machine (localhost) - char hostnamebuf[80]; - if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0) - { - hostnamebuf[sizeof(hostnamebuf)-1] = 0; - if (result == hostnamebuf) - result = "localhost"; - char *dot = strchr(hostnamebuf, '.'); - if (dot && !(*dot = 0) && result == hostnamebuf) - result = "localhost"; - } - } return result; } @@ -1473,11 +1456,16 @@ QCString Client::wmCommand() Returns client machine for this client, taken either from its window or from the leader window. */ -QCString Client::wmClientMachine() const +QCString Client::wmClientMachine( bool use_localhost ) const { QCString result = staticWmClientMachine(window()); if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window()) result = staticWmClientMachine(wmClientLeaderWin); + if( use_localhost ) + { // special name for the local machine (localhost) + if( result != "localhost" && isLocalMachine( result )) + result = "localhost"; + } return result; } diff --git a/client.h b/client.h index fcbd8ecfd2..b3b5318074 100644 --- a/client.h +++ b/client.h @@ -223,7 +223,7 @@ class Client : public QObject, public KDecorationDefines QCString resourceName() const; QCString resourceClass() const; QCString wmCommand(); - QCString wmClientMachine() const; + QCString wmClientMachine( bool use_localhost ) const; Window wmClientLeader() const; pid_t pid() const; diff --git a/group.cpp b/group.cpp index d9f1a99661..6a3a4b621e 100644 --- a/group.cpp +++ b/group.cpp @@ -266,7 +266,7 @@ bool Client::belongToSameApplication( const Client* c1, const Client* c2, bool a else if( c2->isTransient() && c1->hasTransient( c2, true )) same_app = true; // c2 has c1 as mainwindow else if( c1->pid() != c2->pid() - || c1->wmClientMachine() != c2->wmClientMachine()) + || c1->wmClientMachine( false ) != c2->wmClientMachine( false )) ; // different processes else if( c1->wmClientLeader() != c2->wmClientLeader() && c1->wmClientLeader() != c1->window() // if WM_CLIENT_LEADER is not set, it returns window(), diff --git a/rules.cpp b/rules.cpp index 4b91af93b4..01bc20b204 100644 --- a/rules.cpp +++ b/rules.cpp @@ -23,9 +23,11 @@ static WindowRules dummyRules; // dummy used to avoid NULL checks WindowRules::WindowRules() : wmclassregexp( false ) + , wmclasscomplete( false ) , windowroleregexp( false ) , titleregexp( false ) , extraroleregexp( false ) + , clientmachineregexp( false ) , desktoprule( DontCareRule ) , aboverule( DontCareRule ) , belowrule( DontCareRule ) @@ -33,22 +35,18 @@ WindowRules::WindowRules() } WindowRules::WindowRules( KConfig& cfg ) - : wmclassregexp( false ) - , windowroleregexp( false ) - , titleregexp( false ) - , extraroleregexp( false ) - , desktoprule( DontCareRule ) - , aboverule( DontCareRule ) - , belowrule( DontCareRule ) { wmclass = cfg.readEntry( "wmclass" ).lower().latin1(); wmclassregexp = cfg.readBoolEntry( "wmclassregexp" ); + wmclasscomplete = cfg.readBoolEntry( "wmclasscomplete" ); windowrole = cfg.readEntry( "windowrole" ).lower().latin1(); windowroleregexp = cfg.readBoolEntry( "windowroleregexp" ); title = cfg.readEntry( "title" ); titleregexp = cfg.readBoolEntry( "titleregexp" ); extrarole = cfg.readEntry( "extrarole" ).lower().latin1(); extraroleregexp = cfg.readBoolEntry( "extraroleregexp" ); + clientmachine = cfg.readEntry( "clientmachine" ).lower().latin1(); + clientmachineregexp = cfg.readBoolEntry( "clientmachineregexp" ); desktop = cfg.readNumEntry( "desktop" ); desktoprule = readRule( cfg, "desktoprule" ); above = cfg.readBoolEntry( "above" ); @@ -87,9 +85,11 @@ void WindowRules::write( KConfig& cfg ) const // always write wmclass cfg.writeEntry( "wmclass", ( const char* )wmclass ); cfg.writeEntry( "wmclassregexp", wmclassregexp ); + cfg.writeEntry( "wmclasscomplete", wmclasscomplete ); WRITE_MATCH_STRING( windowrole, (const char*) ); WRITE_MATCH_STRING( title, ); WRITE_MATCH_STRING( extrarole, (const char*) ); + WRITE_MATCH_STRING( clientmachine, (const char*) ); WRITE_SET_RULE( desktop ); WRITE_SET_RULE( above ); WRITE_SET_RULE( below ); @@ -122,26 +122,39 @@ bool WindowRules::match( const Client* c ) const // TODO exactMatch() for regexp? if( !wmclass.isEmpty()) { // TODO optimize? - if( wmclassregexp && !QRegExp( wmclass ).exactMatch( c->resourceClass())) + QCString cwmclass = wmclasscomplete + ? c->resourceClass() + ' ' + c->resourceName() : c->resourceClass(); + if( wmclassregexp && !QRegExp( wmclass ).exactMatch( cwmclass )) return false; - if( !wmclassregexp && wmclass != c->resourceClass()) + if( !wmclassregexp && wmclass != cwmclass ) return false; } if( !windowrole.isEmpty()) { - if( windowroleregexp && QRegExp( windowrole ).exactMatch( c->windowRole())) + if( windowroleregexp && !QRegExp( windowrole ).exactMatch( c->windowRole())) return false; if( !windowroleregexp && windowrole != c->windowRole()) return false; } if( !title.isEmpty()) { - if( titleregexp && QRegExp( title ).exactMatch( c->caption( false ))) + if( titleregexp && !QRegExp( title ).exactMatch( c->caption( false ))) return false; if( !titleregexp && title != c->caption( false )) return false; } // TODO extrarole + if( !clientmachine.isEmpty()) + { + if( clientmachineregexp + && !QRegExp( clientmachine ).exactMatch( c->wmClientMachine( true )) + && !QRegExp( clientmachine ).exactMatch( c->wmClientMachine( false ))) + return false; + if( !clientmachineregexp + && clientmachine != c->wmClientMachine( true ) + && clientmachine != c->wmClientMachine( false )) + return false; + } return true; } diff --git a/rules.h b/rules.h index f11b3b6c27..417d68341b 100644 --- a/rules.h +++ b/rules.h @@ -45,13 +45,15 @@ class WindowRules static bool checkRule( SettingRule rule, bool init ); QCString wmclass; bool wmclassregexp; - // TODO bool wmclasscomplete - class+name + bool wmclasscomplete; QCString windowrole; bool windowroleregexp; QString title; // TODO "caption" ? bool titleregexp; QCString extrarole; bool extraroleregexp; + QCString clientmachine; + bool clientmachineregexp; // TODO window type? both to which it applies and to which value to force it int desktop; SettingRule desktoprule; diff --git a/sm.cpp b/sm.cpp index 75f08cba81..c281191468 100644 --- a/sm.cpp +++ b/sm.cpp @@ -91,7 +91,7 @@ void Workspace::storeSession( KConfig* config, SMSavePhase phase ) config->writeEntry( QString("sessionId")+n, sessionId.data() ); config->writeEntry( QString("windowRole")+n, c->windowRole().data() ); config->writeEntry( QString("wmCommand")+n, wmCommand.data() ); - config->writeEntry( QString("wmClientMachine")+n, c->wmClientMachine().data() ); + config->writeEntry( QString("wmClientMachine")+n, c->wmClientMachine( true ).data() ); config->writeEntry( QString("resourceName")+n, c->resourceName().data() ); config->writeEntry( QString("resourceClass")+n, c->resourceClass().data() ); config->writeEntry( QString("geometry")+n, QRect( c->calculateGravitation(TRUE), c->clientSize() ) ); // FRAME @@ -196,7 +196,7 @@ SessionInfo* Workspace::takeSessionInfo( Client* c ) QCString sessionId = c->sessionId(); QCString windowRole = c->windowRole(); QCString wmCommand = c->wmCommand(); - QCString wmClientMachine = c->wmClientMachine(); + QCString wmClientMachine = c->wmClientMachine( true ); QCString resourceName = c->resourceName(); QCString resourceClass = c->resourceClass(); diff --git a/utils.cpp b/utils.cpp index 0fae3dc801..9bb9ce157d 100644 --- a/utils.cpp +++ b/utils.cpp @@ -20,6 +20,7 @@ License. See the file "COPYING" for the exact licensing terms. #include #include +#include #include #include @@ -294,6 +295,25 @@ void ungrabXServer() XUngrabServer( qt_xdisplay()); } +bool isLocalMachine( const QCString& host ) + { +#ifdef HOST_NAME_MAX + char hostnamebuf[HOST_NAME_MAX]; +#else + char hostnamebuf[256]; +#endif + if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0) + { + hostnamebuf[sizeof(hostnamebuf)-1] = 0; + if (host == hostnamebuf) + return true; + char *dot = strchr(hostnamebuf, '.'); + if (dot && !(*dot = 0) && host == hostnamebuf) + return true; + } + return false; + } + } // namespace #include "utils.moc" diff --git a/utils.h b/utils.h index 121de8ba23..c26d861ec9 100644 --- a/utils.h +++ b/utils.h @@ -209,6 +209,8 @@ Time timestampDiff( Time time1, Time time2 ) // returns time2 - time1 { // no need to handle wrapping? return time2 - time1; } + +bool isLocalMachine( const QCString& host ); } // namespace