diff --git a/effects/presentwindows/presentwindows.cpp b/effects/presentwindows/presentwindows.cpp
index d634a69ad7..d2c4b89e17 100644
--- a/effects/presentwindows/presentwindows.cpp
+++ b/effects/presentwindows/presentwindows.cpp
@@ -33,6 +33,10 @@ along with this program. If not, see .
#endif
#include
+#include
+#include
+#include
+#include
#include
#include
@@ -54,6 +58,7 @@ PresentWindowsEffect::PresentWindowsEffect()
, m_managerWindow( NULL )
, m_highlightedWindow( NULL )
, m_filterFrame( effects->effectFrame( EffectFrameStyled, false ) )
+ , m_closeView( NULL )
{
m_atomDesktop = XInternAtom( display(), "_KDE_PRESENT_WINDOWS_DESKTOP", False );
m_atomWindows = XInternAtom( display(), "_KDE_PRESENT_WINDOWS_GROUP", False );
@@ -107,6 +112,7 @@ PresentWindowsEffect::~PresentWindowsEffect()
effects->unreserveElectricBorder( border );
}
delete m_filterFrame;
+ delete m_closeView;
}
void PresentWindowsEffect::reconfigure( ReconfigureFlags )
@@ -277,7 +283,7 @@ void PresentWindowsEffect::prePaintWindow( EffectWindow *w, WindowPrePaintData &
data.setTranslucent();
// Calculate window's brightness
- if( w == m_highlightedWindow || !m_activated )
+ if( w == m_highlightedWindow || w == m_closeWindow || !m_activated )
m_windowData[w].highlight = qMin( 1.0, m_windowData[w].highlight + time / m_fadeDuration );
else
m_windowData[w].highlight = qMax( 0.0, m_windowData[w].highlight - time / m_fadeDuration );
@@ -394,6 +400,12 @@ void PresentWindowsEffect::windowAdded( EffectWindow *w )
m_motionManager.manage( w );
rearrangeWindows();
}
+ if( w == effects->findWindow( m_closeView->winId() ) )
+ {
+ m_windowData[w].visible = true;
+ m_windowData[w].highlight = 1.0;
+ m_closeWindow = w;
+ }
}
void PresentWindowsEffect::windowClosed( EffectWindow *w )
@@ -408,6 +420,8 @@ void PresentWindowsEffect::windowClosed( EffectWindow *w )
if( m_highlightedWindow == w )
setHighlightedWindow( findFirstWindow() );
rearrangeWindows();
+ if( m_closeWindow == w )
+ m_closeWindow = 0;
}
void PresentWindowsEffect::windowDeleted( EffectWindow *w )
@@ -448,6 +462,20 @@ void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent *e )
assert( w == m_input );
Q_UNUSED( w );
+ QMouseEvent* me = static_cast< QMouseEvent* >( e );
+ if( m_closeView->geometry().contains( me->pos() ) )
+ {
+ if( !m_closeView->isVisible() )
+ {
+ updateCloseWindow();
+ return;
+ }
+ const QPoint widgetPos = m_closeView->mapFromGlobal( me->pos() );
+ const QPointF scenePos = m_closeView->mapToScene( widgetPos );
+ QMouseEvent event( me->type(), widgetPos, me->pos(), me->button(), me->buttons(), me->modifiers() );
+ m_closeView->windowInputMouseEvent( &event );
+ return;
+ }
// Which window are we hovering over? Always trigger as we don't always get move events before clicking
// We cannot use m_motionManager.windowAtPoint() as the window might not be visible
EffectWindowList windows = m_motionManager.managedWindows();
@@ -464,11 +492,14 @@ void PresentWindowsEffect::windowInputMouseEvent( Window w, QEvent *e )
break;
}
}
+ if( m_motionManager.transformedGeometry( m_highlightedWindow ).contains( me->pos() ) )
+ updateCloseWindow();
+ else
+ m_closeView->hide();
if( e->type() != QEvent::MouseButtonPress )
return;
- QMouseEvent* me = static_cast( e );
if( me->button() == Qt::LeftButton )
{
if( hovering )
@@ -842,6 +873,7 @@ void PresentWindowsEffect::rearrangeWindows()
return;
effects->addRepaintFull(); // Trigger the first repaint
+ m_closeView->hide();
// Work out which windows are on which screens
EffectWindowList windowlist;
@@ -1542,6 +1574,9 @@ void PresentWindowsEffect::setActive( bool active, bool closingTab )
m_highlightedWindow = NULL;
m_windowFilter.clear();
+ m_closeView = new CloseWindowView();
+ connect( m_closeView, SIGNAL(close()), SLOT(closeWindow()) );
+
// Add every single window to m_windowData (Just calling [w] creates it)
foreach( EffectWindow *w, effects->stackingOrder() )
{
@@ -1643,6 +1678,8 @@ void PresentWindowsEffect::setActive( bool active, bool closingTab )
m_windowData[w].visible = ( w->isOnDesktop( desktop ) || w->isOnAllDesktops() ) &&
!w->isMinimized() && ( w->visibleInClientGroup() || m_windowData[w].visible );
}
+ delete m_closeView;
+ m_closeView = 0;
// Move all windows back to their original position
foreach( EffectWindow *w, m_motionManager.managedWindows() )
@@ -1724,6 +1761,7 @@ void PresentWindowsEffect::setHighlightedWindow( EffectWindow *w )
if( w == m_highlightedWindow || ( w != NULL && !m_motionManager.isManaging( w )))
return;
+ m_closeView->hide();
if( m_highlightedWindow )
m_highlightedWindow->addRepaintFull(); // Trigger the first repaint
m_highlightedWindow = w;
@@ -1732,6 +1770,31 @@ void PresentWindowsEffect::setHighlightedWindow( EffectWindow *w )
if( m_tabBoxEnabled && m_highlightedWindow )
effects->setTabBoxWindow( w );
+ updateCloseWindow();
+ }
+
+void PresentWindowsEffect::updateCloseWindow()
+ {
+ if( m_closeView->isVisible() )
+ return;
+ if( !m_highlightedWindow )
+ {
+ m_closeView->hide();
+ return;
+ }
+ const QRectF rect = m_motionManager.targetGeometry( m_highlightedWindow );
+ m_closeView->setGeometry( rect.x() + rect.width() - m_closeView->sceneRect().width(), rect.y(),
+ m_closeView->sceneRect().width(), m_closeView->sceneRect().height() );
+ if( rect.contains( effects->cursorPos() ) )
+ m_closeView->show();
+ else
+ m_closeView->hide();
+ }
+
+void PresentWindowsEffect::closeWindow()
+ {
+ if( m_highlightedWindow )
+ m_highlightedWindow->closeWindow();
}
EffectWindow* PresentWindowsEffect::relativeWindow( EffectWindow *w, int xdiff, int ydiff, bool wrap ) const
@@ -1933,6 +1996,78 @@ void PresentWindowsEffect::globalShortcutChangedClass( const QKeySequence& seq )
shortcutClass = KShortcut( seq );
}
+/************************************************
+* CloseWindowView
+************************************************/
+CloseWindowView::CloseWindowView( QWidget* parent )
+ : QGraphicsView(parent)
+ {
+ setWindowFlags( Qt::X11BypassWindowManagerHint );
+ setAttribute( Qt::WA_TranslucentBackground );
+ setFrameShape( QFrame::NoFrame );
+ QPalette pal = palette();
+ pal.setColor( backgroundRole(), Qt::transparent );
+ setPalette( pal );
+ setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
+ setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
+
+ // setup the scene
+ QGraphicsScene* scene = new QGraphicsScene( this );
+ m_closeButton = new Plasma::PushButton();
+ m_closeButton->setIcon( KIcon( "window-close" ) );
+ scene->addItem( m_closeButton );
+ connect( m_closeButton, SIGNAL(clicked()), SIGNAL(close()));
+
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
+ layout->addItem( m_closeButton );
+
+ QGraphicsWidget *form = new QGraphicsWidget;
+ form->setLayout( layout );
+ form->setGeometry(0, 0, 32, 32);
+ scene->addItem( form );
+
+ m_frame = new Plasma::FrameSvg( this );
+ m_frame->setImagePath( "dialogs/background" );
+ m_frame->setCacheAllRenderedFrames( true );
+ m_frame->setEnabledBorders( Plasma::FrameSvg::AllBorders );
+ qreal left, top, right, bottom;
+ m_frame->getMargins( left, top, right, bottom );
+ qreal width = form->size().width() + left + right;
+ qreal height = form->size().height() + top + bottom;
+ m_frame->resizeFrame( QSizeF( width, height ) );
+ Plasma::WindowEffects::enableBlurBehind( winId(), true, m_frame->mask() );
+ form->setPos( left, top );
+ scene->setSceneRect( QRectF( QPointF( 0, 0 ), QSizeF( width, height ) ) );
+ setScene( scene );
+ }
+
+void CloseWindowView::windowInputMouseEvent( QMouseEvent* e )
+ {
+ if( e->type() == QEvent::MouseMove )
+ {
+ mouseMoveEvent( e );
+ }
+ else if( e->type() == QEvent::MouseButtonPress )
+ {
+ mousePressEvent( e );
+ }
+ else if( e->type() == QEvent::MouseButtonDblClick )
+ {
+ mouseDoubleClickEvent( e );
+ }
+ else if( e->type() == QEvent::MouseButtonRelease )
+ {
+ mouseReleaseEvent( e );
+ }
+ }
+
+void CloseWindowView::drawBackground( QPainter* painter, const QRectF& rect )
+ {
+ Q_UNUSED( rect )
+ painter->setRenderHint( QPainter::Antialiasing );
+ m_frame->paintFrame( painter );
+ }
+
} // namespace
#include "presentwindows.moc"
diff --git a/effects/presentwindows/presentwindows.h b/effects/presentwindows/presentwindows.h
index 24bc1a0da0..aa89e0309e 100644
--- a/effects/presentwindows/presentwindows.h
+++ b/effects/presentwindows/presentwindows.h
@@ -26,10 +26,32 @@ along with this program. If not, see .
#include
#include
+#include
+
+namespace Plasma
+{
+class PushButton;
+}
namespace KWin
{
+class CloseWindowView : public QGraphicsView
+ {
+ Q_OBJECT
+ public:
+ CloseWindowView( QWidget* parent = 0 );
+ void windowInputMouseEvent( QMouseEvent* e );
+ virtual void drawBackground( QPainter* painter, const QRectF& rect );
+
+ Q_SIGNALS:
+ void close();
+
+ private:
+ Plasma::PushButton* m_closeButton;
+ Plasma::FrameSvg* m_frame;
+ };
+
/**
* Expose-like effect which shows all windows on current desktop side-by-side,
* letting the user select active window.
@@ -132,6 +154,9 @@ class PresentWindowsEffect
void globalShortcutChangedAll( const QKeySequence& seq );
void globalShortcutChangedClass( const QKeySequence& seq );
+ private slots:
+ void closeWindow();
+
protected:
// Window rearranging
void rearrangeWindows();
@@ -164,6 +189,7 @@ class PresentWindowsEffect
void setHighlightedWindow( EffectWindow *w );
EffectWindow* relativeWindow( EffectWindow *w, int xdiff, int ydiff, bool wrap ) const;
EffectWindow* findFirstWindow() const;
+ void updateCloseWindow();
// Helper functions for mouse actions
void mouseActionWindow( WindowMouseAction& action );
@@ -230,6 +256,9 @@ class PresentWindowsEffect
DesktopMouseAction m_leftButtonDesktop;
DesktopMouseAction m_middleButtonDesktop;
DesktopMouseAction m_rightButtonDesktop;
+
+ CloseWindowView* m_closeView;
+ EffectWindow* m_closeWindow;
};
} // namespace