2007-11-27 19:40:25 +00:00
/********************************************************************
2007-04-29 17:35:43 +00:00
KWin - the KDE window manager
This file is part of the KDE project .
Copyright ( C ) 2004 Lubos Lunak < l . lunak @ kde . org >
2007-11-27 19:40:25 +00:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-04-29 17:35:43 +00:00
# include "rules.h"
# include <fixx11h.h>
# include <kconfig.h>
2013-04-26 12:40:35 +00:00
# include <KDE/KXMessages>
2007-04-29 17:35:43 +00:00
# include <QRegExp>
# include <ktemporaryfile.h>
# include <QFile>
# include <ktoolinvocation.h>
# ifndef KCMRULES
# include "client.h"
2013-01-07 07:07:27 +00:00
# include "client_machine.h"
2013-04-03 10:19:27 +00:00
# include "screens.h"
2007-04-29 17:35:43 +00:00
# include "workspace.h"
# endif
namespace KWin
{
Rules : : Rules ( )
2011-01-30 14:34:42 +00:00
: temporary_state ( 0 )
, wmclassmatch ( UnimportantMatch )
, wmclasscomplete ( UnimportantMatch )
, windowrolematch ( UnimportantMatch )
, titlematch ( UnimportantMatch )
, clientmachinematch ( UnimportantMatch )
, types ( NET : : AllTypesMask )
, placementrule ( UnusedForceRule )
, positionrule ( UnusedSetRule )
, sizerule ( UnusedSetRule )
, minsizerule ( UnusedForceRule )
, maxsizerule ( UnusedForceRule )
, opacityactiverule ( UnusedForceRule )
, opacityinactiverule ( UnusedForceRule )
2013-03-24 18:13:00 +00:00
, ignoregeometryrule ( UnusedSetRule )
2011-01-30 14:34:42 +00:00
, desktoprule ( UnusedSetRule )
2012-08-24 16:48:50 +00:00
, screenrule ( UnusedSetRule )
2012-05-17 14:32:06 +00:00
, activityrule ( UnusedSetRule )
2011-01-30 14:34:42 +00:00
, typerule ( UnusedForceRule )
, maximizevertrule ( UnusedSetRule )
, maximizehorizrule ( UnusedSetRule )
, minimizerule ( UnusedSetRule )
, shaderule ( UnusedSetRule )
, skiptaskbarrule ( UnusedSetRule )
, skippagerrule ( UnusedSetRule )
, skipswitcherrule ( UnusedSetRule )
, aboverule ( UnusedSetRule )
, belowrule ( UnusedSetRule )
, fullscreenrule ( UnusedSetRule )
, noborderrule ( UnusedSetRule )
2011-03-20 14:42:05 +00:00
, blockcompositingrule ( UnusedForceRule )
2011-01-30 14:34:42 +00:00
, fsplevelrule ( UnusedForceRule )
, acceptfocusrule ( UnusedForceRule )
, closeablerule ( UnusedForceRule )
, autogrouprule ( UnusedForceRule )
, autogroupfgrule ( UnusedForceRule )
, autogroupidrule ( UnusedForceRule )
, strictgeometryrule ( UnusedForceRule )
, shortcutrule ( UnusedSetRule )
, disableglobalshortcutsrule ( UnusedForceRule )
{
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
Rules : : Rules ( const QString & str , bool temporary )
: temporary_state ( temporary ? 2 : 0 )
{
2007-04-29 17:35:43 +00:00
KTemporaryFile file ;
2011-01-30 14:34:42 +00:00
if ( file . open ( ) ) {
2007-04-29 17:35:43 +00:00
QByteArray s = str . toUtf8 ( ) ;
2011-01-30 14:34:42 +00:00
file . write ( s . data ( ) , s . length ( ) ) ;
}
2007-04-29 17:35:43 +00:00
file . flush ( ) ;
2011-01-30 14:34:42 +00:00
KConfig cfg ( file . fileName ( ) , KConfig : : SimpleConfig ) ;
readFromCfg ( cfg . group ( QString ( ) ) ) ;
if ( description . isEmpty ( ) )
2007-04-29 17:35:43 +00:00
description = " temporary " ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
# define READ_MATCH_STRING( var, func ) \
var = cfg . readEntry ( # var ) func ; \
var # # match = ( StringMatch ) qMax ( FirstStringMatch , \
2011-01-30 14:34:42 +00:00
qMin ( LastStringMatch , static_cast < StringMatch > ( cfg . readEntry ( # var " match " , 0 ) ) ) ) ;
2007-04-29 17:35:43 +00:00
# define READ_SET_RULE( var, func, def ) \
var = func ( cfg . readEntry ( # var , def ) ) ; \
var # # rule = readSetRule ( cfg , # var " rule " ) ;
# define READ_SET_RULE_DEF( var , func, def ) \
var = func ( cfg . readEntry ( # var , def ) ) ; \
var # # rule = readSetRule ( cfg , # var " rule " ) ;
# define READ_FORCE_RULE( var, func, def) \
var = func ( cfg . readEntry ( # var , def ) ) ; \
var # # rule = readForceRule ( cfg , # var " rule " ) ;
# define READ_FORCE_RULE2( var, def, func, funcarg ) \
var = func ( cfg . readEntry ( # var , def ) , funcarg ) ; \
var # # rule = readForceRule ( cfg , # var " rule " ) ;
2011-01-30 14:34:42 +00:00
Rules : : Rules ( const KConfigGroup & cfg )
: temporary_state ( 0 )
{
readFromCfg ( cfg ) ;
}
static int limit0to4 ( int i )
{
return qMax ( 0 , qMin ( 4 , i ) ) ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
void Rules : : readFromCfg ( const KConfigGroup & cfg )
{
description = cfg . readEntry ( " Description " ) ;
if ( description . isEmpty ( ) ) // capitalized first, lowercase for backwards compatibility
description = cfg . readEntry ( " description " ) ;
READ_MATCH_STRING ( wmclass , . toLower ( ) . toLatin1 ( ) ) ;
wmclasscomplete = cfg . readEntry ( " wmclasscomplete " , false ) ;
READ_MATCH_STRING ( windowrole , . toLower ( ) . toLatin1 ( ) ) ;
READ_MATCH_STRING ( title , ) ;
READ_MATCH_STRING ( clientmachine , . toLower ( ) . toLatin1 ( ) ) ;
types = cfg . readEntry ( " types " , uint ( NET : : AllTypesMask ) ) ;
READ_FORCE_RULE2 ( placement , QString ( ) , Placement : : policyFromString , false ) ;
READ_SET_RULE_DEF ( position , , invalidPoint ) ;
READ_SET_RULE ( size , , QSize ( ) ) ;
if ( size . isEmpty ( ) & & sizerule ! = ( SetRule ) Remember )
2007-04-29 17:35:43 +00:00
sizerule = UnusedSetRule ;
2011-01-30 14:34:42 +00:00
READ_FORCE_RULE ( minsize , , QSize ( ) ) ;
if ( ! minsize . isValid ( ) )
minsize = QSize ( 1 , 1 ) ;
READ_FORCE_RULE ( maxsize , , QSize ( ) ) ;
if ( maxsize . isEmpty ( ) )
maxsize = QSize ( 32767 , 32767 ) ;
READ_FORCE_RULE ( opacityactive , , 0 ) ;
if ( opacityactive < 0 | | opacityactive > 100 )
2007-04-29 17:35:43 +00:00
opacityactive = 100 ;
2011-01-30 14:34:42 +00:00
READ_FORCE_RULE ( opacityinactive , , 0 ) ;
if ( opacityinactive < 0 | | opacityinactive > 100 )
2007-04-29 17:35:43 +00:00
opacityinactive = 100 ;
2013-03-24 18:13:00 +00:00
READ_SET_RULE ( ignoregeometry , , false ) ;
2011-01-30 14:34:42 +00:00
READ_SET_RULE ( desktop , , 0 ) ;
2012-08-24 16:48:50 +00:00
READ_SET_RULE ( screen , , 0 ) ;
2012-05-17 14:32:06 +00:00
READ_SET_RULE ( activity , , QString ( ) ) ;
2011-01-30 14:34:42 +00:00
type = readType ( cfg , " type " ) ;
typerule = type ! = NET : : Unknown ? readForceRule ( cfg , " typerule " ) : UnusedForceRule ;
READ_SET_RULE ( maximizevert , , false ) ;
READ_SET_RULE ( maximizehoriz , , false ) ;
READ_SET_RULE ( minimize , , false ) ;
READ_SET_RULE ( shade , , false ) ;
READ_SET_RULE ( skiptaskbar , , false ) ;
READ_SET_RULE ( skippager , , false ) ;
READ_SET_RULE ( skipswitcher , , false ) ;
READ_SET_RULE ( above , , false ) ;
READ_SET_RULE ( below , , false ) ;
READ_SET_RULE ( fullscreen , , false ) ;
READ_SET_RULE ( noborder , , false ) ;
2011-03-20 14:42:05 +00:00
READ_FORCE_RULE ( blockcompositing , , false ) ;
2011-01-30 14:34:42 +00:00
READ_FORCE_RULE ( fsplevel , limit0to4 , 0 ) ; // fsp is 0-4
READ_FORCE_RULE ( acceptfocus , , false ) ;
READ_FORCE_RULE ( closeable , , false ) ;
READ_FORCE_RULE ( autogroup , , false ) ;
READ_FORCE_RULE ( autogroupfg , , true ) ;
READ_FORCE_RULE ( autogroupid , , QString ( ) ) ;
READ_FORCE_RULE ( strictgeometry , , false ) ;
READ_SET_RULE ( shortcut , , QString ( ) ) ;
READ_FORCE_RULE ( disableglobalshortcuts , , false ) ;
}
2007-04-29 17:35:43 +00:00
# undef READ_MATCH_STRING
# undef READ_SET_RULE
# undef READ_FORCE_RULE
# undef READ_FORCE_RULE2
# define WRITE_MATCH_STRING( var, cast, force ) \
2011-01-30 14:34:42 +00:00
if ( ! var . isEmpty ( ) | | force ) \
{ \
2007-04-29 17:35:43 +00:00
cfg . writeEntry ( # var , cast var ) ; \
cfg . writeEntry ( # var " match " , ( int ) var # # match ) ; \
2011-01-30 14:34:42 +00:00
} \
2007-04-29 17:35:43 +00:00
else \
2011-01-30 14:34:42 +00:00
{ \
2007-04-29 17:35:43 +00:00
cfg . deleteEntry ( # var ) ; \
cfg . deleteEntry ( # var " match " ) ; \
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
# define WRITE_SET_RULE( var, func ) \
2011-01-30 14:34:42 +00:00
if ( var # # rule ! = UnusedSetRule ) \
{ \
2007-04-29 17:35:43 +00:00
cfg . writeEntry ( # var , func ( var ) ) ; \
cfg . writeEntry ( # var " rule " , ( int ) var # # rule ) ; \
2011-01-30 14:34:42 +00:00
} \
2007-04-29 17:35:43 +00:00
else \
2011-01-30 14:34:42 +00:00
{ \
2007-04-29 17:35:43 +00:00
cfg . deleteEntry ( # var ) ; \
cfg . deleteEntry ( # var " rule " ) ; \
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
# define WRITE_FORCE_RULE( var, func ) \
2011-01-30 14:34:42 +00:00
if ( var # # rule ! = UnusedForceRule ) \
{ \
2007-04-29 17:35:43 +00:00
cfg . writeEntry ( # var , func ( var ) ) ; \
cfg . writeEntry ( # var " rule " , ( int ) var # # rule ) ; \
2011-01-30 14:34:42 +00:00
} \
2007-04-29 17:35:43 +00:00
else \
2011-01-30 14:34:42 +00:00
{ \
2007-04-29 17:35:43 +00:00
cfg . deleteEntry ( # var ) ; \
cfg . deleteEntry ( # var " rule " ) ; \
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
void Rules : : write ( KConfigGroup & cfg ) const
{
cfg . writeEntry ( " Description " , description ) ;
2007-04-29 17:35:43 +00:00
// always write wmclass
2011-01-30 14:34:42 +00:00
WRITE_MATCH_STRING ( wmclass , ( const char * ) , true ) ;
cfg . writeEntry ( " wmclasscomplete " , wmclasscomplete ) ;
WRITE_MATCH_STRING ( windowrole , ( const char * ) , false ) ;
WRITE_MATCH_STRING ( title , , false ) ;
WRITE_MATCH_STRING ( clientmachine , ( const char * ) , false ) ;
2007-04-29 17:35:43 +00:00
if ( types ! = NET : : AllTypesMask )
cfg . writeEntry ( " types " , uint ( types ) ) ;
else
cfg . deleteEntry ( " types " ) ;
2011-01-30 14:34:42 +00:00
WRITE_FORCE_RULE ( placement , Placement : : policyToString ) ;
WRITE_SET_RULE ( position , ) ;
WRITE_SET_RULE ( size , ) ;
WRITE_FORCE_RULE ( minsize , ) ;
WRITE_FORCE_RULE ( maxsize , ) ;
WRITE_FORCE_RULE ( opacityactive , ) ;
WRITE_FORCE_RULE ( opacityinactive , ) ;
2013-03-24 18:13:00 +00:00
WRITE_SET_RULE ( ignoregeometry , ) ;
2011-01-30 14:34:42 +00:00
WRITE_SET_RULE ( desktop , ) ;
2012-08-24 16:48:50 +00:00
WRITE_SET_RULE ( screen , ) ;
2012-05-17 14:32:06 +00:00
WRITE_SET_RULE ( activity , ) ;
2011-01-30 14:34:42 +00:00
WRITE_FORCE_RULE ( type , int ) ;
WRITE_SET_RULE ( maximizevert , ) ;
WRITE_SET_RULE ( maximizehoriz , ) ;
WRITE_SET_RULE ( minimize , ) ;
WRITE_SET_RULE ( shade , ) ;
WRITE_SET_RULE ( skiptaskbar , ) ;
WRITE_SET_RULE ( skippager , ) ;
WRITE_SET_RULE ( skipswitcher , ) ;
WRITE_SET_RULE ( above , ) ;
WRITE_SET_RULE ( below , ) ;
WRITE_SET_RULE ( fullscreen , ) ;
WRITE_SET_RULE ( noborder , ) ;
2011-03-20 14:42:05 +00:00
WRITE_FORCE_RULE ( blockcompositing , ) ;
2011-01-30 14:34:42 +00:00
WRITE_FORCE_RULE ( fsplevel , ) ;
WRITE_FORCE_RULE ( acceptfocus , ) ;
WRITE_FORCE_RULE ( closeable , ) ;
WRITE_FORCE_RULE ( autogroup , ) ;
WRITE_FORCE_RULE ( autogroupfg , ) ;
WRITE_FORCE_RULE ( autogroupid , ) ;
WRITE_FORCE_RULE ( strictgeometry , ) ;
WRITE_SET_RULE ( shortcut , ) ;
WRITE_FORCE_RULE ( disableglobalshortcuts , ) ;
}
2007-04-29 17:35:43 +00:00
# undef WRITE_MATCH_STRING
# undef WRITE_SET_RULE
# undef WRITE_FORCE_RULE
// returns true if it doesn't affect anything
bool Rules : : isEmpty ( ) const
2011-01-30 14:34:42 +00:00
{
return ( placementrule = = UnusedForceRule
& & positionrule = = UnusedSetRule
& & sizerule = = UnusedSetRule
& & minsizerule = = UnusedForceRule
& & maxsizerule = = UnusedForceRule
& & opacityactiverule = = UnusedForceRule
& & opacityinactiverule = = UnusedForceRule
2013-03-24 18:13:00 +00:00
& & ignoregeometryrule = = UnusedSetRule
2011-01-30 14:34:42 +00:00
& & desktoprule = = UnusedSetRule
2012-08-24 16:48:50 +00:00
& & screenrule = = UnusedSetRule
2012-05-17 14:32:06 +00:00
& & activityrule = = UnusedSetRule
2011-01-30 14:34:42 +00:00
& & typerule = = UnusedForceRule
& & maximizevertrule = = UnusedSetRule
& & maximizehorizrule = = UnusedSetRule
& & minimizerule = = UnusedSetRule
& & shaderule = = UnusedSetRule
& & skiptaskbarrule = = UnusedSetRule
& & skippagerrule = = UnusedSetRule
& & skipswitcherrule = = UnusedSetRule
& & aboverule = = UnusedSetRule
& & belowrule = = UnusedSetRule
& & fullscreenrule = = UnusedSetRule
& & noborderrule = = UnusedSetRule
2011-03-20 14:42:05 +00:00
& & blockcompositingrule = = UnusedForceRule
2011-01-30 14:34:42 +00:00
& & fsplevelrule = = UnusedForceRule
& & acceptfocusrule = = UnusedForceRule
& & closeablerule = = UnusedForceRule
& & autogrouprule = = UnusedForceRule
& & autogroupfgrule = = UnusedForceRule
& & autogroupidrule = = UnusedForceRule
& & strictgeometryrule = = UnusedForceRule
& & shortcutrule = = UnusedSetRule
& & disableglobalshortcutsrule = = UnusedForceRule ) ;
}
Rules : : SetRule Rules : : readSetRule ( const KConfigGroup & cfg , const QString & key )
{
int v = cfg . readEntry ( key , 0 ) ;
if ( v > = DontAffect & & v < = ForceTemporarily )
return static_cast < SetRule > ( v ) ;
2007-04-29 17:35:43 +00:00
return UnusedSetRule ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
Rules : : ForceRule Rules : : readForceRule ( const KConfigGroup & cfg , const QString & key )
{
int v = cfg . readEntry ( key , 0 ) ;
if ( v = = DontAffect | | v = = Force | | v = = ForceTemporarily )
return static_cast < ForceRule > ( v ) ;
2007-04-29 17:35:43 +00:00
return UnusedForceRule ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
NET : : WindowType Rules : : readType ( const KConfigGroup & cfg , const QString & key )
{
int v = cfg . readEntry ( key , 0 ) ;
if ( v > = NET : : Normal & & v < = NET : : Splash )
return static_cast < NET : : WindowType > ( v ) ;
2007-04-29 17:35:43 +00:00
return NET : : Unknown ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : matchType ( NET : : WindowType match_type ) const
{
if ( types ! = NET : : AllTypesMask ) {
if ( match_type = = NET : : Unknown )
2007-04-29 17:35:43 +00:00
match_type = NET : : Normal ; // NET::Unknown->NET::Normal is only here for matching
2011-01-30 14:34:42 +00:00
if ( ! NET : : typeMatchesMask ( match_type , types ) )
2007-04-29 17:35:43 +00:00
return false ;
}
2011-01-30 14:34:42 +00:00
return true ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : matchWMClass ( const QByteArray & match_class , const QByteArray & match_name ) const
{
if ( wmclassmatch ! = UnimportantMatch ) {
// TODO optimize?
2007-04-29 17:35:43 +00:00
QByteArray cwmclass = wmclasscomplete
2011-01-30 14:34:42 +00:00
? match_name + ' ' + match_class : match_class ;
if ( wmclassmatch = = RegExpMatch & & QRegExp ( wmclass ) . indexIn ( cwmclass ) = = - 1 )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( wmclassmatch = = ExactMatch & & wmclass ! = cwmclass )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( wmclassmatch = = SubstringMatch & & ! cwmclass . contains ( wmclass ) )
2007-04-29 17:35:43 +00:00
return false ;
}
2011-01-30 14:34:42 +00:00
return true ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : matchRole ( const QByteArray & match_role ) const
{
if ( windowrolematch ! = UnimportantMatch ) {
if ( windowrolematch = = RegExpMatch & & QRegExp ( windowrole ) . indexIn ( match_role ) = = - 1 )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( windowrolematch = = ExactMatch & & windowrole ! = match_role )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( windowrolematch = = SubstringMatch & & ! match_role . contains ( windowrole ) )
2007-04-29 17:35:43 +00:00
return false ;
}
2011-01-30 14:34:42 +00:00
return true ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : matchTitle ( const QString & match_title ) const
{
if ( titlematch ! = UnimportantMatch ) {
if ( titlematch = = RegExpMatch & & QRegExp ( title ) . indexIn ( match_title ) = = - 1 )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( titlematch = = ExactMatch & & title ! = match_title )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( titlematch = = SubstringMatch & & ! match_title . contains ( title ) )
2007-04-29 17:35:43 +00:00
return false ;
}
2011-01-30 14:34:42 +00:00
return true ;
}
2007-04-29 17:35:43 +00:00
2013-01-07 07:07:27 +00:00
bool Rules : : matchClientMachine ( const QByteArray & match_machine , bool local ) const
2011-01-30 14:34:42 +00:00
{
if ( clientmachinematch ! = UnimportantMatch ) {
2007-04-29 17:35:43 +00:00
// if it's localhost, check also "localhost" before checking hostname
2013-01-07 07:07:27 +00:00
if ( match_machine ! = " localhost " & & local
& & matchClientMachine ( " localhost " , true ) )
2007-04-29 17:35:43 +00:00
return true ;
2011-01-30 14:34:42 +00:00
if ( clientmachinematch = = RegExpMatch
& & QRegExp ( clientmachine ) . indexIn ( match_machine ) = = - 1 )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( clientmachinematch = = ExactMatch
& & clientmachine ! = match_machine )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( clientmachinematch = = SubstringMatch
& & ! match_machine . contains ( clientmachine ) )
2007-04-29 17:35:43 +00:00
return false ;
}
2011-01-30 14:34:42 +00:00
return true ;
}
2007-04-29 17:35:43 +00:00
# ifndef KCMRULES
2011-01-30 14:34:42 +00:00
bool Rules : : match ( const Client * c ) const
{
if ( ! matchType ( c - > windowType ( true ) ) )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( ! matchWMClass ( c - > resourceClass ( ) , c - > resourceName ( ) ) )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( ! matchRole ( c - > windowRole ( ) ) )
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( ! matchTitle ( c - > caption ( false ) ) )
2007-04-29 17:35:43 +00:00
return false ;
2013-01-07 07:07:27 +00:00
if ( ! matchClientMachine ( c - > clientMachine ( ) - > hostName ( ) , c - > clientMachine ( ) - > isLocal ( ) ) )
2007-04-29 17:35:43 +00:00
return false ;
return true ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2012-02-05 17:50:23 +00:00
# define NOW_REMEMBER(_T_, _V_) ((selection & _T_) && (_V_##rule == (SetRule)Remember))
bool Rules : : update ( Client * c , int selection )
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
// TODO check this setting is for this client ?
bool updated = false ;
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( Position , position ) {
2011-01-30 14:34:42 +00:00
if ( ! c - > isFullScreen ( ) ) {
2007-04-29 17:35:43 +00:00
QPoint new_pos = position ;
// don't use the position in the direction which is maximized
2011-01-30 14:34:42 +00:00
if ( ( c - > maximizeMode ( ) & MaximizeHorizontal ) = = 0 )
new_pos . setX ( c - > pos ( ) . x ( ) ) ;
if ( ( c - > maximizeMode ( ) & MaximizeVertical ) = = 0 )
new_pos . setY ( c - > pos ( ) . y ( ) ) ;
2007-04-29 17:35:43 +00:00
updated = updated | | position ! = new_pos ;
position = new_pos ;
}
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( Size , size ) {
2011-01-30 14:34:42 +00:00
if ( ! c - > isFullScreen ( ) ) {
2007-04-29 17:35:43 +00:00
QSize new_size = size ;
// don't use the position in the direction which is maximized
2011-01-30 14:34:42 +00:00
if ( ( c - > maximizeMode ( ) & MaximizeHorizontal ) = = 0 )
new_size . setWidth ( c - > size ( ) . width ( ) ) ;
if ( ( c - > maximizeMode ( ) & MaximizeVertical ) = = 0 )
new_size . setHeight ( c - > size ( ) . height ( ) ) ;
2007-04-29 17:35:43 +00:00
updated = updated | | size ! = new_size ;
size = new_size ;
}
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( Desktop , desktop ) {
2007-04-29 17:35:43 +00:00
updated = updated | | desktop ! = c - > desktop ( ) ;
desktop = c - > desktop ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-08-24 16:48:50 +00:00
if NOW_REMEMBER ( Screen , screen ) {
updated = updated | | screen ! = c - > screen ( ) ;
screen = c - > screen ( ) ;
}
2012-05-17 14:32:06 +00:00
if NOW_REMEMBER ( Activity , activity ) {
// TODO: ivan - multiple activities support
const QString & joinedActivities = c - > activities ( ) . join ( " , " ) ;
updated = updated | | activity ! = joinedActivities ;
activity = joinedActivities ;
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( MaximizeVert , maximizevert ) {
2011-01-30 14:34:42 +00:00
updated = updated | | maximizevert ! = bool ( c - > maximizeMode ( ) & MaximizeVertical ) ;
2007-04-29 17:35:43 +00:00
maximizevert = c - > maximizeMode ( ) & MaximizeVertical ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( MaximizeHoriz , maximizehoriz ) {
2011-01-30 14:34:42 +00:00
updated = updated | | maximizehoriz ! = bool ( c - > maximizeMode ( ) & MaximizeHorizontal ) ;
2007-04-29 17:35:43 +00:00
maximizehoriz = c - > maximizeMode ( ) & MaximizeHorizontal ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( Minimize , minimize ) {
2007-04-29 17:35:43 +00:00
updated = updated | | minimize ! = c - > isMinimized ( ) ;
minimize = c - > isMinimized ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( Shade , shade ) {
2011-01-30 14:34:42 +00:00
updated = updated | | ( shade ! = ( c - > shadeMode ( ) ! = ShadeNone ) ) ;
2007-04-29 17:35:43 +00:00
shade = c - > shadeMode ( ) ! = ShadeNone ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( SkipTaskbar , skiptaskbar ) {
2007-04-29 17:35:43 +00:00
updated = updated | | skiptaskbar ! = c - > skipTaskbar ( ) ;
skiptaskbar = c - > skipTaskbar ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( SkipPager , skippager ) {
2007-04-29 17:35:43 +00:00
updated = updated | | skippager ! = c - > skipPager ( ) ;
skippager = c - > skipPager ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( SkipSwitcher , skipswitcher ) {
2010-05-03 20:04:44 +00:00
updated = updated | | skipswitcher ! = c - > skipSwitcher ( ) ;
skipswitcher = c - > skipSwitcher ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( Above , above ) {
2007-04-29 17:35:43 +00:00
updated = updated | | above ! = c - > keepAbove ( ) ;
above = c - > keepAbove ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( Below , below ) {
2007-04-29 17:35:43 +00:00
updated = updated | | below ! = c - > keepBelow ( ) ;
below = c - > keepBelow ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( Fullscreen , fullscreen ) {
2007-04-29 17:35:43 +00:00
updated = updated | | fullscreen ! = c - > isFullScreen ( ) ;
fullscreen = c - > isFullScreen ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( NoBorder , noborder ) {
2008-03-23 00:12:11 +00:00
updated = updated | | noborder ! = c - > noBorder ( ) ;
noborder = c - > noBorder ( ) ;
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( OpacityActive , opacityactive ) {
2007-04-29 17:35:43 +00:00
// TODO
2011-01-30 14:34:42 +00:00
}
2012-02-05 17:50:23 +00:00
if NOW_REMEMBER ( OpacityInactive , opacityinactive ) {
2007-04-29 17:35:43 +00:00
// TODO
}
2011-01-30 14:34:42 +00:00
return updated ;
}
2007-04-29 17:35:43 +00:00
2012-02-05 17:50:23 +00:00
# undef NOW_REMEMBER
2007-04-29 17:35:43 +00:00
# define APPLY_RULE( var, name, type ) \
2011-01-30 14:34:42 +00:00
bool Rules : : apply # # name ( type & arg , bool init ) const \
2007-04-29 17:35:43 +00:00
{ \
2011-01-30 14:34:42 +00:00
if ( checkSetRule ( var # # rule , init ) ) \
arg = this - > var ; \
return checkSetStop ( var # # rule ) ; \
2007-04-29 17:35:43 +00:00
}
# define APPLY_FORCE_RULE( var, name, type ) \
2011-01-30 14:34:42 +00:00
bool Rules : : apply # # name ( type & arg ) const \
2007-04-29 17:35:43 +00:00
{ \
2011-01-30 14:34:42 +00:00
if ( checkForceRule ( var # # rule ) ) \
arg = this - > var ; \
return checkForceStop ( var # # rule ) ; \
2007-04-29 17:35:43 +00:00
}
2011-01-30 14:34:42 +00:00
APPLY_FORCE_RULE ( placement , Placement , Placement : : Policy )
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : applyGeometry ( QRect & rect , bool init ) const
{
2007-04-29 17:35:43 +00:00
QPoint p = rect . topLeft ( ) ;
QSize s = rect . size ( ) ;
bool ret = false ; // no short-circuiting
2011-01-30 14:34:42 +00:00
if ( applyPosition ( p , init ) ) {
rect . moveTopLeft ( p ) ;
2007-04-29 17:35:43 +00:00
ret = true ;
2011-01-30 14:34:42 +00:00
}
if ( applySize ( s , init ) ) {
rect . setSize ( s ) ;
2007-04-29 17:35:43 +00:00
ret = true ;
}
2011-01-30 14:34:42 +00:00
return ret ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : applyPosition ( QPoint & pos , bool init ) const
{
if ( this - > position ! = invalidPoint & & checkSetRule ( positionrule , init ) )
2007-04-29 17:35:43 +00:00
pos = this - > position ;
2011-01-30 14:34:42 +00:00
return checkSetStop ( positionrule ) ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : applySize ( QSize & s , bool init ) const
{
if ( this - > size . isValid ( ) & & checkSetRule ( sizerule , init ) )
2007-04-29 17:35:43 +00:00
s = this - > size ;
2011-01-30 14:34:42 +00:00
return checkSetStop ( sizerule ) ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
APPLY_FORCE_RULE ( minsize , MinSize , QSize )
APPLY_FORCE_RULE ( maxsize , MaxSize , QSize )
APPLY_FORCE_RULE ( opacityactive , OpacityActive , int )
APPLY_FORCE_RULE ( opacityinactive , OpacityInactive , int )
2013-03-24 18:13:00 +00:00
APPLY_RULE ( ignoregeometry , IgnoreGeometry , bool )
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
APPLY_RULE ( desktop , Desktop , int )
2012-08-24 16:48:50 +00:00
APPLY_RULE ( screen , Screen , int )
2012-05-17 14:32:06 +00:00
APPLY_RULE ( activity , Activity , QString )
2011-01-30 14:34:42 +00:00
APPLY_FORCE_RULE ( type , Type , NET : : WindowType )
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : applyMaximizeHoriz ( MaximizeMode & mode , bool init ) const
{
if ( checkSetRule ( maximizehorizrule , init ) )
mode = static_cast < MaximizeMode > ( ( maximizehoriz ? MaximizeHorizontal : 0 ) | ( mode & MaximizeVertical ) ) ;
return checkSetStop ( maximizehorizrule ) ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : applyMaximizeVert ( MaximizeMode & mode , bool init ) const
{
if ( checkSetRule ( maximizevertrule , init ) )
mode = static_cast < MaximizeMode > ( ( maximizevert ? MaximizeVertical : 0 ) | ( mode & MaximizeHorizontal ) ) ;
return checkSetStop ( maximizevertrule ) ;
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
APPLY_RULE ( minimize , Minimize , bool )
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : applyShade ( ShadeMode & sh , bool init ) const
{
if ( checkSetRule ( shaderule , init ) ) {
if ( ! this - > shade )
2007-04-29 17:35:43 +00:00
sh = ShadeNone ;
2011-01-30 14:34:42 +00:00
if ( this - > shade & & sh = = ShadeNone )
2007-04-29 17:35:43 +00:00
sh = ShadeNormal ;
}
2011-01-30 14:34:42 +00:00
return checkSetStop ( shaderule ) ;
}
APPLY_RULE ( skiptaskbar , SkipTaskbar , bool )
APPLY_RULE ( skippager , SkipPager , bool )
APPLY_RULE ( skipswitcher , SkipSwitcher , bool )
APPLY_RULE ( above , KeepAbove , bool )
APPLY_RULE ( below , KeepBelow , bool )
APPLY_RULE ( fullscreen , FullScreen , bool )
APPLY_RULE ( noborder , NoBorder , bool )
2011-03-20 14:42:05 +00:00
APPLY_FORCE_RULE ( blockcompositing , BlockCompositing , bool )
2011-01-30 14:34:42 +00:00
APPLY_FORCE_RULE ( fsplevel , FSP , int )
APPLY_FORCE_RULE ( acceptfocus , AcceptFocus , bool )
APPLY_FORCE_RULE ( closeable , Closeable , bool )
APPLY_FORCE_RULE ( autogroup , Autogrouping , bool )
APPLY_FORCE_RULE ( autogroupfg , AutogroupInForeground , bool )
APPLY_FORCE_RULE ( autogroupid , AutogroupById , QString )
APPLY_FORCE_RULE ( strictgeometry , StrictGeometry , bool )
APPLY_RULE ( shortcut , Shortcut , QString )
APPLY_FORCE_RULE ( disableglobalshortcuts , DisableGlobalShortcuts , bool )
2007-04-29 17:35:43 +00:00
# undef APPLY_RULE
# undef APPLY_FORCE_RULE
bool Rules : : isTemporary ( ) const
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
return temporary_state > 0 ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
bool Rules : : discardTemporary ( bool force )
{
if ( temporary_state = = 0 ) // not temporary
2007-04-29 17:35:43 +00:00
return false ;
2011-01-30 14:34:42 +00:00
if ( force | | - - temporary_state = = 0 ) { // too old
2007-04-29 17:35:43 +00:00
delete this ;
return true ;
}
2011-01-30 14:34:42 +00:00
return false ;
}
2007-04-29 17:35:43 +00:00
# define DISCARD_USED_SET_RULE( var ) \
do { \
2011-01-30 14:34:42 +00:00
if ( var # # rule = = ( SetRule ) ApplyNow | | ( withdrawn & & var # # rule = = ( SetRule ) ForceTemporarily ) ) \
var # # rule = UnusedSetRule ; \
} while ( false )
2007-04-29 17:35:43 +00:00
# define DISCARD_USED_FORCE_RULE( var ) \
do { \
2011-01-30 14:34:42 +00:00
if ( withdrawn & & var # # rule = = ( ForceRule ) ForceTemporarily ) \
var # # rule = UnusedForceRule ; \
} while ( false )
void Rules : : discardUsed ( bool withdrawn )
{
DISCARD_USED_FORCE_RULE ( placement ) ;
DISCARD_USED_SET_RULE ( position ) ;
DISCARD_USED_SET_RULE ( size ) ;
DISCARD_USED_FORCE_RULE ( minsize ) ;
DISCARD_USED_FORCE_RULE ( maxsize ) ;
DISCARD_USED_FORCE_RULE ( opacityactive ) ;
DISCARD_USED_FORCE_RULE ( opacityinactive ) ;
2013-03-24 18:13:00 +00:00
DISCARD_USED_SET_RULE ( ignoregeometry ) ;
2011-01-30 14:34:42 +00:00
DISCARD_USED_SET_RULE ( desktop ) ;
2012-08-24 16:48:50 +00:00
DISCARD_USED_SET_RULE ( screen ) ;
2012-05-17 14:32:06 +00:00
DISCARD_USED_SET_RULE ( activity ) ;
2011-01-30 14:34:42 +00:00
DISCARD_USED_FORCE_RULE ( type ) ;
DISCARD_USED_SET_RULE ( maximizevert ) ;
DISCARD_USED_SET_RULE ( maximizehoriz ) ;
DISCARD_USED_SET_RULE ( minimize ) ;
DISCARD_USED_SET_RULE ( shade ) ;
DISCARD_USED_SET_RULE ( skiptaskbar ) ;
DISCARD_USED_SET_RULE ( skippager ) ;
DISCARD_USED_SET_RULE ( skipswitcher ) ;
DISCARD_USED_SET_RULE ( above ) ;
DISCARD_USED_SET_RULE ( below ) ;
DISCARD_USED_SET_RULE ( fullscreen ) ;
DISCARD_USED_SET_RULE ( noborder ) ;
2011-03-20 14:42:05 +00:00
DISCARD_USED_FORCE_RULE ( blockcompositing ) ;
2011-01-30 14:34:42 +00:00
DISCARD_USED_FORCE_RULE ( fsplevel ) ;
DISCARD_USED_FORCE_RULE ( acceptfocus ) ;
DISCARD_USED_FORCE_RULE ( closeable ) ;
DISCARD_USED_FORCE_RULE ( autogroup ) ;
DISCARD_USED_FORCE_RULE ( autogroupfg ) ;
DISCARD_USED_FORCE_RULE ( autogroupid ) ;
DISCARD_USED_FORCE_RULE ( strictgeometry ) ;
DISCARD_USED_SET_RULE ( shortcut ) ;
DISCARD_USED_FORCE_RULE ( disableglobalshortcuts ) ;
}
2007-04-29 17:35:43 +00:00
# undef DISCARD_USED_SET_RULE
# undef DISCARD_USED_FORCE_RULE
# endif
2011-01-30 14:34:42 +00:00
QDebug & operator < < ( QDebug & stream , const Rules * r )
{
2007-04-29 17:35:43 +00:00
return stream < < " [ " < < r - > description < < " : " < < r - > wmclass < < " ] " ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
# ifndef KCMRULES
void WindowRules : : discardTemporary ( )
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
QVector < Rules * > : : Iterator it2 = rules . begin ( ) ;
2011-01-30 14:34:42 +00:00
for ( QVector < Rules * > : : Iterator it = rules . begin ( ) ;
it ! = rules . end ( ) ;
) {
if ( ( * it ) - > discardTemporary ( true ) )
2007-04-29 17:35:43 +00:00
+ + it ;
2011-01-30 14:34:42 +00:00
else {
2007-04-29 17:35:43 +00:00
* it2 + + = * it + + ;
}
}
2011-01-30 14:34:42 +00:00
rules . erase ( it2 , rules . end ( ) ) ;
}
2007-04-29 17:35:43 +00:00
2012-02-05 17:50:23 +00:00
void WindowRules : : update ( Client * c , int selection )
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
bool updated = false ;
2011-01-30 14:34:42 +00:00
for ( QVector < Rules * > : : ConstIterator it = rules . constBegin ( ) ;
it ! = rules . constEnd ( ) ;
+ + it )
2012-02-05 17:50:23 +00:00
if ( ( * it ) - > update ( c , selection ) ) // no short-circuiting here
2007-04-29 17:35:43 +00:00
updated = true ;
2011-01-30 14:34:42 +00:00
if ( updated )
2013-04-26 12:40:35 +00:00
RuleBook : : self ( ) - > requestDiskStorage ( ) ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
# define CHECK_RULE( rule, type ) \
2011-01-30 14:34:42 +00:00
type WindowRules : : check # # rule ( type arg , bool init ) const \
2007-04-29 17:35:43 +00:00
{ \
2011-01-30 14:34:42 +00:00
if ( rules . count ( ) = = 0 ) \
return arg ; \
type ret = arg ; \
for ( QVector < Rules * > : : ConstIterator it = rules . constBegin ( ) ; \
it ! = rules . constEnd ( ) ; \
+ + it ) \
2007-04-29 17:35:43 +00:00
{ \
2011-01-30 14:34:42 +00:00
if ( ( * it ) - > apply # # rule ( ret , init ) ) \
break ; \
2007-04-29 17:35:43 +00:00
} \
2011-01-30 14:34:42 +00:00
return ret ; \
2007-04-29 17:35:43 +00:00
}
# define CHECK_FORCE_RULE( rule, type ) \
2011-01-30 14:34:42 +00:00
type WindowRules : : check # # rule ( type arg ) const \
2007-04-29 17:35:43 +00:00
{ \
2011-01-30 14:34:42 +00:00
if ( rules . count ( ) = = 0 ) \
return arg ; \
type ret = arg ; \
for ( QVector < Rules * > : : ConstIterator it = rules . begin ( ) ; \
it ! = rules . end ( ) ; \
+ + it ) \
2007-04-29 17:35:43 +00:00
{ \
2011-01-30 14:34:42 +00:00
if ( ( * it ) - > apply # # rule ( ret ) ) \
break ; \
2007-04-29 17:35:43 +00:00
} \
2011-01-30 14:34:42 +00:00
return ret ; \
2007-04-29 17:35:43 +00:00
}
2011-01-30 14:34:42 +00:00
CHECK_FORCE_RULE ( Placement , Placement : : Policy )
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
QRect WindowRules : : checkGeometry ( QRect rect , bool init ) const
{
return QRect ( checkPosition ( rect . topLeft ( ) , init ) , checkSize ( rect . size ( ) , init ) ) ;
}
CHECK_RULE ( Position , QPoint )
CHECK_RULE ( Size , QSize )
CHECK_FORCE_RULE ( MinSize , QSize )
CHECK_FORCE_RULE ( MaxSize , QSize )
CHECK_FORCE_RULE ( OpacityActive , int )
CHECK_FORCE_RULE ( OpacityInactive , int )
2013-03-24 18:13:00 +00:00
CHECK_RULE ( IgnoreGeometry , bool )
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
CHECK_RULE ( Desktop , int )
2012-05-17 14:32:06 +00:00
CHECK_RULE ( Activity , QString )
2011-01-30 14:34:42 +00:00
CHECK_FORCE_RULE ( Type , NET : : WindowType )
CHECK_RULE ( MaximizeVert , KDecorationDefines : : MaximizeMode )
CHECK_RULE ( MaximizeHoriz , KDecorationDefines : : MaximizeMode )
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
KDecorationDefines : : MaximizeMode WindowRules : : checkMaximize ( MaximizeMode mode , bool init ) const
{
bool vert = checkMaximizeVert ( mode , init ) & MaximizeVertical ;
bool horiz = checkMaximizeHoriz ( mode , init ) & MaximizeHorizontal ;
return static_cast < MaximizeMode > ( ( vert ? MaximizeVertical : 0 ) | ( horiz ? MaximizeHorizontal : 0 ) ) ;
}
2012-08-24 16:48:50 +00:00
int WindowRules : : checkScreen ( int screen , bool init ) const
{
if ( rules . count ( ) = = 0 )
return screen ;
int ret = screen ;
for ( QVector < Rules * > : : ConstIterator it = rules . constBegin ( ) ; it ! = rules . constEnd ( ) ; + + it ) {
if ( ( * it ) - > applyScreen ( ret , init ) )
break ;
}
2013-04-03 10:19:27 +00:00
if ( ret > = Screens : : self ( ) - > count ( ) )
2012-08-24 16:48:50 +00:00
ret = screen ;
return ret ;
}
2011-01-30 14:34:42 +00:00
CHECK_RULE ( Minimize , bool )
CHECK_RULE ( Shade , ShadeMode )
CHECK_RULE ( SkipTaskbar , bool )
CHECK_RULE ( SkipPager , bool )
CHECK_RULE ( SkipSwitcher , bool )
CHECK_RULE ( KeepAbove , bool )
CHECK_RULE ( KeepBelow , bool )
CHECK_RULE ( FullScreen , bool )
CHECK_RULE ( NoBorder , bool )
2011-03-20 14:42:05 +00:00
CHECK_FORCE_RULE ( BlockCompositing , bool )
2011-01-30 14:34:42 +00:00
CHECK_FORCE_RULE ( FSP , int )
CHECK_FORCE_RULE ( AcceptFocus , bool )
CHECK_FORCE_RULE ( Closeable , bool )
CHECK_FORCE_RULE ( Autogrouping , bool )
CHECK_FORCE_RULE ( AutogroupInForeground , bool )
CHECK_FORCE_RULE ( AutogroupById , QString )
CHECK_FORCE_RULE ( StrictGeometry , bool )
CHECK_RULE ( Shortcut , QString )
CHECK_FORCE_RULE ( DisableGlobalShortcuts , bool )
2007-04-29 17:35:43 +00:00
# undef CHECK_RULE
# undef CHECK_FORCE_RULE
// Client
2011-01-30 14:34:42 +00:00
void Client : : setupWindowRules ( bool ignore_temporary )
{
2013-04-26 12:40:35 +00:00
client_rules = RuleBook : : self ( ) - > find ( this , ignore_temporary ) ;
2007-04-29 17:35:43 +00:00
// check only after getting the rules, because there may be a rule forcing window type
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
// Applies Force, ForceTemporarily and ApplyNow rules
// Used e.g. after the rules have been modified using the kcm.
void Client : : applyWindowRules ( )
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
// apply force rules
// Placement - does need explicit update, just like some others below
// Geometry : setGeometry() doesn't check rules
2011-01-30 14:34:42 +00:00
QRect orig_geom = QRect ( pos ( ) , sizeForClientSize ( clientSize ( ) ) ) ; // handle shading
QRect geom = client_rules . checkGeometry ( orig_geom ) ;
if ( geom ! = orig_geom )
setGeometry ( geom ) ;
2007-04-29 17:35:43 +00:00
// MinSize, MaxSize handled by Geometry
2013-03-24 18:13:00 +00:00
// IgnoreGeometry
2011-01-30 14:34:42 +00:00
setDesktop ( desktop ( ) ) ;
2012-08-24 16:48:50 +00:00
workspace ( ) - > sendClientToScreen ( this , screen ( ) ) ;
2012-05-17 14:32:06 +00:00
setOnActivities ( activities ( ) ) ;
2007-04-29 17:35:43 +00:00
// Type
2011-01-30 14:34:42 +00:00
maximize ( maximizeMode ( ) ) ;
2007-04-29 17:35:43 +00:00
// Minimize : functions don't check, and there are two functions
2011-01-30 14:34:42 +00:00
if ( client_rules . checkMinimize ( isMinimized ( ) ) )
2007-04-29 17:35:43 +00:00
minimize ( ) ;
else
unminimize ( ) ;
2011-01-30 14:34:42 +00:00
setShade ( shadeMode ( ) ) ;
setSkipTaskbar ( skipTaskbar ( ) , true ) ;
setSkipPager ( skipPager ( ) ) ;
setSkipSwitcher ( skipSwitcher ( ) ) ;
setKeepAbove ( keepAbove ( ) ) ;
setKeepBelow ( keepBelow ( ) ) ;
setFullScreen ( isFullScreen ( ) , true ) ;
setNoBorder ( noBorder ( ) ) ;
2007-04-29 17:35:43 +00:00
// FSP
// AcceptFocus :
2011-01-30 14:34:42 +00:00
if ( workspace ( ) - > mostRecentlyActivatedClient ( ) = = this
& & ! client_rules . checkAcceptFocus ( true ) )
workspace ( ) - > activateNextClient ( this ) ;
2007-04-29 17:35:43 +00:00
// Closeable
QSize s = adjustedSize ( ) ;
2011-01-30 14:34:42 +00:00
if ( s ! = size ( ) )
resizeWithChecks ( s ) ;
2009-11-16 11:26:37 +00:00
// Autogrouping : Only checked on window manage
2009-11-17 10:41:32 +00:00
// AutogroupInForeground : Only checked on window manage
2009-11-16 13:31:02 +00:00
// AutogroupById : Only checked on window manage
2007-04-29 17:35:43 +00:00
// StrictGeometry
2011-01-30 14:34:42 +00:00
setShortcut ( rules ( ) - > checkShortcut ( shortcut ( ) . toString ( ) ) ) ;
2007-04-29 17:35:43 +00:00
// see also Client::setActive()
2011-01-30 14:34:42 +00:00
if ( isActive ( ) ) {
setOpacity ( rules ( ) - > checkOpacityActive ( qRound ( opacity ( ) * 100.0 ) ) / 100.0 ) ;
workspace ( ) - > disableGlobalShortcutsForClient ( rules ( ) - > checkDisableGlobalShortcuts ( false ) ) ;
} else
setOpacity ( rules ( ) - > checkOpacityInactive ( qRound ( opacity ( ) * 100.0 ) ) / 100.0 ) ;
}
2007-04-29 17:35:43 +00:00
2012-02-05 17:50:23 +00:00
void Client : : updateWindowRules ( Rules : : Types selection )
2011-01-30 14:34:42 +00:00
{
if ( ! isManaged ( ) ) // not fully setup yet
2007-04-29 17:35:43 +00:00
return ;
2013-04-26 12:40:35 +00:00
if ( RuleBook : : self ( ) - > areUpdatesDisabled ( ) )
2007-04-30 12:24:10 +00:00
return ;
2012-02-05 17:50:23 +00:00
client_rules . update ( this , selection ) ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
void Client : : finishWindowRules ( )
2011-01-30 14:34:42 +00:00
{
2012-02-05 17:50:23 +00:00
updateWindowRules ( Rules : : All ) ;
2007-04-29 17:35:43 +00:00
client_rules = WindowRules ( ) ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
// Workspace
2013-04-26 12:40:35 +00:00
KWIN_SINGLETON_FACTORY ( RuleBook )
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
RuleBook : : RuleBook ( QObject * parent )
: QObject ( parent )
, m_updateTimer ( new QTimer ( this ) )
, m_updatesDisabled ( false )
2013-05-10 20:08:47 +00:00
, m_temporaryRulesMessages ( new KXMessages ( " _KDE_NET_WM_TEMPORARY_RULES " , NULL , false ) ) // TODO KF5 - remove *then* obsolete last parameter which is *now* mandatory
2013-04-26 12:40:35 +00:00
{
connect ( m_temporaryRulesMessages . data ( ) , SIGNAL ( gotMessage ( QString ) ) , SLOT ( temporaryRulesMessage ( QString ) ) ) ;
connect ( m_updateTimer , SIGNAL ( timeout ( ) ) , SLOT ( save ( ) ) ) ;
m_updateTimer - > setInterval ( 1000 ) ;
m_updateTimer - > setSingleShot ( true ) ;
}
RuleBook : : ~ RuleBook ( )
{
save ( ) ;
deleteAll ( ) ;
}
void RuleBook : : deleteAll ( )
{
qDeleteAll ( m_rules ) ;
m_rules . clear ( ) ;
}
WindowRules RuleBook : : find ( const Client * c , bool ignore_temporary )
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
QVector < Rules * > ret ;
2013-04-26 12:40:35 +00:00
for ( QList < Rules * > : : Iterator it = m_rules . begin ( ) ;
it ! = m_rules . end ( ) ;
2011-01-30 14:34:42 +00:00
) {
if ( ignore_temporary & & ( * it ) - > isTemporary ( ) ) {
2007-04-29 17:35:43 +00:00
+ + it ;
continue ;
2011-01-30 14:34:42 +00:00
}
if ( ( * it ) - > match ( c ) ) {
2007-04-29 17:35:43 +00:00
Rules * rule = * it ;
2011-01-30 14:34:42 +00:00
kDebug ( 1212 ) < < " Rule found: " < < rule < < " : " < < c ;
if ( rule - > isTemporary ( ) )
2013-04-26 12:40:35 +00:00
it = m_rules . erase ( it ) ;
2007-04-29 17:35:43 +00:00
else
+ + it ;
2011-01-30 14:34:42 +00:00
ret . append ( rule ) ;
2007-04-29 17:35:43 +00:00
continue ;
}
2011-01-30 14:34:42 +00:00
+ + it ;
2007-04-29 17:35:43 +00:00
}
2011-01-30 14:34:42 +00:00
return WindowRules ( ret ) ;
}
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
void RuleBook : : edit ( Client * c , bool whole_app )
2011-01-30 14:34:42 +00:00
{
2013-04-26 12:40:35 +00:00
save ( ) ;
2007-04-29 17:35:43 +00:00
QStringList args ;
2011-01-30 14:34:42 +00:00
args < < " --wid " < < QString : : number ( c - > window ( ) ) ;
if ( whole_app )
2007-04-29 17:35:43 +00:00
args < < " --whole-app " ;
2011-01-30 14:34:42 +00:00
KToolInvocation : : kdeinitExec ( " kwin_rules_dialog " , args ) ;
}
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
void RuleBook : : load ( )
2011-01-30 14:34:42 +00:00
{
2013-04-26 12:40:35 +00:00
deleteAll ( ) ;
2012-11-03 21:07:13 +00:00
KConfig cfg ( QLatin1String ( KWIN_NAME ) + " rulesrc " , KConfig : : NoGlobals ) ;
2011-01-30 14:34:42 +00:00
int count = cfg . group ( " General " ) . readEntry ( " count " , 0 ) ;
for ( int i = 1 ;
i < = count ;
+ + i ) {
KConfigGroup cg ( & cfg , QString : : number ( i ) ) ;
Rules * rule = new Rules ( cg ) ;
2013-04-26 12:40:35 +00:00
m_rules . append ( rule ) ;
2011-01-30 14:34:42 +00:00
}
}
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
void RuleBook : : save ( )
2011-01-30 14:34:42 +00:00
{
2013-04-26 12:40:35 +00:00
m_updateTimer - > stop ( ) ;
2012-11-03 21:07:13 +00:00
KConfig cfg ( QLatin1String ( KWIN_NAME ) + " rulesrc " , KConfig : : NoGlobals ) ;
2007-04-29 17:35:43 +00:00
QStringList groups = cfg . groupList ( ) ;
2011-01-30 14:34:42 +00:00
for ( QStringList : : ConstIterator it = groups . constBegin ( ) ;
it ! = groups . constEnd ( ) ;
+ + it )
cfg . deleteGroup ( * it ) ;
2013-04-26 12:40:35 +00:00
cfg . group ( " General " ) . writeEntry ( " count " , m_rules . count ( ) ) ;
2007-04-29 17:35:43 +00:00
int i = 1 ;
2013-04-26 12:40:35 +00:00
for ( QList < Rules * > : : ConstIterator it = m_rules . constBegin ( ) ;
it ! = m_rules . constEnd ( ) ;
2011-01-30 14:34:42 +00:00
+ + it ) {
if ( ( * it ) - > isTemporary ( ) )
2007-04-29 17:35:43 +00:00
continue ;
2011-01-30 14:34:42 +00:00
KConfigGroup cg ( & cfg , QString : : number ( i ) ) ;
( * it ) - > write ( cg ) ;
2007-04-29 17:35:43 +00:00
+ + i ;
}
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
void RuleBook : : temporaryRulesMessage ( const QString & message )
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
bool was_temporary = false ;
2013-04-26 12:40:35 +00:00
for ( QList < Rules * > : : ConstIterator it = m_rules . constBegin ( ) ;
it ! = m_rules . constEnd ( ) ;
2011-01-30 14:34:42 +00:00
+ + it )
if ( ( * it ) - > isTemporary ( ) )
2007-04-29 17:35:43 +00:00
was_temporary = true ;
2011-01-30 14:34:42 +00:00
Rules * rule = new Rules ( message , true ) ;
2013-04-26 12:40:35 +00:00
m_rules . prepend ( rule ) ; // highest priority first
2011-01-30 14:34:42 +00:00
if ( ! was_temporary )
QTimer : : singleShot ( 60000 , this , SLOT ( cleanupTemporaryRules ( ) ) ) ;
}
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
void RuleBook : : cleanupTemporaryRules ( )
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
bool has_temporary = false ;
2013-04-26 12:40:35 +00:00
for ( QList < Rules * > : : Iterator it = m_rules . begin ( ) ;
it ! = m_rules . end ( ) ;
2011-01-30 14:34:42 +00:00
) {
2013-05-31 17:14:34 +00:00
if ( ( * it ) - > discardTemporary ( false ) ) { // deletes (*it)
2013-04-26 12:40:35 +00:00
it = m_rules . erase ( it ) ;
} else {
2011-01-30 14:34:42 +00:00
if ( ( * it ) - > isTemporary ( ) )
2007-04-29 17:35:43 +00:00
has_temporary = true ;
+ + it ;
}
}
2011-01-30 14:34:42 +00:00
if ( has_temporary )
QTimer : : singleShot ( 60000 , this , SLOT ( cleanupTemporaryRules ( ) ) ) ;
}
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
void RuleBook : : discardUsed ( Client * c , bool withdrawn )
2011-01-30 14:34:42 +00:00
{
2007-04-29 17:35:43 +00:00
bool updated = false ;
2013-04-26 12:40:35 +00:00
for ( QList < Rules * > : : Iterator it = m_rules . begin ( ) ;
it ! = m_rules . end ( ) ;
2011-01-30 14:34:42 +00:00
) {
if ( c - > rules ( ) - > contains ( * it ) ) {
2007-04-29 17:35:43 +00:00
updated = true ;
2011-01-30 14:34:42 +00:00
( * it ) - > discardUsed ( withdrawn ) ;
if ( ( * it ) - > isEmpty ( ) ) {
c - > removeRule ( * it ) ;
2007-04-29 17:35:43 +00:00
Rules * r = * it ;
2013-04-26 12:40:35 +00:00
it = m_rules . erase ( it ) ;
2007-04-29 17:35:43 +00:00
delete r ;
continue ;
}
}
2011-01-30 14:34:42 +00:00
+ + it ;
2007-04-29 17:35:43 +00:00
}
2011-01-30 14:34:42 +00:00
if ( updated )
2013-04-26 12:40:35 +00:00
requestDiskStorage ( ) ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
void RuleBook : : requestDiskStorage ( )
2011-01-30 14:34:42 +00:00
{
2013-04-26 12:40:35 +00:00
m_updateTimer - > start ( ) ;
2011-01-30 14:34:42 +00:00
}
2007-04-29 17:35:43 +00:00
2013-04-26 12:40:35 +00:00
void RuleBook : : setUpdatesDisabled ( bool disable )
2011-01-30 14:34:42 +00:00
{
2013-04-26 12:40:35 +00:00
m_updatesDisabled = disable ;
2012-02-05 17:50:23 +00:00
if ( ! disable ) {
2013-04-26 12:40:35 +00:00
foreach ( Client * c , Workspace : : self ( ) - > clientList ( ) )
2012-02-05 17:50:23 +00:00
c - > updateWindowRules ( Rules : : All ) ;
}
2011-01-30 14:34:42 +00:00
}
2007-04-30 12:24:10 +00:00
2007-04-29 17:35:43 +00:00
# endif
} // namespace