d651d18791
That is remove the window from all desktops on drag begin and attach the window to the mouse cursor. On release add them back to all desktop. That way it's possible to move pinned windows to other screens and it fixes a crash. BUG: 220582 svn path=/trunk/KDE/kdebase/workspace/; revision=1068482
1210 lines
46 KiB
C++
1210 lines
46 KiB
C++
/********************************************************************
|
|
KWin - the KDE window manager
|
|
This file is part of the KDE project.
|
|
|
|
Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
|
|
Copyright (C) 2008 Lucas Murray <lmurray@undefinedfire.com>
|
|
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*********************************************************************/
|
|
|
|
#include "desktopgrid.h"
|
|
|
|
#include "../presentwindows/presentwindows_proxy.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include <kaction.h>
|
|
#include <kactioncollection.h>
|
|
#include <kdebug.h>
|
|
#include <klocale.h>
|
|
#include <kconfiggroup.h>
|
|
#include <netwm_def.h>
|
|
#include <QEvent>
|
|
#include <QMouseEvent>
|
|
#include <kglobalsettings.h>
|
|
|
|
namespace KWin
|
|
{
|
|
|
|
// WARNING, TODO: This effect relies on the desktop layout being EWMH-compliant.
|
|
|
|
KWIN_EFFECT( desktopgrid, DesktopGridEffect )
|
|
|
|
DesktopGridEffect::DesktopGridEffect()
|
|
: activated( false )
|
|
, timeline()
|
|
, keyboardGrab( false )
|
|
, wasWindowMove( false )
|
|
, wasDesktopMove( false )
|
|
, windowMove( NULL )
|
|
, windowMoveDiff()
|
|
, gridSize()
|
|
, orientation( Qt::Horizontal )
|
|
, activeCell( 1, 1 )
|
|
, scale()
|
|
, unscaledBorder()
|
|
, scaledSize()
|
|
, scaledOffset()
|
|
, m_proxy( 0 )
|
|
{
|
|
// Load shortcuts
|
|
KActionCollection* actionCollection = new KActionCollection( this );
|
|
KAction* a = (KAction*) actionCollection->addAction( "ShowDesktopGrid" );
|
|
a->setText( i18n( "Show Desktop Grid" ));
|
|
a->setGlobalShortcut( KShortcut( Qt::CTRL + Qt::Key_F8 ));
|
|
shortcut = a->globalShortcut();
|
|
connect( a, SIGNAL( triggered( bool )), this, SLOT( toggle() ));
|
|
connect( a, SIGNAL( globalShortcutChanged( QKeySequence )), this, SLOT( globalShortcutChanged(QKeySequence)));
|
|
|
|
// Load all other configuration details
|
|
reconfigure( ReconfigureAll );
|
|
}
|
|
|
|
DesktopGridEffect::~DesktopGridEffect()
|
|
{
|
|
foreach( ElectricBorder border, borderActivate )
|
|
{
|
|
effects->unreserveElectricBorder( border );
|
|
}
|
|
}
|
|
|
|
void DesktopGridEffect::reconfigure( ReconfigureFlags )
|
|
{
|
|
KConfigGroup conf = effects->effectConfig( "DesktopGrid" );
|
|
|
|
foreach( ElectricBorder border, borderActivate )
|
|
{
|
|
effects->unreserveElectricBorder( border );
|
|
}
|
|
borderActivate.clear();
|
|
QList<int> borderList = QList<int>();
|
|
borderList.append( int( ElectricNone ) );
|
|
borderList = conf.readEntry( "BorderActivate", borderList );
|
|
foreach( int i, borderList )
|
|
{
|
|
borderActivate.append( ElectricBorder( i ) );
|
|
effects->reserveElectricBorder( ElectricBorder( i ) );
|
|
}
|
|
|
|
zoomDuration = animationTime( conf, "ZoomDuration", 300 );
|
|
timeline.setCurveShape( TimeLine::EaseInOutCurve );
|
|
timeline.setDuration( zoomDuration );
|
|
|
|
border = conf.readEntry( "BorderWidth", 10 );
|
|
desktopNameAlignment = Qt::Alignment( conf.readEntry( "DesktopNameAlignment", 0 ));
|
|
layoutMode = conf.readEntry( "LayoutMode", int( LayoutPager ));
|
|
customLayoutRows = conf.readEntry( "CustomLayoutRows", 2 );
|
|
m_usePresentWindows = conf.readEntry( "PresentWindows", true );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Screen painting
|
|
|
|
void DesktopGridEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
|
{
|
|
if( timeline.value() != 0 || activated || (isUsingPresentWindows() && isMotionManagerMovingWindows()) )
|
|
{
|
|
if( activated )
|
|
timeline.addTime(time);
|
|
else
|
|
timeline.removeTime(time);
|
|
for( int i = 0; i < effects->numberOfDesktops(); i++ )
|
|
{
|
|
if( i == highlightedDesktop - 1 )
|
|
hoverTimeline[i].addTime(time);
|
|
else
|
|
hoverTimeline[i].removeTime(time);
|
|
}
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
QList<WindowMotionManager>::iterator i;
|
|
for( i = m_managers.begin(); i != m_managers.end(); ++i )
|
|
(*i).calculate( time );
|
|
}
|
|
// PAINT_SCREEN_BACKGROUND_FIRST is needed because screen will be actually painted more than once,
|
|
// so with normal screen painting second screen paint would erase parts of the first paint
|
|
if( timeline.value() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows()) )
|
|
data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST;
|
|
if( !activated && timeline.value() == 0 && !(isUsingPresentWindows() && isMotionManagerMovingWindows()) )
|
|
finish();
|
|
}
|
|
effects->prePaintScreen( data, time );
|
|
}
|
|
|
|
void DesktopGridEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
|
{
|
|
if( timeline.value() == 0 && !isUsingPresentWindows() )
|
|
{
|
|
effects->paintScreen( mask, region, data );
|
|
return;
|
|
}
|
|
for( int desktop = 1; desktop <= effects->numberOfDesktops(); desktop++ )
|
|
{
|
|
ScreenPaintData d = data;
|
|
paintingDesktop = desktop;
|
|
effects->paintScreen( mask, region, d );
|
|
}
|
|
if( isUsingPresentWindows() && windowMove )
|
|
{
|
|
// the moving window has to be painted on top of all desktops
|
|
QPoint diff = cursorPos() - m_windowMoveStartPoint;
|
|
QRect geo = m_windowMoveGeometry.translated( diff );
|
|
WindowPaintData d( windowMove );
|
|
d.xScale *= (float)geo.width()/(float)windowMove->width();
|
|
d.yScale *= (float)geo.height()/(float)windowMove->height();
|
|
d.xTranslate += qRound( geo.left() - windowMove->x() );
|
|
d.yTranslate += qRound( geo.top() - windowMove->y() );
|
|
effects->drawWindow( windowMove, PAINT_WINDOW_TRANSFORMED, infiniteRegion(), d );
|
|
}
|
|
|
|
if( desktopNameAlignment )
|
|
{
|
|
for( int screen = 0; screen < effects->numScreens(); screen++ )
|
|
{
|
|
QRect screenGeom = effects->clientArea( ScreenArea, screen, 0 );
|
|
PaintClipper pc( screenGeom ); // TODO: Doesn't work in XRender for some reason?
|
|
for( int desktop = 1; desktop <= effects->numberOfDesktops(); desktop++ )
|
|
{
|
|
QPointF posTL( scalePos( screenGeom.topLeft(), desktop, screen ));
|
|
QPointF posBR( scalePos( screenGeom.bottomRight(), desktop, screen ));
|
|
QRect textArea( posTL.x(), posTL.y(), posBR.x() - posTL.x(), posBR.y() - posTL.y() );
|
|
textArea.adjust( textArea.width() / 10, textArea.height() / 10,
|
|
-textArea.width() / 10, -textArea.height() / 10 );
|
|
int x, y;
|
|
if( desktopNameAlignment & Qt::AlignLeft )
|
|
x = textArea.x();
|
|
else if( desktopNameAlignment & Qt::AlignRight )
|
|
x = textArea.right();
|
|
else
|
|
x = textArea.center().x();
|
|
if( desktopNameAlignment & Qt::AlignTop )
|
|
y = textArea.y();
|
|
else if( desktopNameAlignment & Qt::AlignBottom )
|
|
y = textArea.bottom();
|
|
else
|
|
y = textArea.center().y();
|
|
desktopNames[desktop-1]->setPosition( QPoint( x, y ));
|
|
desktopNames[desktop-1]->render( region, timeline.value(), 0.7 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DesktopGridEffect::postPaintScreen()
|
|
{
|
|
if( activated ? timeline.value() != 1 : timeline.value() != 0 )
|
|
effects->addRepaintFull(); // Repaint during zoom
|
|
if( isUsingPresentWindows() && isMotionManagerMovingWindows() )
|
|
effects->addRepaintFull();
|
|
if( activated )
|
|
{
|
|
for( int i = 0; i < effects->numberOfDesktops(); i++ )
|
|
{
|
|
if( hoverTimeline[i].value() != 0.0 && hoverTimeline[i].value() != 1.0 )
|
|
{ // Repaint during soft highlighting
|
|
effects->addRepaintFull();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
effects->postPaintScreen();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Window painting
|
|
|
|
void DesktopGridEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
|
|
{
|
|
if( timeline.value() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows()) )
|
|
{
|
|
if( w->isOnDesktop( paintingDesktop ))
|
|
{
|
|
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP );
|
|
if( w->isMinimized() && isUsingPresentWindows() )
|
|
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_MINIMIZE );
|
|
data.mask |= PAINT_WINDOW_TRANSFORMED;
|
|
|
|
// Split windows at screen edges
|
|
for( int screen = 0; screen < effects->numScreens(); screen++ )
|
|
{
|
|
QRect screenGeom = effects->clientArea( ScreenArea, screen, 0 );
|
|
if( w->x() < screenGeom.x() )
|
|
data.quads = data.quads.splitAtX( screenGeom.x() - w->x() );
|
|
if( w->x() + w->width() > screenGeom.x() + screenGeom.width() )
|
|
data.quads = data.quads.splitAtX( screenGeom.x() + screenGeom.width() - w->x() );
|
|
if( w->y() < screenGeom.y() )
|
|
data.quads = data.quads.splitAtY( screenGeom.y() - w->y() );
|
|
if( w->y() + w->height() > screenGeom.y() + screenGeom.height() )
|
|
data.quads = data.quads.splitAtY( screenGeom.y() + screenGeom.height() - w->y() );
|
|
}
|
|
}
|
|
else
|
|
w->disablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP );
|
|
}
|
|
effects->prePaintWindow( w, data, time );
|
|
}
|
|
|
|
void DesktopGridEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
|
{
|
|
if( timeline.value() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows()) )
|
|
{
|
|
if( isUsingPresentWindows() && w == windowMove )
|
|
{
|
|
return; // will be painted on top of all other windows
|
|
}
|
|
|
|
double xScale = data.xScale;
|
|
double yScale = data.yScale;
|
|
|
|
// Don't change brightness of windows on all desktops as this causes flickering
|
|
if( !w->isOnAllDesktops() || w->isDesktop() )
|
|
data.brightness *= 1.0 - ( 0.3 * ( 1.0 - hoverTimeline[paintingDesktop - 1].value() ));
|
|
|
|
for( int screen = 0; screen < effects->numScreens(); screen++ )
|
|
{
|
|
// Assume desktop windows can never be on two screens at once (Plasma makes one window per screen)
|
|
if( w->isDesktop() )
|
|
screen = w->screen();
|
|
QRect screenGeom = effects->clientArea( ScreenArea, screen, 0 );
|
|
|
|
QRectF transformedGeo = w->geometry();
|
|
// Display all quads on the same screen on the same pass
|
|
WindowQuadList screenQuads;
|
|
bool quadsAdded = false;
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
WindowMotionManager& manager = m_managers[ (paintingDesktop-1)*(effects->numScreens())+screen ];
|
|
if( manager.isManaging( w ) )
|
|
{
|
|
foreach( const WindowQuad &quad, data.quads )
|
|
screenQuads.append( quad );
|
|
transformedGeo = manager.transformedGeometry( w );
|
|
quadsAdded = true;
|
|
}
|
|
else if( w->screen() != screen )
|
|
quadsAdded = true; // we don't want parts of overlapping windows on the other screen
|
|
}
|
|
if( !quadsAdded )
|
|
{
|
|
foreach( const WindowQuad &quad, data.quads )
|
|
{
|
|
QRect quadRect(
|
|
w->x() + quad.left(), w->y() + quad.top(),
|
|
quad.right() - quad.left(), quad.bottom() - quad.top()
|
|
);
|
|
if( quadRect.intersects( screenGeom ) )
|
|
screenQuads.append( quad );
|
|
}
|
|
}
|
|
if( screenQuads.isEmpty() )
|
|
continue; // Nothing is being displayed, don't bother
|
|
WindowPaintData d = data;
|
|
d.quads = screenQuads;
|
|
|
|
QPointF newPos = scalePos( transformedGeo.topLeft().toPoint(), paintingDesktop, screen);
|
|
double progress = timeline.value();
|
|
d.xScale = interpolate( 1, xScale * scale[screen] * (float)transformedGeo.width()/(float)w->geometry().width(), progress);
|
|
d.yScale = interpolate( 1, yScale * scale[screen] * (float)transformedGeo.height()/(float)w->geometry().height(), progress);
|
|
d.xTranslate += qRound( newPos.x() - w->x() );
|
|
d.yTranslate += qRound( newPos.y() - w->y() );
|
|
|
|
if( isUsingPresentWindows() && w->isDock() )
|
|
{
|
|
// fade out panels if present windows is used
|
|
d.opacity *= ( 1.0 - timeline.value() );
|
|
}
|
|
if( isUsingPresentWindows() && w->isMinimized() )
|
|
{
|
|
d.opacity *= timeline.value();
|
|
}
|
|
|
|
if( effects->compositingType() == XRenderCompositing )
|
|
{ // More exact clipping as XRender displays the entire window instead of just the quad
|
|
QPointF screenPosF = scalePos( screenGeom.topLeft(), paintingDesktop ).toPoint();
|
|
QPoint screenPos(
|
|
qRound( screenPosF.x() ),
|
|
qRound( screenPosF.y() )
|
|
);
|
|
QSize screenSize(
|
|
qRound( interpolate( screenGeom.width(), scaledSize[screen].width(), progress )),
|
|
qRound( interpolate( screenGeom.height(), scaledSize[screen].height(), progress ))
|
|
);
|
|
PaintClipper pc( effects->clientArea( ScreenArea, screen, 0 ) & QRect( screenPos, screenSize ));
|
|
effects->paintWindow( w, mask, region, d );
|
|
}
|
|
else
|
|
{
|
|
PaintClipper pc( effects->clientArea( ScreenArea, screen, 0 ));
|
|
effects->paintWindow( w, mask, region, d );
|
|
}
|
|
// Assume desktop windows can never be on two screens at once (Plasma makes one window per screen)
|
|
if( w->isDesktop() )
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
effects->paintWindow( w, mask, region, data );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// User interaction
|
|
|
|
void DesktopGridEffect::windowAdded( EffectWindow* w )
|
|
{
|
|
if( !activated )
|
|
return;
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
if( w->isOnAllDesktops() )
|
|
{
|
|
for( int i=0; i<effects->numberOfDesktops(); i++ )
|
|
{
|
|
WindowMotionManager& manager = m_managers[ i*effects->numScreens()+w->screen() ];
|
|
manager.manage( w );
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), w->screen(), manager );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WindowMotionManager& manager = m_managers[ (w->desktop()-1)*effects->numScreens()+w->screen() ];
|
|
manager.manage( w );
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), w->screen(), manager );
|
|
}
|
|
}
|
|
effects->addRepaintFull();
|
|
}
|
|
|
|
void DesktopGridEffect::windowClosed( EffectWindow* w )
|
|
{
|
|
if ( !activated )
|
|
return;
|
|
if( w == windowMove )
|
|
{
|
|
effects->setElevatedWindow( windowMove, false );
|
|
windowMove = NULL;
|
|
}
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
if( w->isOnAllDesktops() )
|
|
{
|
|
for( int i=0; i<effects->numberOfDesktops(); i++ )
|
|
{
|
|
WindowMotionManager& manager = m_managers[i*effects->numScreens()+w->screen()];
|
|
manager.unmanage(w);
|
|
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WindowMotionManager& manager = m_managers[(w->desktop()-1)*effects->numScreens()+w->screen()];
|
|
manager.unmanage(w);
|
|
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
|
|
}
|
|
}
|
|
effects->addRepaintFull();
|
|
}
|
|
|
|
void DesktopGridEffect::windowInputMouseEvent( Window, QEvent* e )
|
|
{
|
|
if(( e->type() != QEvent::MouseMove
|
|
&& e->type() != QEvent::MouseButtonPress
|
|
&& e->type() != QEvent::MouseButtonRelease )
|
|
|| timeline.value() != 1 ) // Block user input during animations
|
|
return;
|
|
QMouseEvent* me = static_cast< QMouseEvent* >( e );
|
|
if( e->type() == QEvent::MouseMove )
|
|
{
|
|
int d = posToDesktop( me->pos());
|
|
if( windowMove != NULL &&
|
|
(me->pos() - dragStartPos).manhattanLength() > KGlobalSettings::dndEventDelay() )
|
|
{ // Handle window moving
|
|
if( !wasWindowMove ) // Activate on move
|
|
{
|
|
if( isUsingPresentWindows() && windowMove->isOnAllDesktops() )
|
|
{
|
|
for( int i=0; i<effects->numberOfDesktops(); ++i )
|
|
{
|
|
WindowMotionManager& manager = m_managers[ (i)*(effects->numScreens()) + windowMove->screen() ];
|
|
if( (i+1) == d )
|
|
{
|
|
const QRectF transformedGeo = manager.transformedGeometry( windowMove );
|
|
const QPointF pos = scalePos( transformedGeo.topLeft().toPoint(), d, windowMove->screen() );
|
|
const QSize size( scale[windowMove->screen()] * (float)transformedGeo.width(),
|
|
scale[windowMove->screen()] * (float)transformedGeo.height() );
|
|
m_windowMoveGeometry = QRect( pos.toPoint(), size );
|
|
m_windowMoveStartPoint = me->pos();
|
|
}
|
|
manager.unmanage( windowMove );
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), windowMove->screen(), manager );
|
|
}
|
|
}
|
|
else if( isUsingPresentWindows() )
|
|
{
|
|
WindowMotionManager& manager = m_managers[ (windowMove->desktop()-1)*(effects->numScreens()) + windowMove->screen() ];
|
|
const QRectF transformedGeo = manager.transformedGeometry( windowMove );
|
|
const QPointF pos = scalePos( transformedGeo.topLeft().toPoint(), windowMove->desktop(), windowMove->screen() );
|
|
const QSize size( scale[windowMove->screen()] * (float)transformedGeo.width(),
|
|
scale[windowMove->screen()] * (float)transformedGeo.height() );
|
|
m_windowMoveGeometry = QRect( pos.toPoint(), size );
|
|
m_windowMoveStartPoint = me->pos();
|
|
|
|
manager.unmanage( windowMove );
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), windowMove->screen(), manager );
|
|
}
|
|
XDefineCursor( display(), input, QCursor( Qt::ClosedHandCursor ).handle() );
|
|
}
|
|
wasWindowMove = true;
|
|
if( windowMove->isMovable() && !isUsingPresentWindows() )
|
|
{
|
|
int screen = effects->screenNumber( me->pos() );
|
|
effects->moveWindow( windowMove, unscalePos( me->pos(), NULL ) + windowMoveDiff, true, 1.0 / scale[screen] );
|
|
}
|
|
if( d != highlightedDesktop )
|
|
{
|
|
if( !windowMove->isOnAllDesktops() )
|
|
effects->windowToDesktop( windowMove, d ); // Not true all desktop move
|
|
const int screen = effects->screenNumber( me->pos() );
|
|
if( screen != windowMove->screen() )
|
|
effects->windowToScreen( windowMove, screen );
|
|
}
|
|
effects->addRepaintFull();
|
|
}
|
|
else if( (me->buttons() & Qt::LeftButton) && !wasDesktopMove &&
|
|
(me->pos() - dragStartPos).manhattanLength() > KGlobalSettings::dndEventDelay())
|
|
{
|
|
wasDesktopMove = true;
|
|
XDefineCursor( display(), input, QCursor( Qt::ClosedHandCursor ).handle() );
|
|
}
|
|
if( d != highlightedDesktop ) // Highlight desktop
|
|
{
|
|
if ( (me->buttons() & Qt::LeftButton) && !wasWindowMove )
|
|
{
|
|
EffectWindowList windows = effects->stackingOrder();
|
|
EffectWindowList stack;
|
|
foreach( EffectWindow* w, windows )
|
|
{
|
|
if( w->isOnAllDesktops() )
|
|
continue;
|
|
if( w->isOnDesktop( highlightedDesktop ) )
|
|
{
|
|
effects->windowToDesktop( w, d );
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
m_managers[ (d-1)*(effects->numScreens()) + w->screen() ].manage( w );
|
|
m_managers[ (highlightedDesktop-1)*(effects->numScreens()) + w->screen() ].unmanage( w );
|
|
}
|
|
}
|
|
else if( w->isOnDesktop( d ) )
|
|
stack << w;
|
|
}
|
|
foreach( EffectWindow* w, stack )
|
|
{
|
|
effects->windowToDesktop( w, highlightedDesktop );
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
m_managers[ (d-1)*(effects->numScreens()) + w->screen() ].unmanage( w );
|
|
m_managers[ (highlightedDesktop-1)*(effects->numScreens()) + w->screen() ].manage( w );
|
|
}
|
|
}
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
for( int i=0; i<effects->numScreens(); i++ )
|
|
{
|
|
WindowMotionManager& manager = m_managers[ (d-1)*(effects->numScreens()) + i ];
|
|
WindowMotionManager& manager2 = m_managers[ (highlightedDesktop-1)*(effects->numScreens()) + i ];
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), i, manager );
|
|
m_proxy->calculateWindowTransformations( manager2.managedWindows(), i, manager2 );
|
|
}
|
|
effects->addRepaintFull();
|
|
}
|
|
}
|
|
setHighlightedDesktop( d );
|
|
}
|
|
}
|
|
if( e->type() == QEvent::MouseButtonPress )
|
|
{
|
|
if( me->buttons() == Qt::LeftButton )
|
|
{
|
|
// QRect rect;
|
|
dragStartPos = me->pos();
|
|
bool isDesktop = (me->modifiers() & Qt::ControlModifier);
|
|
EffectWindow* w = isDesktop ? NULL : windowAt( me->pos());
|
|
if ( w != NULL )
|
|
isDesktop = w->isDesktop();
|
|
if( w != NULL && ( w->isMovable() || w->isMovableAcrossScreens() ))
|
|
{ // Prepare it for moving
|
|
windowMoveDiff = w->pos() - unscalePos( me->pos(), NULL );
|
|
windowMove = w;
|
|
effects->setElevatedWindow( windowMove, true );
|
|
}
|
|
}
|
|
else if(( me->buttons() == Qt::MidButton || me->buttons() == Qt::RightButton ) && windowMove == NULL )
|
|
{
|
|
EffectWindow* w = windowAt( me->pos());
|
|
if( w != NULL )
|
|
{
|
|
if( w->isOnAllDesktops())
|
|
{
|
|
const int desktop = posToDesktop( me->pos() );
|
|
effects->windowToDesktop( w, desktop );
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
for( int i=0; i<effects->numberOfDesktops(); i++ )
|
|
{
|
|
if( i != desktop - 1 )
|
|
{
|
|
WindowMotionManager& manager = m_managers[ i*effects->numScreens() + w->screen() ];
|
|
manager.unmanage( w );
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), w->screen(), manager );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
const int desktop = w->desktop();
|
|
for( int i=0; i<effects->numberOfDesktops(); i++ )
|
|
{
|
|
if( i != desktop - 1 )
|
|
{
|
|
WindowMotionManager& manager = m_managers[ i*effects->numScreens() + w->screen() ];
|
|
manager.manage( w );
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), w->screen(), manager );
|
|
}
|
|
}
|
|
}
|
|
effects->windowToDesktop( w, NET::OnAllDesktops );
|
|
}
|
|
effects->addRepaintFull();
|
|
}
|
|
}
|
|
}
|
|
if( e->type() == QEvent::MouseButtonRelease && me->button() == Qt::LeftButton )
|
|
{
|
|
if( !wasWindowMove && !wasDesktopMove )
|
|
{
|
|
setCurrentDesktop( posToDesktop( me->pos() ));
|
|
if( windowMove )
|
|
effects->activateWindow( windowMove );
|
|
setActive( false );
|
|
}
|
|
if( windowMove )
|
|
{
|
|
if( wasWindowMove )
|
|
{
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
if( windowMove->isOnAllDesktops() )
|
|
{
|
|
for( int i=0; i<effects->numberOfDesktops(); ++i )
|
|
{
|
|
WindowMotionManager& manager = m_managers[ (i)*(effects->numScreens()) + windowMove->screen() ];
|
|
manager.manage( windowMove );
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), windowMove->screen(), manager );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WindowMotionManager& manager = m_managers[ (windowMove->desktop()-1)*(effects->numScreens()) + windowMove->screen() ];
|
|
manager.manage( windowMove );
|
|
m_proxy->calculateWindowTransformations( manager.managedWindows(), windowMove->screen(), manager );
|
|
}
|
|
effects->addRepaintFull();
|
|
}
|
|
}
|
|
effects->setElevatedWindow( windowMove, false );
|
|
windowMove = NULL;
|
|
XDefineCursor( display(), input, QCursor( Qt::PointingHandCursor ).handle() );
|
|
}
|
|
else if ( wasDesktopMove )
|
|
XDefineCursor( display(), input, QCursor( Qt::PointingHandCursor ).handle() );
|
|
wasWindowMove = false;
|
|
wasDesktopMove = false;
|
|
}
|
|
}
|
|
|
|
void DesktopGridEffect::grabbedKeyboardEvent( QKeyEvent* e )
|
|
{
|
|
if( e->type() == QEvent::KeyPress )
|
|
{
|
|
// check for global shortcuts
|
|
// HACK: keyboard grab disables the global shortcuts so we have to check for global shortcut (bug 156155)
|
|
if( shortcut.contains( e->key() + e->modifiers() ) )
|
|
{
|
|
toggle();
|
|
return;
|
|
}
|
|
|
|
int desktop = -1;
|
|
// switch by F<number> or just <number>
|
|
if( e->key() >= Qt::Key_F1 && e->key() <= Qt::Key_F35 )
|
|
desktop = e->key() - Qt::Key_F1 + 1;
|
|
else if( e->key() >= Qt::Key_0 && e->key() <= Qt::Key_9 )
|
|
desktop = e->key() == Qt::Key_0 ? 10 : e->key() - Qt::Key_0;
|
|
if( desktop != -1 )
|
|
{
|
|
if( desktop <= effects->numberOfDesktops())
|
|
{
|
|
setHighlightedDesktop( desktop );
|
|
setCurrentDesktop( desktop );
|
|
setActive( false );
|
|
}
|
|
return;
|
|
}
|
|
switch( e->key())
|
|
{ // Wrap only on autorepeat
|
|
case Qt::Key_Left:
|
|
setHighlightedDesktop( desktopToLeft( highlightedDesktop, !e->isAutoRepeat()));
|
|
break;
|
|
case Qt::Key_Right:
|
|
setHighlightedDesktop( desktopToRight( highlightedDesktop, !e->isAutoRepeat()));
|
|
break;
|
|
case Qt::Key_Up:
|
|
setHighlightedDesktop( desktopUp( highlightedDesktop, !e->isAutoRepeat()));
|
|
break;
|
|
case Qt::Key_Down:
|
|
setHighlightedDesktop( desktopDown( highlightedDesktop, !e->isAutoRepeat()));
|
|
break;
|
|
case Qt::Key_Escape:
|
|
setActive( false );
|
|
return;
|
|
case Qt::Key_Enter:
|
|
case Qt::Key_Return:
|
|
case Qt::Key_Space:
|
|
setCurrentDesktop( highlightedDesktop );
|
|
setActive( false );
|
|
return;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool DesktopGridEffect::borderActivated( ElectricBorder border )
|
|
{
|
|
if( !borderActivate.contains( border ) )
|
|
return false;
|
|
if( effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this )
|
|
return true;
|
|
toggle();
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Helper functions
|
|
|
|
// Transform a point to its position on the scaled grid
|
|
QPointF DesktopGridEffect::scalePos( const QPoint& pos, int desktop, int screen ) const
|
|
{
|
|
if( screen == -1 )
|
|
screen = effects->screenNumber( pos );
|
|
QRect screenGeom = effects->clientArea( ScreenArea, screen, 0 );
|
|
QPoint desktopCell;
|
|
if( orientation == Qt::Horizontal )
|
|
{
|
|
desktopCell.setX(( desktop - 1 ) % gridSize.width() + 1 );
|
|
desktopCell.setY(( desktop - 1 ) / gridSize.width() + 1 );
|
|
}
|
|
else
|
|
{
|
|
desktopCell.setX(( desktop - 1 ) / gridSize.height() + 1 );
|
|
desktopCell.setY(( desktop - 1 ) % gridSize.height() + 1 );
|
|
}
|
|
|
|
double progress = timeline.value();
|
|
QPointF point(
|
|
interpolate(
|
|
(
|
|
( screenGeom.width() + unscaledBorder[screen] ) * ( desktopCell.x() - 1 )
|
|
- ( screenGeom.width() + unscaledBorder[screen] ) * ( activeCell.x() - 1 )
|
|
) + pos.x(),
|
|
(
|
|
( scaledSize[screen].width() + border ) * ( desktopCell.x() - 1 )
|
|
+ scaledOffset[screen].x()
|
|
+ ( pos.x() - screenGeom.x() ) * scale[screen]
|
|
),
|
|
progress ),
|
|
interpolate(
|
|
(
|
|
( screenGeom.height() + unscaledBorder[screen] ) * ( desktopCell.y() - 1 )
|
|
- ( screenGeom.height() + unscaledBorder[screen] ) * ( activeCell.y() - 1 )
|
|
) + pos.y(),
|
|
(
|
|
( scaledSize[screen].height() + border ) * ( desktopCell.y() - 1 )
|
|
+ scaledOffset[screen].y()
|
|
+ ( pos.y() - screenGeom.y() ) * scale[screen]
|
|
),
|
|
progress )
|
|
);
|
|
|
|
return point;
|
|
}
|
|
|
|
// Detransform a point to its position on the full grid
|
|
// TODO: Doesn't correctly interpolate (Final position is correct though), don't forget to copy to posToDesktop()
|
|
QPoint DesktopGridEffect::unscalePos( const QPoint& pos, int* desktop ) const
|
|
{
|
|
int screen = effects->screenNumber( pos );
|
|
QRect screenGeom = effects->clientArea( ScreenArea, screen, 0 );
|
|
|
|
//double progress = timeline.value();
|
|
double scaledX = /*interpolate(
|
|
( pos.x() - screenGeom.x() + unscaledBorder[screen] / 2.0 ) / ( screenGeom.width() + unscaledBorder[screen] ) + activeCell.x() - 1,*/
|
|
( pos.x() - scaledOffset[screen].x() + double( border ) / 2.0 ) / ( scaledSize[screen].width() + border )/*,
|
|
progress )*/;
|
|
double scaledY = /*interpolate(
|
|
( pos.y() - screenGeom.y() + unscaledBorder[screen] / 2.0 ) / ( screenGeom.height() + unscaledBorder[screen] ) + activeCell.y() - 1,*/
|
|
( pos.y() - scaledOffset[screen].y() + double( border ) / 2.0 ) / ( scaledSize[screen].height() + border )/*,
|
|
progress )*/;
|
|
int gx = qBound( 0, int( scaledX ), gridSize.width() - 1 ); // Zero-based
|
|
int gy = qBound( 0, int( scaledY ), gridSize.height() - 1 );
|
|
scaledX -= gx;
|
|
scaledY -= gy;
|
|
if( desktop != NULL )
|
|
{
|
|
if( orientation == Qt::Horizontal )
|
|
*desktop = gy * gridSize.width() + gx + 1;
|
|
else
|
|
*desktop = gx * gridSize.height() + gy + 1;
|
|
}
|
|
|
|
return QPoint(
|
|
qBound(
|
|
screenGeom.x(),
|
|
qRound(
|
|
scaledX * ( screenGeom.width() + unscaledBorder[screen] )
|
|
- unscaledBorder[screen] / 2.0
|
|
+ screenGeom.x()
|
|
),
|
|
screenGeom.right()
|
|
),
|
|
qBound(
|
|
screenGeom.y(),
|
|
qRound(
|
|
scaledY * ( screenGeom.height() + unscaledBorder[screen] )
|
|
- unscaledBorder[screen] / 2.0
|
|
+ screenGeom.y()
|
|
),
|
|
screenGeom.bottom()
|
|
)
|
|
);
|
|
}
|
|
|
|
int DesktopGridEffect::posToDesktop( const QPoint& pos ) const
|
|
{ // Copied from unscalePos()
|
|
int screen = effects->screenNumber( pos );
|
|
QRect screenGeom = effects->clientArea( ScreenArea, screen, 0 );
|
|
|
|
//double progress = timeline.value();
|
|
double scaledX = /*interpolate(
|
|
( pos.x() - screenGeom.x() + unscaledBorder[screen] / 2.0 ) / ( screenGeom.width() + unscaledBorder[screen] ) + activeCell.x() - 1,*/
|
|
( pos.x() - scaledOffset[screen].x() + double( border ) / 2.0 ) / ( scaledSize[screen].width() + border )/*,
|
|
progress )*/;
|
|
double scaledY = /*interpolate(
|
|
( pos.y() - screenGeom.y() + unscaledBorder[screen] / 2.0 ) / ( screenGeom.height() + unscaledBorder[screen] ) + activeCell.y() - 1,*/
|
|
( pos.y() - scaledOffset[screen].y() + double( border ) / 2.0 ) / ( scaledSize[screen].height() + border )/*,
|
|
progress )*/;
|
|
int gx = qBound( 0, int( scaledX ), gridSize.width() - 1 ); // Zero-based
|
|
int gy = qBound( 0, int( scaledY ), gridSize.height() - 1 );
|
|
scaledX -= gx;
|
|
scaledY -= gy;
|
|
if( orientation == Qt::Horizontal )
|
|
return gy * gridSize.width() + gx + 1;
|
|
return gx * gridSize.height() + gy + 1;
|
|
}
|
|
|
|
EffectWindow* DesktopGridEffect::windowAt( QPoint pos ) const
|
|
{
|
|
// Get stacking order top first
|
|
EffectWindowList windows = effects->stackingOrder();
|
|
EffectWindowList::Iterator begin = windows.begin();
|
|
EffectWindowList::Iterator end = windows.end();
|
|
--end;
|
|
while( begin < end )
|
|
qSwap( *begin++, *end-- );
|
|
|
|
int desktop;
|
|
pos = unscalePos( pos, &desktop );
|
|
if( desktop > effects->numberOfDesktops() )
|
|
return NULL;
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
const int screen = effects->screenNumber( pos );
|
|
EffectWindow *w =
|
|
m_managers.at((desktop-1)*(effects->numScreens())+screen).windowAtPoint( pos, false );
|
|
if( w )
|
|
return w;
|
|
foreach( EffectWindow* w, windows )
|
|
{
|
|
if( w->isOnDesktop( desktop ) && w->isDesktop() && w->geometry().contains( pos ))
|
|
return w;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach( EffectWindow* w, windows )
|
|
{
|
|
if( w->isOnDesktop( desktop ) && !w->isMinimized() && w->geometry().contains( pos ))
|
|
return w;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void DesktopGridEffect::setCurrentDesktop( int desktop )
|
|
{
|
|
if( orientation == Qt::Horizontal )
|
|
{
|
|
activeCell.setX(( desktop - 1 ) % gridSize.width() + 1 );
|
|
activeCell.setY(( desktop - 1 ) / gridSize.width() + 1 );
|
|
}
|
|
else
|
|
{
|
|
activeCell.setX(( desktop - 1 ) / gridSize.height() + 1 );
|
|
activeCell.setY(( desktop - 1 ) % gridSize.height() + 1 );
|
|
}
|
|
if( effects->currentDesktop() != desktop )
|
|
effects->setCurrentDesktop( desktop );
|
|
}
|
|
|
|
void DesktopGridEffect::setHighlightedDesktop( int d )
|
|
{
|
|
if( d == highlightedDesktop || d <= 0 || d > effects->numberOfDesktops() )
|
|
return;
|
|
highlightedDesktop = d;
|
|
effects->addRepaintFull();
|
|
}
|
|
|
|
int DesktopGridEffect::desktopToRight( int desktop, bool wrap ) const
|
|
{ // Copied from Workspace::desktopToRight()
|
|
int dt = desktop - 1;
|
|
if( orientation == Qt::Vertical )
|
|
{
|
|
dt += gridSize.height();
|
|
if( dt >= effects->numberOfDesktops() )
|
|
{
|
|
if( wrap )
|
|
dt -= effects->numberOfDesktops();
|
|
else
|
|
return desktop;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int d = ( dt % gridSize.width() ) + 1;
|
|
if( d >= gridSize.width() )
|
|
{
|
|
if( wrap )
|
|
d -= gridSize.width();
|
|
else
|
|
return desktop;
|
|
}
|
|
dt = dt - ( dt % gridSize.width() ) + d;
|
|
}
|
|
return dt + 1;
|
|
}
|
|
|
|
int DesktopGridEffect::desktopToLeft( int desktop, bool wrap ) const
|
|
{ // Copied from Workspace::desktopToLeft()
|
|
int dt = desktop - 1;
|
|
if( orientation == Qt::Vertical )
|
|
{
|
|
dt -= gridSize.height();
|
|
if( dt < 0 )
|
|
{
|
|
if( wrap )
|
|
dt += effects->numberOfDesktops();
|
|
else
|
|
return desktop;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int d = ( dt % gridSize.width() ) - 1;
|
|
if( d < 0 )
|
|
{
|
|
if( wrap )
|
|
d += gridSize.width();
|
|
else
|
|
return desktop;
|
|
}
|
|
dt = dt - ( dt % gridSize.width() ) + d;
|
|
}
|
|
return dt + 1;
|
|
}
|
|
|
|
int DesktopGridEffect::desktopUp( int desktop, bool wrap ) const
|
|
{ // Copied from Workspace::desktopUp()
|
|
int dt = desktop - 1;
|
|
if( orientation == Qt::Horizontal )
|
|
{
|
|
dt -= gridSize.width();
|
|
if( dt < 0 )
|
|
{
|
|
if( wrap )
|
|
dt += effects->numberOfDesktops();
|
|
else
|
|
return desktop;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int d = ( dt % gridSize.height() ) - 1;
|
|
if( d < 0 )
|
|
{
|
|
if( wrap )
|
|
d += gridSize.height();
|
|
else
|
|
return desktop;
|
|
}
|
|
dt = dt - ( dt % gridSize.height() ) + d;
|
|
}
|
|
return dt + 1;
|
|
}
|
|
|
|
int DesktopGridEffect::desktopDown( int desktop, bool wrap ) const
|
|
{ // Copied from Workspace::desktopDown()
|
|
int dt = desktop - 1;
|
|
if( orientation == Qt::Horizontal )
|
|
{
|
|
dt += gridSize.width();
|
|
if( dt >= effects->numberOfDesktops() )
|
|
{
|
|
if( wrap )
|
|
dt -= effects->numberOfDesktops();
|
|
else
|
|
return desktop;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int d = ( dt % gridSize.height() ) + 1;
|
|
if( d >= gridSize.height() )
|
|
{
|
|
if( wrap )
|
|
d -= gridSize.height();
|
|
else
|
|
return desktop;
|
|
}
|
|
dt = dt - ( dt % gridSize.height() ) + d;
|
|
}
|
|
return dt + 1;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Activation
|
|
|
|
void DesktopGridEffect::toggle()
|
|
{
|
|
setActive( !activated );
|
|
}
|
|
|
|
void DesktopGridEffect::setActive( bool active )
|
|
{
|
|
if( effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this )
|
|
return; // Only one fullscreen effect at a time thanks
|
|
if( effects->numberOfDesktops() < 2 )
|
|
return; // No point if there is only one desktop
|
|
if( activated == active )
|
|
return; // Already in that state
|
|
|
|
activated = active;
|
|
if( activated && timeline.value() == 0 )
|
|
setup();
|
|
if( !activated )
|
|
{
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
QList<WindowMotionManager>::iterator it;
|
|
for( it = m_managers.begin(); it != m_managers.end(); ++it )
|
|
{
|
|
foreach( EffectWindow* w, (*it).managedWindows() )
|
|
{
|
|
(*it).moveWindow( w, w->geometry() );
|
|
}
|
|
}
|
|
}
|
|
setHighlightedDesktop( effects->currentDesktop() ); // Ensure selected desktop is highlighted
|
|
}
|
|
effects->addRepaintFull();
|
|
}
|
|
|
|
void DesktopGridEffect::setup()
|
|
{
|
|
keyboardGrab = effects->grabKeyboard( this );
|
|
input = effects->createInputWindow( this, 0, 0, displayWidth(), displayHeight(),
|
|
Qt::PointingHandCursor );
|
|
effects->setActiveFullScreenEffect( this );
|
|
setHighlightedDesktop( effects->currentDesktop() );
|
|
|
|
// Soft highlighting
|
|
hoverTimeline.clear();
|
|
for( int i = 0; i < effects->numberOfDesktops(); i++ )
|
|
{
|
|
TimeLine newTimeline( animationTime( zoomDuration ));
|
|
newTimeline.setCurveShape( TimeLine::EaseInOutCurve );
|
|
hoverTimeline.append( newTimeline );
|
|
}
|
|
hoverTimeline[effects->currentDesktop() - 1].setProgress( 1.0 );
|
|
|
|
// Create desktop name textures if enabled
|
|
if( desktopNameAlignment )
|
|
{
|
|
desktopNames = new EffectFrame*[effects->numberOfDesktops()];
|
|
QFont font;
|
|
font.setBold( true );
|
|
font.setPointSize( 12 );
|
|
for( int i = 0; i < effects->numberOfDesktops(); i++ )
|
|
{
|
|
desktopNames[i] = new EffectFrame( EffectFrame::Unstyled, false );
|
|
desktopNames[i]->setFont( font );
|
|
desktopNames[i]->setText( effects->desktopName( i+1 ));
|
|
desktopNames[i]->setAlignment( desktopNameAlignment );
|
|
}
|
|
}
|
|
|
|
// We need these variables for every paint so lets cache them
|
|
int x, y;
|
|
int numDesktops = effects->numberOfDesktops();
|
|
switch( layoutMode )
|
|
{
|
|
default:
|
|
case LayoutPager:
|
|
orientation = Qt::Horizontal;
|
|
gridSize = effects->desktopGridSize();
|
|
break;
|
|
case LayoutAutomatic:
|
|
y = sqrt( float( numDesktops ) ) + 0.5;
|
|
x = float( numDesktops ) / float( y ) + 0.5;
|
|
if( x * y < numDesktops )
|
|
x++;
|
|
orientation = Qt::Horizontal;
|
|
gridSize.setWidth( x );
|
|
gridSize.setHeight( y );
|
|
break;
|
|
case LayoutCustom:
|
|
orientation = Qt::Horizontal;
|
|
gridSize.setWidth( ceil( effects->numberOfDesktops() / double( customLayoutRows )));
|
|
gridSize.setHeight( customLayoutRows );
|
|
break;
|
|
}
|
|
setCurrentDesktop( effects->currentDesktop() );
|
|
scale.clear();
|
|
unscaledBorder.clear();
|
|
scaledSize.clear();
|
|
scaledOffset.clear();
|
|
for( int i = 0; i < effects->numScreens(); i++ )
|
|
{
|
|
QRect geom = effects->clientArea( ScreenArea, i, 0 );
|
|
double sScale;
|
|
if( gridSize.width() > gridSize.height() )
|
|
sScale = ( geom.width() - border * ( gridSize.width() + 1 )) / double( geom.width() * gridSize.width() );
|
|
else
|
|
sScale = ( geom.height() - border * ( gridSize.height() + 1 )) / double( geom.height() * gridSize.height() );
|
|
double sBorder = border / sScale;
|
|
QSizeF size(
|
|
double( geom.width() ) * sScale,
|
|
double( geom.height() ) * sScale
|
|
);
|
|
QPointF offset(
|
|
geom.x() + ( geom.width() - size.width() * gridSize.width() - border * ( gridSize.width() - 1 )) / 2.0,
|
|
geom.y() + ( geom.height() - size.height() * gridSize.height() - border * ( gridSize.height() - 1 )) / 2.0
|
|
);
|
|
scale.append( sScale );
|
|
unscaledBorder.append( sBorder );
|
|
scaledSize.append( size );
|
|
scaledOffset.append( offset );
|
|
}
|
|
|
|
// setup the motion managers
|
|
if( m_usePresentWindows )
|
|
m_proxy = static_cast<PresentWindowsEffectProxy*>( effects->getProxy( "presentwindows" ) );
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
for( int i=1; i<=effects->numberOfDesktops(); i++ )
|
|
{
|
|
for( int j=0; j<effects->numScreens(); j++ )
|
|
{
|
|
WindowMotionManager manager;
|
|
foreach( EffectWindow* w, effects->stackingOrder() )
|
|
{
|
|
if( w->isOnDesktop( i ) && w->screen() == j && !w->isDesktop() && !w->isDock() &&
|
|
w->visibleInClientGroup() )
|
|
{
|
|
manager.manage( w );
|
|
}
|
|
}
|
|
m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager);
|
|
m_managers.append(manager);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DesktopGridEffect::finish()
|
|
{
|
|
if( desktopNameAlignment )
|
|
{
|
|
for( int i = 0; i < effects->numberOfDesktops(); i++ )
|
|
delete desktopNames[i];
|
|
delete[] desktopNames;
|
|
}
|
|
|
|
if( keyboardGrab )
|
|
effects->ungrabKeyboard();
|
|
keyboardGrab = false;
|
|
effects->destroyInputWindow( input );
|
|
effects->setActiveFullScreenEffect( 0 );
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
while( !m_managers.isEmpty() )
|
|
{
|
|
m_managers.first().unmanageAll();
|
|
m_managers.removeFirst();
|
|
}
|
|
m_proxy = 0;
|
|
}
|
|
}
|
|
|
|
void DesktopGridEffect::globalShortcutChanged( const QKeySequence& seq )
|
|
{
|
|
shortcut = KShortcut( seq );
|
|
}
|
|
|
|
bool DesktopGridEffect::isMotionManagerMovingWindows()
|
|
{
|
|
if( isUsingPresentWindows() )
|
|
{
|
|
QList<WindowMotionManager>::iterator it;
|
|
for( it = m_managers.begin(); it != m_managers.end(); ++it )
|
|
{
|
|
if( (*it).areWindowsMoving() )
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DesktopGridEffect::isUsingPresentWindows() const
|
|
{
|
|
return (m_proxy != NULL);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
#include "desktopgrid.moc"
|