Change how quick tiling and maximization is activated slightly. Instead

of using electric borders just check the location of the cursor; if the
cursor is near the edge enable the resize snap. This makes the features
easier to activate, removes the conflict with desktop switching and
allows the features to be used completely on multi-screen systems.
Patch inspired by one from Marcel Schaal.
BUG: 218957

svn path=/trunk/KDE/kdebase/workspace/; revision=1071996
This commit is contained in:
Lucas Murray 2010-01-09 09:49:52 +00:00
parent f98c1f875c
commit 41e5bfd793
6 changed files with 68 additions and 90 deletions

View file

@ -412,6 +412,7 @@ class Client
bool buttonPressEvent( Window w, int button, int state, int x, int y, int x_root, int y_root );
bool buttonReleaseEvent( Window w, int button, int state, int x, int y, int x_root, int y_root );
bool motionNotifyEvent( Window w, int state, int x, int y, int x_root, int y_root );
void checkQuickTilingMaximizationZones( int xroot, int yroot );
bool processDecorationButtonPress( int button, int state, int x, int y, int x_root, int y_root,
bool ignoreMenu = false );

View file

@ -45,15 +45,6 @@ int main( int argc, char* argv[] )
if( !tabbox.hasKey("ShowTabBox") )
tabbox.writeEntry("ShowTabBox", (style.compare("KDE", Qt::CaseInsensitive) == 0)?true:false);
tabbox.sync();
// screen edges - disable quick tiling when switch on desktop edge is activated
KConfigGroup borders(&config, "ElectricBorders");
if( borders.readEntry<int>("ElectricBorders", 0) >= 1 &&
!borders.hasKey("ElectricBorderMaximize") && !borders.hasKey("ElectricBorderTiling") )
{
borders.writeEntry("ElectricBorderMaximize", false);
borders.writeEntry("ElectricBorderTiling", false);
}
borders.sync();
config.sync();
// Send signal to all kwin instances
QDBusMessage message =

View file

@ -50,6 +50,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <X11/extensions/Xrandr.h>
#endif
#include <kephal/screens.h>
namespace KWin
{
@ -1432,6 +1434,39 @@ static bool waitingMotionEvent()
return was_motion;
}
// Checks if the mouse cursor is near the edge of the screen and if so activates quick tiling or maximization
void Client::checkQuickTilingMaximizationZones( int xroot, int yroot )
{
foreach( Kephal::Screen* screen, Kephal::Screens::self()->screens() )
{
if( screen->geom().contains( QPoint( xroot, yroot )))
{
if( options->electricBorderTiling() &&
xroot <= screen->geom().x() + 20 )
{
setElectricBorderMode( ElectricLeftMode );
setElectricBorderMaximizing( true );
return;
}
else if( options->electricBorderTiling() &&
xroot >= screen->geom().x() + screen->geom().width() - 20 )
{
setElectricBorderMode( ElectricRightMode );
setElectricBorderMaximizing( true );
return;
}
if( options->electricBorderMaximize() &&
yroot <= screen->geom().y() + 20 && isMaximizable() )
{
setElectricBorderMode( ElectricMaximizeMode );
setElectricBorderMaximizing( true );
return;
}
}
}
setElectricBorderMaximizing( false );
}
// return value matters only when filtering events before decoration gets them
bool Client::motionNotifyEvent( Window w, int /*state*/, int x, int y, int x_root, int y_root )
{
@ -1455,8 +1490,12 @@ bool Client::motionNotifyEvent( Window w, int /*state*/, int x, int y, int x_roo
x = this->x(); // translate from grab window to local coords
y = this->y();
}
if( !waitingMotionEvent())
if( !waitingMotionEvent() )
{
handleMoveResize( x, y, x_root, y_root );
if( isMove() )
checkQuickTilingMaximizationZones( x_root, y_root );
}
return true;
}

View file

@ -3310,6 +3310,30 @@ void Client::setQuickTileMode( QuickTileMode mode, bool keyboard )
{
setMaximize(false, false);
checkMaximizeGeometry();
QPoint whichScreen = keyboard ? geometry().center() : cursorPos();
// DUPLICATED BELOW: --------------------------------------------------
// Temporary, so the maximize code doesn't get all confused
quick_tile_mode = QuickTileNone;
// Do the actual tile.
if( mode == QuickTileLeft )
{
QRect max = workspace()->clientArea( MaximizeArea, whichScreen, desktop() );
setGeometry( QRect( max.x(), max.y(), max.width()/2, max.height() ) );
}
else
{
QRect max = workspace()->clientArea( MaximizeArea, whichScreen, desktop() );
setGeometry( QRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() ) );
}
// Store the mode change
quick_tile_mode = mode;
return;
}
// First, check if the requested tile negates the tile we're in now: move right when left or left when right
@ -3371,6 +3395,8 @@ void Client::setQuickTileMode( QuickTileMode mode, bool keyboard )
// Store geometry first, so we can go out of this tile later.
geom_pretile = geometry();
// DUPLICATED ABOVE: --------------------------------------------------
// Temporary, so the maximize code doesn't get all confused
quick_tile_mode = QuickTileNone;

View file

@ -92,19 +92,6 @@ void KWinScreenEdgesConfig::groupChanged()
monitorHideEdge( ElectricRight, hide );
monitorHideEdge( ElectricBottom, hide );
monitorHideEdge( ElectricLeft, hide );
// Desktop switch conflicts
if( m_ui->quickTileBox->isChecked() || m_ui->quickMaximizeBox->isChecked() )
{
m_ui->desktopSwitchLabel->setEnabled( false );
m_ui->desktopSwitchCombo->setEnabled( false );
m_ui->desktopSwitchCombo->setCurrentIndex( 0 );
}
else
{
m_ui->desktopSwitchLabel->setEnabled( true );
m_ui->desktopSwitchCombo->setEnabled( true );
}
}
void KWinScreenEdgesConfig::load()

View file

@ -2216,54 +2216,8 @@ void Workspace::checkElectricBorder(const QPoint& pos, Time now)
{
// If moving a client or have force doing the desktop switch
if( options->electricBorders() != Options::ElectricDisabled )
{
electricBorderSwitchDesktop( border, pos );
return; // Don't reset cursor position
}
// maximize only when not using for switch
if( options->electricBorderMaximize() && border == ElectricTop &&
movingClient->isMaximizable() )
{
movingClient->setElectricBorderMode( ElectricMaximizeMode );
movingClient->setElectricBorderMaximizing( true );
// Make electric windows thicker so we can detect when the user wants to cancel
QRect r = Kephal::ScreenUtils::desktopGeometry();
XRaiseWindow( display(), electric_windows[ElectricTop] );
XResizeWindow( display(), electric_windows[ElectricTop],
r.width() - 2, 20 );
return; // Don't reset cursor position
}
if( options->electricBorderTiling() )
{
bool activate = false;
if( border == ElectricLeft )
{
movingClient->setElectricBorderMode( ElectricLeftMode );
activate = true;
// Make electric windows thicker so we can detect when the user wants to cancel
QRect r = Kephal::ScreenUtils::desktopGeometry();
XRaiseWindow( display(), electric_windows[ElectricLeft] );
XResizeWindow( display(), electric_windows[ElectricLeft],
20, r.height() - 2 );
}
else if( border == ElectricRight )
{
movingClient->setElectricBorderMode( ElectricRightMode );
activate = true;
// Make electric windows thicker so we can detect when the user wants to cancel
QRect r = Kephal::ScreenUtils::desktopGeometry();
XRaiseWindow( display(), electric_windows[ElectricRight] );
XMoveResizeWindow( display(), electric_windows[ElectricRight],
r.right() - 19, r.top() + 1, 20, r.height() - 2 );
}
if( activate )
{
movingClient->setElectricBorderMaximizing( true );
return; // Don't reset cursor position
}
}
else
return; // Don't reset cursor position
return; // Don't reset cursor position
}
else
{
@ -2371,26 +2325,6 @@ bool Workspace::electricBorderEvent( XEvent* e )
{
if( e->type == EnterNotify )
{
if( movingClient && movingClient->isElectricBorderMaximizing() &&
e->xcrossing.window == movingClient->moveResizeGrabWindow() )
{ // Cancel the quick tiling/maximization action when the user moves away from the edge.
// This event isn't from the border window; it came from the grab window.
movingClient->setElectricBorderMaximizing( false );
// Restore electric windows back to their normal size
switch( movingClient->electricBorderMode() )
{
case ElectricMaximizeMode:
restoreElectricBorderSize( ElectricTop );
break;
case ElectricLeftMode:
restoreElectricBorderSize( ElectricLeft );
break;
case ElectricRightMode:
restoreElectricBorderSize( ElectricRight );
break;
}
}
for( int i = 0; i < ELECTRIC_COUNT; ++i )
if( electric_windows[i] != None && e->xcrossing.window == electric_windows[i] )
{ // The user entered an electric border