CT: smart placement code. No! It isn't tested and isn't supposed to work.
One 'if' gets a bad turn. But commit it 'cause I'm reknown for doing stupid things with unbacked-up code. Matthias, I managed to reduce all from 175 to 125 lines and from 4740 chars to 3260. This is what you wanted? Don't worry, kwin compiles and works as before. If somebody finds a way to teleport my office in some other dimension, I finish this tomorrow (that is, today + a couple of sleep hours). If not ... svn path=/trunk/kdebase/kwin/; revision=34034
This commit is contained in:
parent
486f0d604d
commit
f49c7be018
4 changed files with 144 additions and 1 deletions
|
@ -11,6 +11,9 @@ Options::Options()
|
|||
for(i=0; i < KWINCOLORS*2; ++i)
|
||||
cg[i] = NULL;
|
||||
reload();
|
||||
|
||||
//CT
|
||||
placement = Random; //ACHTUNG!! for the moment *only*
|
||||
}
|
||||
|
||||
Options::~Options(){
|
||||
|
|
|
@ -51,6 +51,15 @@ public:
|
|||
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 };
|
||||
PlacementPolicy placement;
|
||||
|
||||
bool focusPolicyIsReasonable() {
|
||||
return focusPolicy == ClickToFocus || focusPolicy == FocusFollowsMouse;
|
||||
}
|
||||
|
|
132
workspace.cpp
132
workspace.cpp
|
@ -838,7 +838,10 @@ void Workspace::showPopup( const QPoint& pos, Client* c)
|
|||
*/
|
||||
void Workspace::doPlacement( Client* c )
|
||||
{
|
||||
if (options->placement == Options::Random)
|
||||
randomPlacement( c );
|
||||
else if (options->placement == Options::Smart)
|
||||
smartPlacement( c );
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -881,6 +884,134 @@ void Workspace::randomPlacement(Client* c){
|
|||
c->move( tx, ty );
|
||||
}
|
||||
|
||||
/*!
|
||||
Place the client \a c according to a really smart placement algorithm :-)
|
||||
*/
|
||||
void Workspace::smartPlacement(Client* c){
|
||||
/*
|
||||
* SmartPlacement by Cristian Tibirna (tibirna@kde.org)
|
||||
* adapted for kwm (16-19jan98) and for kwin (16Nov1999) using (with
|
||||
* permission) ideas from fvwm, authored by
|
||||
* Anthony Martin (amartin@engr.csulb.edu).
|
||||
*/
|
||||
|
||||
const int none = 0, least = -1, wrong = -2; // overlap types
|
||||
int overlap, min_overlap;
|
||||
int x_optimal, y_optimal;
|
||||
int possible;
|
||||
|
||||
int cxl, cxr, cyt, cyb; //temp coords
|
||||
int xl, xr, yt, yb; //temp coords
|
||||
|
||||
// get the maximum allowed windows space
|
||||
QRect maxRect = clientArea();
|
||||
int x = maxRect.left(), y = maxRect.top();
|
||||
|
||||
//client gabarit
|
||||
int ch = c->height(), cw = c->width();
|
||||
|
||||
//loop over possible positions
|
||||
do {
|
||||
|
||||
//test if enough room in x and y directions
|
||||
if ( y + ch > maxRect.bottom() )
|
||||
overlap = -1;
|
||||
else if( x + cw > maxRect.right() )
|
||||
overlap = -2;
|
||||
else {
|
||||
overlap = none; //initialize
|
||||
|
||||
cxl = x; cxr = x + cw;
|
||||
cyt = y; cyb = y + ch;
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l ) {
|
||||
if((*l)->isOnDesktop(currentDesktop()) ||
|
||||
!(*l)->isIconified() || !((*l) == c) ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
|
||||
//if windows overlap, calc the overlapping
|
||||
if((cxl < xr) && (cxr > xl) &&
|
||||
(cyt < yb) && (cyb > yt)) {
|
||||
xl = QMAX(cxl, xl); xr = QMIN(cxr, xr);
|
||||
yt = QMAX(cyt, yt); yb = QMIN(cyb, yb);
|
||||
overlap += (xr - xl) * (yb - yt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// really need to loop? test if there's any overlap
|
||||
if ( overlap > none ) {
|
||||
|
||||
possible = maxRect.right();
|
||||
if ( possible - cw > x) possible -= cw;
|
||||
|
||||
// compare to the position of each client on the current desk
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l) {
|
||||
|
||||
if ( (*l)->isOnDesktop(currentDesktop()) ||
|
||||
!(*l)->isIconified() || !((*l) == c) ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
|
||||
// if not enough room above or under the current tested client
|
||||
// determine the first non-overlapped x position
|
||||
if( y < yb && yt < ch + y ) {
|
||||
|
||||
if( yb > x )
|
||||
possible = possible < yb ? possible : yb;
|
||||
|
||||
if( xl - cw > x )
|
||||
possible = possible < xl - cw ? possible : xl - cw;
|
||||
}
|
||||
}
|
||||
x = possible;
|
||||
}
|
||||
}
|
||||
|
||||
// ... else => not enough x dimension (overlap was -2)
|
||||
else if (overlap == wrong) {
|
||||
x = maxRect.left();
|
||||
|
||||
possible = maxRect.bottom();
|
||||
|
||||
if(possible - ch > y) possible -= ch;
|
||||
|
||||
//test the position of each window on current desk
|
||||
//07mar98. fixed bug which made iconified windows avoided as if visible
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l) {
|
||||
if( (*l)->isOnDesktop( currentDesktop() ) ||
|
||||
!((*l) == c) || !c->isIconified() ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
|
||||
if( yb > y)
|
||||
possible = possible < yb ? possible : yb;
|
||||
|
||||
if( yt - ch > y )
|
||||
possible = possible < yt - ch ? possible : yt - ch;
|
||||
}
|
||||
y = possible;
|
||||
}
|
||||
}
|
||||
|
||||
min_overlap = overlap;
|
||||
x_optimal = x;
|
||||
y_optimal = y;
|
||||
|
||||
}
|
||||
while((overlap != none) && (overlap != least));
|
||||
|
||||
// place the window
|
||||
c->move( x_optimal, y_optimal );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -933,7 +1064,6 @@ void Workspace::raiseClient( Client* c )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Private auxiliary function used in raiseClient()
|
||||
*/
|
||||
|
|
|
@ -133,6 +133,7 @@ private:
|
|||
|
||||
void raiseTransientsOf( ClientList& safeset, Client* c );
|
||||
void randomPlacement(Client* c);
|
||||
void smartPlacement(Client* c);
|
||||
|
||||
void focusToNull();
|
||||
Client* desktop_client;
|
||||
|
|
Loading…
Reference in a new issue