WM_CLASS can be matched whole (class+name) or only class

Added client machine to matched properties.

svn path=/trunk/kdebase/kwin/; revision=315449
This commit is contained in:
Luboš Luňák 2004-05-28 13:54:20 +00:00
parent 8e09a9bc22
commit c2fa4013a2
8 changed files with 60 additions and 35 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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(),

View file

@ -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;
}

View file

@ -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;

4
sm.cpp
View file

@ -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();

View file

@ -20,6 +20,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include <kxerrorhandler.h>
#include <assert.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/extensions/shape.h>
@ -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"

View file

@ -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