From kwin Tue Sep 01 07:12:18 2009 From: Martin =?iso-8859-1?q?Gr=E4=DFlin?= Date: Tue, 01 Sep 2009 07:12:18 +0000 To: kwin Subject: Re: [Review Request] Maximizing windows on screen edge Message-Id: <200909010912.30188.kde () martin-graesslin ! com> X-MARC-Message: https://marc.info/?l=kwin&m=125178920127098 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--===============0706768643==" --===============0706768643== Content-Type: multipart/signed; boundary="nextPart4234027.bXMtst8Ekf"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit --nextPart4234027.bXMtst8Ekf Content-Type: multipart/mixed; boundary="Boundary-01=_TlMnKeJeLyA4s6g" Content-Transfer-Encoding: 7bit --Boundary-01=_TlMnKeJeLyA4s6g Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Am Montag 31 August 2009 04:44:50 schrieb Lucas Murray: > On Mon, Aug 31, 2009 at 4:23 AM, Martin Gr=E4=DFlin=20 wrote: > > Attached is a patch which implements "Aero snap" for kwin. I'm still > > totally unsure if we should have such a feature or not. Personally I > > think it's completely useless, but it could help people switching from > > Win7 to KDE. So that could be a pro. > > Haven't reviewed the code yet. Just commenting on the idea: > > It's not a useless feature--I'll actually be voting to have it enabled > by default actually. Plus Metacity uses the quick maximize thing > already by default so it's already been used by Linux people. > > I personally prefer the GUI we had before you removed it in commit > 962763 [1]. It had two separate checkboxes instead of one; one for > quick maximize and one for quick tiling. The more complex part of that > commit doesn't need to be readded as I've since realised that enabling > the quick features is not mutually exclusive with other electric > border triggers (One for while windows are moving, the other when > not). > > [1] http://websvn.kde.org/?view=3Drev&revision=3D962763 new patch with the two settings back --Boundary-01=_TlMnKeJeLyA4s6g Content-Type: text/x-patch; charset="UTF-8"; name="screen-edge-maximizing-v2.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="screen-edge-maximizing-v2.diff" diff --git a/client.cpp b/client.cpp index ce6cb8c..20f22f9 100644 =2D-- 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 =20 // Set the initial mapping state diff --git a/client.h b/client.h index fa5dc47..5ae24aa 100644 =2D-- a/client.h +++ b/client.h @@ -218,6 +218,11 @@ class Client void resizeWithChecks( int w, int h, ForceGeometry_t force =3D Nor= malGeometrySet ); void resizeWithChecks( const QSize& s, ForceGeometry_t force =3D N= ormalGeometrySet ); void keepInArea( QRect area, bool partial =3D false ); + void setElectricBorderMode( ElectricMaximizingMode mode ); + ElectricMaximizingMode electricBorderMode() const; + void setElectricBorderMaximizing( bool maximizing ); + bool isElectricBorderMaximizing() const; + QRect electricBorderMaximizeGeometry(); =20 void growHorizontal(); void shrinkHorizontal(); @@ -582,6 +587,9 @@ class Client QPixmap decorationPixmapLeft, decorationPixmapRight, decorationPix= mapTop, decorationPixmapBottom; PaintRedirector* paintRedirector; =20 + bool electricMaximizing; + ElectricMaximizingMode electricMode; + friend bool performTransiencyCheck(); }; =20 diff --git a/geometry.cpp b/geometry.cpp index c4cc4f2..2af2ee5 100644 =2D-- 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 ); =2D if( options->electricBorders() =3D=3D Options::ElectricMoveOnly ) + if( options->electricBorders() =3D=3D 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 =3D true; + } if( cancel ) setGeometry( initialMoveResizeGeom ); else setGeometry( moveResizeGeom ); + if( isElectricBorderMaximizing() ) + { + electricMaximizing =3D false; + switch( electricMode ) + { + case ElectricMaximizeMode: + if( maximizeMode() =3D=3D MaximizeFull ) + setMaximize( false, false ); + else + setMaximize( true, true ); + break; + case ElectricLeftMode: + { + QRect max =3D workspace()->clientArea( MaximizeArea, curso= rPos() ,workspace()->currentDesktop() ); + setGeometry( QRect( max.x(), max.y(), max.width()/2, max.h= eight() ) ); + break; + } + case ElectricRightMode: + { + QRect max =3D workspace()->clientArea( MaximizeArea, curso= rPos() ,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 =3D 0; delete sync_timeout; sync_timeout =3D NULL; =2D if( options->electricBorders() =3D=3D Options::ElectricMoveOnly ) + if( options->electricBorders() =3D=3D Options::ElectricMoveOnly || + options->electricBorderMaximize() || + options->electricBorderTiling() ) workspace()->reserveElectricBorderSwitching( false ); } =20 @@ -3094,6 +3128,8 @@ void Client::handleMoveResize( int x, int y, int x_ro= ot, int y_root ) =20 void Client::performMoveResize() { + if( isElectricBorderMaximizing() ) + return; #ifdef HAVE_XSYNC if( isResize() && sync_counter !=3D None ) { @@ -3130,4 +3166,57 @@ void Client::syncTimeout() performMoveResize(); } =20 +void Client::setElectricBorderMode( ElectricMaximizingMode mode ) + { + electricMode =3D mode; + } + +ElectricMaximizingMode Client::electricBorderMode() const + { + return electricMode; + } + +bool Client::isElectricBorderMaximizing() const + { + return electricMaximizing; + } + +void Client::setElectricBorderMaximizing( bool maximizing ) + { + electricMaximizing =3D maximizing; + if( maximizing ) + workspace()->showElectricBorderWindowOutline(); + else + workspace()->hideElectricBorderWindowOutline(); + } + +QRect Client::electricBorderMaximizeGeometry() + { + QRect ret; + switch( electricMode ) + { + case ElectricMaximizeMode: + { + if( maximizeMode() =3D=3D MaximizeFull ) + ret =3D geometryRestore(); + else + ret =3D workspace()->clientArea( MaximizeArea, cursorPos()= ,workspace()->currentDesktop() ); + break; + } + case ElectricLeftMode: + { + QRect max =3D workspace()->clientArea( MaximizeArea, cursorPos= () ,workspace()->currentDesktop() ); + ret =3D QRect( max.x(), max.y(), max.width()/2, max.height() ); + break; + } + case ElectricRightMode: + { + QRect max =3D workspace()->clientArea( MaximizeArea, cursorPos= () ,workspace()->currentDesktop() ); + ret =3D 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/mai= n.cpp index d7c0c67..65de840 100644 =2D-- a/kcmkwin/kwinscreenedges/main.cpp +++ b/kcmkwin/kwinscreenedges/main.cpp @@ -56,6 +56,8 @@ KWinScreenEdgesConfig::KWinScreenEdgesConfig( QWidget* pa= rent, 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, SL= OT( changed() )); + connect( m_ui->quickTileBox, SIGNAL( stateChanged(int) ), this, SLOT( = changed() )); =20 // 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 =3D false; + if( m_ui->desktopSwitchCombo->currentIndex() =3D=3D 0 ) + enableMaximize =3D true; + m_ui->quickMaximizeBox->setEnabled( enableMaximize ); } =20 void KWinScreenEdgesConfig::load() @@ -97,6 +104,8 @@ void KWinScreenEdgesConfig::load() m_ui->desktopSwitchCombo->setCurrentIndex( config.readEntry( "Electric= Borders", 0 )); m_ui->activationDelaySpin->setValue( config.readEntry( "ElectricBorder= Delay", 150 )); m_ui->triggerCooldownSpin->setValue( config.readEntry( "ElectricBorder= Cooldown", 350 )); + m_ui->quickMaximizeBox->setChecked( config.readEntry( "ElectricBorderM= aximize", false )); + m_ui->quickTileBox->setChecked( config.readEntry( "ElectricBorderTilin= g", false )); =20 emit changed( false ); } @@ -112,6 +121,8 @@ void KWinScreenEdgesConfig::save() config.writeEntry( "ElectricBorders", m_ui->desktopSwitchCombo->curren= tIndex() ); config.writeEntry( "ElectricBorderDelay", m_ui->activationDelaySpin->v= alue() ); config.writeEntry( "ElectricBorderCooldown", m_ui->triggerCooldownSpin= =2D>value() ); + config.writeEntry( "ElectricBorderMaximize", m_ui->quickMaximizeBox->i= sChecked() ); + config.writeEntry( "ElectricBorderTiling", m_ui->quickTileBox->isCheck= ed() ); =20 config.sync(); =20 @@ -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 ); =20 emit changed( true ); } diff --git a/kcmkwin/kwinscreenedges/main.ui b/kcmkwin/kwinscreenedges/main= =2Eui index c0615a4..7a0b29f 100644 =2D-- a/kcmkwin/kwinscreenedges/main.ui +++ b/kcmkwin/kwinscreenedges/main.ui @@ -58,7 +58,7 @@ =2D + 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 @@ =2D + ms @@ -87,7 +87,7 @@ =2D + true @@ -103,7 +103,7 @@ =2D + true @@ -122,7 +122,7 @@ =2D + Qt::Vertical @@ -135,6 +135,20 @@ + + + + Maximize windows by dragging them to the top of the scree= n + + + + + + + Tile windows by dragging them to the side of the screen + + + diff --git a/lib/kwinglobals.h b/lib/kwinglobals.h index f5113dd..b6f2161 100644 =2D-- a/lib/kwinglobals.h +++ b/lib/kwinglobals.h @@ -72,6 +72,13 @@ enum ElectricBorder ElectricNone }; =20 +enum ElectricMaximizingMode +{ + ElectricMaximizeMode, + ElectricLeftMode, + ElectricRightMode +}; + // TODO: Hardcoding is bad, need to add some way of registering global act= ions to these. // When designing the new system we must keep in mind that we have conditi= onal actions // such as "only when moving windows" desktop switching that the current g= lobal action diff --git a/options.cpp b/options.cpp index 946b91e..ff9e8eb 100644 =2D-- a/options.cpp +++ b/options.cpp @@ -143,6 +143,8 @@ unsigned long Options::updateSettings() electric_borders =3D config.readEntry("ElectricBorders", 0); electric_border_delay =3D config.readEntry("ElectricBorderDelay", 150); electric_border_cooldown =3D config.readEntry("ElectricBorderCooldown"= , 350); + electric_border_maximize =3D config.readEntry("ElectricBorderMaximize"= , false); + electric_border_tiling =3D config.readEntry("ElectricBorderTiling" , f= alse ); =20 OpTitlebarDblClick =3D windowOperation( config.readEntry("TitlebarDoub= leClickCommand", "Maximize"), true ); setOpMaxButtonLeftClick( windowOperation( config.readEntry("MaximizeBu= ttonLeftClickCommand", "Maximize"), true )); diff --git a/options.h b/options.h index 6f72785..b399757 100644 =2D-- a/options.h +++ b/options.h @@ -289,6 +289,16 @@ class Options : public KDecorationOptions * @returns the trigger cooldown for electric borders in millisecon= ds. */ int electricBorderCooldown(); + /** + * @returns true if a window gets maximized when it reaches top scr= een edge + * while being moved. + */ + bool electricBorderMaximize() const { return electric_border_maxim= ize; } + /** + * @returns true if window is tiled to half screen when reaching le= ft or + * right screen edge while been moved + */ + bool electricBorderTiling() const { return electric_border_tiling;= } =20 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 3888727..9efea05 100644 =2D-- a/workspace.cpp +++ b/workspace.cpp @@ -453,6 +453,17 @@ void Workspace::init() } if( new_active_client !=3D NULL ) activateClient( new_active_client ); + + // outline windows for electric border maximize window mode + outline_left =3D XCreateWindow( QX11Info::display(), QX11Info::appRoot= Window(), 0, 0, 1, 1, 0, + CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect= , &attr ); + outline_right =3D XCreateWindow( QX11Info::display(), QX11Info::appRoo= tWindow(), 0, 0, 1, 1, 0, + CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect= , &attr ); + outline_top =3D XCreateWindow( QX11Info::display(), QX11Info::appRootW= indow(), 0, 0, 1, 1, 0, + CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect= , &attr ); + outline_bottom =3D XCreateWindow( QX11Info::display(), QX11Info::appRo= otWindow(), 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(); =20 + // 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 =3D 250; // Reset timeout Time treshold_trigger =3D options->electricBorderCooldown(); // Minimu= m time between triggers int distance_reset =3D 30; // Mouse should not move more than this man= y pixels + int pushback_pixels =3D 1; =20 ElectricBorder border; if( pos.x() =3D=3D electricLeft && pos.y() =3D=3D electricTop ) @@ -2153,41 +2171,80 @@ void Workspace::checkElectricBorder(const QPoint& p= os, Time now) electric_current_border =3D ElectricNone; electric_time_last_trigger =3D now; if( movingClient ) =2D { // If moving a client or have force doing the desktop = switch + { + // If moving a client or have force doing the desktop swit= ch if( options->electricBorders() !=3D Options::ElectricDisab= led ) + { electricBorderSwitchDesktop( border, pos ); =2D return; // Don't reset cursor position =2D } =2D if( options->electricBorders() =3D=3D Options::ElectricAlway= s && =2D ( border =3D=3D ElectricTop || border =3D=3D ElectricRight= || =2D border =3D=3D ElectricBottom || border =3D=3D ElectricLe= ft )) =2D { // If desktop switching is always enabled don't apply = it to the corners if =2D // an effect is applied to it (We will check that late= r). =2D electricBorderSwitchDesktop( border, pos ); =2D return; // Don't reset cursor position =2D } =2D switch( options->electricBorderAction( border )) =2D { =2D case ElectricActionDashboard: // Display Plasma dashboard + return; // Don't reset cursor position + } + // maximize only when not using for switch + if( options->electricBorderMaximize() && border =3D=3D Ele= ctricTop && + movingClient->isMaximizable() ) { =2D QDBusInterface plasmaApp( "org.kde.plasma-desktop", = "/App" ); =2D plasmaApp.call( "toggleDashboard" ); + bool enable =3D !movingClient->isElectricBorderMaximiz= ing(); + movingClient->setElectricBorderMode( ElectricMaximizeM= ode ); + movingClient->setElectricBorderMaximizing( enable ); + // stronger push back + pushback_pixels =3D 10; } =2D break; =2D case ElectricActionShowDesktop: + if( options->electricBorderTiling() ) { =2D setShowingDesktop( !showingDesktop() ); =2D break; + bool enable =3D !movingClient->isElectricBorderMaximiz= ing(); + bool activate =3D false; + if( border =3D=3D ElectricLeft ) + { + movingClient->setElectricBorderMode( ElectricLeftM= ode ); + activate =3D true; + } + else if( border =3D=3D ElectricRight ) + { + movingClient->setElectricBorderMode( ElectricRight= Mode ); + activate =3D true; + } + if( activate ) + { + movingClient->setElectricBorderMaximizing( enable = ); + // stronger push back + pushback_pixels =3D 10; + } } =2D case ElectricActionNone: // Either desktop switching or = an effect =2D default: + else + return; // Don't reset cursor position + } + else + { + if( options->electricBorders() =3D=3D Options::ElectricAlw= ays && + ( border =3D=3D ElectricTop || border =3D=3D ElectricRight= || + border =3D=3D ElectricBottom || border =3D=3D Electric= Left )) + { // If desktop switching is always enabled don't appl= y it to the corners if + // an effect is applied to it (We will check that late= r). + electricBorderSwitchDesktop( border, pos ); + return; // Don't reset cursor position + } + switch( options->electricBorderAction( border )) { =2D if( effects && static_cast( eff= ects )->borderActivated( border )) =2D {} // Handled by effects =2D else + case ElectricActionDashboard: // Display Plasma dashbo= ard { =2D electricBorderSwitchDesktop( border, pos ); =2D return; // Don't reset cursor position + QDBusInterface plasmaApp( "org.kde.plasma-desktop"= , "/App" ); + plasmaApp.call( "toggleDashboard" ); + } + break; + case ElectricActionShowDesktop: + { + setShowingDesktop( !showingDesktop() ); + break; + } + case ElectricActionNone: // Either desktop switching o= r an effect + default: + { + if( effects && static_cast( e= ffects )->borderActivated( border )) + {} // Handled by effects + else + { + electricBorderSwitchDesktop( border, pos ); + return; // Don't reset cursor position + } } } } @@ -2203,8 +2260,22 @@ void Workspace::checkElectricBorder(const QPoint& po= s, Time now) =20 // Reset the pointer to find out whether the user is really pushing // (the direction back from which it came, starting from top clockwise) =2D const int xdiff[ELECTRIC_COUNT] =3D { 0, -1, -1, -1, 0, 1, 1, 1 }; =2D const int ydiff[ELECTRIC_COUNT] =3D { 1, 1, 0, -1, -1, -1, 0, 1 }; + const int xdiff[ELECTRIC_COUNT] =3D { 0, + -pushback_pixels, + -pushback_pixels, + -pushback_pixels, + 0, + pushback_pixels, + pushback_pixels, + pushback_pixels }; + const int ydiff[ELECTRIC_COUNT] =3D { pushback_pixels, + pushback_pixels, + 0, + -pushback_pixels, + -pushback_pixels, + -pushback_pixels, + 0, + pushback_pixels }; QCursor::setPos( pos.x() + xdiff[border], pos.y() + ydiff[border] ); } =20 @@ -2271,6 +2342,94 @@ bool Workspace::electricBorderEvent( XEvent* e ) return false; } =20 +void Workspace::showElectricBorderWindowOutline() + { + if( !movingClient ) + return; + // code copied from TabBox::updateOutline() in tabbox.cpp + QRect c =3D 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.w= idth(), 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.han= dle()); + XSetWindowBackgroundPixmap( QX11Info::display(), outline_right, pix.ha= ndle()); + } + { + 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.hand= le()); + } + { + 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.h= andle()); + } + 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 ); + } + //------------------------------------------------------------------------= =2D---- // Top menu =20 diff --git a/workspace.h b/workspace.h index 483847c..dd922ae 100644 =2D-- a/workspace.h +++ b/workspace.h @@ -467,6 +467,8 @@ class Workspace : public QObject, public KDecorationDef= ines void stopMousePolling(); =20 void raiseElectricBorderWindows(); + void showElectricBorderWindowOutline(); + void hideElectricBorderWindowOutline(); =20 public slots: void addRepaintFull(); @@ -903,6 +905,11 @@ class Workspace : public QObject, public KDecorationDe= fines QList< int > composite_paint_times; QTimer compositeResetTimer; // for compressing composite resets =20 + Window outline_left; + Window outline_right; + Window outline_top; + Window outline_bottom; + private: friend bool performTransiencyCheck(); }; --Boundary-01=_TlMnKeJeLyA4s6g-- --nextPart4234027.bXMtst8Ekf Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iJwEAAECAAYFAkqcyVMACgkQ/umpWjNT6CJ5eQQAuPfplru1MHKKiD0fh+IIijgY oWuCRpvf7VhttoCV/uNcI76oBdZZGxjzQMml9iabV4NKjETsNd/micZPF6O2Ah5o YbDEH7NPiqBnxpWyByczg33SA1Ii6eeDUfMFGsTg0kKfUOoPe9oIJ8nnGyUlkfMw 0HAfqi6L4FCPUjBiNj0= =xWDX -----END PGP SIGNATURE----- --nextPart4234027.bXMtst8Ekf-- --===============0706768643== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kwin mailing list kwin@kde.org https://mail.kde.org/mailman/listinfo/kwin --===============0706768643==--