14 #include <tdeconfig.h>
16 #include <tdetempfile.h>
17 #include <ksimpleconfig.h>
22 #include "workspace.h"
25 namespace KWinInternal
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 )
67 Rules::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 KSimpleConfig 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" );
110 Rules::Rules( TDEConfig& cfg )
111 : temporary_state( 0 )
116 static int limit0to4(
int i ) {
return TQMAX( 0, TQMIN( 4, i )); }
118 void 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 );
219 void 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
260 #undef WRITE_SET_RULE
261 #undef WRITE_FORCE_RULE
262 #undef WRITE_WITH_DEFAULT
265 bool 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 );
296 Rules::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;
304 Rules::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;
312 NET::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 );
320 bool 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 ))
332 bool 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 ))
348 bool 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 ))
362 bool 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 ))
376 bool 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 ))
398 bool 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 )))
414 bool 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 ) \
515 bool 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 ) \
523 bool Rules::apply##name( type& arg ) const \
525 if( checkForceRule( var##rule )) \
527 return checkForceStop( var##rule ); \
530 APPLY_FORCE_RULE( placement, Placement, Placement::Policy )
532 bool 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 ))
550 bool Rules::applyPosition( TQPoint& pos,
bool init )
const
552 if( this->position != invalidPoint && checkSetRule( positionrule, init ))
553 pos = this->position;
554 return checkSetStop( positionrule );
557 bool Rules::applySize( TQSize& s,
bool init )
const
559 if( this->size.isValid() && checkSetRule( sizerule, init ))
561 return checkSetStop( sizerule );
564 APPLY_FORCE_RULE( minsize, MinSize, TQSize )
565 APPLY_FORCE_RULE( maxsize, MaxSize, TQSize )
566 APPLY_FORCE_RULE( opacityactive, OpacityActive,
int )
567 APPLY_FORCE_RULE( opacityinactive, OpacityInactive,
int )
568 APPLY_FORCE_RULE( ignoreposition, IgnorePosition,
bool )
571 bool Rules::applyIgnoreGeometry(
bool& ignore )
const
573 return applyIgnorePosition( ignore );
576 APPLY_RULE( desktop, Desktop,
int )
577 APPLY_FORCE_RULE( type, Type, NET::WindowType )
579 bool 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 );
586 bool 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 );
593 APPLY_RULE( minimize, Minimize,
bool )
595 bool Rules::applyShade( ShadeMode& sh,
bool init )
const
597 if( checkSetRule( shaderule, init ))
601 if( this->shade && sh == ShadeNone )
604 return checkSetStop( shaderule );
607 APPLY_RULE( skiptaskbar, SkipTaskbar,
bool )
608 APPLY_RULE( skippager, SkipPager,
bool )
609 APPLY_RULE( above, KeepAbove,
bool )
610 APPLY_RULE( below, KeepBelow,
bool )
611 APPLY_RULE( fullscreen, FullScreen,
bool )
612 APPLY_RULE( noborder, NoBorder,
bool )
613 APPLY_FORCE_RULE( fsplevel, FSP,
int )
614 APPLY_FORCE_RULE( acceptfocus, AcceptFocus,
bool )
615 APPLY_FORCE_RULE( moveresizemode, MoveResizeMode, Options::MoveResizeMode )
616 APPLY_FORCE_RULE( closeable, Closeable,
bool )
617 APPLY_FORCE_RULE( strictgeometry, StrictGeometry,
bool )
618 APPLY_RULE( shortcut, Shortcut, TQString )
619 APPLY_FORCE_RULE( disableglobalshortcuts, DisableGlobalShortcuts,
bool )
623 #undef APPLY_FORCE_RULE
625 bool Rules::isTemporary()
const
627 return temporary_state > 0;
630 bool 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; \
653 void 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
689 kdbgstream& operator<<( kdbgstream& stream,
const Rules* r )
691 return stream <<
"[" << r->description <<
":" << r->wmclass <<
"]" ;
696 void 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());
713 void 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 ) \
726 type 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 ) \
742 type 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 )) \
757 CHECK_FORCE_RULE( Placement, Placement::Policy )
759 TQRect WindowRules::checkGeometry( TQRect rect,
bool init )
const
761 return TQRect( checkPosition( rect.topLeft(), init ), checkSize( rect.size(), init ));
764 CHECK_RULE( Position, TQPoint )
765 CHECK_RULE( Size, TQSize )
766 CHECK_FORCE_RULE( MinSize, TQSize )
767 CHECK_FORCE_RULE( MaxSize, TQSize )
768 CHECK_FORCE_RULE( OpacityActive,
int )
769 CHECK_FORCE_RULE( OpacityInactive,
int )
770 CHECK_FORCE_RULE( IgnorePosition,
bool )
772 bool WindowRules::checkIgnoreGeometry(
bool ignore )
const
774 return checkIgnorePosition( ignore );
777 CHECK_RULE( Desktop,
int )
778 CHECK_FORCE_RULE( Type, NET::WindowType )
779 CHECK_RULE( MaximizeVert, KDecorationDefines::MaximizeMode )
780 CHECK_RULE( MaximizeHoriz, KDecorationDefines::MaximizeMode )
782 KDecorationDefines::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 ));
789 CHECK_RULE( Minimize,
bool )
790 CHECK_RULE( Shade, ShadeMode )
791 CHECK_RULE( SkipTaskbar,
bool )
792 CHECK_RULE( SkipPager,
bool )
793 CHECK_RULE( KeepAbove,
bool )
794 CHECK_RULE( KeepBelow,
bool )
795 CHECK_RULE( FullScreen,
bool )
796 CHECK_RULE( NoBorder,
bool )
797 CHECK_FORCE_RULE( FSP,
int )
798 CHECK_FORCE_RULE( AcceptFocus,
bool )
799 CHECK_FORCE_RULE( MoveResizeMode, Options::MoveResizeMode )
800 CHECK_FORCE_RULE( Closeable,
bool )
801 CHECK_FORCE_RULE( StrictGeometry,
bool )
802 CHECK_RULE( Shortcut, TQString )
803 CHECK_FORCE_RULE( DisableGlobalShortcuts,
bool )
806 #undef CHECK_FORCE_RULE
810 void Client::setupWindowRules(
bool ignore_temporary )
812 client_rules = workspace()->findWindowRules(
this, ignore_temporary );
815 client_rules = WindowRules();
820 void 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 ));
864 void Client::updateWindowRules()
868 if( workspace()->rulesUpdatesDisabled())
870 client_rules.update(
this );
873 void Client::finishWindowRules()
876 client_rules = WindowRules();
879 void 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);
918 WindowRules 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 );
946 void 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 );
956 void 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 );
976 void 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 ));
1000 void 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()));
1014 void 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()));
1034 void 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 );
1060 void Workspace::rulesUpdated()
1062 rulesUpdatedTimer.start( 1000,
true );
1065 void Workspace::disableRulesUpdates(
bool disable )
1067 rules_updates_disabled = disable;
1069 for( ClientList::ConstIterator it = clients.begin();
1070 it != clients.end();
1072 (*it)->updateWindowRules();