KWin rules - override placement.
svn path=/trunk/kdebase/kwin/; revision=316411
This commit is contained in:
parent
a0384cdd8a
commit
2f7d3203aa
6 changed files with 112 additions and 37 deletions
|
@ -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 );
|
||||||
|
|
||||||
|
|
11
options.h
11
options.h
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
// ********************
|
// ********************
|
||||||
|
|
24
placement.h
24
placement.h
|
@ -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 );
|
||||||
|
|
29
rules.cpp
29
rules.cpp
|
@ -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
|
||||||
|
|
7
rules.h
7
rules.h
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue