Tiling is here!
This commit merges the kwin-tiling branch. Ideally it shouldn't break anything and add a few features ;-) It was applied as a patch. Do not attempt to merge the branch directly, it has a few issues. This feature is currently experimental, although it hasn't crashed in quite a long time. It lacks some features and probably leaks some memory. Fixes will be on the way. Season Of KDE 2009 project by Nikhil Marathe svn path=/trunk/KDE/kdebase/workspace/; revision=1118677
This commit is contained in:
parent
d6861e06e5
commit
5fc7e93d69
33 changed files with 2883 additions and 593 deletions
|
@ -105,8 +105,25 @@ set(kwin_KDEINIT_SRCS
|
|||
compositingprefs.cpp
|
||||
desktoplayout.cpp
|
||||
paintredirector.cpp
|
||||
tile.cpp
|
||||
tiling.cpp
|
||||
tilinglayout.cpp
|
||||
tilinglayoutfactory.cpp
|
||||
|
||||
# tiling layouts
|
||||
# spiral
|
||||
#tilinglayouts/spiral/spiralfactory.cpp
|
||||
tilinglayouts/spiral/spiral.cpp
|
||||
|
||||
# columns
|
||||
#tilinglayouts/columns/columnsfactory.cpp
|
||||
tilinglayouts/columns/columns.cpp
|
||||
|
||||
# floating
|
||||
tilinglayouts/floating/floating.cpp
|
||||
)
|
||||
|
||||
add_subdirectory( tilinglayouts )
|
||||
qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.xml workspace.h KWin::Workspace )
|
||||
|
||||
|
||||
|
|
|
@ -259,6 +259,9 @@ void Workspace::setActiveClient( Client* c, allowed_t )
|
|||
updateColormap();
|
||||
if( effects )
|
||||
static_cast<EffectsHandlerImpl*>(effects)->windowActivated( active_client ? active_client->effectWindow() : NULL );
|
||||
|
||||
if( tilingMode() )
|
||||
notifyWindowActivated( active_client );
|
||||
--set_active_client_recursion;
|
||||
}
|
||||
|
||||
|
|
|
@ -895,6 +895,9 @@ void Client::minimize( bool avoid_animation )
|
|||
if( effects && !avoid_animation ) // TODO: Shouldn't it tell effects at least about the change?
|
||||
static_cast<EffectsHandlerImpl*>(effects)->windowMinimized( effectWindow());
|
||||
|
||||
// when tiling, request a rearrangement
|
||||
workspace()->notifyWindowMinimizeToggled( this );
|
||||
|
||||
// Update states of all other windows in this group
|
||||
if( clientGroup() )
|
||||
clientGroup()->updateStates( this );
|
||||
|
@ -911,9 +914,13 @@ void Client::unminimize( bool avoid_animation )
|
|||
updateAllowedActions();
|
||||
workspace()->updateMinimizedOfTransients( this );
|
||||
updateWindowRules();
|
||||
workspace()->updateAllTiles();
|
||||
if( effects && !avoid_animation )
|
||||
static_cast<EffectsHandlerImpl*>( effects )->windowUnminimized( effectWindow() );
|
||||
|
||||
// when tiling, request a rearrangement
|
||||
workspace()->notifyWindowMinimizeToggled( this );
|
||||
|
||||
// Update states of all other windows in this group
|
||||
if( clientGroup() )
|
||||
clientGroup()->updateStates( this );
|
||||
|
|
66
geometry.cpp
66
geometry.cpp
|
@ -2155,6 +2155,7 @@ void Client::move( int x, int y, ForceGeometry_t force )
|
|||
workspace()->checkActiveScreen( this );
|
||||
workspace()->updateStackingOrder();
|
||||
workspace()->checkUnredirect();
|
||||
workspace()->notifyWindowMove( this, moveResizeGeom, initialMoveResizeGeom );
|
||||
// client itself is not damaged
|
||||
const QRect deco_rect = decorationRect().translated( geom.x(), geom.y() );
|
||||
addWorkspaceRepaint( deco_rect_before_block );
|
||||
|
@ -2807,15 +2808,56 @@ bool Client::startMoveResize()
|
|||
|
||||
void Client::finishMoveResize( bool cancel )
|
||||
{
|
||||
// store for notification
|
||||
bool wasResize = isResize();
|
||||
bool wasMove = isMove();
|
||||
|
||||
leaveMoveResize();
|
||||
if( isElectricBorderMaximizing() )
|
||||
|
||||
if( workspace()->tilingMode() )
|
||||
{
|
||||
cancel = true;
|
||||
if( wasResize )
|
||||
workspace()->notifyWindowResizeDone( this, moveResizeGeom, initialMoveResizeGeom, cancel );
|
||||
else if( wasMove )
|
||||
workspace()->notifyWindowMoveDone( this, moveResizeGeom, initialMoveResizeGeom, cancel );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cancel )
|
||||
setGeometry( initialMoveResizeGeom );
|
||||
else
|
||||
setGeometry( moveResizeGeom );
|
||||
}
|
||||
if( cancel )
|
||||
setGeometry( initialMoveResizeGeom );
|
||||
|
||||
if( isElectricBorderMaximizing() )
|
||||
{
|
||||
cancel = true;
|
||||
}
|
||||
if( isElectricBorderMaximizing() )
|
||||
{
|
||||
switch( electricMode )
|
||||
{
|
||||
case ElectricMaximizeMode:
|
||||
if( maximizeMode() == MaximizeFull )
|
||||
setMaximize( false, false );
|
||||
else
|
||||
setMaximize( true, true );
|
||||
workspace()->restoreElectricBorderSize( ElectricTop );
|
||||
break;
|
||||
case ElectricLeftMode:
|
||||
setQuickTileMode( QuickTileLeft );
|
||||
workspace()->restoreElectricBorderSize( ElectricLeft );
|
||||
break;
|
||||
case ElectricRightMode:
|
||||
setQuickTileMode( QuickTileRight );
|
||||
workspace()->restoreElectricBorderSize( ElectricRight );
|
||||
break;
|
||||
}
|
||||
electricMaximizing = false;
|
||||
workspace()->hideElectricBorderWindowOutline();
|
||||
}
|
||||
if( isElectricBorderMaximizing() )
|
||||
{
|
||||
switch( electricMode )
|
||||
|
@ -2841,6 +2883,7 @@ void Client::finishMoveResize( bool cancel )
|
|||
}
|
||||
checkMaximizeGeometry();
|
||||
// FRAME update();
|
||||
|
||||
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
|
||||
if( effects )
|
||||
static_cast<EffectsHandlerImpl*>(effects)->windowUserMovedResized( effectWindow(), false, true );
|
||||
|
@ -2999,6 +3042,11 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
|
|||
bool update = false;
|
||||
if( isResize())
|
||||
{
|
||||
// query layout for supported resize mode
|
||||
if( workspace()->tilingMode() )
|
||||
{
|
||||
mode = workspace()->supportedTilingResizeMode( this, mode );
|
||||
}
|
||||
// first resize (without checking constrains), then snap, then check bounds, then check constrains
|
||||
QRect orig = initialMoveResizeGeom;
|
||||
Sizemode sizemode = SizemodeAny;
|
||||
|
@ -3033,10 +3081,19 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
|
|||
sizemode = SizemodeFixedW;
|
||||
break;
|
||||
case PositionCenter:
|
||||
// exception for tiling
|
||||
// Center means no resizing allowed
|
||||
if( workspace()->tilingMode() )
|
||||
{
|
||||
finishMoveResize( false );
|
||||
buttonDown = false;
|
||||
return;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
workspace()->notifyWindowResize( this, moveResizeGeom, initialMoveResizeGeom );
|
||||
// adjust new size to snap to other windows/borders
|
||||
moveResizeGeom = workspace()->adjustClientSize( this, moveResizeGeom, mode );
|
||||
|
||||
|
@ -3208,9 +3265,13 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root )
|
|||
|
||||
if( update )
|
||||
performMoveResize();
|
||||
|
||||
if ( isMove() )
|
||||
{
|
||||
workspace()->notifyWindowMove( this, moveResizeGeom, initialMoveResizeGeom );
|
||||
workspace()->checkElectricBorder(globalPos, xTime());
|
||||
}
|
||||
}
|
||||
|
||||
void Client::performMoveResize()
|
||||
{
|
||||
|
@ -3229,6 +3290,7 @@ void Client::performMoveResize()
|
|||
if( rules()->checkMoveResizeMode
|
||||
( isResize() ? options->resizeMode : options->moveMode ) == Options::Opaque )
|
||||
{
|
||||
if( !workspace()->tilingMode() )
|
||||
setGeometry( moveResizeGeom );
|
||||
positionGeometryTip();
|
||||
}
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
#define KWIN_AUTOGROUP_FOREGROUND "AutogroupInForeground"
|
||||
#define KWIN_SEPARATE_SCREEN_FOCUS "SeparateScreenFocus"
|
||||
#define KWIN_ACTIVE_MOUSE_SCREEN "ActiveMouseScreen"
|
||||
#define KWIN_TILINGON "TilingOn"
|
||||
#define KWIN_TILING_DEFAULT_LAYOUT "TilingDefaultLayout"
|
||||
#define KWIN_TILING_RAISE_POLICY "TilingRaisePolicy"
|
||||
|
||||
//CT 15mar 98 - magics
|
||||
#define KWM_BRDR_SNAP_ZONE "BorderSnapZone"
|
||||
|
@ -636,6 +639,54 @@ KAdvancedConfig::KAdvancedConfig (bool _standAlone, KConfig *_config, const KCom
|
|||
connect(hideUtilityWindowsForInactive, SIGNAL(toggled(bool)), SLOT(changed()));
|
||||
vLay->addWidget( hideUtilityWindowsForInactive, 1, 0, 1, 2 );
|
||||
|
||||
tilBox = new KButtonGroup(this);
|
||||
tilBox->setTitle(i18n("Tiling"));
|
||||
QGridLayout *tilBoxLay = new QGridLayout(tilBox);
|
||||
|
||||
tilingOn = new QCheckBox( i18n( "Enable Tiling" ), tilBox );
|
||||
tilingOn->setWhatsThis(
|
||||
i18n( "A tiling window manager lays out all the windows in a non-overlapping manner."
|
||||
" This way all windows are always visible.") );
|
||||
tilBoxLay->addWidget( tilingOn );
|
||||
connect( tilingOn, SIGNAL( toggled(bool) ), SLOT( tilingOnChanged(bool) ) );
|
||||
connect( tilingOn, SIGNAL( toggled(bool) ), SLOT( changed() ) );
|
||||
|
||||
tilingLayoutLabel = new QLabel( i18n("Default Tiling &Layout"), tilBox );
|
||||
tilBoxLay->addWidget( tilingLayoutLabel, 1, 0 );
|
||||
|
||||
tilingLayoutCombo = new QComboBox( tilBox );
|
||||
|
||||
// NOTE: add your layout to the bottom of this list
|
||||
tilingLayoutCombo->addItem( "Spiral" );
|
||||
tilingLayoutCombo->addItem( "Columns" );
|
||||
tilingLayoutCombo->addItem( "Floating" );
|
||||
|
||||
tilingLayoutLabel->setBuddy( tilingLayoutCombo );
|
||||
connect( tilingLayoutCombo, SIGNAL( activated(int) ), SLOT( changed() ) );
|
||||
tilBoxLay->addWidget( tilingLayoutCombo, 1, 1 );
|
||||
|
||||
tilingRaiseLabel = new QLabel( i18n("Floating &Windows Raising"), tilBox );
|
||||
tilBoxLay->addWidget( tilingRaiseLabel, 2, 0 );
|
||||
|
||||
tilingRaiseCombo = new QComboBox( tilBox );
|
||||
tilingRaiseCombo->addItem( i18nc( "Window Raising Policy", "Raise/Lower all floating windows" ) );
|
||||
tilingRaiseCombo->addItem( i18nc( "Window Raising Policy", "Raise/Lower current window only") );
|
||||
tilingRaiseCombo->addItem( i18nc( "Window Raising Policy", "Floating windows are always on top" ) );
|
||||
wtstr = i18n("The window raising policy determines how floating windows are stacked"
|
||||
" <ul>"
|
||||
" <li><em>Raise/Lower all</em> will raise all floating windows when a"
|
||||
" floating window is activated.</li>"
|
||||
" <li><em>Raise/Lower current</em> will raise only the current window.</li>"
|
||||
" <li><em>Floating windows on top</em> will always keep floating windows on top, even"
|
||||
" when a tiled window is activated."
|
||||
"</ul>") ;
|
||||
tilingRaiseCombo->setWhatsThis( wtstr );
|
||||
connect( tilingRaiseCombo, SIGNAL( activated(int) ), SLOT( changed() ) );
|
||||
tilingRaiseLabel->setBuddy( tilingRaiseCombo );
|
||||
tilBoxLay->addWidget( tilingRaiseCombo, 2, 1 );
|
||||
|
||||
lay->addWidget( tilBox );
|
||||
|
||||
lay->addStretch();
|
||||
load();
|
||||
|
||||
|
@ -661,6 +712,24 @@ void KAdvancedConfig::shadeHoverChanged(bool a) {
|
|||
shadeHover->setEnabled(a);
|
||||
}
|
||||
|
||||
void KAdvancedConfig::setTilingOn( bool on ) {
|
||||
tilingOn->setChecked( on );
|
||||
}
|
||||
|
||||
void KAdvancedConfig::setTilingLayout( int l ) {
|
||||
tilingLayoutCombo->setCurrentIndex( l );
|
||||
}
|
||||
|
||||
void KAdvancedConfig::setTilingRaisePolicy( int l ) {
|
||||
tilingRaiseCombo->setCurrentIndex( l );
|
||||
}
|
||||
|
||||
void KAdvancedConfig::tilingOnChanged( bool a ) {
|
||||
tilingLayoutLabel->setEnabled( a );
|
||||
tilingLayoutCombo->setEnabled( a );
|
||||
tilingRaiseLabel->setEnabled( a );
|
||||
tilingRaiseCombo->setEnabled( a );
|
||||
}
|
||||
|
||||
void KAdvancedConfig::showEvent( QShowEvent *ev )
|
||||
{
|
||||
|
@ -719,6 +788,10 @@ void KAdvancedConfig::load( void )
|
|||
setAutogroupSimilarWindows( cg.readEntry( KWIN_AUTOGROUP_SIMILAR, false));
|
||||
setAutogroupInForeground( cg.readEntry( KWIN_AUTOGROUP_FOREGROUND, true));
|
||||
|
||||
setTilingOn( cg.readEntry( KWIN_TILINGON, false ) );
|
||||
setTilingLayout( cg.readEntry( KWIN_TILING_DEFAULT_LAYOUT, 0 ) );
|
||||
setTilingRaisePolicy( cg.readEntry( KWIN_TILING_RAISE_POLICY, 0 ) );
|
||||
|
||||
emit KCModule::changed(false);
|
||||
}
|
||||
|
||||
|
@ -769,6 +842,10 @@ void KAdvancedConfig::save( void )
|
|||
QDBusConnection::sessionBus().send(message);
|
||||
|
||||
}
|
||||
|
||||
cg.writeEntry( KWIN_TILINGON, tilingOn->isChecked() );
|
||||
cg.writeEntry( KWIN_TILING_DEFAULT_LAYOUT, tilingLayoutCombo->currentIndex() );
|
||||
cg.writeEntry( KWIN_TILING_RAISE_POLICY, tilingRaiseCombo->currentIndex() );
|
||||
emit KCModule::changed(false);
|
||||
}
|
||||
|
||||
|
@ -778,6 +855,9 @@ void KAdvancedConfig::defaults()
|
|||
setShadeHoverInterval(250);
|
||||
setPlacement(SMART_PLACEMENT);
|
||||
setHideUtilityWindowsForInactive( true );
|
||||
setTilingOn( false );
|
||||
setTilingLayout( 0 );
|
||||
setTilingRaisePolicy( 0 );
|
||||
setInactiveTabsSkipTaskbar( false );
|
||||
setAutogroupSimilarWindows( false );
|
||||
setAutogroupInForeground( true );
|
||||
|
|
|
@ -196,6 +196,7 @@ private slots:
|
|||
|
||||
void changed() { emit KCModule::changed(true); }
|
||||
|
||||
void tilingOnChanged( bool a );
|
||||
private:
|
||||
|
||||
int getShadeHoverInterval (void );
|
||||
|
@ -225,7 +226,21 @@ private:
|
|||
|
||||
int getPlacement( void ); //CT
|
||||
void setPlacement(int); //CT
|
||||
|
||||
KComboBox *placementCombo;
|
||||
|
||||
// ------------------------------
|
||||
// Tiling related widgets/methods
|
||||
// ------------------------------
|
||||
KButtonGroup *tilBox;
|
||||
QCheckBox *tilingOn;
|
||||
QLabel *tilingLayoutLabel;
|
||||
QLabel *tilingRaiseLabel;
|
||||
QComboBox *tilingLayoutCombo;
|
||||
QComboBox *tilingRaiseCombo;
|
||||
void setTilingOn( bool );
|
||||
void setTilingLayout( int );
|
||||
void setTilingRaisePolicy( int );
|
||||
};
|
||||
|
||||
#endif // KKWMWINDOWS_H
|
||||
|
|
|
@ -103,6 +103,7 @@ RulesWidget::RulesWidget( QWidget* parent )
|
|||
SETUP( autogroupid, force );
|
||||
SETUP( opacityactive, force );
|
||||
SETUP( opacityinactive, force );
|
||||
SETUP( tilingoption, force );
|
||||
SETUP( shortcut, force );
|
||||
// workarounds tab
|
||||
SETUP( fsplevel, force );
|
||||
|
@ -153,6 +154,7 @@ UPDATE_ENABLE_SLOT( autogroupfg )
|
|||
UPDATE_ENABLE_SLOT( autogroupid )
|
||||
UPDATE_ENABLE_SLOT( opacityactive )
|
||||
UPDATE_ENABLE_SLOT( opacityinactive )
|
||||
UPDATE_ENABLE_SLOT( tilingoption )
|
||||
void RulesWidget::updateEnableshortcut()
|
||||
{
|
||||
shortcut->setEnabled( enable_shortcut->isChecked() && rule_shortcut->currentIndex() != 0 );
|
||||
|
@ -269,6 +271,16 @@ int RulesWidget::comboToDesktop( int val ) const
|
|||
return val + 1;
|
||||
}
|
||||
|
||||
int RulesWidget::tilingToCombo( int t ) const
|
||||
{
|
||||
return qBound(0, t, 1);
|
||||
}
|
||||
|
||||
int RulesWidget::comboToTiling( int val ) const
|
||||
{
|
||||
return val; // 0 is tiling, 1 is floating
|
||||
}
|
||||
|
||||
static int placementToCombo( Placement::Policy placement )
|
||||
{
|
||||
static const int conv[] =
|
||||
|
@ -431,6 +443,7 @@ void RulesWidget::setRules( Rules* rules )
|
|||
LINEEDIT_FORCE_RULE( autogroupid, );
|
||||
LINEEDIT_FORCE_RULE( opacityactive, intToStr );
|
||||
LINEEDIT_FORCE_RULE( opacityinactive, intToStr );
|
||||
COMBOBOX_FORCE_RULE( tilingoption, tilingToCombo );
|
||||
LINEEDIT_SET_RULE( shortcut, );
|
||||
COMBOBOX_FORCE_RULE( fsplevel, );
|
||||
COMBOBOX_FORCE_RULE( moveresizemode, moveresizeToCombo );
|
||||
|
@ -524,6 +537,7 @@ Rules* RulesWidget::rules() const
|
|||
LINEEDIT_FORCE_RULE( autogroupid, );
|
||||
LINEEDIT_FORCE_RULE( opacityactive, strToInt );
|
||||
LINEEDIT_FORCE_RULE( opacityinactive, strToInt );
|
||||
COMBOBOX_FORCE_RULE( tilingoption, comboToTiling );
|
||||
LINEEDIT_SET_RULE( shortcut, );
|
||||
COMBOBOX_FORCE_RULE( fsplevel, );
|
||||
COMBOBOX_FORCE_RULE( moveresizemode, comboToMoveResize );
|
||||
|
@ -644,6 +658,7 @@ void RulesWidget::prefillUnusedValues( const KWindowInfo& info )
|
|||
//LINEEDIT_PREFILL( autogroupid, );
|
||||
LINEEDIT_PREFILL( opacityactive, intToStr, 100 /*get the actual opacity somehow*/);
|
||||
LINEEDIT_PREFILL( opacityinactive, intToStr, 100 /*get the actual opacity somehow*/);
|
||||
COMBOBOX_PREFILL( tilingoption, tilingToCombo, 0 );
|
||||
//LINEEDIT_PREFILL( shortcut, );
|
||||
//COMBOBOX_PREFILL( fsplevel, );
|
||||
//COMBOBOX_PREFILL( moveresizemode, moveresizeToCombo );
|
||||
|
|
|
@ -77,6 +77,7 @@ class RulesWidget
|
|||
void updateEnableautogroupid();
|
||||
void updateEnableopacityactive();
|
||||
void updateEnableopacityinactive();
|
||||
void updateEnabletilingoption();
|
||||
// workarounds tab
|
||||
void updateEnablefsplevel();
|
||||
void updateEnablemoveresizemode();
|
||||
|
@ -92,6 +93,8 @@ class RulesWidget
|
|||
private:
|
||||
int desktopToCombo( int d ) const;
|
||||
int comboToDesktop( int val ) const;
|
||||
int tilingToCombo( int t ) const;
|
||||
int comboToTiling( int val ) const;
|
||||
void prefillUnusedValues( const KWindowInfo& info );
|
||||
DetectDialog* detect_dlg;
|
||||
bool detect_dlg_ok;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6775,3 +6775,18 @@ Comment[x-test]=xxSome effects are not supported by backend or hardware.xx
|
|||
Comment[zh_CN]=因为后端或硬件的关系,一些效果不受支持。
|
||||
Comment[zh_TW]=有些效果未被後端介面或硬體支援。
|
||||
Action=Popup
|
||||
|
||||
[Event/tilingenabled]
|
||||
Name=Tiling Enabled
|
||||
Comment=Tiling mode has been enabled
|
||||
Action=Popup
|
||||
|
||||
[Event/tilingdisabled]
|
||||
Name=Tiling Disabled
|
||||
Comment=Tiling mode has been disabled
|
||||
Action=Popup
|
||||
|
||||
[Event/tilinglayoutchanged]
|
||||
Name=Tiling Layout Changed
|
||||
Comment=Tiling Layout has been changed
|
||||
Action=Popup
|
||||
|
|
|
@ -219,6 +219,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
DEF( I18N_NOOP("Block Global Shortcuts"), 0, slotDisableGlobalShortcuts());
|
||||
DEF( I18N_NOOP("Suspend Compositing"), Qt::SHIFT+Qt::ALT+Qt::Key_F12, slotToggleCompositing());
|
||||
|
||||
a = actionCollection->addAction( "Group:Tiling" );
|
||||
a->setText( i18n("Tiling") );
|
||||
DEF( I18N_NOOP("Toggle Tiling"), Qt::SHIFT+Qt::ALT+Qt::Key_F11, slotToggleTiling() );
|
||||
DEF( I18N_NOOP("Toggle Orientation"), Qt::META+Qt::Key_Space, slotToggleOrientation() );
|
||||
DEF( I18N_NOOP("Increase Ratio"), Qt::META+Qt::Key_Right, slotTileIncreaseRatio() );
|
||||
DEF( I18N_NOOP("Decrease Ratio"), Qt::META+Qt::Key_Left, slotTileDecreaseRatio() );
|
||||
DEF( I18N_NOOP("Toggle Floating"), Qt::META+Qt::Key_F, slotToggleFloating() );
|
||||
|
||||
DEF( I18N_NOOP("Switch Focus Left") , Qt::META+Qt::Key_H, slotLeft() );
|
||||
DEF( I18N_NOOP("Switch Focus Right") , Qt::META+Qt::Key_L, slotRight() );
|
||||
DEF( I18N_NOOP("Switch Focus Up") , Qt::META+Qt::Key_K, slotTop() );
|
||||
DEF( I18N_NOOP("Switch Focus Down") , Qt::META+Qt::Key_J, slotBottom() );
|
||||
DEF( I18N_NOOP("Move Left") , Qt::SHIFT+Qt::META+Qt::Key_H, slotMoveLeft() );
|
||||
DEF( I18N_NOOP("Move Right") , Qt::SHIFT+Qt::META+Qt::Key_L, slotMoveRight() );
|
||||
DEF( I18N_NOOP("Move Up") , Qt::SHIFT+Qt::META+Qt::Key_K, slotMoveTop() );
|
||||
DEF( I18N_NOOP("Move Down") , Qt::SHIFT+Qt::META+Qt::Key_J, slotMoveBottom() );
|
||||
DEF( I18N_NOOP("Next Layout"), Qt::META+Qt::Key_PageDown, slotNextTileLayout() );
|
||||
DEF( I18N_NOOP("Previous Layout"), Qt::META+Qt::Key_PageUp, slotPreviousTileLayout() );
|
||||
// NOTE: temporary
|
||||
DEF( I18N_NOOP("Test Dump tiles"), Qt::META+Qt::Key_D, dumpTiles() );
|
||||
DEF( I18N_NOOP("Test Below Cursor"), Qt::META+Qt::Key_X, belowCursor() );
|
||||
|
||||
#undef DEF
|
||||
#undef DEF2
|
||||
|
||||
|
|
|
@ -124,6 +124,10 @@ unsigned long Options::updateSettings()
|
|||
shadeHover = config.readEntry("ShadeHover", false);
|
||||
shadeHoverInterval = config.readEntry("ShadeHoverInterval", 250 );
|
||||
|
||||
tilingOn = config.readEntry( "TilingOn", false );
|
||||
tilingLayout = config.readEntry( "TilingDefaultLayout", 0 );
|
||||
tilingRaisePolicy = config.readEntry( "TilingRaisePolicy", 0 );
|
||||
|
||||
// important: autoRaise implies ClickRaise
|
||||
clickRaise = autoRaise || config.readEntry("ClickRaise", true);
|
||||
|
||||
|
|
15
options.h
15
options.h
|
@ -116,6 +116,21 @@ class Options : public KDecorationOptions
|
|||
*/
|
||||
int shadeHoverInterval;
|
||||
|
||||
/**
|
||||
* Whether tiling is enabled or not
|
||||
*/
|
||||
bool tilingOn;
|
||||
|
||||
/**
|
||||
* Tiling Layout
|
||||
*/
|
||||
int tilingLayout;
|
||||
|
||||
/**
|
||||
* Tiling window raise policy.
|
||||
*/
|
||||
int tilingRaisePolicy;
|
||||
|
||||
/**
|
||||
Different Alt-Tab-Styles:
|
||||
<ul>
|
||||
|
|
|
@ -69,5 +69,9 @@
|
|||
<arg type="ai" direction="out"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QList<int>"/>
|
||||
</method>
|
||||
<method name="toggleTiling"/>
|
||||
<method name="nextTileLayout"/>
|
||||
<method name="previousTileLayout"/>
|
||||
<method name="dumpTiles"/>
|
||||
</interface>
|
||||
</node>
|
||||
|
|
|
@ -51,6 +51,7 @@ Rules::Rules()
|
|||
, maxsizerule( UnusedForceRule )
|
||||
, opacityactiverule( UnusedForceRule )
|
||||
, opacityinactiverule( UnusedForceRule )
|
||||
, tilingoptionrule( UnusedForceRule )
|
||||
, ignorepositionrule( UnusedForceRule )
|
||||
, desktoprule( UnusedSetRule )
|
||||
, typerule( UnusedForceRule )
|
||||
|
@ -153,6 +154,7 @@ void Rules::readFromCfg( const KConfigGroup& cfg )
|
|||
READ_FORCE_RULE( opacityinactive,, 0);
|
||||
if( opacityinactive < 0 || opacityinactive > 100 )
|
||||
opacityinactive = 100;
|
||||
READ_FORCE_RULE( tilingoption,, 0 );
|
||||
READ_FORCE_RULE( ignoreposition,, false);
|
||||
READ_SET_RULE( desktop,,0 );
|
||||
type = readType( cfg, "type" );
|
||||
|
@ -241,6 +243,7 @@ void Rules::write( KConfigGroup& cfg ) const
|
|||
WRITE_FORCE_RULE( maxsize, );
|
||||
WRITE_FORCE_RULE( opacityactive, );
|
||||
WRITE_FORCE_RULE( opacityinactive, );
|
||||
WRITE_FORCE_RULE( tilingoption, );
|
||||
WRITE_FORCE_RULE( ignoreposition, );
|
||||
WRITE_SET_RULE( desktop, );
|
||||
WRITE_FORCE_RULE( type, int );
|
||||
|
@ -280,6 +283,7 @@ bool Rules::isEmpty() const
|
|||
&& maxsizerule == UnusedForceRule
|
||||
&& opacityactiverule == UnusedForceRule
|
||||
&& opacityinactiverule == UnusedForceRule
|
||||
&& tilingoptionrule == UnusedForceRule
|
||||
&& ignorepositionrule == UnusedForceRule
|
||||
&& desktoprule == UnusedSetRule
|
||||
&& typerule == UnusedForceRule
|
||||
|
@ -576,6 +580,7 @@ APPLY_FORCE_RULE( maxsize, MaxSize, QSize )
|
|||
APPLY_FORCE_RULE( opacityactive, OpacityActive, int )
|
||||
APPLY_FORCE_RULE( opacityinactive, OpacityInactive, int )
|
||||
APPLY_FORCE_RULE( ignoreposition, IgnorePosition, bool )
|
||||
APPLY_FORCE_RULE( tilingoption, TilingOption, int )
|
||||
|
||||
// the cfg. entry needs to stay named the say for backwards compatibility
|
||||
bool Rules::applyIgnoreGeometry( bool& ignore ) const
|
||||
|
@ -672,6 +677,7 @@ void Rules::discardUsed( bool withdrawn )
|
|||
DISCARD_USED_FORCE_RULE( maxsize );
|
||||
DISCARD_USED_FORCE_RULE( opacityactive );
|
||||
DISCARD_USED_FORCE_RULE( opacityinactive );
|
||||
DISCARD_USED_FORCE_RULE( tilingoption );
|
||||
DISCARD_USED_FORCE_RULE( ignoreposition );
|
||||
DISCARD_USED_SET_RULE( desktop );
|
||||
DISCARD_USED_FORCE_RULE( type );
|
||||
|
@ -781,6 +787,7 @@ CHECK_FORCE_RULE( MinSize, QSize )
|
|||
CHECK_FORCE_RULE( MaxSize, QSize )
|
||||
CHECK_FORCE_RULE( OpacityActive, int )
|
||||
CHECK_FORCE_RULE( OpacityInactive, int )
|
||||
CHECK_FORCE_RULE( TilingOption, int )
|
||||
CHECK_FORCE_RULE( IgnorePosition, bool )
|
||||
|
||||
bool WindowRules::checkIgnoreGeometry( bool ignore ) const
|
||||
|
|
4
rules.h
4
rules.h
|
@ -61,6 +61,7 @@ class WindowRules
|
|||
QSize checkMaxSize( QSize s ) const;
|
||||
int checkOpacityActive(int s) const;
|
||||
int checkOpacityInactive(int s) const;
|
||||
int checkTilingOption( int s ) const;
|
||||
bool checkIgnoreGeometry( bool ignore ) const;
|
||||
int checkDesktop( int desktop, bool init = false ) const;
|
||||
NET::WindowType checkType( NET::WindowType type ) const;
|
||||
|
@ -115,6 +116,7 @@ class Rules
|
|||
bool applyMaxSize( QSize& s ) const;
|
||||
bool applyOpacityActive(int& s) const;
|
||||
bool applyOpacityInactive(int& s) const;
|
||||
bool applyTilingOption( int& s ) const;
|
||||
bool applyIgnoreGeometry( bool& ignore ) const;
|
||||
bool applyDesktop( int& desktop, bool init ) const;
|
||||
bool applyType( NET::WindowType& type ) const;
|
||||
|
@ -214,6 +216,8 @@ class Rules
|
|||
ForceRule opacityactiverule;
|
||||
int opacityinactive;
|
||||
ForceRule opacityinactiverule;
|
||||
int tilingoption;
|
||||
ForceRule tilingoptionrule;
|
||||
bool ignoreposition;
|
||||
ForceRule ignorepositionrule;
|
||||
int desktop;
|
||||
|
|
14
sm.cpp
14
sm.cpp
|
@ -82,6 +82,17 @@ void Workspace::storeSession( KConfig* config, SMSavePhase phase )
|
|||
KConfigGroup cg(config, "Session");
|
||||
int count = 0;
|
||||
int active_client = -1;
|
||||
|
||||
if( phase == SMSavePhase2 || phase == SMSavePhase2Full )
|
||||
{
|
||||
cg.writeEntry( "tiling", tilingMode() );
|
||||
if( tilingMode() )
|
||||
{
|
||||
kDebug(1212) << "Tiling was ON";
|
||||
setTilingMode( false );
|
||||
}
|
||||
}
|
||||
|
||||
for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it)
|
||||
{
|
||||
Client* c = (*it);
|
||||
|
@ -167,6 +178,9 @@ void Workspace::loadSessionInfo()
|
|||
{
|
||||
session.clear();
|
||||
KConfigGroup cg(kapp->sessionConfig(), "Session");
|
||||
|
||||
setTilingMode( cg.readEntry( "tiling", false ) );
|
||||
|
||||
int count = cg.readEntry( "count",0 );
|
||||
int active_client = cg.readEntry( "active",0 );
|
||||
for ( int i = 1; i <= count; i++ )
|
||||
|
|
152
tile.cpp
Normal file
152
tile.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#include "tile.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <QQueue>
|
||||
|
||||
#include "client.h"
|
||||
#include "workspace.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
Tile::Tile( Client *c, const QRect& area)
|
||||
: m_client(c),
|
||||
m_floating(false)
|
||||
{
|
||||
setGeometry(area);
|
||||
if( c )
|
||||
{
|
||||
m_prevGeom = c->geometry();
|
||||
}
|
||||
if( c && !c->isResizable() )
|
||||
floatTile();
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: Why isn't left/right/parent copied?
|
||||
* Because they might be deleted at any point, so we can't keep pointers to them
|
||||
* Also it doesn't make sense in the areas where copy is actually going to be used.
|
||||
* Since we will be getting a new parent and children.
|
||||
*/
|
||||
Tile::Tile( const Tile& orig )
|
||||
: m_client( orig.client() ),
|
||||
m_floating( orig.floating() ),
|
||||
m_prevGeom( orig.m_prevGeom )
|
||||
{
|
||||
setGeometry( orig.geometry() );
|
||||
}
|
||||
|
||||
Tile::~Tile()
|
||||
{
|
||||
restorePreviousGeometry();
|
||||
|
||||
m_client = NULL;
|
||||
}
|
||||
|
||||
void Tile::commit()
|
||||
{
|
||||
m_client->setGeometry(geometry(), ForceGeometrySet);
|
||||
}
|
||||
|
||||
void Tile::setGeometry(int x, int y, int w, int h)
|
||||
{
|
||||
QRect old = m_geom;
|
||||
m_geom.setTopLeft( QPoint(x, y) );
|
||||
m_geom.setWidth( w );
|
||||
m_geom.setHeight( h );
|
||||
|
||||
if( old == m_geom )
|
||||
return;
|
||||
|
||||
if( floating() )
|
||||
m_prevGeom = m_geom;
|
||||
|
||||
}
|
||||
|
||||
void Tile::floatTile()
|
||||
{
|
||||
if( floating() ) return;
|
||||
|
||||
// note, order of setting m_floating to true
|
||||
// then calling restore is important
|
||||
// childGeometryChanged will check for ignoreGeometry()
|
||||
m_floating = true;
|
||||
|
||||
restorePreviousGeometry();
|
||||
|
||||
commit();
|
||||
client()->workspace()->notifyWindowActivated( client() );
|
||||
// TODO: notify layout manager
|
||||
}
|
||||
|
||||
void Tile::unfloatTile()
|
||||
{
|
||||
if( !floating() ) return;
|
||||
|
||||
m_floating = false;
|
||||
m_prevGeom = m_client->geometry();
|
||||
|
||||
setGeometry( m_client->workspace()->clientArea( PlacementArea, m_client ) );
|
||||
commit();
|
||||
// TODO: notify layout manager
|
||||
|
||||
}
|
||||
|
||||
void Tile::restorePreviousGeometry()
|
||||
{
|
||||
// why this check?
|
||||
// sometimes we remove a Tile, but don't want to remove the children
|
||||
// so the children are set to NULL. In this case leaf() will return
|
||||
// true but m_client will still be null
|
||||
if( !m_client ) return;
|
||||
if( m_prevGeom.isNull() )
|
||||
{
|
||||
QRect area = m_client->workspace()->clientArea( PlacementArea, m_client );
|
||||
m_client->workspace()->place( m_client, area );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_client->setGeometry( m_prevGeom, ForceGeometrySet );
|
||||
}
|
||||
setGeometry( m_client->geometry() );
|
||||
}
|
||||
|
||||
inline bool Tile::minimized() const
|
||||
{
|
||||
return m_client->isMinimized();
|
||||
}
|
||||
|
||||
void Tile::focus()
|
||||
{
|
||||
m_client->workspace()->activateClient( m_client, true );
|
||||
}
|
||||
|
||||
void Tile::dumpTile(const QString& indent ) const
|
||||
{
|
||||
kDebug(1212) << indent << m_client
|
||||
<< ( floating() ? "floating" : "not floating" )
|
||||
<< ( ignoreGeometry() ? "ignored" : "tiled" )
|
||||
<< m_geom ;
|
||||
}
|
||||
}
|
125
tile.h
Normal file
125
tile.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef KWIN_TILE_H
|
||||
#define KWIN_TILE_H
|
||||
|
||||
#include <QRect>
|
||||
#include <QString>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class Client;
|
||||
class Workspace;
|
||||
|
||||
class Tile
|
||||
{
|
||||
public:
|
||||
enum Direction {
|
||||
Top,
|
||||
Right,
|
||||
Bottom,
|
||||
Left
|
||||
};
|
||||
|
||||
enum LayoutMode {
|
||||
UseRatio, // uses m_ratio
|
||||
UseGeometry, // uses current geometry of children
|
||||
Equal // distribute equally
|
||||
};
|
||||
|
||||
Tile( Client *c, const QRect& area);
|
||||
Tile(const Tile& orig);
|
||||
virtual ~Tile();
|
||||
void setGeometry(const QRect& area);
|
||||
void setGeometry(int x, int y, int w, int h);
|
||||
|
||||
void resize( const QRect area );
|
||||
|
||||
void restorePreviousGeometry();
|
||||
|
||||
void commit();
|
||||
|
||||
void focus();
|
||||
|
||||
// :| the float datatype interferes with naming
|
||||
void floatTile();
|
||||
void unfloatTile();
|
||||
|
||||
bool minimized() const;
|
||||
bool floating() const;
|
||||
bool ignoreGeometry() const;
|
||||
QRect geometry() const;
|
||||
Client* client() const;
|
||||
|
||||
void dumpTile( const QString& indent = "" ) const;
|
||||
|
||||
private:
|
||||
|
||||
// -------------
|
||||
// PROPERTIES
|
||||
// -------------
|
||||
|
||||
// our client
|
||||
Client *m_client;
|
||||
|
||||
// tiled geometry
|
||||
QRect m_geom;
|
||||
// before tiling was enabled, if any
|
||||
QRect m_prevGeom;
|
||||
|
||||
bool m_floating;
|
||||
|
||||
};
|
||||
|
||||
inline QRect Tile::geometry() const
|
||||
{
|
||||
return m_geom;
|
||||
}
|
||||
|
||||
inline Client* Tile::client() const
|
||||
{
|
||||
return m_client;
|
||||
}
|
||||
|
||||
inline bool Tile::floating() const
|
||||
{
|
||||
return m_floating;
|
||||
}
|
||||
|
||||
/*
|
||||
* should be respected by all geometry modifying methods.
|
||||
* It returns true if the Tile is 'out' of the layout,
|
||||
* due to being minimized, floating or for some other reason.
|
||||
*/
|
||||
inline bool Tile::ignoreGeometry() const
|
||||
{
|
||||
return minimized() || floating();
|
||||
}
|
||||
|
||||
inline void Tile::setGeometry(const QRect& area)
|
||||
{
|
||||
setGeometry(area.x(), area.y(), area.width(), area.height());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
504
tiling.cpp
Normal file
504
tiling.cpp
Normal file
|
@ -0,0 +1,504 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
// all the tiling related code that is extensions to existing KWin classes
|
||||
// Includes Workspace for now
|
||||
|
||||
#include "client.h"
|
||||
#include "workspace.h"
|
||||
#include "tile.h"
|
||||
#include "tilinglayout.h"
|
||||
#include "tilinglayoutfactory.h"
|
||||
|
||||
#include <knotification.h>
|
||||
#include <klocale.h>
|
||||
#include "lib/kdecoration.h"
|
||||
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
bool Workspace::tilingMode() const
|
||||
{
|
||||
return tilingMode_;
|
||||
}
|
||||
|
||||
void Workspace::setTilingMode( bool tiling )
|
||||
{
|
||||
if( tilingMode() == tiling ) return;
|
||||
tilingMode_ = tiling;
|
||||
|
||||
if( tilingMode_ )
|
||||
{
|
||||
tilingLayouts.resize( numberOfDesktops() + 1 );
|
||||
foreach( Client *c, stackingOrder() )
|
||||
{
|
||||
createTile( c );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach( TilingLayout *t, tilingLayouts )
|
||||
{
|
||||
if( t )
|
||||
delete t;
|
||||
}
|
||||
tilingLayouts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotToggleTiling()
|
||||
{
|
||||
if ( tilingMode() )
|
||||
{
|
||||
setTilingMode( false );
|
||||
QString message = i18n( "Tiling Disabled" );
|
||||
KNotification::event( "tilingdisabled", message, QPixmap(), NULL, KNotification::CloseOnTimeout, KComponentData( "kwin" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
setTilingMode( true );
|
||||
QString message = i18n( "Tiling Enabled" );
|
||||
KNotification::event( "tilingenabled", message, QPixmap(), NULL, KNotification::CloseOnTimeout, KComponentData( "kwin" ) );
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::createTile( Client *c )
|
||||
{
|
||||
if( c == NULL ) return;
|
||||
if( c->desktop() < 0 || c->desktop() >= tilingLayouts.size() ) return;
|
||||
|
||||
kDebug(1212) << "Now tiling " << c->caption();
|
||||
if( !tilingMode() || !tileable(c) )
|
||||
return;
|
||||
|
||||
Tile *t = new Tile( c, clientArea( PlacementArea, c ) );
|
||||
if( !tileable( c ) )
|
||||
{
|
||||
kDebug(1212) << c->caption() << "is not tileable";
|
||||
t->floatTile();
|
||||
}
|
||||
|
||||
if( !tilingLayouts.value(c->desktop()) )
|
||||
{
|
||||
tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout( TilingLayoutFactory::DefaultL, this );
|
||||
}
|
||||
tilingLayouts[c->desktop()]->addTile( t );
|
||||
tilingLayouts[c->desktop()]->commit();
|
||||
}
|
||||
|
||||
void Workspace::removeTile( Client *c )
|
||||
{
|
||||
if( tilingLayouts[ c->desktop() ] )
|
||||
tilingLayouts[ c->desktop() ]->removeTile( c );
|
||||
}
|
||||
|
||||
bool Workspace::tileable( Client *c )
|
||||
{
|
||||
kDebug(1212) << c->caption();
|
||||
// TODO: if application specific settings
|
||||
// to ignore, put them here
|
||||
|
||||
// as suggested by Lucas Murray
|
||||
// see Client::manage ( ~ line 270 of manage.cpp at time of writing )
|
||||
// This is useful to ignore plasma widget placing.
|
||||
// According to the ICCCM if an application
|
||||
// or user requests a certain geometry
|
||||
// respect it
|
||||
long msize;
|
||||
XSizeHints xSizeHint;
|
||||
XGetWMNormalHints(display(), c->window(), &xSizeHint, &msize);
|
||||
if( xSizeHint.flags & PPosition ||
|
||||
xSizeHint.flags & USPosition ) {
|
||||
kDebug(1212) << "Not tileable due to USPosition requirement";
|
||||
return false;
|
||||
}
|
||||
|
||||
kDebug(1212) << "c->isNormalWindow()" << c->isNormalWindow() ;
|
||||
kDebug(1212) << "c->isUtility() " << c->isUtility() ;
|
||||
kDebug(1212) << "c->isDialog() " << c->isDialog() ;
|
||||
kDebug(1212) << "c->isSplash() " << c->isSplash() ;
|
||||
kDebug(1212) << "c->isToolbar() " << c->isToolbar() ;
|
||||
kDebug(1212) << "c->isPopupMenu() " << c->isPopupMenu() ;
|
||||
kDebug(1212) << "c->isTransient() " << c->isTransient() ;
|
||||
if( !c->isNormalWindow() ||
|
||||
c->isUtility() ||
|
||||
c->isDialog() ||
|
||||
c->isSplash() ||
|
||||
c->isToolbar() ||
|
||||
c->isPopupMenu() ||
|
||||
c->isTransient() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Workspace::belowCursor()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
Tile* Workspace::getNiceTile() const
|
||||
{
|
||||
if( !tilingMode() ) return NULL;
|
||||
if( !tilingLayouts.value( activeClient()->desktop() ) ) return NULL;
|
||||
|
||||
return tilingLayouts[ activeClient()->desktop() ]->findTile( activeClient() );
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Workspace::updateAllTiles()
|
||||
{
|
||||
foreach( TilingLayout *t, tilingLayouts )
|
||||
{
|
||||
if( !t ) continue;
|
||||
t->commit();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Resize the neighbouring clients to close any gaps
|
||||
*/
|
||||
void Workspace::notifyWindowResize( Client *c, const QRect &moveResizeGeom, const QRect &orig )
|
||||
{
|
||||
if( tilingLayouts.value( c->desktop() ) == NULL )
|
||||
return;
|
||||
tilingLayouts[ c->desktop() ]->clientResized( c, moveResizeGeom, orig );
|
||||
}
|
||||
|
||||
void Workspace::notifyWindowMove( Client *c, const QRect &moveResizeGeom, const QRect &orig )
|
||||
{
|
||||
if( tilingLayouts.value( c->desktop() ) == NULL )
|
||||
{
|
||||
c->setGeometry( moveResizeGeom );
|
||||
return;
|
||||
}
|
||||
tilingLayouts[ c->desktop() ]->clientMoved( c, moveResizeGeom, orig );
|
||||
updateAllTiles();
|
||||
}
|
||||
|
||||
void Workspace::notifyWindowResizeDone( Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled )
|
||||
{
|
||||
if( canceled )
|
||||
notifyWindowResize( c, orig, moveResizeGeom );
|
||||
else
|
||||
notifyWindowResize( c, moveResizeGeom, orig );
|
||||
}
|
||||
|
||||
void Workspace::notifyWindowMoveDone( Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled )
|
||||
{
|
||||
if( canceled )
|
||||
notifyWindowMove( c, orig, moveResizeGeom );
|
||||
else
|
||||
notifyWindowMove( c, moveResizeGeom, orig );
|
||||
}
|
||||
|
||||
void Workspace::notifyWindowDesktopChanged( Client *c, int old_desktop )
|
||||
{
|
||||
if( c->desktop() < 1 || c->desktop() > numberOfDesktops() )
|
||||
return;
|
||||
|
||||
if( tilingLayouts.value( old_desktop ) )
|
||||
{
|
||||
Tile *t = tilingLayouts[ old_desktop ]->findTile( c );
|
||||
|
||||
// TODO: copied from createTile(), move this into separate method?
|
||||
if( !tilingLayouts.value( c->desktop() ) )
|
||||
{
|
||||
tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout( TilingLayoutFactory::DefaultL, this );
|
||||
}
|
||||
|
||||
if( t )
|
||||
tilingLayouts[ c->desktop() ]->addTile( t );
|
||||
|
||||
tilingLayouts[ old_desktop ]->removeTile( c );
|
||||
tilingLayouts[ old_desktop ]->commit();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make this configurable
|
||||
/*
|
||||
* If a floating window was activated, raise all floating windows.
|
||||
* If a tiled window was activated, lower all floating windows.
|
||||
*/
|
||||
void Workspace::notifyWindowActivated( Client *c )
|
||||
{
|
||||
if( c == NULL )
|
||||
return;
|
||||
|
||||
if( options->tilingRaisePolicy == 1 ) // individual raise/lowers
|
||||
return;
|
||||
|
||||
if( tilingLayouts.value( c->desktop() ) )
|
||||
{
|
||||
QList<Tile *> tiles = tilingLayouts[ c->desktop() ]->tiles();
|
||||
|
||||
StackingUpdatesBlocker blocker( this );
|
||||
|
||||
Tile *tile_to_raise = tilingLayouts[ c->desktop() ]->findTile( c );
|
||||
|
||||
if( !tile_to_raise )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug(1212) << "FOUND TILE";
|
||||
bool raise_floating = false;
|
||||
if( options->tilingRaisePolicy == 2 ) // floating always on top
|
||||
raise_floating = true;
|
||||
else
|
||||
raise_floating = tile_to_raise->floating();
|
||||
|
||||
foreach( Tile *t, tiles )
|
||||
{
|
||||
kDebug(1212) << t->client() << t->floating();
|
||||
if( t->floating() == raise_floating && t != tile_to_raise )
|
||||
raiseClient( t->client() );
|
||||
}
|
||||
// raise the current tile last so that it ends up on top
|
||||
// but only if it supposed to be raised, required to support tilingRaisePolicy
|
||||
kDebug(1212) << "Raise floating? " << raise_floating << "to raise is floating?" << tile_to_raise->floating();
|
||||
if( tile_to_raise->floating() == raise_floating )
|
||||
raiseClient( tile_to_raise->client() );
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::notifyWindowMinimizeToggled( Client *c )
|
||||
{
|
||||
if( tilingLayouts.value( c->desktop() ) )
|
||||
{
|
||||
tilingLayouts[ c->desktop() ]->clientMinimizeToggled( c );
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::notifyWindowMaximized( Client *c, Options::WindowOperation op )
|
||||
{
|
||||
if( tilingLayouts.value( c->desktop() ) )
|
||||
{
|
||||
Tile *t = tilingLayouts[ c->desktop() ]->findTile( c );
|
||||
if( !t )
|
||||
{
|
||||
createTile( c );
|
||||
t = tilingLayouts[ c->desktop() ]->findTile( c );
|
||||
|
||||
// if still no tile, it couldn't be tiled
|
||||
// so ignore it
|
||||
if( !t )
|
||||
return;
|
||||
}
|
||||
|
||||
// if window IS tiled and a maximize
|
||||
// is attempted, make the window float.
|
||||
// That is all we do since that can
|
||||
// mess up the layout.
|
||||
// In all other cases, don't do
|
||||
// anything, let the user manage toggling
|
||||
// using Meta+F
|
||||
if ( !t->floating()
|
||||
&& ( op == Options::MaximizeOp
|
||||
|| op == Options::HMaximizeOp
|
||||
|| op == Options::VMaximizeOp ) )
|
||||
{
|
||||
tilingLayouts[ c->desktop() ]->toggleFloatTile( c );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Tile* Workspace::findAdjacentTile( Tile *ref, int d )
|
||||
{
|
||||
QRect reference = ref->geometry();
|
||||
QPoint origin = reference.center();
|
||||
|
||||
Tile *closest = NULL;
|
||||
int minDist = -1;
|
||||
|
||||
QList<Tile *> tiles = tilingLayouts[ ref->client()->desktop() ]->tiles();
|
||||
|
||||
foreach( Tile *t, tiles )
|
||||
{
|
||||
if( t->client() == ref->client() || t->ignoreGeometry() )
|
||||
continue;
|
||||
|
||||
bool consider = false;
|
||||
|
||||
QRect other = t->geometry();
|
||||
QPoint otherCenter = other.center();
|
||||
|
||||
switch( d )
|
||||
{
|
||||
case Tile::Top:
|
||||
consider = otherCenter.y() < origin.y()
|
||||
&& other.bottom() < reference.top();
|
||||
break;
|
||||
|
||||
case Tile::Right:
|
||||
consider = otherCenter.x() > origin.x()
|
||||
&& other.left() > reference.right();
|
||||
break;
|
||||
|
||||
case Tile::Bottom:
|
||||
consider = otherCenter.y() > origin.y()
|
||||
&& other.top() > reference.bottom();
|
||||
break;
|
||||
|
||||
case Tile::Left:
|
||||
consider = otherCenter.x() < origin.x()
|
||||
&& other.right() < reference.left();
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
if( consider )
|
||||
{
|
||||
int dist = ( otherCenter - origin ).manhattanLength();
|
||||
if( minDist > dist || minDist < 0 )
|
||||
{
|
||||
minDist = dist;
|
||||
closest = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
void Workspace::focusTile( int d )
|
||||
{
|
||||
Tile *t = getNiceTile();
|
||||
if( t )
|
||||
{
|
||||
Tile *adj = findAdjacentTile(t, d);
|
||||
if( adj )
|
||||
activateClient( adj->client() );
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::moveTile( int d )
|
||||
{
|
||||
Tile *t = getNiceTile();
|
||||
if( t )
|
||||
{
|
||||
Tile* adj = findAdjacentTile( t, d );
|
||||
|
||||
tilingLayouts[ t->client()->desktop() ]->swapTiles( t, adj );
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotLeft()
|
||||
{
|
||||
focusTile( Tile::Left );
|
||||
}
|
||||
|
||||
void Workspace::slotRight()
|
||||
{
|
||||
focusTile( Tile::Right );
|
||||
}
|
||||
|
||||
void Workspace::slotTop()
|
||||
{
|
||||
focusTile( Tile::Top );
|
||||
}
|
||||
|
||||
void Workspace::slotBottom()
|
||||
{
|
||||
focusTile( Tile::Bottom );
|
||||
}
|
||||
|
||||
void Workspace::slotMoveLeft()
|
||||
{
|
||||
moveTile( Tile::Left );
|
||||
}
|
||||
|
||||
void Workspace::slotMoveRight()
|
||||
{
|
||||
moveTile( Tile::Right );
|
||||
}
|
||||
|
||||
void Workspace::slotMoveTop()
|
||||
{
|
||||
moveTile( Tile::Top );
|
||||
}
|
||||
|
||||
void Workspace::slotMoveBottom()
|
||||
{
|
||||
moveTile( Tile::Bottom );
|
||||
}
|
||||
|
||||
void Workspace::slotToggleFloating()
|
||||
{
|
||||
Client *c = activeClient();
|
||||
if( tilingLayouts.value( c->desktop() ) )
|
||||
{
|
||||
tilingLayouts[ c->desktop() ]->toggleFloatTile( c );
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotNextTileLayout()
|
||||
{
|
||||
if( tilingLayouts.value( currentDesktop() ) )
|
||||
{
|
||||
|
||||
tilingLayouts.replace( currentDesktop(), TilingLayoutFactory::nextLayout( tilingLayouts[currentDesktop()] ) );
|
||||
|
||||
tilingLayouts[currentDesktop()]->commit();
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotPreviousTileLayout()
|
||||
{
|
||||
if( tilingLayouts.value( currentDesktop() ) )
|
||||
{
|
||||
|
||||
tilingLayouts.replace( currentDesktop(), TilingLayoutFactory::previousLayout( tilingLayouts[currentDesktop()] ) );
|
||||
|
||||
tilingLayouts[currentDesktop()]->commit();
|
||||
}
|
||||
}
|
||||
|
||||
KDecorationDefines::Position Workspace::supportedTilingResizeMode( Client *c, KDecorationDefines::Position currentMode )
|
||||
{
|
||||
if( tilingLayouts.value( c->desktop() ) )
|
||||
{
|
||||
return tilingLayouts[c->desktop()]->resizeMode( c, currentMode );
|
||||
}
|
||||
return currentMode;
|
||||
}
|
||||
|
||||
void Workspace::dumpTiles() const
|
||||
{
|
||||
foreach( TilingLayout *t, tilingLayouts )
|
||||
{
|
||||
if( !t ) {
|
||||
kDebug(1212) << "EMPTY DESKTOP";
|
||||
continue;
|
||||
}
|
||||
kDebug(1212) << "Desktop" << tilingLayouts.indexOf( t );
|
||||
foreach( Tile *tile, t->tiles() )
|
||||
{
|
||||
tile->dumpTile( "--" );
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
218
tilinglayout.cpp
Normal file
218
tilinglayout.cpp
Normal file
|
@ -0,0 +1,218 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#include "tilinglayout.h"
|
||||
|
||||
#include <QCursor>
|
||||
|
||||
#include "client.h"
|
||||
#include "tile.h"
|
||||
#include "workspace.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
TilingLayout::TilingLayout( Workspace *w )
|
||||
: m_workspace( w )
|
||||
{
|
||||
}
|
||||
|
||||
TilingLayout::~TilingLayout()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int TilingLayout::findTilePos( Client *c ) const
|
||||
{
|
||||
unsigned int i = 0;
|
||||
foreach( Tile *t, m_tiles )
|
||||
{
|
||||
if( t->client() == c )
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Tile* TilingLayout::findTile( Client *c ) const
|
||||
{
|
||||
unsigned int i = findTilePos( c );
|
||||
if( i != -1 )
|
||||
return m_tiles[ i ];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TilingLayout::clientMinimizeToggled( Client *c )
|
||||
{
|
||||
Tile *t = findTile( c );
|
||||
if( t )
|
||||
arrange( layoutArea( t ) );
|
||||
}
|
||||
|
||||
void TilingLayout::clientResized( Client *c, const QRect &moveResizeGeom, const QRect &orig )
|
||||
{
|
||||
if( moveResizeGeom == orig )
|
||||
return;
|
||||
|
||||
Tile *t = findTile( c );
|
||||
if( !t || t->ignoreGeometry() )
|
||||
{
|
||||
c->setGeometry( moveResizeGeom );
|
||||
return;
|
||||
}
|
||||
|
||||
t->setGeometry( moveResizeGeom );
|
||||
commit();
|
||||
}
|
||||
|
||||
void TilingLayout::clientMoved( Client *c, const QRect &moveResizeGeom, const QRect &orig )
|
||||
{
|
||||
if( moveResizeGeom == orig )
|
||||
return;
|
||||
|
||||
Tile *t = findTile( c );
|
||||
if( !t )
|
||||
{
|
||||
c->setGeometry( moveResizeGeom );
|
||||
return;
|
||||
}
|
||||
if( t->floating() )
|
||||
{
|
||||
t->setGeometry( moveResizeGeom );
|
||||
t->commit();
|
||||
return;
|
||||
}
|
||||
|
||||
Tile *r = findTileBelowPoint( QCursor::pos() );
|
||||
// TODO: if the client moved in from another desktop, don't swap, add
|
||||
if( r && t )
|
||||
{
|
||||
swapTiles( r, t );
|
||||
}
|
||||
}
|
||||
|
||||
void TilingLayout::swapTiles( Tile *a, Tile *b )
|
||||
{
|
||||
if( a && b )
|
||||
{
|
||||
// t is the tile the user requested a move of
|
||||
// r is the tile below it
|
||||
int a_index = tiles().indexOf( a );
|
||||
int b_index = tiles().indexOf( b );
|
||||
|
||||
// use m_tiles since tiles() is const
|
||||
// not sure how good an idea this is
|
||||
m_tiles.replace( a_index, b );
|
||||
m_tiles.replace( b_index, a );
|
||||
arrange( layoutArea( a ) );
|
||||
}
|
||||
}
|
||||
|
||||
void TilingLayout::addTileNoArrange( Tile * t )
|
||||
{
|
||||
m_tiles.append( t );
|
||||
postAddTile( t );
|
||||
}
|
||||
|
||||
void TilingLayout::addTile( Tile *t )
|
||||
{
|
||||
addTileNoArrange( t );
|
||||
arrange( layoutArea( t ) );
|
||||
}
|
||||
|
||||
void TilingLayout::addTile( Client *c )
|
||||
{
|
||||
}
|
||||
|
||||
void TilingLayout::removeTileNoArrange( Tile * t )
|
||||
{
|
||||
if( t == NULL )
|
||||
return;
|
||||
preRemoveTile( t );
|
||||
m_tiles.removeOne( t );
|
||||
}
|
||||
|
||||
const QRect TilingLayout::layoutArea( Tile *t ) const
|
||||
{
|
||||
return m_workspace->clientArea( PlacementArea, t->client() );
|
||||
}
|
||||
|
||||
void TilingLayout::removeTile( Tile *t )
|
||||
{
|
||||
if( t == NULL )
|
||||
return;
|
||||
removeTileNoArrange( t );
|
||||
arrange( layoutArea( t ) );
|
||||
}
|
||||
|
||||
void TilingLayout::removeTile( Client *c )
|
||||
{
|
||||
removeTile( findTile( c ) );
|
||||
}
|
||||
|
||||
void TilingLayout::toggleFloatTile( Client *c )
|
||||
{
|
||||
Tile *t = findTile( c );
|
||||
if( t && t->floating() )
|
||||
t->unfloatTile();
|
||||
else if( t )
|
||||
t->floatTile();
|
||||
|
||||
if( t )
|
||||
arrange( layoutArea( t ) );
|
||||
}
|
||||
|
||||
Tile* TilingLayout::findTileBelowPoint( const QPoint &p ) const
|
||||
{
|
||||
foreach( Tile *t, tiles() )
|
||||
{
|
||||
if( t->floating() )
|
||||
continue;
|
||||
if( t->geometry().contains( p ) )
|
||||
return t;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TilingLayout::commit()
|
||||
{
|
||||
foreach( Tile *t, m_tiles )
|
||||
t->commit();
|
||||
}
|
||||
|
||||
/*
|
||||
* Default is to allow no resizing
|
||||
*/
|
||||
KDecorationDefines::Position TilingLayout::resizeMode( Client *c, KDecorationDefines::Position currentMode ) const
|
||||
{
|
||||
Tile *t = findTile( c );
|
||||
// if not tiled, allow resize
|
||||
if( !t )
|
||||
return currentMode;
|
||||
|
||||
if( t && t->floating() )
|
||||
return currentMode;
|
||||
// We return PositionCenter since it makes
|
||||
// no sense in resizing.
|
||||
return KDecorationDefines::PositionCenter;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
118
tilinglayout.h
Normal file
118
tilinglayout.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef KWIN_TILINGLAYOUT_H
|
||||
#define KWIN_TILINGLAYOUT_H
|
||||
|
||||
#include <QRect>
|
||||
#include <QList>
|
||||
|
||||
#include "lib/kdecoration.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class Workspace;
|
||||
class Client;
|
||||
class Tile;
|
||||
|
||||
class TilingLayout
|
||||
{
|
||||
public:
|
||||
TilingLayout( Workspace *w );
|
||||
virtual ~TilingLayout();
|
||||
|
||||
virtual void clientResized( Client *c, const QRect &moveResizeGeom, const QRect &orig );
|
||||
void clientMoved( Client *c, const QRect &moveResizeGeom, const QRect &orig );
|
||||
void clientMinimizeToggled( Client *c );
|
||||
|
||||
void commit();
|
||||
|
||||
void setLayoutType( int t );
|
||||
int layoutType() const;
|
||||
|
||||
void addTile( Tile *t );
|
||||
void addTile( Client *c );
|
||||
void removeTile( Tile *t );
|
||||
void removeTile( Client *c );
|
||||
void toggleFloatTile( Client *c );
|
||||
void swapTiles( Tile *a, Tile *b );
|
||||
|
||||
virtual KDecorationDefines::Position resizeMode( Client *c, KDecorationDefines::Position currentMode ) const;
|
||||
|
||||
const QList<Tile *>& tiles() const;
|
||||
Tile* findTile( Client *c ) const;
|
||||
|
||||
protected:
|
||||
Workspace * workspace() const;
|
||||
const QRect layoutArea( Tile *t ) const;
|
||||
// currently only required by floating layout
|
||||
virtual void postAddTile( Tile *t );
|
||||
virtual void preRemoveTile( Tile *t );
|
||||
|
||||
private:
|
||||
unsigned int findTilePos( Client *c ) const;
|
||||
virtual void arrange( QRect wgeom ) = 0;
|
||||
|
||||
void addTileNoArrange( Tile *t );
|
||||
void removeTileNoArrange( Tile *t );
|
||||
|
||||
Tile* findTileBelowPoint( const QPoint &p ) const;
|
||||
|
||||
|
||||
QList<Tile *> m_tiles;
|
||||
int m_layoutType;
|
||||
Workspace *m_workspace;
|
||||
|
||||
|
||||
friend class TilingLayoutFactory;
|
||||
};
|
||||
|
||||
inline void TilingLayout::setLayoutType( int t )
|
||||
{
|
||||
m_layoutType = t;
|
||||
}
|
||||
|
||||
inline int TilingLayout::layoutType() const
|
||||
{
|
||||
return m_layoutType;
|
||||
}
|
||||
|
||||
inline const QList<Tile *>& TilingLayout::tiles() const
|
||||
{
|
||||
return m_tiles;
|
||||
}
|
||||
|
||||
inline Workspace* TilingLayout::workspace() const
|
||||
{
|
||||
return m_workspace;
|
||||
}
|
||||
|
||||
inline void TilingLayout::postAddTile( Tile *t )
|
||||
{
|
||||
}
|
||||
|
||||
inline void TilingLayout::preRemoveTile( Tile *t )
|
||||
{
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
#endif
|
126
tilinglayoutfactory.cpp
Normal file
126
tilinglayoutfactory.cpp
Normal file
|
@ -0,0 +1,126 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#include "tilinglayoutfactory.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QList>
|
||||
#include <knotification.h>
|
||||
#include <klocale.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include "tile.h"
|
||||
#include "client.h"
|
||||
|
||||
#include "tilinglayouts/spiral/spiral.h"
|
||||
#include "tilinglayouts/columns/columns.h"
|
||||
#include "tilinglayouts/floating/floating.h"
|
||||
|
||||
// w is the workspace pointer
|
||||
#define ADD_LAYOUT( lay ) \
|
||||
case lay##L:\
|
||||
kDebug(1212) << #lay;\
|
||||
layout = new lay( w );\
|
||||
layout->setLayoutType( lay##L );\
|
||||
KNotification::event( "tilinglayoutchanged", \
|
||||
i18n( "Layout changed to %1" ).arg( #lay ),\
|
||||
QPixmap(), NULL, KNotification::CloseOnTimeout, KComponentData( "kwin" ) );\
|
||||
break
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
TilingLayout* TilingLayoutFactory::createLayout( int type, Workspace *w )
|
||||
{
|
||||
Q_ASSERT( type != First && type != Last );
|
||||
TilingLayout *layout;
|
||||
|
||||
/* For new layouts, make a case entry here */
|
||||
switch( type )
|
||||
{
|
||||
case DefaultL: // NOTE: fall through makes first layout default
|
||||
layout = createLayout( indexToLayoutIndex( options->tilingLayout ), w );
|
||||
break;
|
||||
|
||||
ADD_LAYOUT( Spiral );
|
||||
ADD_LAYOUT( Columns );
|
||||
ADD_LAYOUT( Floating );
|
||||
|
||||
default:
|
||||
kDebug(1212) << "INVALID LAYOUT!";
|
||||
return NULL;
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
// if next, goes next, otherwise previous
|
||||
TilingLayout* TilingLayoutFactory::cycleLayout( TilingLayout *curr, bool next )
|
||||
{
|
||||
int type = curr->layoutType();
|
||||
|
||||
if( next )
|
||||
{
|
||||
type++;
|
||||
|
||||
if( type >= Last )
|
||||
type = First + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
type--;
|
||||
|
||||
if( type <= First )
|
||||
type = Last - 1;
|
||||
}
|
||||
|
||||
QList<Tile *> tiles = curr->tiles(); //root->flatten();
|
||||
|
||||
TilingLayout *l = createLayout( type, curr->workspace() );
|
||||
|
||||
foreach( Tile *t, tiles )
|
||||
{
|
||||
curr->removeTileNoArrange( t );
|
||||
}
|
||||
|
||||
Tile *last = tiles.takeLast();
|
||||
foreach( Tile *t, tiles )
|
||||
{
|
||||
l->addTileNoArrange( t );
|
||||
}
|
||||
l->addTile( last );
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate layout enum item
|
||||
* Meant to be used with a combo box.
|
||||
* This function handles the issues of DefaultL and First and Last layouts
|
||||
*/
|
||||
int TilingLayoutFactory::indexToLayoutIndex( int index )
|
||||
{
|
||||
int layout = DefaultL + index + 1;
|
||||
if( layout >= Last )
|
||||
layout = DefaultL + 1;
|
||||
if( layout <= First )
|
||||
layout = Last - 1;
|
||||
return layout;
|
||||
}
|
||||
} // end namespace
|
71
tilinglayoutfactory.h
Normal file
71
tilinglayoutfactory.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef KWIN_TILINGLAYOUTFACTORY_H
|
||||
#define KWIN_TILINGLAYOUTFACTORY_H
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class Workspace;
|
||||
class TilingLayout;
|
||||
class Tile;
|
||||
class TilingLayoutFactory
|
||||
{
|
||||
public:
|
||||
/** When adding your own layout, edit this
|
||||
* Remember to suffix an L for now
|
||||
*/
|
||||
enum Layouts {
|
||||
First, // special, do not modify/move
|
||||
DefaultL,
|
||||
|
||||
/* Actual layouts */
|
||||
SpiralL,
|
||||
ColumnsL,
|
||||
FloatingL,
|
||||
/* Put your layout above this line ^^^ */
|
||||
|
||||
Last // special, do not modify/move
|
||||
};
|
||||
|
||||
static TilingLayout* createLayout( int type, Workspace * );
|
||||
static TilingLayout* nextLayout( TilingLayout *curr );
|
||||
static TilingLayout* previousLayout( TilingLayout *curr );
|
||||
|
||||
static int indexToLayoutIndex( int index );
|
||||
|
||||
private:
|
||||
static TilingLayout* cycleLayout( TilingLayout *curr, bool next );
|
||||
|
||||
};
|
||||
|
||||
inline TilingLayout* TilingLayoutFactory::nextLayout( TilingLayout *curr )
|
||||
{
|
||||
return cycleLayout( curr, true );
|
||||
}
|
||||
|
||||
inline TilingLayout* TilingLayoutFactory::previousLayout( TilingLayout *curr )
|
||||
{
|
||||
return cycleLayout( curr, false );
|
||||
}
|
||||
} // end namespace
|
||||
|
||||
#endif
|
162
tilinglayouts/columns/columns.cpp
Normal file
162
tilinglayouts/columns/columns.cpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#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<Tile *> tiled( tiles() );
|
||||
|
||||
QMutableListIterator<Tile *> 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;
|
||||
}
|
||||
|
||||
void Columns::clientResized( Client *c, const QRect &moveResizeGeom, const QRect &orig )
|
||||
{
|
||||
TilingLayout::clientResized( c, moveResizeGeom, orig );
|
||||
|
||||
Tile *t = findTile( c );
|
||||
|
||||
QList<Tile *> tiled( tiles() );
|
||||
|
||||
QMutableListIterator<Tile *> 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 ) );
|
||||
}
|
||||
|
||||
void Columns::arrange( QRect wgeom )
|
||||
{
|
||||
QList<Tile *> tiled( tiles() );
|
||||
|
||||
QMutableListIterator<Tile *> 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<Tile *>::const_iterator it = ++tiled.begin() ; it != tiled.end() ; it++ )
|
||||
{
|
||||
if( (*it)->floating() )
|
||||
continue;
|
||||
(*it)->setGeometry( wgeom );
|
||||
(*it)->commit();
|
||||
mult++;
|
||||
wgeom.moveTop( originalTop + mult*ht );
|
||||
}
|
||||
}
|
||||
}
|
49
tilinglayouts/columns/columns.h
Normal file
49
tilinglayouts/columns/columns.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef COLUMNS_H
|
||||
#define COLUMNS_H
|
||||
|
||||
#include <Qt>
|
||||
|
||||
#include "tilinglayout.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class Workspace;
|
||||
class Tile;
|
||||
class Client;
|
||||
|
||||
// simulates a 2 column right layout for now, make it arbitrary
|
||||
// in columns and direction
|
||||
class Columns : public TilingLayout
|
||||
{
|
||||
public:
|
||||
Columns( Workspace * );
|
||||
KDecorationDefines::Position resizeMode( Client *c, KDecorationDefines::Position currentMode ) const;
|
||||
void clientResized( Client *c, const QRect &moveResizeGeom, const QRect &orig );
|
||||
|
||||
private:
|
||||
void arrange( QRect wgeom );
|
||||
int m_leftWidth; // width of left column
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
#endif
|
61
tilinglayouts/floating/floating.cpp
Normal file
61
tilinglayouts/floating/floating.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#include "floating.h"
|
||||
|
||||
#include "tile.h"
|
||||
#include "client.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
Floating::Floating( Workspace *w )
|
||||
: TilingLayout( w )
|
||||
{
|
||||
}
|
||||
|
||||
void Floating::postAddTile( Tile *t )
|
||||
{
|
||||
if( t->floating() )
|
||||
was_floating.insert( t );
|
||||
}
|
||||
|
||||
void Floating::arrange( QRect wgeom )
|
||||
{
|
||||
foreach( Tile *t, tiles() )
|
||||
{
|
||||
if( !t->floating() )
|
||||
t->floatTile();
|
||||
workspace()->place( t->client(), wgeom );
|
||||
t->setGeometry( t->client()->geometry() );
|
||||
}
|
||||
}
|
||||
|
||||
void Floating::preRemoveTile( Tile *t )
|
||||
{
|
||||
if( ! was_floating.contains( t ) )
|
||||
t->unfloatTile();
|
||||
}
|
||||
|
||||
Floating::~Floating()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
59
tilinglayouts/floating/floating.h
Normal file
59
tilinglayouts/floating/floating.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef FLOATING_H
|
||||
#define FLOATING_H
|
||||
|
||||
#include <Qt>
|
||||
#include <QSet>
|
||||
|
||||
#include "tilinglayout.h"
|
||||
#include "tile.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class Workspace;
|
||||
class Floating : public TilingLayout
|
||||
{
|
||||
public:
|
||||
Floating( Workspace * );
|
||||
~Floating();
|
||||
|
||||
private:
|
||||
void arrange( QRect wgeom );
|
||||
void postAddTile( Tile *t );
|
||||
void preRemoveTile( Tile *t );
|
||||
|
||||
Tile::Direction m_dir;
|
||||
Tile *m_split;
|
||||
|
||||
/*
|
||||
* Tiles are added to was_floating if they
|
||||
* were floating before being added to this layout
|
||||
*
|
||||
* When the layout is changed, was_floating is
|
||||
* referred to, to restore the final state of the
|
||||
* Tile
|
||||
*/
|
||||
QSet<Tile *> was_floating;
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
#endif
|
82
tilinglayouts/spiral/spiral.cpp
Normal file
82
tilinglayouts/spiral/spiral.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#include "spiral.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "tile.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
Spiral::Spiral( Workspace *w )
|
||||
: TilingLayout( w )
|
||||
{
|
||||
}
|
||||
|
||||
Spiral::~Spiral()
|
||||
{
|
||||
}
|
||||
|
||||
void Spiral::arrange( QRect wgeom )
|
||||
{
|
||||
QList<Tile *> tiled( tiles() );
|
||||
|
||||
QMutableListIterator<Tile *> it(tiled);
|
||||
while( it.hasNext() )
|
||||
{
|
||||
Tile *t = it.next();
|
||||
if( t->ignoreGeometry() )
|
||||
it.remove();
|
||||
}
|
||||
|
||||
int n = tiled.length();
|
||||
int i = 1;
|
||||
|
||||
foreach( Tile *t, tiled )
|
||||
{
|
||||
if( t->floating() )
|
||||
continue;
|
||||
|
||||
if( i < n )
|
||||
{
|
||||
if( i % 2 == 0 )
|
||||
wgeom.setHeight( wgeom.height() / 2 );
|
||||
else
|
||||
wgeom.setWidth( wgeom.width() / 2 );
|
||||
}
|
||||
|
||||
if( i % 4 == 0 )
|
||||
wgeom.moveLeft( wgeom.x() - wgeom.width() );
|
||||
else if( i % 2 == 0 || ( i % 4 == 3 && i < n ) )
|
||||
wgeom.moveLeft( wgeom.x() + wgeom.width() );
|
||||
|
||||
if( i % 4 == 1 && i != 1 )
|
||||
wgeom.moveTop( wgeom.y() - wgeom.height() );
|
||||
else if( i % 2 == 1 && i != 1
|
||||
|| ( i % 4 == 0 && i < n ) )
|
||||
wgeom.moveTop( wgeom.y() + wgeom.height() );
|
||||
|
||||
t->setGeometry( wgeom );
|
||||
t->commit();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
49
tilinglayouts/spiral/spiral.h
Normal file
49
tilinglayouts/spiral/spiral.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef SPIRAL_H
|
||||
#define SPIRAL_H
|
||||
|
||||
#include <Qt>
|
||||
|
||||
#include "tilinglayout.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class Workspace;
|
||||
class Tile;
|
||||
class Client;
|
||||
|
||||
class Spiral : public TilingLayout
|
||||
{
|
||||
public:
|
||||
Spiral( Workspace * );
|
||||
~Spiral();
|
||||
|
||||
void addTile( Tile *t );
|
||||
void removeTile( Tile *t );
|
||||
|
||||
private:
|
||||
void arrange( QRect wgeom );
|
||||
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
#endif
|
|
@ -668,6 +668,15 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
|
|||
if ( !c )
|
||||
return;
|
||||
|
||||
if( tilingMode()
|
||||
&& ( op == Options::MaximizeOp
|
||||
|| op == Options::HMaximizeOp
|
||||
|| op == Options::VMaximizeOp
|
||||
|| op == Options::RestoreOp ) )
|
||||
{
|
||||
notifyWindowMaximized( c, op );
|
||||
}
|
||||
|
||||
if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp )
|
||||
QCursor::setPos( c->geometry().center() );
|
||||
if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp )
|
||||
|
|
|
@ -44,6 +44,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include "client.h"
|
||||
#include "tile.h"
|
||||
#include "tabbox.h"
|
||||
#include "desktopchangeosd.h"
|
||||
#include "atoms.h"
|
||||
|
@ -56,6 +57,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "scene.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
#include "tilinglayout.h"
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/keysym.h>
|
||||
|
@ -151,6 +153,7 @@ Workspace::Workspace( bool restore )
|
|||
, transSlider( NULL )
|
||||
, transButton( NULL )
|
||||
, forceUnredirectCheck( true )
|
||||
, tilingMode_( false )
|
||||
{
|
||||
(void) new KWinAdaptor( this );
|
||||
|
||||
|
@ -469,6 +472,9 @@ void Workspace::init()
|
|||
outline_bottom = XCreateWindow( QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
|
||||
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
|
||||
|
||||
// Enable/disable tiling
|
||||
setTilingMode( options->tilingOn );
|
||||
|
||||
// SELI TODO: This won't work with unreasonable focus policies,
|
||||
// and maybe in rare cases also if the selected client doesn't
|
||||
// want focus
|
||||
|
@ -550,6 +556,11 @@ Client* Workspace::createClient( Window w, bool is_mapped )
|
|||
return NULL;
|
||||
}
|
||||
addClient( c, Allowed );
|
||||
|
||||
tilingLayouts.resize( numberOfDesktops() + 1 );
|
||||
|
||||
createTile( c );
|
||||
|
||||
if( scene )
|
||||
scene->windowAdded( c );
|
||||
if( effects )
|
||||
|
@ -649,6 +660,11 @@ void Workspace::removeClient( Client* c, allowed_t )
|
|||
tab_box->nextPrev( true );
|
||||
|
||||
Q_ASSERT( clients.contains( c ) || desktops.contains( c ));
|
||||
if( tilingMode() && tilingLayouts.value(c->desktop()) )
|
||||
{
|
||||
removeTile( c );
|
||||
}
|
||||
// TODO: if marked client is removed, notify the marked list
|
||||
clients.removeAll( c );
|
||||
desktops.removeAll( c );
|
||||
unconstrained_stacking_order.removeAll( c );
|
||||
|
@ -1134,6 +1150,10 @@ void Workspace::slotReconfigure()
|
|||
(*it)->applyWindowRules();
|
||||
discardUsedWindowRules( *it, false );
|
||||
}
|
||||
|
||||
setTilingMode( options->tilingOn );
|
||||
// just so that we reset windows in the right manner, 'activate' the current active window
|
||||
notifyWindowActivated( activeClient() );
|
||||
rootInfo->setSupported( NET::WM2FrameOverlap, mgr->factory()->supports( AbilityExtendIntoClientArea ) );
|
||||
}
|
||||
|
||||
|
@ -1398,7 +1418,14 @@ bool Workspace::setCurrentDesktop( int new_desktop )
|
|||
rootInfo->setCurrentDesktop( currentDesktop() );
|
||||
|
||||
if( movingClient && !movingClient->isOnDesktop( new_desktop ))
|
||||
{
|
||||
int old_desktop = movingClient->desktop();
|
||||
movingClient->setDesktop( new_desktop );
|
||||
if( tilingMode() )
|
||||
{
|
||||
notifyWindowDesktopChanged( movingClient, old_desktop );
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = stacking_order.size() - 1; i >= 0 ; --i )
|
||||
if( stacking_order.at( i )->isOnDesktop( new_desktop ))
|
||||
|
@ -1532,6 +1559,7 @@ void Workspace::setNumberOfDesktops( int n )
|
|||
++it)
|
||||
if( !(*it)->isOnAllDesktops() && (*it)->desktop() > numberOfDesktops() )
|
||||
sendClientToDesktop( *it, numberOfDesktops(), true );
|
||||
// TODO: Tile should have a method allClients, push them into other tiles
|
||||
}
|
||||
if( old_number_of_desktops > numberOfDesktops() )
|
||||
{
|
||||
|
@ -1550,6 +1578,8 @@ void Workspace::setNumberOfDesktops( int n )
|
|||
for( int i = 0; i < int( desktop_focus_chain.size() ); i++ )
|
||||
desktop_focus_chain[i] = i+1;
|
||||
|
||||
tilingLayouts.resize( numberOfDesktops() + 1 );
|
||||
|
||||
// reset the desktop change osd
|
||||
desktop_change_osd->numberDesktopsChanged();
|
||||
// inform effects
|
||||
|
@ -1564,6 +1594,7 @@ void Workspace::setNumberOfDesktops( int n )
|
|||
*/
|
||||
void Workspace::sendClientToDesktop( Client* c, int desk, bool dont_activate )
|
||||
{
|
||||
int old_desktop = c->desktop();
|
||||
bool was_on_desktop = c->isOnDesktop( desk ) || c->isOnAllDesktops();
|
||||
c->setDesktop( desk );
|
||||
if( c->desktop() != desk ) // No change or desktop forced
|
||||
|
@ -1582,6 +1613,8 @@ void Workspace::sendClientToDesktop( Client* c, int desk, bool dont_activate )
|
|||
else
|
||||
raiseClient( c );
|
||||
|
||||
notifyWindowDesktopChanged( c, old_desktop );
|
||||
|
||||
ClientList transients_stacking_order = ensureStackingOrder( c->transients() );
|
||||
for( ClientList::ConstIterator it = transients_stacking_order.constBegin();
|
||||
it != transients_stacking_order.constEnd();
|
||||
|
|
77
workspace.h
77
workspace.h
|
@ -61,6 +61,8 @@ class TabBox;
|
|||
}
|
||||
|
||||
class Client;
|
||||
class Tile;
|
||||
class TilingLayout;
|
||||
class ClientGroup;
|
||||
class DesktopChangeOSD;
|
||||
class RootInfo;
|
||||
|
@ -169,6 +171,23 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
void reserveElectricBorderActions( bool reserve );
|
||||
void reserveElectricBorderSwitching( bool reserve );
|
||||
|
||||
//-------------------------------------------------
|
||||
// Tiling
|
||||
public:
|
||||
bool tilingMode() const;
|
||||
void setTilingMode( bool tiling );
|
||||
void updateAllTiles();
|
||||
void notifyWindowResize( Client *c, const QRect &moveResizeGeom, const QRect &orig );
|
||||
void notifyWindowMove( Client *c, const QRect &moveResizeGeom, const QRect &orig );
|
||||
void notifyWindowResizeDone( Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled );
|
||||
void notifyWindowMoveDone( Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled );
|
||||
void notifyWindowDesktopChanged( Client *c, int old_desktop );
|
||||
void notifyWindowActivated( Client *c );
|
||||
void notifyWindowMinimizeToggled( Client *c );
|
||||
void notifyWindowMaximized( Client *c, WindowOperation op );
|
||||
|
||||
Position supportedTilingResizeMode( Client *c, Position currentMode );
|
||||
|
||||
//-------------------------------------------------
|
||||
// Desktop layout
|
||||
|
||||
|
@ -286,6 +305,9 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
int currentDesktop_;
|
||||
bool desktopLayoutDynamicity_;
|
||||
|
||||
bool tilingMode_;
|
||||
QVector<TilingLayout *> tilingLayouts;
|
||||
|
||||
//-------------------------------------------------
|
||||
// Unsorted
|
||||
|
||||
|
@ -396,6 +418,9 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
void circulateDesktopApplications();
|
||||
bool compositingActive();
|
||||
bool waitForCompositingSetup();
|
||||
void toggleTiling();
|
||||
void nextTileLayout();
|
||||
void previousTileLayout();
|
||||
|
||||
void setCurrentScreen( int new_screen );
|
||||
|
||||
|
@ -652,6 +677,24 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
void suspendCompositing();
|
||||
void suspendCompositing( bool suspend );
|
||||
|
||||
void slotToggleTiling();
|
||||
void slotToggleFloating();
|
||||
void slotNextTileLayout();
|
||||
void slotPreviousTileLayout();
|
||||
|
||||
void slotLeft();
|
||||
void slotRight();
|
||||
void slotTop();
|
||||
void slotBottom();
|
||||
void slotMoveLeft();
|
||||
void slotMoveRight();
|
||||
void slotMoveTop();
|
||||
void slotMoveBottom();
|
||||
void belowCursor();
|
||||
|
||||
// NOTE: debug method
|
||||
void dumpTiles() const;
|
||||
|
||||
void slotSwitchToTabLeft(); // Slot to move left the active Client.
|
||||
void slotSwitchToTabRight(); // Slot to move right the active Client.
|
||||
void slotRemoveFromGroup(); // Slot to remove the active client from its group.
|
||||
|
@ -799,6 +842,16 @@ class Workspace : public QObject, public KDecorationDefines
|
|||
static NET::WindowType txtToWindowType( const char* txt );
|
||||
static bool sessionInfoWindowTypeMatch( Client* c, SessionInfo* info );
|
||||
|
||||
Tile* getNiceTile() const;
|
||||
void createTile( Client *c );
|
||||
void removeTile( Client *c );
|
||||
bool tileable( Client *c );
|
||||
// int, and not Tile::Direction because
|
||||
// we are using a forward declaration for Tile
|
||||
Tile* findAdjacentTile( Tile *ref, int d );
|
||||
void focusTile( int d );
|
||||
void moveTile( int d );
|
||||
|
||||
Client* active_client;
|
||||
Client* last_active_client;
|
||||
Client* most_recently_raised; // Used ONLY by raiseOrLowerClient()
|
||||
|
@ -1276,6 +1329,30 @@ inline void Workspace::removeClientGroup( ClientGroup* group )
|
|||
clientGroups.removeAll( group );
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from D-BUS
|
||||
*/
|
||||
inline void Workspace::toggleTiling()
|
||||
{
|
||||
slotToggleTiling();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from D-BUS
|
||||
*/
|
||||
inline void Workspace::nextTileLayout()
|
||||
{
|
||||
slotNextTileLayout();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from D-BUS
|
||||
*/
|
||||
inline void Workspace::previousTileLayout()
|
||||
{
|
||||
slotPreviousTileLayout();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue