From 754f5d0829afb1a12ea4bf2302e9c9a35383ba70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 8 Sep 2009 20:01:08 +0000 Subject: [PATCH] Quick maximize and tiling when moving a window to the left/right or top screen edge. Top screen edge (un)maximizes. Left screen edge sets window to left half of screen geometry, right edge to other half. svn path=/trunk/KDE/kdebase/workspace/; revision=1021305 --- client.cpp | 1 + client.h | 8 ++ geometry.cpp | 93 ++++++++++++- kcmkwin/kwinscreenedges/main.cpp | 13 ++ kcmkwin/kwinscreenedges/main.ui | 24 +++- lib/kwinglobals.h | 7 + options.cpp | 2 + options.h | 12 ++ workspace.cpp | 219 ++++++++++++++++++++++++++----- workspace.h | 7 + 10 files changed, 349 insertions(+), 37 deletions(-) diff --git a/client.cpp b/client.cpp index ce6cb8c817..20f22f971d 100644 --- a/client.cpp +++ b/client.cpp @@ -121,6 +121,7 @@ Client::Client( Workspace* ws ) , padding_right( 0 ) , padding_top( 0 ) , padding_bottom( 0 ) + , electricMaximizing( false ) { // TODO: Do all as initialization // Set the initial mapping state diff --git a/client.h b/client.h index fa5dc47bd3..5ae24aa773 100644 --- a/client.h +++ b/client.h @@ -218,6 +218,11 @@ class Client void resizeWithChecks( int w, int h, ForceGeometry_t force = NormalGeometrySet ); void resizeWithChecks( const QSize& s, ForceGeometry_t force = NormalGeometrySet ); void keepInArea( QRect area, bool partial = false ); + void setElectricBorderMode( ElectricMaximizingMode mode ); + ElectricMaximizingMode electricBorderMode() const; + void setElectricBorderMaximizing( bool maximizing ); + bool isElectricBorderMaximizing() const; + QRect electricBorderMaximizeGeometry(); void growHorizontal(); void shrinkHorizontal(); @@ -582,6 +587,9 @@ class Client QPixmap decorationPixmapLeft, decorationPixmapRight, decorationPixmapTop, decorationPixmapBottom; PaintRedirector* paintRedirector; + bool electricMaximizing; + ElectricMaximizingMode electricMode; + friend bool performTransiencyCheck(); }; diff --git a/geometry.cpp b/geometry.cpp index c4cc4f2b70..2af2ee59af 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -2709,7 +2709,9 @@ bool Client::startMoveResize() Notify::raise( isResize() ? Notify::ResizeStart : Notify::MoveStart ); if( effects ) static_cast(effects)->windowUserMovedResized( effectWindow(), true, false ); - if( options->electricBorders() == Options::ElectricMoveOnly ) + if( options->electricBorders() == Options::ElectricMoveOnly || + options->electricBorderMaximize() || + options->electricBorderTiling() ) workspace()->reserveElectricBorderSwitching( true ); return true; } @@ -2717,10 +2719,40 @@ bool Client::startMoveResize() void Client::finishMoveResize( bool cancel ) { leaveMoveResize(); + if( isElectricBorderMaximizing() ) + { + cancel = true; + } if( cancel ) setGeometry( initialMoveResizeGeom ); else setGeometry( moveResizeGeom ); + if( isElectricBorderMaximizing() ) + { + electricMaximizing = false; + switch( electricMode ) + { + case ElectricMaximizeMode: + if( maximizeMode() == MaximizeFull ) + setMaximize( false, false ); + else + setMaximize( true, true ); + break; + case ElectricLeftMode: + { + QRect max = workspace()->clientArea( MaximizeArea, cursorPos() ,workspace()->currentDesktop() ); + setGeometry( QRect( max.x(), max.y(), max.width()/2, max.height() ) ); + break; + } + case ElectricRightMode: + { + QRect max = workspace()->clientArea( MaximizeArea, cursorPos() ,workspace()->currentDesktop() ); + setGeometry( QRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() ) ); + break; + } + } + workspace()->hideElectricBorderWindowOutline(); + } checkMaximizeGeometry(); // FRAME update(); Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd ); @@ -2755,7 +2787,9 @@ void Client::leaveMoveResize() eater = 0; delete sync_timeout; sync_timeout = NULL; - if( options->electricBorders() == Options::ElectricMoveOnly ) + if( options->electricBorders() == Options::ElectricMoveOnly || + options->electricBorderMaximize() || + options->electricBorderTiling() ) workspace()->reserveElectricBorderSwitching( false ); } @@ -3094,6 +3128,8 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root ) void Client::performMoveResize() { + if( isElectricBorderMaximizing() ) + return; #ifdef HAVE_XSYNC if( isResize() && sync_counter != None ) { @@ -3130,4 +3166,57 @@ void Client::syncTimeout() performMoveResize(); } +void Client::setElectricBorderMode( ElectricMaximizingMode mode ) + { + electricMode = mode; + } + +ElectricMaximizingMode Client::electricBorderMode() const + { + return electricMode; + } + +bool Client::isElectricBorderMaximizing() const + { + return electricMaximizing; + } + +void Client::setElectricBorderMaximizing( bool maximizing ) + { + electricMaximizing = maximizing; + if( maximizing ) + workspace()->showElectricBorderWindowOutline(); + else + workspace()->hideElectricBorderWindowOutline(); + } + +QRect Client::electricBorderMaximizeGeometry() + { + QRect ret; + switch( electricMode ) + { + case ElectricMaximizeMode: + { + if( maximizeMode() == MaximizeFull ) + ret = geometryRestore(); + else + ret = workspace()->clientArea( MaximizeArea, cursorPos() ,workspace()->currentDesktop() ); + break; + } + case ElectricLeftMode: + { + QRect max = workspace()->clientArea( MaximizeArea, cursorPos() ,workspace()->currentDesktop() ); + ret = QRect( max.x(), max.y(), max.width()/2, max.height() ); + break; + } + case ElectricRightMode: + { + QRect max = workspace()->clientArea( MaximizeArea, cursorPos() ,workspace()->currentDesktop() ); + ret = QRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() ); + break; + } + } + return ret; + } + } // namespace diff --git a/kcmkwin/kwinscreenedges/main.cpp b/kcmkwin/kwinscreenedges/main.cpp index d7c0c67836..65de840299 100644 --- a/kcmkwin/kwinscreenedges/main.cpp +++ b/kcmkwin/kwinscreenedges/main.cpp @@ -56,6 +56,8 @@ KWinScreenEdgesConfig::KWinScreenEdgesConfig( QWidget* parent, const QVariantLis connect( m_ui->desktopSwitchCombo, SIGNAL( currentIndexChanged(int) ), this, SLOT( changed() )); connect( m_ui->activationDelaySpin, SIGNAL( valueChanged(int) ), this, SLOT( changed() )); connect( m_ui->triggerCooldownSpin, SIGNAL( valueChanged(int) ), this, SLOT( changed() )); + connect( m_ui->quickMaximizeBox, SIGNAL( stateChanged(int) ), this, SLOT( changed() )); + connect( m_ui->quickTileBox, SIGNAL( stateChanged(int) ), this, SLOT( changed() )); // Visual feedback of action group conflicts connect( m_ui->desktopSwitchCombo, SIGNAL( currentIndexChanged(int) ), this, SLOT( groupChanged() )); @@ -84,6 +86,11 @@ void KWinScreenEdgesConfig::groupChanged() // Desktop switch conflicts m_ui->desktopSwitchLabel->setEnabled( true ); m_ui->desktopSwitchCombo->setEnabled( true ); + + bool enableMaximize = false; + if( m_ui->desktopSwitchCombo->currentIndex() == 0 ) + enableMaximize = true; + m_ui->quickMaximizeBox->setEnabled( enableMaximize ); } void KWinScreenEdgesConfig::load() @@ -97,6 +104,8 @@ void KWinScreenEdgesConfig::load() m_ui->desktopSwitchCombo->setCurrentIndex( config.readEntry( "ElectricBorders", 0 )); m_ui->activationDelaySpin->setValue( config.readEntry( "ElectricBorderDelay", 150 )); m_ui->triggerCooldownSpin->setValue( config.readEntry( "ElectricBorderCooldown", 350 )); + m_ui->quickMaximizeBox->setChecked( config.readEntry( "ElectricBorderMaximize", false )); + m_ui->quickTileBox->setChecked( config.readEntry( "ElectricBorderTiling", false )); emit changed( false ); } @@ -112,6 +121,8 @@ void KWinScreenEdgesConfig::save() config.writeEntry( "ElectricBorders", m_ui->desktopSwitchCombo->currentIndex() ); config.writeEntry( "ElectricBorderDelay", m_ui->activationDelaySpin->value() ); config.writeEntry( "ElectricBorderCooldown", m_ui->triggerCooldownSpin->value() ); + config.writeEntry( "ElectricBorderMaximize", m_ui->quickMaximizeBox->isChecked() ); + config.writeEntry( "ElectricBorderTiling", m_ui->quickTileBox->isChecked() ); config.sync(); @@ -129,6 +140,8 @@ void KWinScreenEdgesConfig::defaults() m_ui->desktopSwitchCombo->setCurrentIndex( 0 ); m_ui->activationDelaySpin->setValue( 150 ); m_ui->triggerCooldownSpin->setValue( 350 ); + m_ui->quickMaximizeBox->setChecked( false ); + m_ui->quickTileBox->setChecked( false ); emit changed( true ); } diff --git a/kcmkwin/kwinscreenedges/main.ui b/kcmkwin/kwinscreenedges/main.ui index c0615a4da6..7a0b29fc1f 100644 --- a/kcmkwin/kwinscreenedges/main.ui +++ b/kcmkwin/kwinscreenedges/main.ui @@ -58,7 +58,7 @@ - + Amount of time required for the mouse cursor to be pushed against the edge of the screen before the action is triggered @@ -71,7 +71,7 @@ - + ms @@ -87,7 +87,7 @@ - + true @@ -103,7 +103,7 @@ - + true @@ -122,7 +122,7 @@ - + Qt::Vertical @@ -135,6 +135,20 @@ + + + + Maximize windows by dragging them to the top of the screen + + + + + + + Tile windows by dragging them to the side of the screen + + + diff --git a/lib/kwinglobals.h b/lib/kwinglobals.h index f5113dd5bc..b6f2161274 100644 --- a/lib/kwinglobals.h +++ b/lib/kwinglobals.h @@ -72,6 +72,13 @@ enum ElectricBorder ElectricNone }; +enum ElectricMaximizingMode +{ + ElectricMaximizeMode, + ElectricLeftMode, + ElectricRightMode +}; + // TODO: Hardcoding is bad, need to add some way of registering global actions to these. // When designing the new system we must keep in mind that we have conditional actions // such as "only when moving windows" desktop switching that the current global action diff --git a/options.cpp b/options.cpp index 946b91e3bc..ff9e8ebd01 100644 --- a/options.cpp +++ b/options.cpp @@ -143,6 +143,8 @@ unsigned long Options::updateSettings() electric_borders = config.readEntry("ElectricBorders", 0); electric_border_delay = config.readEntry("ElectricBorderDelay", 150); electric_border_cooldown = config.readEntry("ElectricBorderCooldown", 350); + electric_border_maximize = config.readEntry("ElectricBorderMaximize", false); + electric_border_tiling = config.readEntry("ElectricBorderTiling" , false ); OpTitlebarDblClick = windowOperation( config.readEntry("TitlebarDoubleClickCommand", "Maximize"), true ); setOpMaxButtonLeftClick( windowOperation( config.readEntry("MaximizeButtonLeftClickCommand", "Maximize"), true )); diff --git a/options.h b/options.h index 6f727855d5..b399757fb5 100644 --- a/options.h +++ b/options.h @@ -289,6 +289,16 @@ class Options : public KDecorationOptions * @returns the trigger cooldown for electric borders in milliseconds. */ int electricBorderCooldown(); + /** + * @returns true if a window gets maximized when it reaches top screen edge + * while being moved. + */ + bool electricBorderMaximize() const { return electric_border_maximize; } + /** + * @returns true if window is tiled to half screen when reaching left or + * right screen edge while been moved + */ + bool electricBorderTiling() const { return electric_border_tiling; } bool topMenuEnabled() const { return topmenus; } bool desktopTopMenu() const { return desktop_topmenu; } @@ -353,6 +363,8 @@ class Options : public KDecorationOptions int electric_borders; int electric_border_delay; int electric_border_cooldown; + bool electric_border_maximize; + bool electric_border_tiling; bool show_geometry_tip; bool topmenus; bool desktop_topmenu; diff --git a/workspace.cpp b/workspace.cpp index 3888727a9e..9efea05dd7 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -453,6 +453,17 @@ void Workspace::init() } if( new_active_client != NULL ) activateClient( new_active_client ); + + // outline windows for electric border maximize window mode + outline_left = XCreateWindow( QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0, + CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr ); + outline_right = XCreateWindow( QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0, + CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr ); + outline_top = XCreateWindow( QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0, + CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr ); + outline_bottom = XCreateWindow( QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0, + CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr ); + // SELI TODO: This won't work with unreasonable focus policies, // and maybe in rare cases also if the selected client doesn't // want focus @@ -493,6 +504,12 @@ Workspace::~Workspace() writeWindowRules(); KGlobal::config()->sync(); + // destroy outline windows for electric border maximize window mode + XDestroyWindow( QX11Info::display(), outline_left ); + XDestroyWindow( QX11Info::display(), outline_right ); + XDestroyWindow( QX11Info::display(), outline_top ); + XDestroyWindow( QX11Info::display(), outline_bottom ); + delete rootInfo; delete supportWindow; delete mgr; @@ -2117,6 +2134,7 @@ void Workspace::checkElectricBorder(const QPoint& pos, Time now) Time treshold_reset = 250; // Reset timeout Time treshold_trigger = options->electricBorderCooldown(); // Minimum time between triggers int distance_reset = 30; // Mouse should not move more than this many pixels + int pushback_pixels = 1; ElectricBorder border; if( pos.x() == electricLeft && pos.y() == electricTop ) @@ -2153,41 +2171,80 @@ void Workspace::checkElectricBorder(const QPoint& pos, Time now) electric_current_border = ElectricNone; electric_time_last_trigger = now; if( movingClient ) - { // 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 - } - if( options->electricBorders() == Options::ElectricAlways && - ( border == ElectricTop || border == ElectricRight || - border == ElectricBottom || border == ElectricLeft )) - { // If desktop switching is always enabled don't apply it to the corners if - // an effect is applied to it (We will check that later). - electricBorderSwitchDesktop( border, pos ); - return; // Don't reset cursor position - } - switch( options->electricBorderAction( border )) { - case ElectricActionDashboard: // Display Plasma dashboard + // If moving a client or have force doing the desktop switch + if( options->electricBorders() != Options::ElectricDisabled ) { - QDBusInterface plasmaApp( "org.kde.plasma-desktop", "/App" ); - plasmaApp.call( "toggleDashboard" ); + electricBorderSwitchDesktop( border, pos ); + return; // Don't reset cursor position } - break; - case ElectricActionShowDesktop: + // maximize only when not using for switch + if( options->electricBorderMaximize() && border == ElectricTop && + movingClient->isMaximizable() ) { - setShowingDesktop( !showingDesktop() ); - break; + bool enable = !movingClient->isElectricBorderMaximizing(); + movingClient->setElectricBorderMode( ElectricMaximizeMode ); + movingClient->setElectricBorderMaximizing( enable ); + // stronger push back + pushback_pixels = 10; } - case ElectricActionNone: // Either desktop switching or an effect - default: + if( options->electricBorderTiling() ) { - if( effects && static_cast( effects )->borderActivated( border )) - {} // Handled by effects - else + bool enable = !movingClient->isElectricBorderMaximizing(); + bool activate = false; + if( border == ElectricLeft ) { - electricBorderSwitchDesktop( border, pos ); - return; // Don't reset cursor position + movingClient->setElectricBorderMode( ElectricLeftMode ); + activate = true; + } + else if( border == ElectricRight ) + { + movingClient->setElectricBorderMode( ElectricRightMode ); + activate = true; + } + if( activate ) + { + movingClient->setElectricBorderMaximizing( enable ); + // stronger push back + pushback_pixels = 10; + } + } + else + return; // Don't reset cursor position + } + else + { + if( options->electricBorders() == Options::ElectricAlways && + ( border == ElectricTop || border == ElectricRight || + border == ElectricBottom || border == ElectricLeft )) + { // If desktop switching is always enabled don't apply it to the corners if + // an effect is applied to it (We will check that later). + electricBorderSwitchDesktop( border, pos ); + return; // Don't reset cursor position + } + switch( options->electricBorderAction( border )) + { + case ElectricActionDashboard: // Display Plasma dashboard + { + QDBusInterface plasmaApp( "org.kde.plasma-desktop", "/App" ); + plasmaApp.call( "toggleDashboard" ); + } + break; + case ElectricActionShowDesktop: + { + setShowingDesktop( !showingDesktop() ); + break; + } + case ElectricActionNone: // Either desktop switching or an effect + default: + { + if( effects && static_cast( effects )->borderActivated( border )) + {} // Handled by effects + else + { + electricBorderSwitchDesktop( border, pos ); + return; // Don't reset cursor position + } } } } @@ -2203,8 +2260,22 @@ void Workspace::checkElectricBorder(const QPoint& pos, Time now) // Reset the pointer to find out whether the user is really pushing // (the direction back from which it came, starting from top clockwise) - const int xdiff[ELECTRIC_COUNT] = { 0, -1, -1, -1, 0, 1, 1, 1 }; - const int ydiff[ELECTRIC_COUNT] = { 1, 1, 0, -1, -1, -1, 0, 1 }; + const int xdiff[ELECTRIC_COUNT] = { 0, + -pushback_pixels, + -pushback_pixels, + -pushback_pixels, + 0, + pushback_pixels, + pushback_pixels, + pushback_pixels }; + const int ydiff[ELECTRIC_COUNT] = { pushback_pixels, + pushback_pixels, + 0, + -pushback_pixels, + -pushback_pixels, + -pushback_pixels, + 0, + pushback_pixels }; QCursor::setPos( pos.x() + xdiff[border], pos.y() + ydiff[border] ); } @@ -2271,6 +2342,94 @@ bool Workspace::electricBorderEvent( XEvent* e ) return false; } +void Workspace::showElectricBorderWindowOutline() + { + if( !movingClient ) + return; + // code copied from TabBox::updateOutline() in tabbox.cpp + QRect c = movingClient->electricBorderMaximizeGeometry(); + // left/right parts are between top/bottom, they don't reach as far as the corners + XMoveResizeWindow( QX11Info::display(), outline_left, c.x(), c.y() + 5, 5, c.height() - 10 ); + XMoveResizeWindow( QX11Info::display(), outline_right, c.x() + c.width() - 5, c.y() + 5, 5, c.height() - 10 ); + XMoveResizeWindow( QX11Info::display(), outline_top, c.x(), c.y(), c.width(), 5 ); + XMoveResizeWindow( QX11Info::display(), outline_bottom, c.x(), c.y() + c.height() - 5, c.width(), 5 ); + { + QPixmap pix( 5, c.height() - 10 ); + QPainter p( &pix ); + p.setPen( Qt::white ); + p.drawLine( 0, 0, 0, pix.height() - 1 ); + p.drawLine( 4, 0, 4, pix.height() - 1 ); + p.setPen( Qt::gray ); + p.drawLine( 1, 0, 1, pix.height() - 1 ); + p.drawLine( 3, 0, 3, pix.height() - 1 ); + p.setPen( Qt::black ); + p.drawLine( 2, 0, 2, pix.height() - 1 ); + p.end(); + XSetWindowBackgroundPixmap( QX11Info::display(), outline_left, pix.handle()); + XSetWindowBackgroundPixmap( QX11Info::display(), outline_right, pix.handle()); + } + { + QPixmap pix( c.width(), 5 ); + QPainter p( &pix ); + p.setPen( Qt::white ); + p.drawLine( 0, 0, pix.width() - 1 - 0, 0 ); + p.drawLine( 4, 4, pix.width() - 1 - 4, 4 ); + p.drawLine( 0, 0, 0, 4 ); + p.drawLine( pix.width() - 1 - 0, 0, pix.width() - 1 - 0, 4 ); + p.setPen( Qt::gray ); + p.drawLine( 1, 1, pix.width() - 1 - 1, 1 ); + p.drawLine( 3, 3, pix.width() - 1 - 3, 3 ); + p.drawLine( 1, 1, 1, 4 ); + p.drawLine( 3, 3, 3, 4 ); + p.drawLine( pix.width() - 1 - 1, 1, pix.width() - 1 - 1, 4 ); + p.drawLine( pix.width() - 1 - 3, 3, pix.width() - 1 - 3, 4 ); + p.setPen( Qt::black ); + p.drawLine( 2, 2, pix.width() - 1 - 2, 2 ); + p.drawLine( 2, 2, 2, 4 ); + p.drawLine( pix.width() - 1 - 2, 2, pix.width() - 1 - 2, 4 ); + p.end(); + XSetWindowBackgroundPixmap( QX11Info::display(), outline_top, pix.handle()); + } + { + QPixmap pix( c.width(), 5 ); + QPainter p( &pix ); + p.setPen( Qt::white ); + p.drawLine( 4, 0, pix.width() - 1 - 4, 0 ); + p.drawLine( 0, 4, pix.width() - 1 - 0, 4 ); + p.drawLine( 0, 4, 0, 0 ); + p.drawLine( pix.width() - 1 - 0, 4, pix.width() - 1 - 0, 0 ); + p.setPen( Qt::gray ); + p.drawLine( 3, 1, pix.width() - 1 - 3, 1 ); + p.drawLine( 1, 3, pix.width() - 1 - 1, 3 ); + p.drawLine( 3, 1, 3, 0 ); + p.drawLine( 1, 3, 1, 0 ); + p.drawLine( pix.width() - 1 - 3, 1, pix.width() - 1 - 3, 0 ); + p.drawLine( pix.width() - 1 - 1, 3, pix.width() - 1 - 1, 0 ); + p.setPen( Qt::black ); + p.drawLine( 2, 2, pix.width() - 1 - 2, 2 ); + p.drawLine( 2, 0, 2, 2 ); + p.drawLine( pix.width() - 1 - 2, 0, pix.width() - 1 - 2, 2 ); + p.end(); + XSetWindowBackgroundPixmap( QX11Info::display(), outline_bottom, pix.handle()); + } + XClearWindow( QX11Info::display(), outline_left ); + XClearWindow( QX11Info::display(), outline_right ); + XClearWindow( QX11Info::display(), outline_top ); + XClearWindow( QX11Info::display(), outline_bottom ); + XMapWindow( QX11Info::display(), outline_left ); + XMapWindow( QX11Info::display(), outline_right ); + XMapWindow( QX11Info::display(), outline_top ); + XMapWindow( QX11Info::display(), outline_bottom ); + } + +void Workspace::hideElectricBorderWindowOutline() + { + XUnmapWindow( QX11Info::display(), outline_left ); + XUnmapWindow( QX11Info::display(), outline_right ); + XUnmapWindow( QX11Info::display(), outline_top ); + XUnmapWindow( QX11Info::display(), outline_bottom ); + } + //----------------------------------------------------------------------------- // Top menu diff --git a/workspace.h b/workspace.h index 483847c809..dd922ae6a8 100644 --- a/workspace.h +++ b/workspace.h @@ -467,6 +467,8 @@ class Workspace : public QObject, public KDecorationDefines void stopMousePolling(); void raiseElectricBorderWindows(); + void showElectricBorderWindowOutline(); + void hideElectricBorderWindowOutline(); public slots: void addRepaintFull(); @@ -903,6 +905,11 @@ class Workspace : public QObject, public KDecorationDefines QList< int > composite_paint_times; QTimer compositeResetTimer; // for compressing composite resets + Window outline_left; + Window outline_right; + Window outline_top; + Window outline_bottom; + private: friend bool performTransiencyCheck(); };