KWin rules - override placement.

svn path=/trunk/kdebase/kwin/; revision=316411
This commit is contained in:
Luboš Luňák 2004-05-31 14:14:10 +00:00
parent a0384cdd8a
commit 2f7d3203aa
6 changed files with 112 additions and 37 deletions

View file

@ -92,12 +92,7 @@ unsigned long Options::updateSettings()
} }
delete gc; delete gc;
val = config->readEntry("Placement","Smart"); placement = Placement::policyFromString( config->readEntry("Placement"), true );
if (val == "Random") placement = Random;
else if (val == "Cascade") placement = Cascade;
else if (val == "Centered") placement = Centered;
else if (val == "ZeroCornered") placement = ZeroCornered;
else placement = Smart;
animateShade = config->readBoolEntry("AnimateShade", TRUE ); animateShade = config->readBoolEntry("AnimateShade", TRUE );

View file

@ -18,6 +18,8 @@ License. See the file "COPYING" for the exact licensing terms.
#include <qstringlist.h> #include <qstringlist.h>
#include <kdecoration_p.h> #include <kdecoration_p.h>
#include "placement.h"
namespace KWinInternal namespace KWinInternal
{ {
@ -140,14 +142,7 @@ class Options : public KDecorationOptions
MoveResizeMode resizeMode; MoveResizeMode resizeMode;
MoveResizeMode moveMode; MoveResizeMode moveMode;
/** Placement::Policy placement;
* Placement policies. How workspace decides the way windows get positioned
* on the screen. The better the policy, the heavier the resource use.
* Normally you don't have to worry. What the WM adds to the startup time
* is nil compared to the creation of the window itself in the memory
*/
enum PlacementPolicy { Random, Smart, Cascade, Centered, ZeroCornered };
PlacementPolicy placement;
bool focusPolicyIsReasonable() bool focusPolicyIsReasonable()
{ {

View file

@ -10,13 +10,13 @@ You can Freely distribute this program under the GNU General Public
License. See the file "COPYING" for the exact licensing terms. License. See the file "COPYING" for the exact licensing terms.
******************************************************************/ ******************************************************************/
#include <qrect.h>
#include "workspace.h" #include "workspace.h"
#include "client.h" #include "client.h"
#include "options.h" #include "options.h"
#include "placement.h" #include "placement.h"
#include "rules.h"
#include <qrect.h>
namespace KWinInternal namespace KWinInternal
{ {
@ -42,6 +42,10 @@ Placement::Placement(Workspace* w)
*/ */
void Placement::place(Client* c, QRect& area ) void Placement::place(Client* c, QRect& area )
{ {
Policy policy = c->rules()->checkPlacement( Default );
if( policy != Default )
return place( c, policy, area );
if( c->isUtility()) if( c->isUtility())
placeUtility(c, area); placeUtility(c, area);
else if( c->isDialog()) else if( c->isDialog())
@ -49,16 +53,29 @@ void Placement::place(Client* c, QRect& area )
else if( c->isSplash()) else if( c->isSplash())
placeOnMainWindow( c, area ); // on mainwindow, if any, otherwise centered placeOnMainWindow( c, area ); // on mainwindow, if any, otherwise centered
else else
placeInternal(c, area); place(c, options->placement, area);
} }
void Placement::placeInternal(Client* c, const QRect& area ) void Placement::place(Client* c, Policy policy, QRect& area )
{ {
if (options->placement == Options::Random) placeAtRandom(c, area); if( policy == Default )
else if (options->placement == Options::Cascade) placeCascaded(c, area); policy = options->placement;
else if (options->placement == Options::Centered) placeCentered(c, area); if( policy == NoPlacement )
else if (options->placement == Options::ZeroCornered) placeZeroCornered(c, area); return;
else placeSmart(c, area); else if (policy == Random)
placeAtRandom(c, area);
else if (policy == Cascade)
placeCascaded(c, area);
else if (policy == Centered)
placeCentered(c, area);
else if (policy == ZeroCornered)
placeZeroCornered(c, area);
else if (policy == UnderMouse)
placeUnderMouse(c, area);
else if (policy == OnMainWindow)
placeOnMainWindow(c, area);
else
placeSmart(c, area);
} }
/*! /*!
@ -395,7 +412,7 @@ void Placement::placeUtility(Client* c, QRect& area )
// if there's not enough place outside the mainwindow, it should prefer // if there's not enough place outside the mainwindow, it should prefer
// top-right corner // top-right corner
// use the default placement for now // use the default placement for now
placeInternal( c, area ); place( c, Default, area );
} }
@ -467,6 +484,38 @@ QRect Placement::checkArea( const Client* c, const QRect& area )
return area; return area;
} }
Placement::Policy Placement::policyFromString( const QString& policy, bool no_special )
{
if( policy == "NoPlacement" )
return NoPlacement;
else if( policy == "Default" && !no_special )
return Default;
else if( policy == "Random" )
return Random;
else if( policy == "Cascade" )
return Cascade;
else if( policy == "Centered" )
return Centered;
else if( policy == "ZeroCornered" )
return ZeroCornered;
else if( policy == "UnderMouse" && !no_special)
return UnderMouse;
else if( policy == "OnMainWindow" && !no_special)
return OnMainWindow;
else
return Smart;
}
const char* Placement::policyToString( Policy policy )
{
const char* const policies[] =
{ "NoPlacement", "Default", "Random", "Smart", "Cascade", "Centered",
"ZeroCornered", "UnderMouse", "OnMainWindow" };
assert( policy < int( sizeof( policies ) / sizeof( policies[ 0 ] )));
return policies[ policy ];
}
// ******************** // ********************
// Workspace // Workspace
// ******************** // ********************

View file

@ -38,9 +38,31 @@ class Placement
void placeDialog (Client* c, QRect& area ); void placeDialog (Client* c, QRect& area );
void placeUtility (Client* c, QRect& area ); void placeUtility (Client* c, QRect& area );
/**
* Placement policies. How workspace decides the way windows get positioned
* on the screen. The better the policy, the heavier the resource use.
* Normally you don't have to worry. What the WM adds to the startup time
* is nil compared to the creation of the window itself in the memory
*/
enum Policy
{
NoPlacement, // not really a placement
Default, // special, means to use the global default
Random,
Smart,
Cascade,
Centered,
ZeroCornered,
UnderMouse, // special
OnMainWindow // special
};
static Policy policyFromString( const QString& policy, bool no_special );
static const char* policyToString( Policy policy );
private: private:
void placeInternal(Client* c, const QRect& area ); void place(Client* c, Policy policy, QRect& area);
void placeUnderMouse(Client* c, QRect& area ); void placeUnderMouse(Client* c, QRect& area );
void placeOnMainWindow(Client* c, QRect& area ); void placeOnMainWindow(Client* c, QRect& area );
QRect checkArea( const Client*c, const QRect& area ); QRect checkArea( const Client*c, const QRect& area );

View file

@ -29,6 +29,7 @@ WindowRules::WindowRules()
, extraroleregexp( false ) , extraroleregexp( false )
, clientmachineregexp( false ) , clientmachineregexp( false )
, types( NET::AllTypesMask ) , types( NET::AllTypesMask )
, placementrule( DontCareRule )
, desktoprule( DontCareRule ) , desktoprule( DontCareRule )
, typerule( DontCareRule ) , typerule( DontCareRule )
, aboverule( DontCareRule ) , aboverule( DontCareRule )
@ -50,6 +51,8 @@ WindowRules::WindowRules( KConfig& cfg )
clientmachine = cfg.readEntry( "clientmachine" ).lower().latin1(); clientmachine = cfg.readEntry( "clientmachine" ).lower().latin1();
clientmachineregexp = cfg.readBoolEntry( "clientmachineregexp" ); clientmachineregexp = cfg.readBoolEntry( "clientmachineregexp" );
types = cfg.readUnsignedLongNumEntry( "types", NET::AllTypesMask ); types = cfg.readUnsignedLongNumEntry( "types", NET::AllTypesMask );
placement = Placement::policyFromString( cfg.readEntry( "placement" ), false );
placementrule = readRule( cfg, "placementrule" );
desktop = cfg.readNumEntry( "desktop" ); desktop = cfg.readNumEntry( "desktop" );
desktoprule = readRule( cfg, "desktoprule" ); desktoprule = readRule( cfg, "desktoprule" );
type = readType( cfg, "type" ); type = readType( cfg, "type" );
@ -73,10 +76,10 @@ WindowRules::WindowRules( KConfig& cfg )
cfg.deleteEntry( #var "regexp" ); \ cfg.deleteEntry( #var "regexp" ); \
} }
#define WRITE_SET_RULE( var ) \ #define WRITE_SET_RULE( var, func ) \
if( var##rule != DontCareRule ) \ if( var##rule != DontCareRule ) \
{ \ { \
cfg.writeEntry( #var, var ); \ cfg.writeEntry( #var, func ( var )); \
cfg.writeEntry( #var "rule", var##rule ); \ cfg.writeEntry( #var "rule", var##rule ); \
} \ } \
else \ else \
@ -103,10 +106,11 @@ void WindowRules::write( KConfig& cfg ) const
WRITE_MATCH_STRING( extrarole, (const char*) ); WRITE_MATCH_STRING( extrarole, (const char*) );
WRITE_MATCH_STRING( clientmachine, (const char*) ); WRITE_MATCH_STRING( clientmachine, (const char*) );
WRITE_WITH_DEFAULT( types, NET::AllTypesMask ); WRITE_WITH_DEFAULT( types, NET::AllTypesMask );
WRITE_SET_RULE( desktop ); WRITE_SET_RULE( placement, Placement::policyToString );
WRITE_SET_RULE( type ); WRITE_SET_RULE( desktop, );
WRITE_SET_RULE( above ); WRITE_SET_RULE( type, );
WRITE_SET_RULE( below ); WRITE_SET_RULE( above, );
WRITE_SET_RULE( below, );
} }
#undef WRITE_MATCH_STRING #undef WRITE_MATCH_STRING
@ -194,25 +198,30 @@ void WindowRules::update( Client* c )
below = c->keepBelow(); below = c->keepBelow();
} }
Placement::Policy WindowRules::checkPlacement( Placement::Policy placement ) const
{
return checkForceRule( placementrule ) ? this->placement : placement;
}
int WindowRules::checkDesktop( int req_desktop, bool init ) const int WindowRules::checkDesktop( int req_desktop, bool init ) const
{ {
// TODO chaining? // TODO chaining?
return checkRule( desktoprule, init ) ? desktop : req_desktop; return checkRule( desktoprule, init ) ? this->desktop : req_desktop;
} }
bool WindowRules::checkKeepAbove( bool req_above, bool init ) const bool WindowRules::checkKeepAbove( bool req_above, bool init ) const
{ {
return checkRule( aboverule, init ) ? above : req_above; return checkRule( aboverule, init ) ? this->above : req_above;
} }
bool WindowRules::checkKeepBelow( bool req_below, bool init ) const bool WindowRules::checkKeepBelow( bool req_below, bool init ) const
{ {
return checkRule( belowrule, init ) ? below : req_below; return checkRule( belowrule, init ) ? this->below : req_below;
} }
NET::WindowType WindowRules::checkType( NET::WindowType req_type ) const NET::WindowType WindowRules::checkType( NET::WindowType req_type ) const
{ {
return checkForceRule( typerule ) ? type : req_type; return checkForceRule( typerule ) ? this->type : req_type;
} }
// Client // Client

View file

@ -14,6 +14,8 @@ License. See the file "COPYING" for the exact licensing terms.
#include <qstring.h> #include <qstring.h>
#include <netwm_def.h> #include <netwm_def.h>
#include "placement.h"
class KConfig; class KConfig;
namespace KWinInternal namespace KWinInternal
@ -38,10 +40,11 @@ class WindowRules
void write( KConfig& ) const; void write( KConfig& ) const;
void update( Client* ); void update( Client* );
bool match( const Client* c ) const; bool match( const Client* c ) const;
Placement::Policy checkPlacement( Placement::Policy placement ) const;
int checkDesktop( int desktop, bool init = false ) const; int checkDesktop( int desktop, bool init = false ) const;
NET::WindowType checkType( NET::WindowType type ) const;
bool checkKeepAbove( bool above, bool init = false ) const; bool checkKeepAbove( bool above, bool init = false ) const;
bool checkKeepBelow( bool above, bool init = false ) const; bool checkKeepBelow( bool above, bool init = false ) const;
NET::WindowType checkType( NET::WindowType type ) const;
private: private:
static SettingRule readRule( KConfig&, const QString& key ); static SettingRule readRule( KConfig&, const QString& key );
static SettingRule readForceRule( KConfig&, const QString& key ); static SettingRule readForceRule( KConfig&, const QString& key );
@ -60,6 +63,8 @@ class WindowRules
QCString clientmachine; QCString clientmachine;
bool clientmachineregexp; bool clientmachineregexp;
unsigned long types; // types for matching unsigned long types; // types for matching
Placement::Policy placement;
SettingRule placementrule;
int desktop; int desktop;
SettingRule desktoprule; SettingRule desktoprule;
NET::WindowType type; // type for setting NET::WindowType type; // type for setting