KWin rules - position and size.
Forcing position doesn't work yet, and forcing size needs more testing. svn path=/trunk/kdebase/kwin/; revision=316414
This commit is contained in:
parent
a114e9acc3
commit
7eadd6463f
7 changed files with 108 additions and 27 deletions
21
client.cpp
21
client.cpp
|
@ -175,7 +175,7 @@ void Client::releaseWindow( bool on_shutdown )
|
|||
{
|
||||
if (moveResizeMode)
|
||||
leaveMoveResize();
|
||||
updateWindowRules();
|
||||
finishWindowRules();
|
||||
setModal( false ); // otherwise its mainwindow wouldn't get focus
|
||||
hidden = true; // so that it's not considered visible anymore (can't use hideClient(), it would set flags)
|
||||
if( !on_shutdown )
|
||||
|
@ -223,7 +223,7 @@ void Client::destroyClient()
|
|||
{
|
||||
if (moveResizeMode)
|
||||
leaveMoveResize();
|
||||
updateWindowRules();
|
||||
finishWindowRules();
|
||||
++block_geometry;
|
||||
setModal( false );
|
||||
hidden = true; // so that it's not considered visible anymore
|
||||
|
@ -292,9 +292,9 @@ void Client::destroyDecoration()
|
|||
int save_workarea_diff_x = workarea_diff_x;
|
||||
int save_workarea_diff_y = workarea_diff_y;
|
||||
if( !isShade())
|
||||
plainResize( clientSize(), ForceGeometrySet );
|
||||
plainResize( sizeForClientSize( clientSize()), ForceGeometrySet );
|
||||
else
|
||||
plainResize( QSize( clientSize().width(), 0 ), ForceGeometrySet );
|
||||
plainResize( sizeForClientSize( QSize( clientSize().width(), 0 ), SizemodeShaded ), ForceGeometrySet );
|
||||
move( grav );
|
||||
workarea_diff_x = save_workarea_diff_x;
|
||||
workarea_diff_y = save_workarea_diff_y;
|
||||
|
@ -1499,17 +1499,6 @@ bool Client::wantsInput() const
|
|||
return input || Ptakefocus;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether the window is moveable or has a fixed
|
||||
position. !isMovable implies !isResizable.
|
||||
*/
|
||||
bool Client::isMovable() const
|
||||
{
|
||||
return motif_may_move && !isFullScreen() &&
|
||||
( !isSpecialWindow() || isOverride() || isSplash() || isToolbar()) && // allow moving of splashscreens :)
|
||||
( maximizeMode() != MaximizeFull || options->moveResizeMaximizedWindows() );
|
||||
}
|
||||
|
||||
bool Client::isDesktop() const
|
||||
{
|
||||
return windowType() == NET::Desktop;
|
||||
|
@ -1628,7 +1617,7 @@ void Client::setCursor( Position m )
|
|||
setCursor( sizeHorCursor );
|
||||
break;
|
||||
default:
|
||||
if( buttonDown )
|
||||
if( buttonDown && isMovable())
|
||||
setCursor( sizeAllCursor );
|
||||
else
|
||||
setCursor( arrowCursor );
|
||||
|
|
3
client.h
3
client.h
|
@ -344,8 +344,9 @@ private slots:
|
|||
QString readName() const;
|
||||
void setCaption( const QString& s, bool force = false );
|
||||
bool hasTransientInternal( const Client* c, bool indirect, ConstClientList& set ) const;
|
||||
void initWindowRules();
|
||||
void setupWindowRules();
|
||||
void updateWindowRules();
|
||||
void finishWindowRules();
|
||||
|
||||
void updateWorkareaDiffs();
|
||||
void checkDirection( int new_diff, int old_diff, QRect& rect, const QRect& area );
|
||||
|
|
46
geometry.cpp
46
geometry.cpp
|
@ -959,9 +959,12 @@ QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode ) const
|
|||
h += xSizeHint.base_height;
|
||||
}
|
||||
|
||||
w += border_left + border_right;
|
||||
h += border_top + border_bottom;
|
||||
QSize ret = rules()->checkSize( QSize( w, h ));
|
||||
if ( mode == SizemodeShaded && wsize.height() == 0 )
|
||||
h = 0;
|
||||
return QSize( w + border_left + border_right, h + border_top + border_bottom );
|
||||
ret.setHeight( border_top + border_bottom );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1290,13 +1293,36 @@ void Client::NETMoveResizeWindow( int flags, int x, int y, int width, int height
|
|||
configureRequest( value_mask, x, y, width, height, gravity );
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether the window is moveable or has a fixed
|
||||
position.
|
||||
*/
|
||||
bool Client::isMovable() const
|
||||
{
|
||||
if( !motif_may_move || isFullScreen())
|
||||
return false;
|
||||
if( isSpecialWindow() && !isOverride() && !isSplash() && !isToolbar()) // allow moving of splashscreens :)
|
||||
return false;
|
||||
if( maximizeMode() == MaximizeFull && !options->moveResizeMaximizedWindows() )
|
||||
return false;
|
||||
if( rules()->checkPosition( invalidPoint ) != invalidPoint ) // forced position
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether the window is resizable or has a fixed size.
|
||||
*/
|
||||
bool Client::isResizable() const
|
||||
{
|
||||
if ( !isMovable() || !motif_may_resize || isSplash())
|
||||
return FALSE;
|
||||
if( !motif_may_resize || isFullScreen())
|
||||
return false;
|
||||
if( isSpecialWindow() || isSplash() || isToolbar())
|
||||
return false;
|
||||
if( maximizeMode() == MaximizeFull && !options->moveResizeMaximizedWindows() )
|
||||
return false;
|
||||
if( rules()->checkSize( QSize()).isValid()) // forced size
|
||||
return false;
|
||||
|
||||
QSize min = minSize();
|
||||
QSize max = maxSize();
|
||||
|
@ -1310,7 +1336,7 @@ bool Client::isMaximizable() const
|
|||
{
|
||||
if ( maximizeMode() != MaximizeRestore )
|
||||
return TRUE;
|
||||
if( !isResizable() || isToolbar()) // SELI isToolbar() ?
|
||||
if( !isMovable() || !isResizable() || isToolbar()) // SELI isToolbar() ?
|
||||
return false;
|
||||
QSize max = maxSize();
|
||||
if( max.width() < 32767 || max.height() < 32767 ) // sizes are 16bit with X
|
||||
|
@ -1357,11 +1383,17 @@ void Client::setGeometry( int x, int y, int w, int h, ForceGeometry_t force )
|
|||
// SELI TODO won't this be too expensive?
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::plainResize( int w, int h, ForceGeometry_t force )
|
||||
{ // TODO make this deffered with isResize() ? old kwin did
|
||||
{
|
||||
if( QSize( w, h ) != rules()->checkSize( QSize( w, h )))
|
||||
{
|
||||
kdDebug() << "forced size fail:" << QSize( w,h ) << ":" << rules()->checkSize( QSize( w, h )) << endl;
|
||||
kdDebug() << kdBacktrace() << endl;
|
||||
}
|
||||
if( force == NormalGeometrySet && frame_geometry.size() == QSize( w, h ))
|
||||
return;
|
||||
frame_geometry.setSize( QSize( w, h ));
|
||||
|
@ -1394,6 +1426,7 @@ void Client::plainResize( int w, int h, ForceGeometry_t force )
|
|||
updateShape();
|
||||
updateWorkareaDiffs();
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1410,6 +1443,7 @@ void Client::move( int x, int y, ForceGeometry_t force )
|
|||
{
|
||||
XMoveWindow( qt_xdisplay(), frameId(), x, y );
|
||||
sendSyntheticConfigureNotify();
|
||||
updateWindowRules();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
manage.cpp
12
manage.cpp
|
@ -107,11 +107,11 @@ bool Client::manage( Window w, bool isMapped )
|
|||
ignore_focus_stealing = options->checkIgnoreFocusStealing( this ); // TODO change to rules
|
||||
|
||||
window_role = getStringProperty( w, qt_window_role );
|
||||
// first only read the caption text, so that initWindowRules() can use it for matching,
|
||||
// first only read the caption text, so that setupWindowRules() can use it for matching,
|
||||
// and only then really set the caption using setCaption(), which checks for duplicates etc.
|
||||
// and also relies on rules already existing
|
||||
cap_normal = readName();
|
||||
initWindowRules();
|
||||
setupWindowRules();
|
||||
setCaption( cap_normal, true );
|
||||
|
||||
detectNoBorder();
|
||||
|
@ -269,8 +269,14 @@ bool Client::manage( Window w, bool isMapped )
|
|||
|
||||
updateDecoration( false ); // also gravitates
|
||||
// TODO is CentralGravity right here, when resizing is done after gravitating?
|
||||
plainResize( sizeForClientSize( geom.size()));
|
||||
plainResize( rules()->checkSize( sizeForClientSize( geom.size()), true ));
|
||||
|
||||
QPoint forced_pos = rules()->checkPosition( invalidPoint, true );
|
||||
if( forced_pos != invalidPoint )
|
||||
{
|
||||
move( forced_pos );
|
||||
placementDone = true;
|
||||
}
|
||||
if( !placementDone )
|
||||
{ // placement needs to be after setting size
|
||||
workspace()->place( this, area );
|
||||
|
|
43
rules.cpp
43
rules.cpp
|
@ -30,6 +30,8 @@ WindowRules::WindowRules()
|
|||
, clientmachineregexp( false )
|
||||
, types( NET::AllTypesMask )
|
||||
, placementrule( DontCareRule )
|
||||
, positionrule( DontCareRule )
|
||||
, sizerule( DontCareRule )
|
||||
, minsizerule( DontCareRule )
|
||||
, maxsizerule( DontCareRule )
|
||||
, desktoprule( DontCareRule )
|
||||
|
@ -55,10 +57,20 @@ WindowRules::WindowRules( KConfig& cfg )
|
|||
types = cfg.readUnsignedLongNumEntry( "types", NET::AllTypesMask );
|
||||
placement = Placement::policyFromString( cfg.readEntry( "placement" ), false );
|
||||
placementrule = readRule( cfg, "placementrule" );
|
||||
position = cfg.readPointEntry( "position" );
|
||||
positionrule = readRule( cfg, "positionrule" );
|
||||
size = cfg.readSizeEntry( "size" );
|
||||
sizerule = readRule( cfg, "sizerule" );
|
||||
if( size.isEmpty())
|
||||
sizerule = DontCareRule;
|
||||
minsize = cfg.readSizeEntry( "minsize" );
|
||||
minsizerule = readRule( cfg, "minsizerule" );
|
||||
if( !minsize.isValid())
|
||||
minsizerule = DontCareRule;
|
||||
maxsize = cfg.readSizeEntry( "maxsize" );
|
||||
maxsizerule = readRule( cfg, "maxsizerule" );
|
||||
if( maxsize.isEmpty())
|
||||
maxsizerule = DontCareRule;
|
||||
desktop = cfg.readNumEntry( "desktop" );
|
||||
desktoprule = readRule( cfg, "desktoprule" );
|
||||
type = readType( cfg, "type" );
|
||||
|
@ -113,6 +125,8 @@ void WindowRules::write( KConfig& cfg ) const
|
|||
WRITE_MATCH_STRING( clientmachine, (const char*) );
|
||||
WRITE_WITH_DEFAULT( types, NET::AllTypesMask );
|
||||
WRITE_SET_RULE( placement, Placement::policyToString );
|
||||
WRITE_SET_RULE( position, );
|
||||
WRITE_SET_RULE( size, );
|
||||
WRITE_SET_RULE( minsize, );
|
||||
WRITE_SET_RULE( maxsize, );
|
||||
WRITE_SET_RULE( desktop, );
|
||||
|
@ -198,6 +212,10 @@ bool WindowRules::match( const Client* c ) const
|
|||
void WindowRules::update( Client* c )
|
||||
{
|
||||
// TODO check this setting is for this client ?
|
||||
if( positionrule == RememberRule )
|
||||
position = c->pos();
|
||||
if( sizerule == RememberRule )
|
||||
size = c->size();
|
||||
if( desktoprule == RememberRule )
|
||||
desktop = c->desktop();
|
||||
if( aboverule == RememberRule )
|
||||
|
@ -211,6 +229,23 @@ Placement::Policy WindowRules::checkPlacement( Placement::Policy placement ) con
|
|||
return checkForceRule( placementrule ) ? this->placement : placement;
|
||||
}
|
||||
|
||||
// TODO at to porad jeste kontroluje min/max size , + udelat override pro min/max?
|
||||
QRect WindowRules::checkGeometry( const QRect& rect, bool init ) const
|
||||
{
|
||||
return QRect( checkRule( positionrule, init ) ? this->position : rect.topLeft(),
|
||||
checkRule( sizerule, init ) ? this->size : rect.size());
|
||||
}
|
||||
|
||||
QPoint WindowRules::checkPosition( const QPoint& pos, bool init ) const
|
||||
{
|
||||
return checkRule( positionrule, init ) ? this->position : pos;
|
||||
}
|
||||
|
||||
QSize WindowRules::checkSize( const QSize& s, bool init ) const
|
||||
{
|
||||
return checkRule( sizerule, init ) ? this->size : s;
|
||||
}
|
||||
|
||||
QSize WindowRules::checkMinSize( const QSize& s ) const
|
||||
{
|
||||
return checkForceRule( minsizerule ) ? this->minsize : s;
|
||||
|
@ -244,7 +279,7 @@ NET::WindowType WindowRules::checkType( NET::WindowType req_type ) const
|
|||
|
||||
// Client
|
||||
|
||||
void Client::initWindowRules()
|
||||
void Client::setupWindowRules()
|
||||
{
|
||||
client_rules = workspace()->findWindowRules( this );
|
||||
// check only after getting the rules, because there may be a rule forcing window type
|
||||
|
@ -257,6 +292,12 @@ void Client::updateWindowRules()
|
|||
client_rules->update( this );
|
||||
}
|
||||
|
||||
void Client::finishWindowRules()
|
||||
{
|
||||
updateWindowRules();
|
||||
client_rules = &dummyRules;
|
||||
}
|
||||
|
||||
// Workspace
|
||||
|
||||
WindowRules* Workspace::findWindowRules( const Client* c ) const
|
||||
|
|
8
rules.h
8
rules.h
|
@ -42,6 +42,10 @@ class WindowRules
|
|||
void update( Client* );
|
||||
bool match( const Client* c ) const;
|
||||
Placement::Policy checkPlacement( Placement::Policy placement ) const;
|
||||
QRect checkGeometry( const QRect& rect, bool init = false ) const;
|
||||
// use 'invalidPoint' with checkPosition, unlike QSize() and QRect(), QPoint() is a valid point
|
||||
QPoint checkPosition( const QPoint& pos, bool init = false ) const;
|
||||
QSize checkSize( const QSize& s, bool init = false ) const;
|
||||
QSize checkMinSize( const QSize& s ) const;
|
||||
QSize checkMaxSize( const QSize& s ) const;
|
||||
int checkDesktop( int desktop, bool init = false ) const;
|
||||
|
@ -68,6 +72,10 @@ class WindowRules
|
|||
unsigned long types; // types for matching
|
||||
Placement::Policy placement;
|
||||
SettingRule placementrule;
|
||||
QPoint position;
|
||||
SettingRule positionrule;
|
||||
QSize size;
|
||||
SettingRule sizerule;
|
||||
QSize minsize;
|
||||
SettingRule minsizerule;
|
||||
QSize maxsize;
|
||||
|
|
2
utils.h
2
utils.h
|
@ -35,6 +35,8 @@ const long ClientWinMask = KeyPressMask | KeyReleaseMask |
|
|||
StructureNotifyMask |
|
||||
SubstructureRedirectMask;
|
||||
|
||||
const QPoint invalidPoint( INT_MIN, INT_MIN );
|
||||
|
||||
class Client;
|
||||
class Group;
|
||||
class Options;
|
||||
|
|
Loading…
Reference in a new issue