From ab8ff468771a47270ec9d5fd83be20096faf5fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Fri, 28 May 2004 15:04:01 +0000 Subject: [PATCH] Forcing of a specific window type. svn path=/trunk/kdebase/kwin/; revision=315469 --- client.cpp | 25 +++++++++++++++++++------ client.h | 2 ++ manage.cpp | 8 ++++++-- rules.cpp | 46 ++++++++++++++++++++++++++++++++++++---------- rules.h | 16 ++++++++++++++-- 5 files changed, 77 insertions(+), 20 deletions(-) diff --git a/client.cpp b/client.cpp index 7e89c18238..cfdb37691b 100644 --- a/client.cpp +++ b/client.cpp @@ -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 diff --git a/client.h b/client.h index b3b5318074..cbabe167fe 100644 --- a/client.h +++ b/client.h @@ -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(); diff --git a/manage.cpp b/manage.cpp index 903843e5ee..26946bcb29 100644 --- a/manage.cpp +++ b/manage.cpp @@ -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(); diff --git a/rules.cpp b/rules.cpp index 01bc20b204..a6f2ff7b3f 100644 --- a/rules.cpp +++ b/rules.cpp @@ -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 ) diff --git a/rules.h b/rules.h index 417d68341b..f4d564d807 100644 --- a/rules.h +++ b/rules.h @@ -12,6 +12,7 @@ License. See the file "COPYING" for the exact licensing terms. #define KWIN_RULES_H #include +#include 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