Forcing of a specific window type.

svn path=/trunk/kdebase/kwin/; revision=315469
This commit is contained in:
Luboš Luňák 2004-05-28 15:04:01 +00:00
parent c2fa4013a2
commit ab8ff46877
5 changed files with 77 additions and 20 deletions

View file

@ -1198,17 +1198,24 @@ void Client::showContextHelp()
Fetches the window's caption (WM_NAME property). It will be
stored in the client's caption().
*/
KWIN_COMPARE_PREDICATE( FetchNameInternalPredicate, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption());
void Client::fetchName()
{
QString s;
setCaption( readName());
}
QString Client::readName() const
{
if ( info->name() && info->name()[ 0 ] != '\0' )
s = QString::fromUtf8( info->name() );
return QString::fromUtf8( info->name() );
else
s = KWin::readNameProperty( window(), XA_WM_NAME );
if ( s != cap_normal )
return KWin::readNameProperty( window(), XA_WM_NAME );
}
KWIN_COMPARE_PREDICATE( FetchNameInternalPredicate, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption());
void Client::setCaption( const QString& s, bool force )
{
if ( s != cap_normal || force )
{
bool reset_name = cap_normal.isEmpty();
for( unsigned int i = 0;
@ -1564,6 +1571,12 @@ bool Client::isSpecialWindow() const
NET::WindowType Client::windowType( bool strict, int supported_types ) const
{
NET::WindowType wt = info->windowType( supported_types );
NET::WindowType wt2 = rules()->checkType( wt );
if( wt != wt2 )
{
wt = wt2;
info->setWindowType( wt ); // force hint change
}
// TODO is this 'strict' really needed (and used?)
if( !strict )
{ // hacks here

View file

@ -340,6 +340,8 @@ private slots:
void getWmClientLeader();
void fetchName();
void fetchIconicName();
QString readName() const;
void setCaption( const QString& s, bool force = false );
bool hasTransientInternal( const Client* c, bool indirect, ConstClientList& set ) const;
void initWindowRules();
void updateWindowRules();

View file

@ -104,11 +104,15 @@ bool Client::manage( Window w, bool isMapped )
XFree( classHint.res_name );
XFree( classHint.res_class );
}
ignore_focus_stealing = options->checkIgnoreFocusStealing( this );
ignore_focus_stealing = options->checkIgnoreFocusStealing( this ); // TODO change to rules
fetchName();
window_role = getStringProperty( w, qt_window_role );
// first only read the caption text, so that initWindowRules() can use it for matching,
// and only then really set the caption using setCaption(), which checks for duplicates etc.
// and also relies on rules already existing
cap_normal = readName();
initWindowRules();
setCaption( cap_normal, true );
detectNoBorder();
fetchIconicName();

View file

@ -29,6 +29,7 @@ WindowRules::WindowRules()
, extraroleregexp( false )
, clientmachineregexp( false )
, desktoprule( DontCareRule )
, typerule( DontCareRule )
, aboverule( DontCareRule )
, belowrule( DontCareRule )
{
@ -49,6 +50,8 @@ WindowRules::WindowRules( KConfig& cfg )
clientmachineregexp = cfg.readBoolEntry( "clientmachineregexp" );
desktop = cfg.readNumEntry( "desktop" );
desktoprule = readRule( cfg, "desktoprule" );
type = readType( cfg, "type" );
typerule = type != NET::Unknown ? readForceRule( cfg, "typerule" ) : DontCareRule;
above = cfg.readBoolEntry( "above" );
aboverule = readRule( cfg, "aboverule" );
below = cfg.readBoolEntry( "below" );
@ -91,6 +94,7 @@ void WindowRules::write( KConfig& cfg ) const
WRITE_MATCH_STRING( extrarole, (const char*) );
WRITE_MATCH_STRING( clientmachine, (const char*) );
WRITE_SET_RULE( desktop );
WRITE_SET_RULE( type );
WRITE_SET_RULE( above );
WRITE_SET_RULE( below );
}
@ -106,15 +110,20 @@ SettingRule WindowRules::readRule( KConfig& cfg, const QString& key )
return DontCareRule;
}
void WindowRules::update( Client* c )
SettingRule WindowRules::readForceRule( KConfig& cfg, const QString& key )
{
// TODO check this setting is for this client ?
if( desktoprule == RememberRule )
desktop = c->desktop();
if( aboverule == RememberRule )
above = c->keepAbove();
if( belowrule == RememberRule )
below = c->keepBelow();
int v = cfg.readNumEntry( key );
if( v == DontCareRule || v == ForceRule )
return static_cast< SettingRule >( v );
return DontCareRule;
}
NET::WindowType WindowRules::readType( KConfig& cfg, const QString& key )
{
int v = cfg.readNumEntry( key );
if( v >= NET::Normal && v <= NET::Splash )
return static_cast< NET::WindowType >( v );
return NET::Unknown;
}
bool WindowRules::match( const Client* c ) const
@ -158,6 +167,17 @@ bool WindowRules::match( const Client* c ) const
return true;
}
void WindowRules::update( Client* c )
{
// TODO check this setting is for this client ?
if( desktoprule == RememberRule )
desktop = c->desktop();
if( aboverule == RememberRule )
above = c->keepAbove();
if( belowrule == RememberRule )
below = c->keepBelow();
}
int WindowRules::checkDesktop( int req_desktop, bool init ) const
{
// TODO chaining?
@ -173,12 +193,20 @@ bool WindowRules::checkKeepBelow( bool req_below, bool init ) const
{
return checkRule( belowrule, init ) ? below : req_below;
}
NET::WindowType WindowRules::checkType( NET::WindowType req_type ) const
{
return checkForceRule( typerule ) ? type : req_type;
}
// Client
void Client::initWindowRules()
{
client_rules = workspace()->findWindowRules( this );
// check only after getting the rules, because there may be a rule forcing window type
if( isTopMenu()) // TODO cannot have restrictions
client_rules = &dummyRules;
}
void Client::updateWindowRules()
@ -190,8 +218,6 @@ void Client::updateWindowRules()
WindowRules* Workspace::findWindowRules( const Client* c ) const
{
if( c->isTopMenu()) // TODO cannot have restrictions
return &dummyRules;
for( QValueList< WindowRules* >::ConstIterator it = windowRules.begin();
it != windowRules.end();
++it )

16
rules.h
View file

@ -12,6 +12,7 @@ License. See the file "COPYING" for the exact licensing terms.
#define KWIN_RULES_H
#include <qstring.h>
#include <netwm_def.h>
class KConfig;
@ -23,8 +24,8 @@ class Client;
enum SettingRule
{
DontCareRule,
ApplyRule,
ForceRule,
ApplyRule,
RememberRule,
LastRule = RememberRule
};
@ -40,9 +41,13 @@ class WindowRules
int checkDesktop( int desktop, bool init = false ) const;
bool checkKeepAbove( bool above, bool init = false ) const;
bool checkKeepBelow( bool above, bool init = false ) const;
NET::WindowType checkType( NET::WindowType type ) const;
private:
static SettingRule readRule( KConfig&, const QString& key );
static SettingRule readForceRule( KConfig&, const QString& key );
static NET::WindowType readType( KConfig&, const QString& key );
static bool checkRule( SettingRule rule, bool init );
static bool checkForceRule( SettingRule rule );
QCString wmclass;
bool wmclassregexp;
bool wmclasscomplete;
@ -54,9 +59,10 @@ class WindowRules
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;
NET::WindowType type;
SettingRule typerule;
bool above;
SettingRule aboverule;
bool below;
@ -74,6 +80,12 @@ bool WindowRules::checkRule( SettingRule rule, bool init )
return false;
}
inline
bool WindowRules::checkForceRule( SettingRule rule )
{
return rule == ForceRule;
}
} // namespace
#endif