From 41e5bfd7932f8cb1554badf432921bffbfdbe343 Mon Sep 17 00:00:00 2001 From: Lucas Murray Date: Sat, 9 Jan 2010 09:49:52 +0000 Subject: [PATCH] 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 --- client.h | 1 + data/update_tabbox_settings.cpp | 9 ----- events.cpp | 41 ++++++++++++++++++- geometry.cpp | 26 ++++++++++++ kcmkwin/kwinscreenedges/main.cpp | 13 ------ workspace.cpp | 68 +------------------------------- 6 files changed, 68 insertions(+), 90 deletions(-) diff --git a/client.h b/client.h index aa7272158a..2c8671faf1 100644 --- a/client.h +++ b/client.h @@ -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 ); diff --git a/data/update_tabbox_settings.cpp b/data/update_tabbox_settings.cpp index d43e835daf..87a76a4c22 100644 --- a/data/update_tabbox_settings.cpp +++ b/data/update_tabbox_settings.cpp @@ -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("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 = diff --git a/events.cpp b/events.cpp index 2431526d72..aa02424d7e 100644 --- a/events.cpp +++ b/events.cpp @@ -50,6 +50,8 @@ along with this program. If not, see . #include #endif +#include + 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; } diff --git a/geometry.cpp b/geometry.cpp index c4cf73848b..1a8a87f14e 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -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; diff --git a/kcmkwin/kwinscreenedges/main.cpp b/kcmkwin/kwinscreenedges/main.cpp index 3776c38468..b971cb4ae6 100644 --- a/kcmkwin/kwinscreenedges/main.cpp +++ b/kcmkwin/kwinscreenedges/main.cpp @@ -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() diff --git a/workspace.cpp b/workspace.cpp index e1d5d6dc4c..01cc317bd3 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -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