more reasonable focus handling when switching desktops

svn path=/trunk/kdebase/kwin/; revision=34472
This commit is contained in:
Matthias Ettrich 1999-11-20 13:51:29 +00:00
parent 52d957df8e
commit 4bc6ce23fb

View file

@ -244,7 +244,7 @@ bool Workspace::workspaceEvent( XEvent * e )
if ( removeDockwin( e->xunmap.window ) ) if ( removeDockwin( e->xunmap.window ) )
return TRUE; return TRUE;
if ( e->xunmap.event == root ) { if ( e->xunmap.event == root ) {
// keep track of map/unmap for own own windows to avoid // keep track of map/unmap for own own windows to avoid
// race conditions // race conditions
c = findClientWidthId( e->xunmap.window ); c = findClientWidthId( e->xunmap.window );
@ -255,7 +255,7 @@ bool Workspace::workspaceEvent( XEvent * e )
if ( e->xunmap.event != e->xunmap.window ) // hide wm typical event from Qt if ( e->xunmap.event != e->xunmap.window ) // hide wm typical event from Qt
return TRUE; return TRUE;
case MapNotify: case MapNotify:
if ( e->xunmap.event == root ) { if ( e->xunmap.event == root ) {
// keep track of map/unmap for own own windows to avoid // keep track of map/unmap for own own windows to avoid
// race conditions // race conditions
c = findClientWidthId( e->xmap.window ); c = findClientWidthId( e->xmap.window );
@ -922,7 +922,7 @@ void Workspace::smartPlacement(Client* c){
QRect maxRect = clientArea(); QRect maxRect = clientArea();
int x = maxRect.left(), y = maxRect.top(); int x = maxRect.left(), y = maxRect.top();
x_optimal = x; y_optimal = y; x_optimal = x; y_optimal = y;
//client gabarit //client gabarit
int ch = c->height(), cw = c->width(); int ch = c->height(), cw = c->width();
@ -933,21 +933,21 @@ void Workspace::smartPlacement(Client* c){
//test if enough room in x and y directions //test if enough room in x and y directions
if ( y + ch > maxRect.bottom() ) if ( y + ch > maxRect.bottom() )
overlap = h_wrong; // this throws the algorithm to an exit overlap = h_wrong; // this throws the algorithm to an exit
else if( x + cw > maxRect.right() ) else if( x + cw > maxRect.right() )
overlap = w_wrong; overlap = w_wrong;
else { else {
overlap = none; //initialize overlap = none; //initialize
cxl = x; cxr = x + cw; cxl = x; cxr = x + cw;
cyt = y; cyb = y + ch; cyt = y; cyb = y + ch;
QValueList<Client*>::ConstIterator l; QValueList<Client*>::ConstIterator l;
for(l = clients.begin(); l != clients.end() ; ++l ) { for(l = clients.begin(); l != clients.end() ; ++l ) {
if((*l)->isOnDesktop(currentDesktop()) && (*l) != desktop_client && if((*l)->isOnDesktop(currentDesktop()) && (*l) != desktop_client &&
!(*l)->isIconified() && (*l) != c ) { !(*l)->isIconified() && (*l) != c ) {
xl = (*l)->x(); yt = (*l)->y(); xl = (*l)->x(); yt = (*l)->y();
xr = xl + (*l)->height(); yb = yt + (*l)->width(); xr = xl + (*l)->height(); yb = yt + (*l)->width();
//if windows overlap, calc the overall overlapping //if windows overlap, calc the overall overlapping
if((cxl < xr) && (cxr > xl) && if((cxl < xr) && (cxr > xl) &&
(cyt < yb) && (cyb > yt)) { (cyt < yb) && (cyb > yt)) {
@ -979,10 +979,10 @@ void Workspace::smartPlacement(Client* c){
// really need to loop? test if there's any overlap // really need to loop? test if there's any overlap
if ( overlap > none ) { if ( overlap > none ) {
possible = maxRect.right(); possible = maxRect.right();
if ( possible - cw > x) possible -= cw; if ( possible - cw > x) possible -= cw;
// compare to the position of each client on the current desk // compare to the position of each client on the current desk
QValueList<Client*>::ConstIterator l; QValueList<Client*>::ConstIterator l;
for(l = clients.begin(); l != clients.end() ; ++l) { for(l = clients.begin(); l != clients.end() ; ++l) {
@ -992,42 +992,42 @@ void Workspace::smartPlacement(Client* c){
xl = (*l)->x(); yt = (*l)->y(); xl = (*l)->x(); yt = (*l)->y();
xr = xl + (*l)->height(); yb = yt + (*l)->width(); xr = xl + (*l)->height(); yb = yt + (*l)->width();
// if not enough room above or under the current tested client // if not enough room above or under the current tested client
// determine the first non-overlapped x position // determine the first non-overlapped x position
if( y < yb && yt < ch + y ) { if( y < yb && yt < ch + y ) {
if( yb > x ) if( yb > x )
possible = possible < yb ? possible : yb; possible = possible < yb ? possible : yb;
if( xl - cw > x ) if( xl - cw > x )
possible = possible < xl - cw ? possible : xl - cw; possible = possible < xl - cw ? possible : xl - cw;
} }
} }
x = possible; x = possible;
} }
} }
// ... else ==> not enough x dimension (overlap was wrong on horizontal) // ... else ==> not enough x dimension (overlap was wrong on horizontal)
else if ( overlap == w_wrong ) { else if ( overlap == w_wrong ) {
x = maxRect.left(); x = maxRect.left();
possible = maxRect.bottom(); possible = maxRect.bottom();
if ( possible - ch > y ) possible -= ch; if ( possible - ch > y ) possible -= ch;
//test the position of each window on current desk //test the position of each window on current desk
QValueList<Client*>::ConstIterator l; QValueList<Client*>::ConstIterator l;
for( l = clients.begin(); l != clients.end() ; ++l ) { for( l = clients.begin(); l != clients.end() ; ++l ) {
if( (*l)->isOnDesktop( currentDesktop() ) && (*l) != desktop_client && if( (*l)->isOnDesktop( currentDesktop() ) && (*l) != desktop_client &&
(*l) != c && !c->isIconified() ) { (*l) != c && !c->isIconified() ) {
xl = (*l)->x(); yt = (*l)->y(); xl = (*l)->x(); yt = (*l)->y();
xr = xl + (*l)->height(); yb = yt + (*l)->width(); xr = xl + (*l)->height(); yb = yt + (*l)->width();
if( yb > y) if( yb > y)
possible = possible < yb ? possible : yb; possible = possible < yb ? possible : yb;
if( yt - ch > y ) if( yt - ch > y )
possible = possible < yt - ch ? possible : yt - ch; possible = possible < yt - ch ? possible : yt - ch;
} }
y = possible; y = possible;
@ -1035,7 +1035,7 @@ void Workspace::smartPlacement(Client* c){
} }
} }
while( overlap != none && overlap != h_wrong ); while( overlap != none && overlap != h_wrong );
// place the window // place the window
c->move( x_optimal, y_optimal ); c->move( x_optimal, y_optimal );
@ -1043,7 +1043,7 @@ void Workspace::smartPlacement(Client* c){
/*! /*!
Place windows in a cascading order, remembering positions for each desktop Place windows in a cascading order, remembering positions for each desktop
*/ */
void Workspace::cascadePlacement (Client* c, bool re_init) { void Workspace::cascadePlacement (Client* c, bool re_init) {
/* cascadePlacement by Cristian Tibirna (tibirna@kde.org) (30Jan98) /* cascadePlacement by Cristian Tibirna (tibirna@kde.org) (30Jan98)
*/ */
@ -1052,12 +1052,12 @@ void Workspace::cascadePlacement (Client* c, bool re_init) {
int xp, yp; int xp, yp;
//CT how do I get from the 'Client' class the size that NW squarish "handle" //CT how do I get from the 'Client' class the size that NW squarish "handle"
int delta_x = 24; int delta_x = 24;
int delta_y = 24; int delta_y = 24;
int d = currentDesktop() - 1; int d = currentDesktop() - 1;
// get the maximum allowed windows space and desk's origin // get the maximum allowed windows space and desk's origin
// (CT 20Nov1999 - is this common to all desktops?) // (CT 20Nov1999 - is this common to all desktops?)
QRect maxRect = clientArea(); QRect maxRect = clientArea();
@ -1093,17 +1093,17 @@ void Workspace::cascadePlacement (Client* c, bool re_init) {
if ( cci[d].pos.x() != X && cci[d].pos.y() != Y ) { if ( cci[d].pos.x() != X && cci[d].pos.y() != Y ) {
if ( xp != X && yp == Y ) xp = delta_x * (++(cci[d].col)); if ( xp != X && yp == Y ) xp = delta_x * (++(cci[d].col));
if ( yp != Y && xp == X ) yp = delta_y * (++(cci[d].row)); if ( yp != Y && xp == X ) yp = delta_y * (++(cci[d].row));
// last resort: if still doesn't fit, smart place it // last resort: if still doesn't fit, smart place it
if ( ((xp + cw) > W - X) || ((yp + ch) > H - Y) ) { if ( ((xp + cw) > W - X) || ((yp + ch) > H - Y) ) {
smartPlacement(c); smartPlacement(c);
return; return;
} }
} }
// place the window // place the window
c->move( QPoint( xp, yp ) ); c->move( QPoint( xp, yp ) );
// new position // new position
cci[d].pos = QPoint( xp + delta_x, yp + delta_y ); cci[d].pos = QPoint( xp + delta_x, yp + delta_y );
} }
@ -1225,9 +1225,8 @@ void Workspace::setCurrentDesktop( int new_desktop ){
} }
for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) { for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
if ( (*it)->isOnDesktop( new_desktop ) ) { if ( (*it)->isOnDesktop( new_desktop ) && !(*it)->isIconified() ) {
(*it)->show(); (*it)->show();
//XMapWindow( qt_xdisplay(), (*it)->winId() );
} }
} }
@ -1237,6 +1236,28 @@ void Workspace::setCurrentDesktop( int new_desktop ){
atoms->net_current_desktop, XA_CARDINAL, 32, atoms->net_current_desktop, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&current_desktop, 1); PropModeReplace, (unsigned char *)&current_desktop, 1);
// try to restore the focus on this desktop
Client* c = active_client?active_client:previousClient(0);
Client* stop = c;
while ( c && !c->isVisible() ) {
c = previousClient( c );
if ( c == stop )
break;
}
if ( !c || !c->isVisible() ) {
// there's no suitable client in the focus chain. Try to find any other client then.
for ( ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it) {
if ( (*it)->isVisible() ) {
c = *it;
break;
}
}
}
if ( c && c->isVisible() )
requestFocus( c );
QApplication::syncX(); QApplication::syncX();
KWM::switchToDesktop( current_desktop ); // ### compatibility KWM::switchToDesktop( current_desktop ); // ### compatibility
} }