diff --git a/geometry.cpp b/geometry.cpp index cf3a3eb6b9..cd9fe57426 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -297,7 +297,7 @@ QPoint Workspace::adjustClientPosition( Client* c, QPoint pos ) //CT 16mar98, 27May98 - magics: BorderSnapZone, WindowSnapZone //CT adapted for kwin on 25Nov1999 //aleXXX 02Nov2000 added second snapping mode - if (options->windowSnapZone || options->borderSnapZone ) + if (options->windowSnapZone || options->borderSnapZone || options->centerSnapZone ) { const bool sOWO=options->snapOnlyWhenOverlapping; const QRect maxRect = clientArea(MovementArea, pos+c->rect().center(), c->desktop()); @@ -397,6 +397,35 @@ QPoint Workspace::adjustClientPosition( Client* c, QPoint pos ) } } } + + // center snap + snap = options->centerSnapZone; //snap trigger + if (snap) + { + int diffX = qAbs( (xmin + xmax)/2 - (cx + cw/2) ); + int diffY = qAbs( (ymin + ymax)/2 - (cy + ch/2) ); + if (diffX < snap && diffY < snap) + { // Snap to center of screen + deltaX = diffX; + deltaY = diffY; + nx = (xmin + xmax)/2 - cw/2; + ny = (ymin + ymax)/2 - ch/2; + } + else if ( options->borderSnapZone ) + { // Enhance border snap + if( ( nx == xmin || nx == xmax - cw ) && diffY < snap) + { // Snap to vertical center on screen edge + deltaY = diffY; + ny = (ymin + ymax)/2 - ch/2; + } + else if ( ( ( ny <= ymin && ny > ymin - snap ) || ny == ymax - ch ) && diffX < snap) // Extra snap on the top of screen to prevent misses + { // Snap to horizontal center on screen edge + deltaX = diffX; + nx = (xmin + xmax)/2 - cw/2; + } + } + } + pos = QPoint(nx, ny); } return pos; @@ -407,7 +436,7 @@ QRect Workspace::adjustClientSize( Client* c, QRect moveResizeGeom, int mode ) //adapted from adjustClientPosition on 29May2004 //this function is called when resizing a window and will modify //the new dimensions to snap to other windows/borders if appropriate - if ( options->windowSnapZone || options->borderSnapZone ) + if ( options->windowSnapZone || options->borderSnapZone ) // || options->centerSnapZone ) { const bool sOWO=options->snapOnlyWhenOverlapping; @@ -593,6 +622,17 @@ QRect Workspace::adjustClientSize( Client* c, QRect moveResizeGeom, int mode ) } } } + + // center snap + //snap = options->centerSnapZone; + //if (snap) + // { + // // Don't resize snap to center as it interferes too much + // // There are two ways of implementing this if wanted: + // // 1) Snap only to the same points that the move snap does, and + // // 2) Snap to the horizontal and vertical center lines of the screen + // } + moveResizeGeom = QRect(QPoint(newcx, newcy), QPoint(newrx, newry)); } return moveResizeGeom; diff --git a/kcmkwin/kwinoptions/windows.cpp b/kcmkwin/kwinoptions/windows.cpp index f635ff90f2..24218113ae 100644 --- a/kcmkwin/kwinoptions/windows.cpp +++ b/kcmkwin/kwinoptions/windows.cpp @@ -75,9 +75,12 @@ #define KWM_BRDR_SNAP_ZONE_DEFAULT 10 #define KWM_WNDW_SNAP_ZONE "WindowSnapZone" #define KWM_WNDW_SNAP_ZONE_DEFAULT 10 +#define KWM_CNTR_SNAP_ZONE "CenterSnapZone" +#define KWM_CNTR_SNAP_ZONE_DEFAULT 0 #define MAX_BRDR_SNAP 100 #define MAX_WNDW_SNAP 100 +#define MAX_CNTR_SNAP 100 #define MAX_EDGE_RES 1000 @@ -917,12 +920,22 @@ KMovingConfig::KMovingConfig (bool _standAlone, KConfig *_config, const KCompone WndwSnap->setSpecialValueText( i18n("none") ); WndwSnap->setRange( 0, MAX_WNDW_SNAP); WndwSnap->setLabel(i18n("&Window snap zone:")); - BrdrSnap->setSteps(1,10); + WndwSnap->setSteps(1,10); WndwSnap->setWhatsThis( i18n("Here you can set the snap zone for windows, i.e." " the 'strength' of the magnetic field which will make windows snap to each other when" " they are moved near another window.") ); kLay->addWidget(WndwSnap); + CntrSnap = new KIntNumInput(10, MagicBox); + CntrSnap->setSpecialValueText( i18n("none") ); + CntrSnap->setRange( 0, MAX_CNTR_SNAP); + CntrSnap->setLabel(i18n("&Center snap zone:")); + CntrSnap->setSteps(1,10); + CntrSnap->setWhatsThis( i18n("Here you can set the snap zone for the screen center, i.e." + " the 'strength' of the magnetic field which will make windows snap to the center of" + " the screen when moved near it.") ); + kLay->addWidget(CntrSnap); + OverlapSnap=new QCheckBox(i18n("Snap windows onl&y when overlapping"),MagicBox); OverlapSnap->setWhatsThis( i18n("Here you can set that windows will be only" " snapped if you try to overlap them, i.e. they will not be snapped if the windows" @@ -944,11 +957,14 @@ KMovingConfig::KMovingConfig (bool _standAlone, KConfig *_config, const KCompone connect( BrdrSnap, SIGNAL(valueChanged(int)), SLOT(slotBrdrSnapChanged(int))); connect( WndwSnap, SIGNAL(valueChanged(int)), SLOT(changed())); connect( WndwSnap, SIGNAL(valueChanged(int)), SLOT(slotWndwSnapChanged(int))); + connect( CntrSnap, SIGNAL(valueChanged(int)), SLOT(changed())); + connect( CntrSnap, SIGNAL(valueChanged(int)), SLOT(slotCntrSnapChanged(int))); connect( OverlapSnap, SIGNAL(clicked()), SLOT(changed())); - // To get suffix to BrdrSnap and WndwSnap inputs with default values. + // To get suffix to BrdrSnap, WndwSnap and CntrSnap inputs with default values. slotBrdrSnapChanged(BrdrSnap->value()); slotWndwSnapChanged(WndwSnap->value()); + slotCntrSnapChanged(CntrSnap->value()); } int KMovingConfig::getMove() @@ -1004,6 +1020,10 @@ void KMovingConfig::slotWndwSnapChanged(int value) { WndwSnap->setSuffix(i18np(" pixel", " pixels", value)); } +void KMovingConfig::slotCntrSnapChanged(int value) { + CntrSnap->setSuffix(i18np(" pixel", " pixels", value)); +} + void KMovingConfig::load( void ) { QString key; @@ -1076,6 +1096,11 @@ void KMovingConfig::load( void ) else if (v < 0) setWindowSnapZone (0); else setWindowSnapZone(v); + v = cg.readEntry(KWM_CNTR_SNAP_ZONE, KWM_CNTR_SNAP_ZONE_DEFAULT); + if (v > MAX_CNTR_SNAP) setCenterSnapZone(MAX_CNTR_SNAP); + else if (v < 0) setCenterSnapZone (0); + else setCenterSnapZone(v); + OverlapSnap->setChecked(cg.readEntry("SnapOnlyWhenOverlapping", false)); emit KCModule::changed(false); } @@ -1127,6 +1152,7 @@ void KMovingConfig::save( void ) cg.writeEntry(KWM_BRDR_SNAP_ZONE,getBorderSnapZone()); cg.writeEntry(KWM_WNDW_SNAP_ZONE,getWindowSnapZone()); + cg.writeEntry(KWM_CNTR_SNAP_ZONE,getCenterSnapZone()); cg.writeEntry("SnapOnlyWhenOverlapping",OverlapSnap->isChecked()); if (standAlone) @@ -1151,6 +1177,7 @@ void KMovingConfig::defaults() //copied from kcontrol/konq/kwindesktop, aleXXX setWindowSnapZone(KWM_WNDW_SNAP_ZONE_DEFAULT); setBorderSnapZone(KWM_BRDR_SNAP_ZONE_DEFAULT); + setCenterSnapZone(KWM_CNTR_SNAP_ZONE_DEFAULT); OverlapSnap->setChecked(false); emit KCModule::changed(true); @@ -1172,4 +1199,12 @@ void KMovingConfig::setWindowSnapZone(int pxls) { WndwSnap->setValue(pxls); } +int KMovingConfig::getCenterSnapZone() { + return CntrSnap->value(); +} + +void KMovingConfig::setCenterSnapZone(int pxls) { + CntrSnap->setValue(pxls); +} + #include "windows.moc" diff --git a/kcmkwin/kwinoptions/windows.h b/kcmkwin/kwinoptions/windows.h index 6d43cf6bd0..4e80e7b437 100644 --- a/kcmkwin/kwinoptions/windows.h +++ b/kcmkwin/kwinoptions/windows.h @@ -143,6 +143,7 @@ private slots: void changed() { emit KCModule::changed(true); } void slotBrdrSnapChanged( int ); void slotWndwSnapChanged( int ); + void slotCntrSnapChanged( int ); private: int getMove( void ); @@ -171,9 +172,11 @@ private: void setBorderSnapZone( int ); int getWindowSnapZone(); void setWindowSnapZone( int ); + int getCenterSnapZone(); + void setCenterSnapZone( int ); KButtonGroup *MagicBox; - KIntNumInput *BrdrSnap, *WndwSnap; + KIntNumInput *BrdrSnap, *WndwSnap, *CntrSnap; QCheckBox *OverlapSnap; }; diff --git a/options.cpp b/options.cpp index a68c2ddb83..631201cb84 100644 --- a/options.cpp +++ b/options.cpp @@ -126,6 +126,7 @@ unsigned long Options::updateSettings() borderSnapZone = config.readEntry("BorderSnapZone", 10); windowSnapZone = config.readEntry("WindowSnapZone", 10); + centerSnapZone = config.readEntry("CenterSnapZone", 0); snapOnlyWhenOverlapping = config.readEntry("SnapOnlyWhenOverlapping", false); electric_borders = config.readEntry("ElectricBorders", 0); electric_border_delay = config.readEntry("ElectricBorderDelay", 150); diff --git a/options.h b/options.h index f159e9a812..a5ca3eb970 100644 --- a/options.h +++ b/options.h @@ -177,10 +177,15 @@ class Options : public KDecorationOptions int borderSnapZone; /** - * the number of animation steps (would this be general?) + * the size of the zone that triggers snapping with other windows */ int windowSnapZone; + /** + * the size of the zone that triggers snapping on the screen center + */ + int centerSnapZone; + /** * snap only when windows will overlap