From 5d5673ebc0057dc6313470428b06ac21a1da2a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 25 Oct 2013 12:57:34 +0200 Subject: [PATCH] Fix rendering errors of close window button in Present Windows Hiding and Showing the close window button all the time can result in the window not having a proper content. To fix this issue we keep the window around, but just don't show it. For this the CloseWindowView inherits from QObject and delegates the needed calls to the nested QQuickView. --- effects/presentwindows/presentwindows.cpp | 84 +++++++++++++++++------ effects/presentwindows/presentwindows.h | 24 +++++-- 2 files changed, 80 insertions(+), 28 deletions(-) diff --git a/effects/presentwindows/presentwindows.cpp b/effects/presentwindows/presentwindows.cpp index 766f2189df..82af622df8 100755 --- a/effects/presentwindows/presentwindows.cpp +++ b/effects/presentwindows/presentwindows.cpp @@ -41,6 +41,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -400,8 +401,12 @@ void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region } winData->textFrame->render(region, 0.9 * data.opacity() * m_decalOpacity, 0.75); } - } else + } else { + if (w == m_closeWindow && m_closeView && !m_closeView->isVisible()) { + data.setOpacity(0); + } effects->paintWindow(w, mask, region, data); + } } else effects->paintWindow(w, mask, region, data); } @@ -522,8 +527,9 @@ bool PresentWindowsEffect::borderActivated(ElectricBorder border) void PresentWindowsEffect::windowInputMouseEvent(QEvent *e) { QMouseEvent* me = static_cast< QMouseEvent* >(e); - if (m_closeView && m_closeView->geometry().contains(me->pos())) { - if (!m_closeView->isVisible()) { + if (m_closeView) { + const bool contains = m_closeView->geometry().contains(me->pos()); + if (!m_closeView->isVisible() && contains) { updateCloseWindow(); } if (m_closeView->isVisible()) { @@ -531,7 +537,10 @@ void PresentWindowsEffect::windowInputMouseEvent(QEvent *e) // 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; + if (contains) { + // filter out + return; + } } } // Which window are we hovering over? Always trigger as we don't always get move events before clicking @@ -1945,15 +1954,17 @@ void PresentWindowsEffect::screenCountChanged() /************************************************ * CloseWindowView ************************************************/ -CloseWindowView::CloseWindowView(QWindow *parent) - : QQuickView(parent) +CloseWindowView::CloseWindowView(QObject *parent) + : QObject(parent) , m_armTimer(new QElapsedTimer()) + , m_window(new QQuickView()) + , m_visible(false) { - setFlags(Qt::X11BypassWindowManagerHint); - setColor(Qt::transparent); + m_window->setFlags(Qt::X11BypassWindowManagerHint); + m_window->setColor(Qt::transparent); - setSource(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/presentwindows/main.qml")))); - if (QObject *item = rootObject()->findChild(QStringLiteral("closeButton"))) { + m_window->setSource(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/presentwindows/main.qml")))); + if (QObject *item = m_window->rootObject()->findChild(QStringLiteral("closeButton"))) { connect(item, SIGNAL(clicked()), SIGNAL(requestClose())); } @@ -1963,17 +1974,12 @@ CloseWindowView::CloseWindowView(QWindow *parent) void CloseWindowView::windowInputMouseEvent(QMouseEvent *e) { if (e->type() == QEvent::MouseMove) { - mouseMoveEvent(e); + 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; - } else if (e->type() == QEvent::MouseButtonPress) { - mousePressEvent(e); - } else if (e->type() == QEvent::MouseButtonDblClick) { - mouseDoubleClickEvent(e); - } else if (e->type() == QEvent::MouseButtonRelease) { - mouseReleaseEvent(e); } + qApp->sendEvent(m_window.data(), e); } void CloseWindowView::disarm() @@ -1981,12 +1987,46 @@ void CloseWindowView::disarm() m_armTimer->restart(); } -void CloseWindowView::hideEvent(QHideEvent *event) +bool CloseWindowView::isVisible() const { - const QPoint globalPos = mapToGlobal(QPoint(-1,-1)); - QMouseEvent me(QEvent::MouseMove, QPoint(-1,-1), globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier); - mouseMoveEvent(&me); - QQuickView::hideEvent(event); + return m_visible; +} + +void CloseWindowView::show() +{ + m_visible = true; + m_window->show(); +} + +void CloseWindowView::hide() +{ + 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_window->setGeometry(geometry); +} + +QPoint CloseWindowView::mapFromGlobal(const QPoint &pos) const +{ + return m_window->mapFromGlobal(pos); } } // namespace diff --git a/effects/presentwindows/presentwindows.h b/effects/presentwindows/presentwindows.h index a4cb7881eb..7565c26909 100644 --- a/effects/presentwindows/presentwindows.h +++ b/effects/presentwindows/presentwindows.h @@ -25,28 +25,40 @@ along with this program. If not, see . #include "presentwindows_proxy.h" #include -#include class QElapsedTimer; +class QQuickView; namespace KWin { -class CloseWindowView : public QQuickView +class CloseWindowView : public QObject { Q_OBJECT public: - explicit CloseWindowView(QWindow *parent = 0); + explicit CloseWindowView(QObject *parent = 0); 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(); -protected: - void hideEvent(QHideEvent *event); - private: QScopedPointer m_armTimer; + QScopedPointer m_window; + bool m_visible; }; /**