[effects/presentwindows] Port present windows to EffectQuickView
Summary: Removes over 100 lines of rather confusing code, implicitly introduces a sharedEngine. Doesn't perform hide/show by moving a window offscreen. As for the freeze, proving that EffectQuickView covers this case without lots of extra C++ is an important pre-requisite for ever moving this effect to a magic declarative API. General code structure remains the same. Test Plan: Opened present windows Reviewers: #kwin, zzag Reviewed By: #kwin, zzag Subscribers: zzag, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D24240
This commit is contained in:
parent
d9ed103196
commit
cd99a901f6
3 changed files with 32 additions and 162 deletions
|
@ -20,14 +20,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
import QtQuick 2.0
|
||||
import org.kde.plasma.components 2.0 as Plasma
|
||||
|
||||
Item {
|
||||
width: units.iconSizes.medium
|
||||
height: width
|
||||
|
||||
Plasma.Button {
|
||||
id: closeButton
|
||||
objectName: "closeButton"
|
||||
iconSource: "window-close"
|
||||
anchors.fill: parent
|
||||
}
|
||||
Plasma.Button {
|
||||
id: closeButton
|
||||
iconSource: "window-close"
|
||||
anchors.fill: parent
|
||||
implicitWidth: units.iconSizes.medium
|
||||
implicitHeight: implicitWidth
|
||||
}
|
||||
|
|
|
@ -60,7 +60,6 @@ PresentWindowsEffect::PresentWindowsEffect()
|
|||
, m_highlightedWindow(nullptr)
|
||||
, m_filterFrame(nullptr)
|
||||
, m_closeView(nullptr)
|
||||
, m_closeWindow(nullptr)
|
||||
, m_exposeAction(new QAction(this))
|
||||
, m_exposeAllAction(new QAction(this))
|
||||
, m_exposeClassAction(new QAction(this))
|
||||
|
@ -152,7 +151,6 @@ void PresentWindowsEffect::reconfigure(ReconfigureFlags)
|
|||
if (m_doNotCloseWindows) {
|
||||
delete m_closeView;
|
||||
m_closeView = nullptr;
|
||||
m_closeWindow = nullptr;
|
||||
}
|
||||
m_ignoreMinimized = PresentWindowsConfig::ignoreMinimized();
|
||||
m_accuracy = PresentWindowsConfig::accuracy() * 20;
|
||||
|
@ -228,13 +226,16 @@ void PresentWindowsEffect::paintScreen(int mask, QRegion region, ScreenPaintData
|
|||
// Display the filter box
|
||||
if (!m_windowFilter.isEmpty())
|
||||
m_filterFrame->render(region);
|
||||
|
||||
if (m_closeView)
|
||||
effects->renderEffectQuickView(m_closeView);
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::postPaintScreen()
|
||||
{
|
||||
if (m_motionManager.areWindowsMoving())
|
||||
effects->addRepaintFull();
|
||||
else if (!m_activated && m_motionManager.managingWindows() && !(m_closeWindow && m_closeView->isVisible())) {
|
||||
else if (!m_activated && m_motionManager.managingWindows() && !(m_closeView && m_closeView->isVisible())) {
|
||||
// We have finished moving them back, stop processing
|
||||
m_motionManager.unmanageAll();
|
||||
|
||||
|
@ -281,7 +282,7 @@ void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &d
|
|||
{
|
||||
// TODO: We should also check to see if any windows are fading just in case fading takes longer
|
||||
// than moving the windows when the effect is deactivated.
|
||||
if (m_activated || m_motionManager.areWindowsMoving() || m_closeWindow) {
|
||||
if (m_activated || m_motionManager.areWindowsMoving() || m_closeView) {
|
||||
DataHash::iterator winData = m_windowData.find(w);
|
||||
if (winData == m_windowData.end()) {
|
||||
effects->prePaintWindow(w, data, time);
|
||||
|
@ -309,7 +310,7 @@ void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &d
|
|||
|
||||
const bool isInMotion = m_motionManager.isManaging(w);
|
||||
// Calculate window's brightness
|
||||
if (w == m_highlightedWindow || w == m_closeWindow || !m_activated)
|
||||
if (w == m_highlightedWindow || !m_activated)
|
||||
winData->highlight = qMin(1.0, winData->highlight + time / m_fadeDuration);
|
||||
else if (!isInMotion && w->isDesktop())
|
||||
winData->highlight = 0.3;
|
||||
|
@ -324,9 +325,6 @@ void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &d
|
|||
// we have to keep the window in the list to prevent flickering
|
||||
winData->referenced = false;
|
||||
w->unrefWindow();
|
||||
if (w == m_closeWindow) {
|
||||
m_closeWindow = nullptr;
|
||||
}
|
||||
} else
|
||||
w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
|
||||
}
|
||||
|
@ -433,9 +431,6 @@ void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region
|
|||
winData->textFrame->render(region, 0.9 * data.opacity() * m_decalOpacity, 0.75);
|
||||
}
|
||||
} else {
|
||||
if (w == m_closeWindow && m_closeView && !m_closeView->isVisible()) {
|
||||
data.setOpacity(0);
|
||||
}
|
||||
effects->paintWindow(w, mask, region, data);
|
||||
}
|
||||
} else
|
||||
|
@ -466,22 +461,6 @@ void PresentWindowsEffect::slotWindowAdded(EffectWindow *w)
|
|||
m_motionManager.manage(w);
|
||||
rearrangeWindows();
|
||||
}
|
||||
if (m_closeView && w == effects->findWindow(m_closeView->winId())) {
|
||||
if (m_closeWindow != w) {
|
||||
DataHash::iterator winDataIt = m_windowData.find(m_closeWindow);
|
||||
if (winDataIt != m_windowData.end()) {
|
||||
if (winDataIt->referenced) {
|
||||
m_closeWindow->unrefWindow();
|
||||
}
|
||||
m_windowData.erase(winDataIt);
|
||||
}
|
||||
}
|
||||
winData->visible = true;
|
||||
winData->highlight = 1.0;
|
||||
m_closeWindow = w;
|
||||
w->setData(WindowForceBlurRole, QVariant(true));
|
||||
w->setData(WindowForceBackgroundContrastRole, QVariant(true));
|
||||
}
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::slotWindowClosed(EffectWindow *w)
|
||||
|
@ -498,9 +477,6 @@ void PresentWindowsEffect::slotWindowClosed(EffectWindow *w)
|
|||
}
|
||||
if (m_highlightedWindow == w)
|
||||
setHighlightedWindow(findFirstWindow());
|
||||
if (m_closeWindow == w) {
|
||||
return; // don't rearrange, get's nulled when unref'd
|
||||
}
|
||||
rearrangeWindows();
|
||||
|
||||
foreach (EffectWindow *w, m_motionManager.managedWindows()) {
|
||||
|
@ -529,7 +505,6 @@ void PresentWindowsEffect::slotWindowGeometryShapeChanged(EffectWindow* w, const
|
|||
return;
|
||||
if (!m_windowData.contains(w))
|
||||
return;
|
||||
if (w != m_closeWindow)
|
||||
rearrangeWindows();
|
||||
}
|
||||
|
||||
|
@ -569,16 +544,7 @@ void PresentWindowsEffect::windowInputMouseEvent(QEvent *e)
|
|||
if (!m_closeView->isVisible() && contains) {
|
||||
updateCloseWindow();
|
||||
}
|
||||
if (m_closeView->isVisible()) {
|
||||
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);
|
||||
if (contains) {
|
||||
// filter out
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_closeView->forwardMouseEvent(e);
|
||||
}
|
||||
inputEventUpdate(me->pos(), me->type(), me->button());
|
||||
}
|
||||
|
@ -1539,6 +1505,9 @@ void PresentWindowsEffect::setActive(bool active)
|
|||
|
||||
if (!(m_doNotCloseWindows || m_closeView)) {
|
||||
m_closeView = new CloseWindowView();
|
||||
connect(m_closeView, &EffectQuickView::repaintNeeded, this, []() {
|
||||
effects->addRepaintFull();
|
||||
});
|
||||
connect(m_closeView, &CloseWindowView::requestClose, this, &PresentWindowsEffect::closeWindow);
|
||||
}
|
||||
|
||||
|
@ -1681,8 +1650,6 @@ bool PresentWindowsEffect::isSelectableWindow(EffectWindow *w)
|
|||
return false;
|
||||
if (w->isSkipSwitcher())
|
||||
return false;
|
||||
if (m_closeView && w == effects->findWindow(m_closeView->winId()))
|
||||
return false;
|
||||
if (m_ignoreMinimized && w->isMinimized())
|
||||
return false;
|
||||
switch(m_mode) {
|
||||
|
@ -1702,7 +1669,7 @@ bool PresentWindowsEffect::isSelectableWindow(EffectWindow *w)
|
|||
|
||||
bool PresentWindowsEffect::isVisibleWindow(EffectWindow *w)
|
||||
{
|
||||
if (w->isDesktop() || w == m_closeWindow)
|
||||
if (w->isDesktop())
|
||||
return true;
|
||||
return isSelectableWindow(w);
|
||||
}
|
||||
|
@ -1727,14 +1694,6 @@ void PresentWindowsEffect::setHighlightedWindow(EffectWindow *w)
|
|||
updateCloseWindow();
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::elevateCloseWindow()
|
||||
{
|
||||
if (!m_closeView || !m_activated)
|
||||
return;
|
||||
if (EffectWindow *cw = effects->findWindow(m_closeView->winId()))
|
||||
effects->setElevatedWindow(cw, true);
|
||||
}
|
||||
|
||||
void PresentWindowsEffect::updateCloseWindow()
|
||||
{
|
||||
if (!m_closeView || m_doNotCloseWindows)
|
||||
|
@ -1748,7 +1707,7 @@ void PresentWindowsEffect::updateCloseWindow()
|
|||
return;
|
||||
|
||||
const QRectF rect(m_motionManager.targetGeometry(m_highlightedWindow));
|
||||
if (2*m_closeView->width() > rect.width() && 2*m_closeView->height() > rect.height()) {
|
||||
if (2*m_closeView->geometry().width() > rect.width() && 2*m_closeView->geometry().height() > rect.height()) {
|
||||
// not for tiny windows (eg. with many windows) - they might become unselectable
|
||||
m_closeView->hide();
|
||||
return;
|
||||
|
@ -1770,9 +1729,6 @@ void PresentWindowsEffect::updateCloseWindow()
|
|||
if (rect.contains(effects->cursorPos())) {
|
||||
m_closeView->show();
|
||||
m_closeView->disarm();
|
||||
// to wait for the next event cycle (or more if the show takes more time)
|
||||
// TODO: make the closeWindow a graphicsviewitem? why should there be an extra scene to be used in an exiting scene??
|
||||
QTimer::singleShot(50, this, SLOT(elevateCloseWindow()));
|
||||
}
|
||||
else
|
||||
m_closeView->hide();
|
||||
|
@ -1978,36 +1934,24 @@ void PresentWindowsEffect::reCreateGrids()
|
|||
rearrangeWindows();
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* CloseWindowView
|
||||
************************************************/
|
||||
CloseWindowView::CloseWindowView(QObject *parent)
|
||||
: QObject(parent)
|
||||
: EffectQuickScene(parent)
|
||||
, m_armTimer(new QElapsedTimer())
|
||||
, m_window(new QQuickView())
|
||||
, m_visible(false)
|
||||
, m_posIsValid(false)
|
||||
{
|
||||
m_window->setFlags(Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint);
|
||||
m_window->setColor(Qt::transparent);
|
||||
|
||||
m_window->setSource(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/presentwindows/main.qml"))));
|
||||
if (QObject *item = m_window->rootObject()->findChild<QObject*>(QStringLiteral("closeButton"))) {
|
||||
connect(item, SIGNAL(clicked()), SIGNAL(requestClose()));
|
||||
setSource(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/presentwindows/main.qml"))));
|
||||
if (QQuickItem *item = rootItem()) {
|
||||
connect(item, SIGNAL(clicked()), this, SLOT(clicked()));
|
||||
setGeometry(QRect(QPoint(), QSize(item->implicitWidth(), item->implicitHeight())));
|
||||
}
|
||||
|
||||
m_armTimer->restart();
|
||||
}
|
||||
|
||||
void CloseWindowView::windowInputMouseEvent(QMouseEvent *e)
|
||||
void CloseWindowView::clicked()
|
||||
{
|
||||
if (e->type() == QEvent::MouseMove) {
|
||||
qApp->sendEvent(m_window.data(), e);
|
||||
} else if (!m_armTimer->hasExpired(350)) {
|
||||
// 50ms until the window is elevated (seen!) and 300ms more to be "realized" by the user.
|
||||
return;
|
||||
// 50ms until the window is elevated (seen!) and 300ms more to be "realized" by the user.
|
||||
if (m_armTimer->hasExpired(350)) {
|
||||
emit requestClose();
|
||||
}
|
||||
qApp->sendEvent(m_window.data(), e);
|
||||
}
|
||||
|
||||
void CloseWindowView::disarm()
|
||||
|
@ -2015,57 +1959,6 @@ void CloseWindowView::disarm()
|
|||
m_armTimer->restart();
|
||||
}
|
||||
|
||||
bool CloseWindowView::isVisible() const
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
void CloseWindowView::show()
|
||||
{
|
||||
if (!m_visible && m_posIsValid) {
|
||||
m_window->setPosition(m_pos);
|
||||
m_posIsValid = false;
|
||||
}
|
||||
m_visible = true;
|
||||
m_window->show();
|
||||
}
|
||||
|
||||
void CloseWindowView::hide()
|
||||
{
|
||||
if (!m_posIsValid) {
|
||||
m_pos = m_window->position();
|
||||
m_posIsValid = true;
|
||||
m_window->setPosition(-m_window->width(), -m_window->height());
|
||||
}
|
||||
m_visible = false;
|
||||
QEvent event(QEvent::Leave);
|
||||
qApp->sendEvent(m_window.data(), &event);
|
||||
}
|
||||
|
||||
#define DELEGATE(type, name) \
|
||||
type CloseWindowView::name() const \
|
||||
{ \
|
||||
return m_window->name(); \
|
||||
}
|
||||
|
||||
DELEGATE(int, width)
|
||||
DELEGATE(int, height)
|
||||
DELEGATE(QSize, size)
|
||||
DELEGATE(QRect, geometry)
|
||||
DELEGATE(WId, winId)
|
||||
|
||||
#undef DELEGATE
|
||||
|
||||
void CloseWindowView::setGeometry(const QRect &geometry)
|
||||
{
|
||||
m_posIsValid = false;
|
||||
m_window->setGeometry(geometry);
|
||||
}
|
||||
|
||||
QPoint CloseWindowView::mapFromGlobal(const QPoint &pos) const
|
||||
{
|
||||
return m_window->mapFromGlobal(pos);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "presentwindows_proxy.h"
|
||||
|
||||
#include <kwineffects.h>
|
||||
#include <kwineffectquickview.h>
|
||||
|
||||
class QMouseEvent;
|
||||
class QElapsedTimer;
|
||||
|
@ -32,36 +33,18 @@ class QQuickView;
|
|||
|
||||
namespace KWin
|
||||
{
|
||||
class CloseWindowView : public QObject
|
||||
class CloseWindowView : public EffectQuickScene
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CloseWindowView(QObject *parent = nullptr);
|
||||
void windowInputMouseEvent(QMouseEvent* e);
|
||||
void disarm();
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
bool isVisible() const;
|
||||
|
||||
// delegate to QWindow
|
||||
int width() const;
|
||||
int height() const;
|
||||
QSize size() const;
|
||||
QRect geometry() const;
|
||||
WId winId() const;
|
||||
void setGeometry(const QRect &geometry);
|
||||
QPoint mapFromGlobal(const QPoint &pos) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void requestClose();
|
||||
|
||||
private Q_SLOTS:
|
||||
void clicked();
|
||||
private:
|
||||
QScopedPointer<QElapsedTimer> m_armTimer;
|
||||
QScopedPointer<QQuickView> m_window;
|
||||
bool m_visible;
|
||||
QPoint m_pos;
|
||||
bool m_posIsValid;
|
||||
QElapsedTimer *m_armTimer;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -230,7 +213,6 @@ public Q_SLOTS:
|
|||
|
||||
private Q_SLOTS:
|
||||
void closeWindow();
|
||||
void elevateCloseWindow();
|
||||
|
||||
protected:
|
||||
// Window rearranging
|
||||
|
@ -335,7 +317,6 @@ private:
|
|||
DesktopMouseAction m_rightButtonDesktop;
|
||||
|
||||
CloseWindowView* m_closeView;
|
||||
EffectWindow* m_closeWindow;
|
||||
Qt::Corner m_closeButtonCorner;
|
||||
struct {
|
||||
qint32 id = 0;
|
||||
|
|
Loading…
Reference in a new issue