16#include <tdetempfile.h> 
   17#include <tdesimpleconfig.h> 
   29    : temporary_state( 0 )
 
   30    , wmclassmatch( UnimportantMatch )
 
   31    , wmclasscomplete( UnimportantMatch )
 
   32    , windowrolematch( UnimportantMatch )
 
   33    , titlematch( UnimportantMatch )
 
   34    , extrarolematch( UnimportantMatch )
 
   35    , clientmachinematch( UnimportantMatch )
 
   36    , types( NET::AllTypesMask )
 
   37    , placementrule( UnusedForceRule )
 
   38    , positionrule( UnusedSetRule )
 
   39    , sizerule( UnusedSetRule )
 
   40    , minsizerule( UnusedForceRule )
 
   41    , maxsizerule( UnusedForceRule )
 
   42    , opacityactiverule( UnusedForceRule )
 
   43    , opacityinactiverule( UnusedForceRule )
 
   44    , ignorepositionrule( UnusedForceRule )
 
   45    , desktoprule( UnusedSetRule )
 
   46    , typerule( UnusedForceRule )
 
   47    , maximizevertrule( UnusedSetRule )
 
   48    , maximizehorizrule( UnusedSetRule )
 
   49    , minimizerule( UnusedSetRule )
 
   50    , shaderule( UnusedSetRule )
 
   51    , skiptaskbarrule( UnusedSetRule )
 
   52    , skippagerrule( UnusedSetRule )
 
   53    , aboverule( UnusedSetRule )
 
   54    , belowrule( UnusedSetRule )
 
   55    , fullscreenrule( UnusedSetRule )
 
   56    , noborderrule( UnusedSetRule )
 
   57    , fsplevelrule( UnusedForceRule )
 
   58    , acceptfocusrule( UnusedForceRule )
 
   59    , moveresizemoderule( UnusedForceRule )
 
   60    , closeablerule( UnusedForceRule )
 
   61    , strictgeometryrule( UnusedForceRule )
 
   62    , shortcutrule( UnusedSetRule )
 
   63    , disableglobalshortcutsrule( UnusedForceRule )
 
   67Rules::Rules( 
const TQString& str, 
bool temporary )
 
   68    : temporary_state( temporary ? 2 : 0 )
 
   71    TQFile* f = file.file();
 
   74        TQCString s = str.utf8();
 
   75        f->writeBlock( s.data(), s.length());
 
   78    TDESimpleConfig cfg( file.name());
 
   80    if( description.isEmpty())
 
   81        description = 
"temporary";
 
   85#define READ_MATCH_STRING( var, func ) \ 
   86    var = cfg.readEntry( #var ) func; \ 
   87    var##match = (StringMatch) TQMAX( FirstStringMatch, TQMIN( LastStringMatch, cfg.readNumEntry( #var "match" )));
 
   89#define READ_SET_RULE( var, type, func ) \ 
   90    var = func ( cfg.read##type##Entry( #var )); \ 
   91    var##rule = readSetRule( cfg, #var "rule" );
 
   93#define READ_SET_RULE_DEF( var, type, func, def ) \ 
   94    var = func ( cfg.read##type##Entry( #var, def )); \ 
   95    var##rule = readSetRule( cfg, #var "rule" );
 
   97#define READ_SET_RULE_2( var, type, func, funcarg ) \ 
   98    var = func ( cfg.read##type##Entry( #var ), funcarg ); \ 
   99    var##rule = readSetRule( cfg, #var "rule" );
 
  101#define READ_FORCE_RULE( var, type, func ) \ 
  102    var = func ( cfg.read##type##Entry( #var )); \ 
  103    var##rule = readForceRule( cfg, #var "rule" );
 
  105#define READ_FORCE_RULE_2( var, type, func, funcarg ) \ 
  106    var = func ( cfg.read##type##Entry( #var ), funcarg ); \ 
  107    var##rule = readForceRule( cfg, #var "rule" );
 
  110Rules::Rules( TDEConfig& cfg )
 
  111    : temporary_state( 0 )
 
  116static int limit0to4( 
int i ) { 
return TQMAX( 0, TQMIN( 4, i )); }
 
  118void Rules::readFromCfg( TDEConfig& cfg )
 
  120    description = cfg.readEntry( 
"Description" );
 
  121    if( description.isEmpty()) 
 
  122        description = cfg.readEntry( 
"description" );
 
  123    READ_MATCH_STRING( wmclass, .lower().latin1() );
 
  124    wmclasscomplete = cfg.readBoolEntry( 
"wmclasscomplete" );
 
  125    READ_MATCH_STRING( windowrole, .lower().latin1() );
 
  126    READ_MATCH_STRING( title, );
 
  127    READ_MATCH_STRING( extrarole, .lower().latin1() );
 
  128    READ_MATCH_STRING( clientmachine, .lower().latin1() );
 
  129    types = cfg.readUnsignedLongNumEntry( 
"types", NET::AllTypesMask );
 
  130    READ_FORCE_RULE_2( placement,, Placement::policyFromString, 
false );
 
  131    READ_SET_RULE_DEF( position, Point,, &invalidPoint );
 
  132    READ_SET_RULE( size, Size, );
 
  133    if( size.isEmpty() && sizerule != ( SetRule )Remember)
 
  134        sizerule = UnusedSetRule;
 
  135    READ_FORCE_RULE( minsize, Size, );
 
  136    if( !minsize.isValid())
 
  137        minsize = TQSize( 1, 1 );
 
  138    READ_FORCE_RULE( maxsize, Size, );
 
  139    if( maxsize.isEmpty())
 
  140        maxsize = TQSize( 32767, 32767 );
 
  141    READ_FORCE_RULE( opacityactive, Num, );
 
  142    if( opacityactive < 0 || opacityactive > 100 )
 
  144    READ_FORCE_RULE( opacityinactive, Num, );
 
  145    if( opacityinactive < 0 || opacityinactive > 100 )
 
  146        opacityinactive = 100;
 
  147    READ_FORCE_RULE( ignoreposition, Bool, );
 
  148    READ_SET_RULE( desktop, Num, );
 
  149    type = readType( cfg, 
"type" );
 
  150    typerule = type != NET::Unknown ? readForceRule( cfg, 
"typerule" ) : UnusedForceRule;
 
  151    READ_SET_RULE( maximizevert, Bool, );
 
  152    READ_SET_RULE( maximizehoriz, Bool, );
 
  153    READ_SET_RULE( minimize, Bool, );
 
  154    READ_SET_RULE( shade, Bool, );
 
  155    READ_SET_RULE( skiptaskbar, Bool, );
 
  156    READ_SET_RULE( skippager, Bool, );
 
  157    READ_SET_RULE( above, Bool, );
 
  158    READ_SET_RULE( below, Bool, );
 
  159    READ_SET_RULE( fullscreen, Bool, );
 
  160    READ_SET_RULE( noborder, Bool, );
 
  161    READ_FORCE_RULE( fsplevel, Num, limit0to4 ); 
 
  162    READ_FORCE_RULE( acceptfocus, Bool, );
 
  163    READ_FORCE_RULE( moveresizemode, , Options::stringToMoveResizeMode );
 
  164    READ_FORCE_RULE( closeable, Bool, );
 
  165    READ_FORCE_RULE( strictgeometry, Bool, );
 
  166    READ_SET_RULE( shortcut, , );
 
  167    READ_FORCE_RULE( disableglobalshortcuts, Bool, );
 
  170#undef READ_MATCH_STRING 
  172#undef READ_SET_RULE_2 
  173#undef READ_FORCE_RULE 
  174#undef READ_FORCE_RULE_2 
  176#define WRITE_MATCH_STRING( var, cast, force ) \ 
  177    if( !var.isEmpty() || force ) \ 
  179        cfg.writeEntry( #var, cast var ); \ 
  180        cfg.writeEntry( #var "match", var##match ); \
 
  184        cfg.deleteEntry( #var ); \
 
  185        cfg.deleteEntry( #var "match" ); \
 
  188#define WRITE_SET_RULE( var, func ) \ 
  189    if( var##rule != UnusedSetRule ) \ 
  191        cfg.writeEntry( #var, func ( var )); \ 
  192        cfg.writeEntry( #var "rule", var##rule ); \
 
  196        cfg.deleteEntry( #var ); \
 
  197        cfg.deleteEntry( #var "rule" ); \
 
  200#define WRITE_FORCE_RULE( var, func ) \ 
  201    if( var##rule != UnusedForceRule ) \ 
  203        cfg.writeEntry( #var, func ( var )); \ 
  204        cfg.writeEntry( #var "rule", var##rule ); \
 
  208        cfg.deleteEntry( #var ); \
 
  209        cfg.deleteEntry( #var "rule" ); \
 
  212#define WRITE_WITH_DEFAULT( var, default ) \ 
  213    if( var != default ) \ 
  214        cfg.writeEntry( #var, var ); \ 
  216        cfg.deleteEntry( #var ); 
  219void Rules::write( TDEConfig& cfg )
 const 
  221    cfg.writeEntry( 
"Description", description );
 
  223    WRITE_MATCH_STRING( wmclass, (
const char*), 
true );
 
  224    cfg.writeEntry( 
"wmclasscomplete", wmclasscomplete );
 
  225    WRITE_MATCH_STRING( windowrole, (
const char*), 
false );
 
  226    WRITE_MATCH_STRING( title,, 
false );
 
  227    WRITE_MATCH_STRING( extrarole, (
const char*), 
false );
 
  228    WRITE_MATCH_STRING( clientmachine, (
const char*), 
false );
 
  229    WRITE_WITH_DEFAULT( types, NET::AllTypesMask );
 
  230    WRITE_FORCE_RULE( placement, Placement::policyToString );
 
  231    WRITE_SET_RULE( position, );
 
  232    WRITE_SET_RULE( size, );
 
  233    WRITE_FORCE_RULE( minsize, );
 
  234    WRITE_FORCE_RULE( maxsize, );
 
  235    WRITE_FORCE_RULE( opacityactive, );
 
  236    WRITE_FORCE_RULE( opacityinactive, );
 
  237    WRITE_FORCE_RULE( ignoreposition, );
 
  238    WRITE_SET_RULE( desktop, );
 
  239    WRITE_FORCE_RULE( type, );
 
  240    WRITE_SET_RULE( maximizevert, );
 
  241    WRITE_SET_RULE( maximizehoriz, );
 
  242    WRITE_SET_RULE( minimize, );
 
  243    WRITE_SET_RULE( shade, );
 
  244    WRITE_SET_RULE( skiptaskbar, );
 
  245    WRITE_SET_RULE( skippager, );
 
  246    WRITE_SET_RULE( above, );
 
  247    WRITE_SET_RULE( below, );
 
  248    WRITE_SET_RULE( fullscreen, );
 
  249    WRITE_SET_RULE( noborder, );
 
  250    WRITE_FORCE_RULE( fsplevel, );
 
  251    WRITE_FORCE_RULE( acceptfocus, );
 
  252    WRITE_FORCE_RULE( moveresizemode, Options::moveResizeModeToString );
 
  253    WRITE_FORCE_RULE( closeable, );
 
  254    WRITE_FORCE_RULE( strictgeometry, );
 
  255    WRITE_SET_RULE( shortcut, );
 
  256    WRITE_FORCE_RULE( disableglobalshortcuts, );
 
  259#undef WRITE_MATCH_STRING 
  261#undef WRITE_FORCE_RULE 
  262#undef WRITE_WITH_DEFAULT 
  265bool Rules::isEmpty()
 const 
  267    return( placementrule == UnusedForceRule
 
  268        && positionrule == UnusedSetRule
 
  269        && sizerule == UnusedSetRule
 
  270        && minsizerule == UnusedForceRule
 
  271        && maxsizerule == UnusedForceRule
 
  272        && opacityactiverule == UnusedForceRule
 
  273        && opacityinactiverule == UnusedForceRule
 
  274        && ignorepositionrule == UnusedForceRule
 
  275        && desktoprule == UnusedSetRule
 
  276        && typerule == UnusedForceRule
 
  277        && maximizevertrule == UnusedSetRule
 
  278        && maximizehorizrule == UnusedSetRule
 
  279        && minimizerule == UnusedSetRule
 
  280        && shaderule == UnusedSetRule
 
  281        && skiptaskbarrule == UnusedSetRule
 
  282        && skippagerrule == UnusedSetRule
 
  283        && aboverule == UnusedSetRule
 
  284        && belowrule == UnusedSetRule
 
  285        && fullscreenrule == UnusedSetRule
 
  286        && noborderrule == UnusedSetRule
 
  287        && fsplevelrule == UnusedForceRule
 
  288        && acceptfocusrule == UnusedForceRule
 
  289        && moveresizemoderule == UnusedForceRule
 
  290        && closeablerule == UnusedForceRule
 
  291        && strictgeometryrule == UnusedForceRule
 
  292        && shortcutrule == UnusedSetRule
 
  293        && disableglobalshortcutsrule == UnusedForceRule );
 
  296Rules::SetRule Rules::readSetRule( TDEConfig& cfg, 
const TQString& key )
 
  298    int v = cfg.readNumEntry( key );
 
  299    if( v >= DontAffect && v <= ForceTemporarily )
 
  300        return static_cast< SetRule 
>( v );
 
  301    return UnusedSetRule;
 
  304Rules::ForceRule Rules::readForceRule( TDEConfig& cfg, 
const TQString& key )
 
  306    int v = cfg.readNumEntry( key );
 
  307    if( v == DontAffect || v == Force || v == ForceTemporarily )
 
  308        return static_cast< ForceRule 
>( v );
 
  309    return UnusedForceRule;
 
  312NET::WindowType Rules::readType( TDEConfig& cfg, 
const TQString& key )
 
  314    int v = cfg.readNumEntry( key );
 
  315    if( v >= NET::Normal && v <= NET::Splash )
 
  316        return static_cast< NET::WindowType 
>( v );
 
  320bool Rules::matchType( NET::WindowType match_type )
 const 
  322    if( types != NET::AllTypesMask )
 
  324        if( match_type == NET::Unknown )
 
  325            match_type = NET::Normal; 
 
  326        if( !NET::typeMatchesMask( match_type, types ))
 
  332bool Rules::matchWMClass( 
const TQCString& match_class, 
const TQCString& match_name )
 const 
  334    if( wmclassmatch != UnimportantMatch )
 
  336        TQCString cwmclass = wmclasscomplete
 
  337            ? match_name + 
' ' + match_class : match_class;
 
  338        if( wmclassmatch == RegExpMatch && TQRegExp( wmclass ).search( cwmclass ) == -1 )
 
  340        if( wmclassmatch == ExactMatch && wmclass != cwmclass )
 
  342        if( wmclassmatch == SubstringMatch && !cwmclass.contains( wmclass ))
 
  348bool Rules::matchRole( 
const TQCString& match_role )
 const 
  350    if( windowrolematch != UnimportantMatch )
 
  352        if( windowrolematch == RegExpMatch && TQRegExp( windowrole ).search( match_role ) == -1 )
 
  354        if( windowrolematch == ExactMatch && windowrole != match_role )
 
  356        if( windowrolematch == SubstringMatch && !match_role.contains( windowrole ))
 
  362bool Rules::matchTitle( 
const TQString& match_title )
 const 
  364    if( titlematch != UnimportantMatch )
 
  366        if( titlematch == RegExpMatch && TQRegExp( title ).search( match_title ) == -1 )
 
  368        if( titlematch == ExactMatch && title != match_title )
 
  370        if( titlematch == SubstringMatch && !match_title.contains( title ))
 
  376bool Rules::matchClientMachine( 
const TQCString& match_machine )
 const 
  378    if( clientmachinematch != UnimportantMatch )
 
  381        if( match_machine != 
"localhost" && isLocalMachine( match_machine )
 
  382            && matchClientMachine( 
"localhost" ))
 
  384        if( clientmachinematch == RegExpMatch
 
  385            && TQRegExp( clientmachine ).search( match_machine ) == -1 )
 
  387        if( clientmachinematch == ExactMatch
 
  388            && clientmachine != match_machine )
 
  390        if( clientmachinematch == SubstringMatch
 
  391            && !match_machine.contains( clientmachine ))
 
  398bool Rules::match( 
const Client* c )
 const 
  400    if( !matchType( c->windowType( 
true )))
 
  402    if( !matchWMClass( c->resourceClass(), c->resourceName()))
 
  404    if( !matchRole( c->windowRole()))
 
  406    if( !matchTitle( c->caption( 
false )))
 
  409    if( !matchClientMachine( c->wmClientMachine( 
false )))
 
  414bool Rules::update( Client* c )
 
  417    bool updated = 
false;
 
  418    if( positionrule == ( SetRule )Remember)
 
  420        if( !c->isFullScreen())
 
  422            TQPoint new_pos = position;
 
  424            if(( c->maximizeMode() & MaximizeHorizontal ) == 0 )
 
  425                new_pos.setX( c->pos().x());
 
  426            if(( c->maximizeMode() & MaximizeVertical ) == 0 )
 
  427                new_pos.setY( c->pos().y());
 
  428            updated = updated || position != new_pos;
 
  432    if( sizerule == ( SetRule )Remember)
 
  434        if( !c->isFullScreen())
 
  436            TQSize new_size = size;
 
  438            if(( c->maximizeMode() & MaximizeHorizontal ) == 0 )
 
  439                new_size.setWidth( c->size().width());
 
  440            if(( c->maximizeMode() & MaximizeVertical ) == 0 )
 
  441                new_size.setHeight( c->size().height());
 
  442            updated = updated || size != new_size;
 
  446    if( desktoprule == ( SetRule )Remember)
 
  448        updated = updated || desktop != c->desktop();
 
  449        desktop = c->desktop();
 
  451    if( maximizevertrule == ( SetRule )Remember)
 
  453        updated = updated || maximizevert != bool( c->maximizeMode() & MaximizeVertical );
 
  454        maximizevert = c->maximizeMode() & MaximizeVertical;
 
  456    if( maximizehorizrule == ( SetRule )Remember)
 
  458        updated = updated || maximizehoriz != bool( c->maximizeMode() & MaximizeHorizontal );
 
  459        maximizehoriz = c->maximizeMode() & MaximizeHorizontal;
 
  461    if( minimizerule == ( SetRule )Remember)
 
  463        updated = updated || minimize != c->isMinimized();
 
  464        minimize = c->isMinimized();
 
  466    if( shaderule == ( SetRule )Remember)
 
  468        updated = updated || ( shade != ( c->shadeMode() != ShadeNone ));
 
  469        shade = c->shadeMode() != ShadeNone;
 
  471    if( skiptaskbarrule == ( SetRule )Remember)
 
  473        updated = updated || skiptaskbar != c->skipTaskbar();
 
  474        skiptaskbar = c->skipTaskbar();
 
  476    if( skippagerrule == ( SetRule )Remember)
 
  478        updated = updated || skippager != c->skipPager();
 
  479        skippager = c->skipPager();
 
  481    if( aboverule == ( SetRule )Remember)
 
  483        updated = updated || above != c->keepAbove();
 
  484        above = c->keepAbove();
 
  486    if( belowrule == ( SetRule )Remember)
 
  488        updated = updated || below != c->keepBelow();
 
  489        below = c->keepBelow();
 
  491    if( fullscreenrule == ( SetRule )Remember)
 
  493        updated = updated || fullscreen != c->isFullScreen();
 
  494        fullscreen = c->isFullScreen();
 
  496    if( noborderrule == ( SetRule )Remember)
 
  498        updated = updated || noborder != c->isUserNoBorder();
 
  499        noborder = c->isUserNoBorder();
 
  501    if (opacityactiverule == ( ForceRule )Force)
 
  503        updated = updated || (uint) (opacityactive/100.0*0xffffffff) != c->ruleOpacityActive();
 
  504        opacityactive = (uint)(((
double)c->ruleOpacityActive())/0xffffffff*100);
 
  506    if (opacityinactiverule == ( ForceRule )Force)
 
  508        updated = updated || (uint) (opacityinactive/100.0*0xffffffff) != c->ruleOpacityInactive();
 
  509        opacityinactive = (uint)(((
double)c->ruleOpacityInactive())/0xffffffff*100);
 
  514#define APPLY_RULE( var, name, type ) \ 
  515bool Rules::apply##name( type& arg, bool init ) const \ 
  517    if( checkSetRule( var##rule, init )) \ 
  519    return checkSetStop( var##rule ); \ 
  522#define APPLY_FORCE_RULE( var, name, type ) \ 
  523bool Rules::apply##name( type& arg ) const \ 
  525    if( checkForceRule( var##rule )) \ 
  527    return checkForceStop( var##rule ); \ 
  530APPLY_FORCE_RULE( placement, Placement, Placement::Policy )
 
  532bool Rules::applyGeometry( TQRect& rect, 
bool init )
 const 
  534    TQPoint p = rect.topLeft();
 
  535    TQSize s = rect.size();
 
  537    if( applyPosition( p, init ))
 
  539        rect.moveTopLeft( p );
 
  542    if( applySize( s, init ))
 
  550bool Rules::applyPosition( TQPoint& pos, 
bool init )
 const 
  552    if( this->position != invalidPoint && checkSetRule( positionrule, init ))
 
  553        pos = this->position;
 
  554    return checkSetStop( positionrule );
 
  557bool Rules::applySize( TQSize& s, 
bool init )
 const 
  559    if( this->size.isValid() && checkSetRule( sizerule, init ))
 
  561    return checkSetStop( sizerule );
 
  564APPLY_FORCE_RULE( minsize, MinSize, TQSize )
 
  565APPLY_FORCE_RULE( maxsize, MaxSize, TQSize )
 
  566APPLY_FORCE_RULE( opacityactive, OpacityActive, 
int )
 
  567APPLY_FORCE_RULE( opacityinactive, OpacityInactive, 
int )
 
  568APPLY_FORCE_RULE( ignoreposition, IgnorePosition, 
bool )
 
  571bool Rules::applyIgnoreGeometry( 
bool& ignore )
 const 
  573    return applyIgnorePosition( ignore );
 
  576APPLY_RULE( desktop, Desktop, 
int )
 
  577APPLY_FORCE_RULE( type, Type, NET::WindowType )
 
  579bool Rules::applyMaximizeHoriz( MaximizeMode& mode, 
bool init )
 const 
  581    if( checkSetRule( maximizehorizrule, init ))
 
  582        mode = 
static_cast< MaximizeMode 
>(( maximizehoriz ? MaximizeHorizontal : 0 ) | ( mode & MaximizeVertical ));
 
  583    return checkSetStop( maximizehorizrule );
 
  586bool Rules::applyMaximizeVert( MaximizeMode& mode, 
bool init )
 const 
  588    if( checkSetRule( maximizevertrule, init ))
 
  589        mode = 
static_cast< MaximizeMode 
>(( maximizevert ? MaximizeVertical : 0 ) | ( mode & MaximizeHorizontal ));
 
  590    return checkSetStop( maximizevertrule );
 
  593APPLY_RULE( minimize, Minimize, 
bool )
 
  595bool Rules::applyShade( ShadeMode& sh, 
bool init )
 const 
  597    if( checkSetRule( shaderule, init ))
 
  601        if( this->shade && sh == ShadeNone )
 
  604    return checkSetStop( shaderule );
 
  607APPLY_RULE( skiptaskbar, SkipTaskbar, 
bool )
 
  608APPLY_RULE( skippager, SkipPager, 
bool )
 
  609APPLY_RULE( above, KeepAbove, 
bool )
 
  610APPLY_RULE( below, KeepBelow, 
bool )
 
  611APPLY_RULE( fullscreen, FullScreen, 
bool )
 
  612APPLY_RULE( noborder, NoBorder, 
bool )
 
  613APPLY_FORCE_RULE( fsplevel, FSP, 
int )
 
  614APPLY_FORCE_RULE( acceptfocus, AcceptFocus, 
bool )
 
  615APPLY_FORCE_RULE( moveresizemode, MoveResizeMode, Options::MoveResizeMode )
 
  616APPLY_FORCE_RULE( closeable, Closeable, 
bool )
 
  617APPLY_FORCE_RULE( strictgeometry, StrictGeometry, 
bool )
 
  618APPLY_RULE( shortcut, Shortcut, TQString )
 
  619APPLY_FORCE_RULE( disableglobalshortcuts, DisableGlobalShortcuts, 
bool )
 
  623#undef APPLY_FORCE_RULE 
  625bool Rules::isTemporary()
 const 
  627    return temporary_state > 0;
 
  630bool Rules::discardTemporary( 
bool force )
 
  632    if( temporary_state == 0 ) 
 
  634    if( force || --temporary_state == 0 ) 
 
  642#define DISCARD_USED_SET_RULE( var ) \ 
  644    if( var##rule == ( SetRule ) ApplyNow || ( withdrawn && var##rule == ( SetRule ) ForceTemporarily )) \ 
  645        var##rule = UnusedSetRule; \ 
  647#define DISCARD_USED_FORCE_RULE( var ) \ 
  649    if( withdrawn && var##rule == ( ForceRule ) ForceTemporarily ) \ 
  650        var##rule = UnusedForceRule; \ 
  653void Rules::discardUsed( 
bool withdrawn )
 
  655    DISCARD_USED_FORCE_RULE( placement );
 
  656    DISCARD_USED_SET_RULE( position );
 
  657    DISCARD_USED_SET_RULE( size );
 
  658    DISCARD_USED_FORCE_RULE( minsize );
 
  659    DISCARD_USED_FORCE_RULE( maxsize );
 
  660    DISCARD_USED_FORCE_RULE( opacityactive );
 
  661    DISCARD_USED_FORCE_RULE( opacityinactive );
 
  662    DISCARD_USED_FORCE_RULE( ignoreposition );
 
  663    DISCARD_USED_SET_RULE( desktop );
 
  664    DISCARD_USED_FORCE_RULE( type );
 
  665    DISCARD_USED_SET_RULE( maximizevert );
 
  666    DISCARD_USED_SET_RULE( maximizehoriz );
 
  667    DISCARD_USED_SET_RULE( minimize );
 
  668    DISCARD_USED_SET_RULE( shade );
 
  669    DISCARD_USED_SET_RULE( skiptaskbar );
 
  670    DISCARD_USED_SET_RULE( skippager );
 
  671    DISCARD_USED_SET_RULE( above );
 
  672    DISCARD_USED_SET_RULE( below );
 
  673    DISCARD_USED_SET_RULE( fullscreen );
 
  674    DISCARD_USED_SET_RULE( noborder );
 
  675    DISCARD_USED_FORCE_RULE( fsplevel );
 
  676    DISCARD_USED_FORCE_RULE( acceptfocus );
 
  677    DISCARD_USED_FORCE_RULE( moveresizemode );
 
  678    DISCARD_USED_FORCE_RULE( closeable );
 
  679    DISCARD_USED_FORCE_RULE( strictgeometry );
 
  680    DISCARD_USED_SET_RULE( shortcut );
 
  681    DISCARD_USED_FORCE_RULE( disableglobalshortcuts );
 
  683#undef DISCARD_USED_SET_RULE 
  684#undef DISCARD_USED_FORCE_RULE 
  689kdbgstream& operator<<( kdbgstream& stream, 
const Rules* r )
 
  691    return stream << 
"[" << r->description << 
":" << r->wmclass << 
"]" ;
 
  696void WindowRules::discardTemporary()
 
  698    TQValueVector< Rules* >::Iterator it2 = rules.begin();
 
  699    for( TQValueVector< Rules* >::Iterator it = rules.begin();
 
  703        if( (*it)->discardTemporary( 
true ))
 
  710    rules.erase( it2, rules.end());
 
  713void WindowRules::update( Client* c )
 
  715    bool updated = 
false;
 
  716    for( TQValueVector< Rules* >::ConstIterator it = rules.begin();
 
  719        if( (*it)->update( c )) 
 
  722        Workspace::self()->rulesUpdated();
 
  725#define CHECK_RULE( rule, type ) \ 
  726type WindowRules::check##rule( type arg, bool init ) const \ 
  728    if( rules.count() == 0 ) \ 
  731    for( TQValueVector< Rules* >::ConstIterator it = rules.begin(); \ 
  735        if( (*it)->apply##rule( ret, init )) \ 
  741#define CHECK_FORCE_RULE( rule, type ) \ 
  742type WindowRules::check##rule( type arg ) const \ 
  744    if( rules.count() == 0 ) \ 
  747    for( TQValueVector< Rules* >::ConstIterator it = rules.begin(); \ 
  751        if( (*it)->apply##rule( ret )) \ 
  757CHECK_FORCE_RULE( Placement, Placement::Policy )
 
  759TQRect WindowRules::checkGeometry( TQRect rect, 
bool init )
 const 
  761    return TQRect( checkPosition( rect.topLeft(), init ), checkSize( rect.size(), init ));
 
  764CHECK_RULE( Position, TQPoint )
 
  765CHECK_RULE( Size, TQSize )
 
  766CHECK_FORCE_RULE( MinSize, TQSize )
 
  767CHECK_FORCE_RULE( MaxSize, TQSize )
 
  768CHECK_FORCE_RULE( OpacityActive, 
int )
 
  769CHECK_FORCE_RULE( OpacityInactive, 
int )
 
  770CHECK_FORCE_RULE( IgnorePosition, 
bool )
 
  772bool WindowRules::checkIgnoreGeometry( 
bool ignore )
 const 
  774    return checkIgnorePosition( ignore );
 
  777CHECK_RULE( Desktop, 
int )
 
  778CHECK_FORCE_RULE( Type, NET::WindowType )
 
  779CHECK_RULE( MaximizeVert, KDecorationDefines::MaximizeMode )
 
  780CHECK_RULE( MaximizeHoriz, KDecorationDefines::MaximizeMode )
 
  782KDecorationDefines::MaximizeMode WindowRules::checkMaximize( MaximizeMode mode, 
bool init )
 const 
  784    bool vert = checkMaximizeVert( mode, init ) & MaximizeVertical;
 
  785    bool horiz = checkMaximizeHoriz( mode, init ) & MaximizeHorizontal;
 
  786    return static_cast< MaximizeMode 
>(( vert ? MaximizeVertical : 0 ) | ( horiz ? MaximizeHorizontal : 0 ));
 
  789CHECK_RULE( Minimize, 
bool )
 
  790CHECK_RULE( Shade, ShadeMode )
 
  791CHECK_RULE( SkipTaskbar, 
bool )
 
  792CHECK_RULE( SkipPager, 
bool )
 
  793CHECK_RULE( KeepAbove, 
bool )
 
  794CHECK_RULE( KeepBelow, 
bool )
 
  795CHECK_RULE( FullScreen, 
bool )
 
  796CHECK_RULE( NoBorder, 
bool )
 
  797CHECK_FORCE_RULE( FSP, 
int )
 
  798CHECK_FORCE_RULE( AcceptFocus, 
bool )
 
  799CHECK_FORCE_RULE( MoveResizeMode, Options::MoveResizeMode )
 
  800CHECK_FORCE_RULE( Closeable, 
bool )
 
  801CHECK_FORCE_RULE( StrictGeometry, 
bool )
 
  802CHECK_RULE( Shortcut, TQString )
 
  803CHECK_FORCE_RULE( DisableGlobalShortcuts, 
bool )
 
  806#undef CHECK_FORCE_RULE 
  810void Client::setupWindowRules( 
bool ignore_temporary )
 
  812    client_rules = workspace()->findWindowRules( 
this, ignore_temporary );
 
  815        client_rules = WindowRules();
 
  820void Client::applyWindowRules()
 
  822    checkAndSetInitialRuledOpacity();        
 
  826    TQRect orig_geom = TQRect( pos(), sizeForClientSize( clientSize())); 
 
  827    TQRect geom = client_rules.checkGeometry( orig_geom );
 
  828    if( geom != orig_geom )
 
  832    setDesktop( desktop());
 
  834    maximize( maximizeMode());
 
  836    if( client_rules.checkMinimize( isMinimized()))
 
  840    setShade( shadeMode());
 
  841    setSkipTaskbar( skipTaskbar(), 
true );
 
  842    setSkipPager( skipPager());
 
  843    setKeepAbove( keepAbove());
 
  844    setKeepBelow( keepBelow());
 
  845    setFullScreen( isFullScreen(), 
true );
 
  846    setUserNoBorder( isUserNoBorder());
 
  849    if( workspace()->mostRecentlyActivatedClient() == 
this 
  850        && !client_rules.checkAcceptFocus( 
true ))
 
  851        workspace()->activateNextClient( 
this );
 
  854    TQSize s = adjustedSize();
 
  856        resizeWithChecks( s );
 
  858    setShortcut( rules()->checkShortcut( shortcut().toString()));
 
  861        workspace()->disableGlobalShortcutsForClient( rules()->checkDisableGlobalShortcuts( 
false ));
 
  864void Client::updateWindowRules()
 
  868    if( workspace()->rulesUpdatesDisabled())
 
  870    client_rules.update( 
this );
 
  873void Client::finishWindowRules()
 
  876    client_rules = WindowRules();
 
  879void Client::checkAndSetInitialRuledOpacity()
 
  886    tmp = rules()->checkOpacityActive(tmp);
 
  889        rule_opacity_active = (uint)((tmp/100.0)*0xffffffff);
 
  892        rule_opacity_active = 0;
 
  896    tmp = rules()->checkOpacityInactive(tmp);
 
  899        rule_opacity_inactive = (uint)((tmp/100.0)*0xffffffff);
 
  902        rule_opacity_inactive = 0;
 
  909        uint tmp = rule_opacity_active ? rule_opacity_active : options->dockOpacity;
 
  910        setOpacity(tmp < 0xFFFFFFFF && (rule_opacity_active || options->translucentDocks), tmp);
 
  918WindowRules Workspace::findWindowRules( 
const Client* c, 
bool ignore_temporary )
 
  920    TQValueVector< Rules* > ret;
 
  921    for( TQValueList< Rules* >::Iterator it = rules.begin();
 
  925        if( ignore_temporary && (*it)->isTemporary())
 
  930        if( (*it)->match( c ))
 
  933            kdDebug( 1212 ) << 
"Rule found:" << rule << 
":" << c << endl;
 
  934            if( rule->isTemporary())
 
  935                it = rules.remove( it );
 
  943    return WindowRules( ret );
 
  946void Workspace::editWindowRules( Client* c, 
bool whole_app )
 
  950    args << 
"--wid" << TQString::number( c->window());
 
  952        args << 
"--whole-app";
 
  953    TDEApplication::tdeinitExec( 
"twin_rules_dialog", args );
 
  956void Workspace::loadWindowRules()
 
  958    while( !rules.isEmpty())
 
  960        delete rules.front();
 
  963    TDEConfig cfg( 
"twinrulesrc", 
true );
 
  964    cfg.setGroup( 
"General" );
 
  965    int count = cfg.readNumEntry( 
"count" );
 
  970        cfg.setGroup( TQString::number( i ));
 
  971        Rules* rule = 
new Rules( cfg );
 
  972        rules.append( rule );
 
  976void Workspace::writeWindowRules()
 
  978    rulesUpdatedTimer.stop();
 
  979    TDEConfig cfg( 
"twinrulesrc" );
 
  980    TQStringList groups = cfg.groupList();
 
  981    for( TQStringList::ConstIterator it = groups.begin();
 
  984        cfg.deleteGroup( *it );
 
  985    cfg.setGroup( 
"General" );
 
  986    cfg.writeEntry( 
"count", rules.count());
 
  988    for( TQValueList< Rules* >::ConstIterator it = rules.begin();
 
  992        if( (*it)->isTemporary())
 
  994        cfg.setGroup( TQString::number( i ));
 
 1000void Workspace::gotTemporaryRulesMessage( 
const TQString& message )
 
 1002    bool was_temporary = 
false;
 
 1003    for( TQValueList< Rules* >::ConstIterator it = rules.begin();
 
 1006        if( (*it)->isTemporary())
 
 1007            was_temporary = 
true;
 
 1008    Rules* rule = 
new Rules( message, 
true );
 
 1009    rules.prepend( rule ); 
 
 1010    if( !was_temporary )
 
 1011        TQTimer::singleShot( 60000, 
this, TQ_SLOT( cleanupTemporaryRules()));
 
 1014void Workspace::cleanupTemporaryRules()
 
 1016    bool has_temporary = 
false;
 
 1017    for( TQValueList< Rules* >::Iterator it = rules.begin();
 
 1021        if( (*it)->discardTemporary( 
false ))
 
 1022            it = rules.remove( it );
 
 1025            if( (*it)->isTemporary())
 
 1026                has_temporary = 
true;
 
 1031        TQTimer::singleShot( 60000, 
this, TQ_SLOT( cleanupTemporaryRules()));
 
 1034void Workspace::discardUsedWindowRules( Client* c, 
bool withdrawn )
 
 1036    bool updated = 
false;
 
 1037    for( TQValueList< Rules* >::Iterator it = rules.begin();
 
 1041        if( c->rules()->contains( *it ))
 
 1044            (*it)->discardUsed( withdrawn );
 
 1045            if( (*it)->isEmpty())
 
 1047                c->removeRule( *it );
 
 1049                it = rules.remove( it );
 
 1060void Workspace::rulesUpdated()
 
 1062    rulesUpdatedTimer.start( 1000, 
true );
 
 1065void Workspace::disableRulesUpdates( 
bool disable )
 
 1067    rules_updates_disabled = disable;
 
 1069        for( ClientList::ConstIterator it = clients.begin();
 
 1070             it != clients.end();
 
 1072            (*it)->updateWindowRules();