Make it possible to use the window-specific settings dialog

to also set some things only temporarily. E.g. in order
to set skiptaskbar flag on a window, it's just
Alt+F3/Advanced/Special Window Settings/Preferences ->
Apply Now for Skip taskbar, and turn on the checkbox.


svn path=/trunk/KDE/kdebase/kwin/; revision=423112
This commit is contained in:
Luboš Luňák 2005-06-07 15:31:15 +00:00
parent c748f46346
commit 20f80af287
9 changed files with 377 additions and 59 deletions

View file

@ -181,6 +181,7 @@ void Client::releaseWindow( bool on_shutdown )
{
assert( !deleting );
deleting = true;
workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules
StackingUpdatesBlocker blocker( workspace());
if (!custom_opacity) setOpacity(FALSE);
if (moveResizeMode)
@ -235,6 +236,7 @@ void Client::destroyClient()
{
assert( !deleting );
deleting = true;
workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules
StackingUpdatesBlocker blocker( workspace());
if (moveResizeMode)
leaveMoveResize();

View file

@ -70,6 +70,9 @@ class Client : public QObject, public KDecorationDefines
// prefer isXXX() instead
NET::WindowType windowType( bool direct = false, int supported_types = SUPPORTED_WINDOW_TYPES_MASK ) const;
const WindowRules* rules() const;
void removeRule( Rules* r );
void setupWindowRules( bool ignore_temporary );
void applyWindowRules();
QRect geometry() const;
QSize size() const;
@ -366,7 +369,6 @@ class Client : public QObject, public KDecorationDefines
QString readName() const;
void setCaption( const QString& s, bool force = false );
bool hasTransientInternal( const Client* c, bool indirect, ConstClientList& set ) const;
void setupWindowRules( bool ignore_temporary );
void updateWindowRules();
void finishWindowRules();
void setShortcutInternal( const KShortcut& cut );
@ -890,7 +892,12 @@ inline void Client::setBMP(bool b)
{
isBMP_ = b;
}
inline void Client::removeRule( Rules* rule )
{
client_rules.remove( rule );
}
#ifdef NDEBUG
inline
kndbgstream& operator<<( kndbgstream& stream, const Client* ) { return stream; }

View file

@ -61,13 +61,21 @@ RulesWidget::RulesWidget( QWidget* parent, const char* name )
" after the window is created. No further changes will be affected.</li>"
"<li><em>Remember:</em> The value of the window property will be remembered and every time"
" time the window is created, the last remembered value will be applied.</li>"
"<li><em>Force:</em> The window property will be always forced to the given value.</li></ul>" );
"<li><em>Force:</em> The window property will be always forced to the given value.</li>"
"<li><em>Apply Now:</em> The window property will be set to the given value immediatelly"
"and will not be affected later (this action will be deleted afterwards).</li>"
"<li><em>Force temporarily:</em> The window property will be forced to the given value"
"until it is hidden (this action will be deleted after the window is hidden).</li>"
"</ul>" );
QString forceRuleDesc =
i18n( "Specify how the window property should be affected:<ul>"
"<li><em>Do Not Affect:</em> The window property will not be affected and therefore"
" the default handling for it will be used. Specifying this will block more generic"
" window settings from taking effect.</li>"
"<li><em>Force:</em> The window property will be always forced to the given value.</li></ul>" );
"<li><em>Force:</em> The window property will be always forced to the given value.</li>"
"<li><em>Force temporarily:</em> The window property will be forced to the given value"
"until it is hidden (this action will be deleted after the window is hidden).</li>"
"</ul>" );
// window tabs have enable signals done in designer
// geometry tab
SETUP( position, set );
@ -159,6 +167,8 @@ static const int set_rule_to_combo[] =
3, // Force
1, // Apply
2, // Remember
4, // ApplyNow
5 // ForceTemporarily
};
static const Rules::SetRule combo_to_set_rule[] =
@ -166,20 +176,27 @@ static const Rules::SetRule combo_to_set_rule[] =
( Rules::SetRule )Rules::DontAffect,
( Rules::SetRule )Rules::Apply,
( Rules::SetRule )Rules::Remember,
( Rules::SetRule )Rules::Force
( Rules::SetRule )Rules::Force,
( Rules::SetRule )Rules::ApplyNow,
( Rules::SetRule )Rules::ForceTemporarily
};
static const int force_rule_to_combo[] =
{
0, // Unused
0, // Don't Affect
1 // Force
1, // Force
0, // Apply
0, // Remember
0, // ApplyNow
2 // ForceTemporarily
};
static const Rules::ForceRule combo_to_force_rule[] =
{
( Rules::ForceRule )Rules::DontAffect,
( Rules::ForceRule )Rules::Force
( Rules::ForceRule )Rules::Force,
( Rules::ForceRule )Rules::ForceTemporarily
};
static QString positionToStr( const QPoint& p )

View file

@ -688,6 +688,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_size</cstring>
</property>
@ -754,6 +764,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_position</cstring>
</property>
@ -793,6 +813,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_maximizehoriz</cstring>
</property>
@ -851,6 +881,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_fullscreen</cstring>
</property>
@ -887,6 +927,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_maximizevert</cstring>
</property>
@ -923,6 +973,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_desktop</cstring>
</property>
@ -986,6 +1046,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_minimize</cstring>
</property>
@ -1023,6 +1093,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_placement</cstring>
</property>
@ -1129,6 +1204,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_shade</cstring>
</property>
@ -1224,6 +1309,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_opacityactive</cstring>
</property>
@ -1466,6 +1556,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_closeable</cstring>
</property>
@ -1484,6 +1579,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_acceptfocus</cstring>
</property>
@ -1512,6 +1612,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_skippager</cstring>
</property>
@ -1540,6 +1650,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_skiptaskbar</cstring>
</property>
@ -1568,6 +1688,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_noborder</cstring>
</property>
@ -1596,6 +1726,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_below</cstring>
</property>
@ -1624,6 +1764,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_above</cstring>
</property>
@ -1659,6 +1809,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_opacityinactive</cstring>
</property>
@ -1734,6 +1889,16 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Now</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_shortcut</cstring>
</property>
@ -1789,6 +1954,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_type</cstring>
</property>
@ -1899,6 +2069,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_fsplevel</cstring>
</property>
@ -1917,6 +2092,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_moveresizemode</cstring>
</property>
@ -1987,6 +2167,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_minsize</cstring>
</property>
@ -2024,6 +2209,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_maxsize</cstring>
</property>
@ -2050,6 +2240,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_ignoreposition</cstring>
</property>
@ -2107,6 +2302,11 @@
<string>Force</string>
</property>
</item>
<item>
<property name="text">
<string>Force Temporarily</string>
</property>
</item>
<property name="name">
<cstring>rule_strictgeometry</cstring>
</property>

View file

@ -495,6 +495,8 @@ bool Client::manage( Window w, bool isMapped )
ungrabXServer();
client_rules.discardTemporary();
applyWindowRules(); // just in case
workspace()->discardUsedWindowRules( this, false ); // remove ApplyNow rules
updateWindowRules(); // was blocked while !isManaged()
// TODO there's a small problem here - isManaged() depends on the mapping state,

156
rules.cpp
View file

@ -290,7 +290,7 @@ bool Rules::isEmpty() const
Rules::SetRule Rules::readSetRule( KConfig& cfg, const QString& key )
{
int v = cfg.readNumEntry( key );
if( v >= DontAffect && v <= Remember )
if( v >= DontAffect && v <= ForceTemporarily )
return static_cast< SetRule >( v );
return UnusedSetRule;
}
@ -298,7 +298,7 @@ Rules::SetRule Rules::readSetRule( KConfig& cfg, const QString& key )
Rules::ForceRule Rules::readForceRule( KConfig& cfg, const QString& key )
{
int v = cfg.readNumEntry( key );
if( v == DontAffect || v == Force )
if( v == DontAffect || v == Force || v == ForceTemporarily )
return static_cast< ForceRule >( v );
return UnusedForceRule;
}
@ -623,6 +623,50 @@ bool Rules::discardTemporary( bool force )
}
return false;
}
#define DISCARD_USED_SET_RULE( var ) \
do { \
if( var##rule == ( SetRule ) ApplyNow || ( withdrawn && var##rule == ( SetRule ) ForceTemporarily )) \
var##rule = UnusedSetRule; \
} while( false )
#define DISCARD_USED_FORCE_RULE( var ) \
do { \
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 );
DISCARD_USED_FORCE_RULE( ignoreposition );
DISCARD_USED_SET_RULE( desktop );
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( above );
DISCARD_USED_SET_RULE( below );
DISCARD_USED_SET_RULE( fullscreen );
DISCARD_USED_SET_RULE( noborder );
DISCARD_USED_FORCE_RULE( fsplevel );
DISCARD_USED_FORCE_RULE( acceptfocus );
DISCARD_USED_FORCE_RULE( moveresizemode );
DISCARD_USED_FORCE_RULE( closeable );
DISCARD_USED_FORCE_RULE( strictgeometry );
DISCARD_USED_SET_RULE( shortcut );
}
#undef DISCARD_USED_SET_RULE
#undef DISCARD_USED_FORCE_RULE
#endif
#ifndef NDEBUG
@ -740,59 +784,54 @@ CHECK_RULE( Shortcut, QString )
// Client
#define FORCE_RULE( rule, type, getf, setf ) \
{ \
type val = client_rules.check##rule( getf()); \
if( val != getf()) \
setf( val ); \
}
void Client::setupWindowRules( bool ignore_temporary )
{
client_rules = workspace()->findWindowRules( this, ignore_temporary );
// check only after getting the rules, because there may be a rule forcing window type
if( isTopMenu()) // TODO cannot have restrictions
client_rules = WindowRules();
checkAndSetInitialRuledOpacity();
if( isManaged())
{ // apply force rules
// Placement - does need explicit update, just like some others below
// Geometry : setGeometry() doesn't check rules
QRect geom = client_rules.checkGeometry( geometry());
if( geom != geometry())
setGeometry( geom );
// MinSize, MaxSize handled by Geometry
// IgnorePosition
setDesktop( desktop());
// Type
maximize( maximizeMode());
// Minimize : functions don't check, and there are two functions
if( client_rules.checkMinimize( isMinimized()))
minimize();
else
unminimize();
setShade( shadeMode());
setSkipTaskbar( skipTaskbar(), true );
setSkipPager( skipPager());
setKeepAbove( keepAbove());
setKeepBelow( keepBelow());
setFullScreen( isFullScreen(), true );
setUserNoBorder( isUserNoBorder());
// FSP
// AcceptFocus :
if( workspace()->mostRecentlyActivatedClient() == this
&& !client_rules.checkAcceptFocus( true ))
workspace()->activateNextClient( this );
// MoveResizeMode
// Closeable
QSize s = adjustedSize( size());
if( s != size())
resizeWithChecks( s );
setShortcut( rules()->checkShortcut( shortcut().toString()));
}
}
#undef FORCE_RULE
// Applies Force, ForceTemporarily and ApplyNow rules
// Used e.g. after the rules have been modified using the kcm.
void Client::applyWindowRules()
{
checkAndSetInitialRuledOpacity();
// apply force rules
// Placement - does need explicit update, just like some others below
// Geometry : setGeometry() doesn't check rules
QRect geom = client_rules.checkGeometry( geometry());
if( geom != geometry())
setGeometry( geom );
// MinSize, MaxSize handled by Geometry
// IgnorePosition
setDesktop( desktop());
// Type
maximize( maximizeMode());
// Minimize : functions don't check, and there are two functions
if( client_rules.checkMinimize( isMinimized()))
minimize();
else
unminimize();
setShade( shadeMode());
setSkipTaskbar( skipTaskbar(), true );
setSkipPager( skipPager());
setKeepAbove( keepAbove());
setKeepBelow( keepBelow());
setFullScreen( isFullScreen(), true );
setUserNoBorder( isUserNoBorder());
// FSP
// AcceptFocus :
if( workspace()->mostRecentlyActivatedClient() == this
&& !client_rules.checkAcceptFocus( true ))
workspace()->activateNextClient( this );
// MoveResizeMode
// Closeable
QSize s = adjustedSize( size());
if( s != size())
resizeWithChecks( s );
setShortcut( rules()->checkShortcut( shortcut().toString()));
}
void Client::updateWindowRules()
{
@ -953,6 +992,29 @@ void Workspace::cleanupTemporaryRules()
QTimer::singleShot( 60000, this, SLOT( cleanupTemporaryRules()));
}
void Workspace::discardUsedWindowRules( Client* c, bool withdrawn )
{
for( QValueList< Rules* >::Iterator it = rules.begin();
it != rules.end();
)
{
if( c->rules()->contains( *it ))
{
(*it)->discardUsed( withdrawn );
if( (*it)->isEmpty())
{
c->removeRule( *it );
Rules* r = *it;
it = rules.remove( it );
delete r;
continue;
}
}
++it;
}
rulesUpdated();
}
void Workspace::rulesUpdated()
{
rulesUpdatedTimer.start( 1000, true );

27
rules.h
View file

@ -40,6 +40,8 @@ class WindowRules
WindowRules();
void update( Client* );
void discardTemporary();
bool contains( const Rules* rule ) const;
void remove( Rules* rule );
Placement::Policy checkPlacement( Placement::Policy placement ) const;
QRect checkGeometry( QRect rect, bool init = false ) const;
// use 'invalidPoint' with checkPosition, unlike QSize() and QRect(), QPoint() is a valid point
@ -84,6 +86,7 @@ class Rules
void write( KConfig& ) const;
bool isEmpty() const;
#ifndef KCMRULES
void discardUsed( bool withdrawn );
bool match( const Client* c ) const;
bool update( Client* );
bool isTemporary() const;
@ -130,7 +133,9 @@ class Rules
DontAffect, // use the default value
Force, // force the given value
Apply, // apply only after initial mapping
Remember // like apply, and remember the value when the window is withdrawn
Remember, // like apply, and remember the value when the window is withdrawn
ApplyNow, // apply immediatelly, then forget the setting
ForceTemporarily // apply and force until the window is withdrawn
};
enum SetRule
{
@ -236,7 +241,8 @@ bool Rules::checkSetRule( SetRule rule, bool init )
{
if( rule > ( SetRule )DontAffect) // Unused or DontAffect
{
if( rule == ( SetRule )Force || init )
if( rule == ( SetRule )Force || rule == ( SetRule ) ApplyNow
|| rule == ( SetRule ) ForceTemporarily || init )
return true;
}
return false;
@ -245,7 +251,7 @@ bool Rules::checkSetRule( SetRule rule, bool init )
inline
bool Rules::checkForceRule( ForceRule rule )
{
return rule == ( ForceRule )Force;
return rule == ( ForceRule )Force || rule == ( ForceRule ) ForceTemporarily;
}
inline
@ -270,6 +276,21 @@ inline
WindowRules::WindowRules()
{
}
inline
bool WindowRules::contains( const Rules* rule ) const
{
return qFind( rules.begin(), rules.end(), rule ) != rules.end();
}
inline
void WindowRules::remove( Rules* rule )
{
QValueVector< Rules* >::Iterator pos = qFind( rules.begin(), rules.end(), rule );
if( pos != rules.end())
rules.erase( pos );
}
#endif
#ifdef NDEBUG

View file

@ -815,7 +815,6 @@ void Workspace::slotSettingsChanged(int category)
Reread settings
*/
KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() );
KWIN_PROCEDURE( ResetupRulesProcedure, cl->setupWindowRules( true ) );
void Workspace::slotReconfigure()
{
@ -873,7 +872,14 @@ void Workspace::slotReconfigure()
}
loadWindowRules();
forEachClient( ResetupRulesProcedure());
for( ClientList::Iterator it = clients.begin();
it != clients.end();
++it )
{
(*it)->setupWindowRules( true );
(*it)->applyWindowRules();
discardUsedWindowRules( *it, false );
}
if (options->resetKompmgr) // need restart
{

View file

@ -211,6 +211,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
SessionInfo* takeSessionInfo( Client* );
WindowRules findWindowRules( const Client*, bool );
void rulesUpdated();
void discardUsedWindowRules( Client* c, bool withdraw );
// dcop interface
void cascadeDesktop();