/******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2009 Nikhil Marathe This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "columns.h" #include "client.h" #include "tile.h" #include "lib/kdecoration.h" namespace KWin { // TODO: caching of actually tiled windows // Columns is doing a lot of looping // checking which tiles are actually *tiled* // ( ie. not floating or minimized ) // This can probably be moved to TilingLayout // and cached. But remember to preserve order! Columns::Columns( Workspace *w ) : TilingLayout( w ) , m_leftWidth( 0 ) { } KDecorationDefines::Position Columns::resizeMode( Client *c, KDecorationDefines::Position currentMode ) const { Tile *t = findTile( c ); if( !t ) return currentMode; if( t && t->floating() ) return currentMode; QList tiled( tiles() ); QMutableListIterator i(tiled); while( i.hasNext() ) { Tile *tile = i.next(); if( tile->ignoreGeometry() ) i.remove(); } if( tiled.first() == t && ( currentMode == KDecorationDefines::PositionRight || currentMode == KDecorationDefines::PositionTopRight || currentMode == KDecorationDefines::PositionBottomRight ) ) { return KDecorationDefines::PositionRight; } // in right column so only left resize allowed if( tiled.contains( t ) && ( tiled.first() != t ) && ( currentMode == KDecorationDefines::PositionLeft || currentMode == KDecorationDefines::PositionTopLeft || currentMode == KDecorationDefines::PositionBottomLeft ) ) { return KDecorationDefines::PositionLeft; } return KDecorationDefines::PositionCenter; } bool Columns::clientResized( Client *c, const QRect &moveResizeGeom, const QRect &orig ) { if( TilingLayout::clientResized( c, moveResizeGeom, orig ) ) return true; Tile *t = findTile( c ); QList tiled( tiles() ); QMutableListIterator i(tiled); while( i.hasNext() ) { Tile *tile = i.next(); if( tile->ignoreGeometry() ) i.remove(); } if( tiled.first() == t ) { m_leftWidth = moveResizeGeom.width(); } else { m_leftWidth = layoutArea( t ).width() - moveResizeGeom.width(); } arrange( layoutArea( t ) ); return true; } void Columns::arrange( QRect wgeom ) { QList tiled( tiles() ); QMutableListIterator i(tiled); while( i.hasNext() ) { Tile *t = i.next(); if( t->ignoreGeometry() ) i.remove(); } int n = tiled.length(); if( n < 1 ) return; if( n == 1 ) { tiled.first()->setGeometry( wgeom ); tiled.first()->commit(); return; } // save the original before we mangle it int totalWidth = wgeom.width(); if( m_leftWidth == 0 ) m_leftWidth = wgeom.width() / 2; if( n > 1 ) wgeom.setWidth( m_leftWidth ); tiled.first()->setGeometry( wgeom ); tiled.first()->commit(); wgeom.moveLeft( wgeom.x() + m_leftWidth ); wgeom.setWidth( totalWidth - m_leftWidth ); int ht = wgeom.height()/(n-1); wgeom.setHeight( ht ); int mult = 0; int originalTop = wgeom.y(); for( QList::const_iterator it = ++tiled.constBegin() ; it != tiled.constEnd() ; ++it ) { if( (*it)->floating() ) continue; (*it)->setGeometry( wgeom ); (*it)->commit(); mult++; wgeom.moveTop( originalTop + mult*ht ); } } }