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:
parent
8e09a9bc22
commit
c2fa4013a2
8 changed files with 60 additions and 35 deletions
26
client.cpp
26
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;
|
||||
}
|
||||
|
||||
|
|
2
client.h
2
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;
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
35
rules.cpp
35
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;
|
||||
}
|
||||
|
||||
|
|
4
rules.h
4
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;
|
||||
|
|
4
sm.cpp
4
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();
|
||||
|
||||
|
|
20
utils.cpp
20
utils.cpp
|
@ -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"
|
||||
|
|
2
utils.h
2
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
|
||||
|
||||
|
|
Loading…
Reference in a new issue