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;
val = config->readEntry("Placement","Smart");
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;
placement = Placement::policyFromString( config->readEntry("Placement"), 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 <kdecoration_p.h>
#include "placement.h"
namespace KWinInternal
{
@ -140,14 +142,7 @@ class Options : public KDecorationOptions
MoveResizeMode resizeMode;
MoveResizeMode moveMode;
/**
* 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;
Placement::Policy placement;
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.
******************************************************************/
#include <qrect.h>
#include "workspace.h"
#include "client.h"
#include "options.h"
#include "placement.h"
#include <qrect.h>
#include "rules.h"
namespace KWinInternal
{
@ -42,6 +42,10 @@ Placement::Placement(Workspace* w)
*/
void Placement::place(Client* c, QRect& area )
{
Policy policy = c->rules()->checkPlacement( Default );
if( policy != Default )
return place( c, policy, area );
if( c->isUtility())
placeUtility(c, area);
else if( c->isDialog())
@ -49,16 +53,29 @@ void Placement::place(Client* c, QRect& area )
else if( c->isSplash())
placeOnMainWindow( c, area ); // on mainwindow, if any, otherwise centered
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);
else if (options->placement == Options::Cascade) placeCascaded(c, area);
else if (options->placement == Options::Centered) placeCentered(c, area);
else if (options->placement == Options::ZeroCornered) placeZeroCornered(c, area);
else placeSmart(c, area);
if( policy == Default )
policy = options->placement;
if( policy == NoPlacement )
return;
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
// top-right corner
// 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;
}
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
// ********************

View file

@ -38,9 +38,31 @@ class Placement
void placeDialog (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:
void placeInternal(Client* c, const QRect& area );
void place(Client* c, Policy policy, QRect& area);
void placeUnderMouse(Client* c, QRect& area );
void placeOnMainWindow(Client* c, QRect& area );
QRect checkArea( const Client*c, const QRect& area );

View file

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

View file

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