diff --git a/src/effects.cpp b/src/effects.cpp index 557b7c7c26..c24725f590 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -89,14 +89,6 @@ static QByteArray readWindowProperty(xcb_window_t win, xcb_atom_t atom, xcb_atom } } -static void deleteWindowProperty(xcb_window_t win, long int atom) -{ - if (win == XCB_WINDOW_NONE) { - return; - } - xcb_delete_property(kwinApp()->x11Connection(), win, atom); -} - static xcb_atom_t registerSupportProperty(const QByteArray &propertyName) { auto c = kwinApp()->x11Connection(); @@ -314,7 +306,7 @@ void EffectsHandlerImpl::paintWindow(const RenderTarget &renderTarget, const Ren (*m_currentPaintWindowIterator++)->paintWindow(renderTarget, viewport, w, mask, region, data); --m_currentPaintWindowIterator; } else { - m_scene->finalPaintWindow(renderTarget, viewport, static_cast(w), mask, region, data); + m_scene->finalPaintWindow(renderTarget, viewport, w, mask, region, data); } } @@ -343,13 +335,13 @@ void EffectsHandlerImpl::drawWindow(const RenderTarget &renderTarget, const Rend (*m_currentDrawWindowIterator++)->drawWindow(renderTarget, viewport, w, mask, region, data); --m_currentDrawWindowIterator; } else { - m_scene->finalDrawWindow(renderTarget, viewport, static_cast(w), mask, region, data); + m_scene->finalDrawWindow(renderTarget, viewport, w, mask, region, data); } } void EffectsHandlerImpl::renderWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) { - m_scene->finalDrawWindow(renderTarget, viewport, static_cast(w), mask, region, data); + m_scene->finalDrawWindow(renderTarget, viewport, w, mask, region, data); } bool EffectsHandlerImpl::hasDecorationShadows() const @@ -682,7 +674,7 @@ QByteArray EffectsHandlerImpl::readRootProperty(long atom, long type, int format void EffectsHandlerImpl::activateWindow(EffectWindow *effectWindow) { - auto window = static_cast(effectWindow)->window(); + auto window = effectWindow->window(); if (window->isClient()) { Workspace::self()->activateWindow(window, true); } @@ -695,7 +687,7 @@ EffectWindow *EffectsHandlerImpl::activeWindow() const void EffectsHandlerImpl::moveWindow(EffectWindow *w, const QPoint &pos, bool snap, double snapAdjust) { - auto window = static_cast(w)->window(); + auto window = w->window(); if (!window->isClient() || !window->isMovable()) { return; } @@ -709,7 +701,7 @@ void EffectsHandlerImpl::moveWindow(EffectWindow *w, const QPoint &pos, bool sna void EffectsHandlerImpl::windowToDesktops(EffectWindow *w, const QList &desktops) { - auto window = static_cast(w)->window(); + auto window = w->window(); if (!window->isClient() || window->isDesktop() || window->isDock()) { return; } @@ -718,7 +710,7 @@ void EffectsHandlerImpl::windowToDesktops(EffectWindow *w, const QList(w)->window(); + auto window = w->window(); if (window->isClient() && !window->isDesktop() && !window->isDock()) { Workspace::self()->sendWindowToOutput(window, screen); } @@ -887,7 +879,7 @@ EffectWindowList EffectsHandlerImpl::stackingOrder() const void EffectsHandlerImpl::setElevatedWindow(KWin::EffectWindow *w, bool set) { - WindowItem *item = static_cast(w)->windowItem(); + WindowItem *item = w->windowItem(); if (set) { item->elevate(); @@ -899,7 +891,7 @@ void EffectsHandlerImpl::setElevatedWindow(KWin::EffectWindow *w, bool set) void EffectsHandlerImpl::setTabBoxWindow(EffectWindow *w) { #if KWIN_BUILD_TABBOX - auto window = static_cast(w)->window(); + auto window = w->window(); if (window->isClient()) { workspace()->tabbox()->setCurrentClient(window); } @@ -991,7 +983,7 @@ QRectF EffectsHandlerImpl::clientArea(clientAreaOption opt, const Output *screen QRectF EffectsHandlerImpl::clientArea(clientAreaOption opt, const EffectWindow *effectWindow) const { - const Window *window = static_cast(effectWindow)->window(); + const Window *window = effectWindow->window(); return Workspace::self()->clientArea(opt, window); } @@ -1603,401 +1595,6 @@ QQmlEngine *EffectsHandlerImpl::qmlEngine() const return Scripting::self()->qmlEngine(); } -//**************************************** -// EffectWindowImpl -//**************************************** - -EffectWindowImpl::EffectWindowImpl(WindowItem *windowItem) - : m_window(windowItem->window()) - , m_windowItem(windowItem) -{ - // Deleted windows are not managed. So, when windowClosed signal is - // emitted, effects can't distinguish managed windows from unmanaged - // windows(e.g. combo box popups, popup menus, etc). Save value of the - // managed property during construction of EffectWindow. At that time, - // parent can be Client, XdgShellClient, or Unmanaged. So, later on, when - // an instance of Deleted becomes parent of the EffectWindow, effects - // can still figure out whether it is/was a managed window. - managed = m_window->isClient(); - - m_waylandWindow = qobject_cast(m_window) != nullptr; - m_x11Window = qobject_cast(m_window) != nullptr; - - connect(m_window, &Window::windowShown, this, [this]() { - Q_EMIT windowShown(this); - }); - connect(m_window, &Window::windowHidden, this, [this]() { - Q_EMIT windowHidden(this); - }); - connect(m_window, &Window::maximizedChanged, this, [this]() { - const MaximizeMode mode = m_window->maximizeMode(); - Q_EMIT windowMaximizedStateChanged(this, mode & MaximizeHorizontal, mode & MaximizeVertical); - }); - connect(m_window, &Window::maximizedAboutToChange, this, [this](MaximizeMode m) { - Q_EMIT windowMaximizedStateAboutToChange(this, m & MaximizeHorizontal, m & MaximizeVertical); - }); - connect(m_window, &Window::frameGeometryAboutToChange, this, [this]() { - Q_EMIT windowFrameGeometryAboutToChange(this); - }); - connect(m_window, &Window::interactiveMoveResizeStarted, this, [this]() { - Q_EMIT windowStartUserMovedResized(this); - }); - connect(m_window, &Window::interactiveMoveResizeStepped, this, [this](const QRectF &geometry) { - Q_EMIT windowStepUserMovedResized(this, geometry); - }); - connect(m_window, &Window::interactiveMoveResizeFinished, this, [this]() { - Q_EMIT windowFinishUserMovedResized(this); - }); - connect(m_window, &Window::opacityChanged, this, [this](Window *window, qreal oldOpacity) { - Q_EMIT windowOpacityChanged(this, oldOpacity, window->opacity()); - }); - connect(m_window, &Window::minimizedChanged, this, [this]() { - if (m_window->isMinimized()) { - Q_EMIT windowMinimized(this); - } else { - Q_EMIT windowUnminimized(this); - } - }); - connect(m_window, &Window::modalChanged, this, [this]() { - Q_EMIT windowModalityChanged(this); - }); - connect(m_window, &Window::frameGeometryChanged, this, [this](const QRectF &oldGeometry) { - Q_EMIT windowFrameGeometryChanged(this, oldGeometry); - }); - connect(m_window, &Window::damaged, this, [this]() { - Q_EMIT windowDamaged(this); - }); - connect(m_window, &Window::unresponsiveChanged, this, [this](bool unresponsive) { - Q_EMIT windowUnresponsiveChanged(this, unresponsive); - }); - connect(m_window, &Window::keepAboveChanged, this, [this]() { - Q_EMIT windowKeepAboveChanged(this); - }); - connect(m_window, &Window::keepBelowChanged, this, [this]() { - Q_EMIT windowKeepBelowChanged(this); - }); - connect(m_window, &Window::fullScreenChanged, this, [this]() { - Q_EMIT windowFullScreenChanged(this); - }); - connect(m_window, &Window::visibleGeometryChanged, this, [this]() { - Q_EMIT windowExpandedGeometryChanged(this); - }); - connect(m_window, &Window::decorationChanged, this, [this]() { - Q_EMIT windowDecorationChanged(this); - }); - connect(m_window, &Window::desktopsChanged, this, [this]() { - Q_EMIT windowDesktopsChanged(this); - }); -} - -EffectWindowImpl::~EffectWindowImpl() -{ -} - -void EffectWindowImpl::refVisible(const EffectWindowVisibleRef *holder) -{ - m_windowItem->refVisible(holder->reason()); -} - -void EffectWindowImpl::unrefVisible(const EffectWindowVisibleRef *holder) -{ - m_windowItem->unrefVisible(holder->reason()); -} - -void EffectWindowImpl::addRepaint(const QRect &r) -{ - m_windowItem->scheduleRepaint(QRegion(r)); -} - -void EffectWindowImpl::addRepaintFull() -{ - m_windowItem->scheduleRepaint(m_windowItem->boundingRect()); -} - -void EffectWindowImpl::addLayerRepaint(const QRect &r) -{ - m_windowItem->scheduleRepaint(m_windowItem->mapFromGlobal(r)); -} - -const EffectWindowGroup *EffectWindowImpl::group() const -{ - if (auto c = qobject_cast(m_window)) { - return c->group()->effectGroup(); - } - return nullptr; // TODO -} - -void EffectWindowImpl::refWindow() -{ - if (m_window->isDeleted()) { - return m_window->ref(); - } - Q_UNREACHABLE(); // TODO -} - -void EffectWindowImpl::unrefWindow() -{ - if (m_window->isDeleted()) { - return m_window->unref(); - } - Q_UNREACHABLE(); // TODO -} - -Output *EffectWindowImpl::screen() const -{ - return m_window->output(); -} - -#define WINDOW_HELPER(rettype, prototype, toplevelPrototype) \ - rettype EffectWindowImpl::prototype() const \ - { \ - return m_window->toplevelPrototype(); \ - } - -WINDOW_HELPER(double, opacity, opacity) -WINDOW_HELPER(qreal, x, x) -WINDOW_HELPER(qreal, y, y) -WINDOW_HELPER(qreal, width, width) -WINDOW_HELPER(qreal, height, height) -WINDOW_HELPER(QPointF, pos, pos) -WINDOW_HELPER(QSizeF, size, size) -WINDOW_HELPER(QRectF, frameGeometry, frameGeometry) -WINDOW_HELPER(QRectF, bufferGeometry, bufferGeometry) -WINDOW_HELPER(QRectF, clientGeometry, clientGeometry) -WINDOW_HELPER(QRectF, expandedGeometry, visibleGeometry) -WINDOW_HELPER(QRectF, rect, rect) -WINDOW_HELPER(bool, isDesktop, isDesktop) -WINDOW_HELPER(bool, isDock, isDock) -WINDOW_HELPER(bool, isToolbar, isToolbar) -WINDOW_HELPER(bool, isMenu, isMenu) -WINDOW_HELPER(bool, isNormalWindow, isNormalWindow) -WINDOW_HELPER(bool, isDialog, isDialog) -WINDOW_HELPER(bool, isSplash, isSplash) -WINDOW_HELPER(bool, isUtility, isUtility) -WINDOW_HELPER(bool, isDropdownMenu, isDropdownMenu) -WINDOW_HELPER(bool, isPopupMenu, isPopupMenu) -WINDOW_HELPER(bool, isTooltip, isTooltip) -WINDOW_HELPER(bool, isNotification, isNotification) -WINDOW_HELPER(bool, isCriticalNotification, isCriticalNotification) -WINDOW_HELPER(bool, isAppletPopup, isAppletPopup) -WINDOW_HELPER(bool, isOnScreenDisplay, isOnScreenDisplay) -WINDOW_HELPER(bool, isComboBox, isComboBox) -WINDOW_HELPER(bool, isDNDIcon, isDNDIcon) -WINDOW_HELPER(bool, isDeleted, isDeleted) -WINDOW_HELPER(QString, windowRole, windowRole) -WINDOW_HELPER(QStringList, activities, activities) -WINDOW_HELPER(bool, skipsCloseAnimation, skipsCloseAnimation) -WINDOW_HELPER(SurfaceInterface *, surface, surface) -WINDOW_HELPER(bool, isPopupWindow, isPopupWindow) -WINDOW_HELPER(bool, isOutline, isOutline) -WINDOW_HELPER(bool, isLockScreen, isLockScreen) -WINDOW_HELPER(pid_t, pid, pid) -WINDOW_HELPER(QUuid, internalId, internalId) -WINDOW_HELPER(bool, isMinimized, isMinimized) -WINDOW_HELPER(bool, isHidden, isHidden) -WINDOW_HELPER(bool, isHiddenByShowDesktop, isHiddenByShowDesktop) -WINDOW_HELPER(bool, isModal, isModal) -WINDOW_HELPER(bool, isFullScreen, isFullScreen) -WINDOW_HELPER(bool, keepAbove, keepAbove) -WINDOW_HELPER(bool, keepBelow, keepBelow) -WINDOW_HELPER(QString, caption, caption) -WINDOW_HELPER(bool, isMovable, isMovable) -WINDOW_HELPER(bool, isMovableAcrossScreens, isMovableAcrossScreens) -WINDOW_HELPER(bool, isUserMove, isInteractiveMove) -WINDOW_HELPER(bool, isUserResize, isInteractiveResize) -WINDOW_HELPER(QRectF, iconGeometry, iconGeometry) -WINDOW_HELPER(bool, isSpecialWindow, isSpecialWindow) -WINDOW_HELPER(bool, acceptsFocus, wantsInput) -WINDOW_HELPER(QIcon, icon, icon) -WINDOW_HELPER(bool, isSkipSwitcher, skipSwitcher) -WINDOW_HELPER(bool, decorationHasAlpha, decorationHasAlpha) -WINDOW_HELPER(bool, isUnresponsive, unresponsive) -WINDOW_HELPER(QList, desktops, desktops) - -#undef WINDOW_HELPER - -qlonglong EffectWindowImpl::windowId() const -{ - if (X11Window *x11Window = qobject_cast(m_window)) { - return x11Window->window(); - } - return 0; -} - -QString EffectWindowImpl::windowClass() const -{ - return m_window->resourceName() + QLatin1Char(' ') + m_window->resourceClass(); -} - -QRectF EffectWindowImpl::contentsRect() const -{ - return QRectF(m_window->clientPos(), m_window->clientSize()); -} - -NET::WindowType EffectWindowImpl::windowType() const -{ - return m_window->windowType(); -} - -QSizeF EffectWindowImpl::basicUnit() const -{ - if (auto window = qobject_cast(m_window)) { - return window->basicUnit(); - } - return QSize(1, 1); -} - -QRectF EffectWindowImpl::decorationInnerRect() const -{ - return m_window->rect() - m_window->frameMargins(); -} - -KDecoration2::Decoration *EffectWindowImpl::decoration() const -{ - return m_window->decoration(); -} - -QByteArray EffectWindowImpl::readProperty(long atom, long type, int format) const -{ - auto x11Window = qobject_cast(m_window); - if (!x11Window) { - return QByteArray(); - } - if (!kwinApp()->x11Connection()) { - return QByteArray(); - } - return readWindowProperty(x11Window->window(), atom, type, format); -} - -void EffectWindowImpl::deleteProperty(long int atom) const -{ - auto x11Window = qobject_cast(m_window); - if (!x11Window) { - return; - } - if (kwinApp()->x11Connection()) { - deleteWindowProperty(x11Window->window(), atom); - } -} - -EffectWindow *EffectWindowImpl::findModal() -{ - Window *modal = m_window->findModal(); - if (modal) { - return modal->effectWindow(); - } - - return nullptr; -} - -EffectWindow *EffectWindowImpl::transientFor() -{ - Window *transientFor = m_window->transientFor(); - if (transientFor) { - return transientFor->effectWindow(); - } - - return nullptr; -} - -QWindow *EffectWindowImpl::internalWindow() const -{ - if (auto window = qobject_cast(m_window)) { - return window->handle(); - } - return nullptr; -} - -template -EffectWindowList getMainWindows(T *c) -{ - const auto mainwindows = c->mainWindows(); - EffectWindowList ret; - ret.reserve(mainwindows.size()); - std::transform(std::cbegin(mainwindows), std::cend(mainwindows), - std::back_inserter(ret), - [](auto window) { - return window->effectWindow(); - }); - return ret; -} - -EffectWindowList EffectWindowImpl::mainWindows() const -{ - return getMainWindows(m_window); -} - -void EffectWindowImpl::setData(int role, const QVariant &data) -{ - if (!data.isNull()) { - dataMap[role] = data; - } else { - dataMap.remove(role); - } - Q_EMIT effects->windowDataChanged(this, role); -} - -QVariant EffectWindowImpl::data(int role) const -{ - return dataMap.value(role); -} - -void EffectWindowImpl::elevate(bool elevate) -{ - effects->setElevatedWindow(this, elevate); -} - -void EffectWindowImpl::minimize() -{ - if (m_window->isClient()) { - m_window->setMinimized(true); - } -} - -void EffectWindowImpl::unminimize() -{ - if (m_window->isClient()) { - m_window->setMinimized(false); - } -} - -void EffectWindowImpl::closeWindow() -{ - if (m_window->isClient()) { - m_window->closeWindow(); - } -} - -bool EffectWindowImpl::isManaged() const -{ - return managed; -} - -bool EffectWindowImpl::isWaylandClient() const -{ - return m_waylandWindow; -} - -bool EffectWindowImpl::isX11Client() const -{ - return m_x11Window; -} - -//**************************************** -// EffectWindowGroupImpl -//**************************************** - -EffectWindowList EffectWindowGroupImpl::members() const -{ - const auto memberList = group->members(); - EffectWindowList ret; - ret.reserve(memberList.size()); - std::transform(std::cbegin(memberList), std::cend(memberList), std::back_inserter(ret), [](auto window) { - return window->effectWindow(); - }); - return ret; -} - //**************************************** // EffectFrameImpl //**************************************** diff --git a/src/effects.h b/src/effects.h index 056a9ae390..03b9ff8901 100644 --- a/src/effects.h +++ b/src/effects.h @@ -32,7 +32,6 @@ class Display; class Window; class Compositor; class EffectLoader; -class Group; class Unmanaged; class WindowPropertyNotifyX11Filter; class TabletEvent; @@ -317,150 +316,6 @@ private: std::unique_ptr m_x11WindowPropertyNotify; }; -class EffectWindowImpl : public EffectWindow -{ - Q_OBJECT -public: - explicit EffectWindowImpl(WindowItem *windowItem); - ~EffectWindowImpl() override; - - void addRepaint(const QRect &r) override; - void addRepaintFull() override; - void addLayerRepaint(const QRect &r) override; - - void refWindow() override; - void unrefWindow() override; - - const EffectWindowGroup *group() const override; - - bool isDeleted() const override; - bool isMinimized() const override; - bool isHidden() const override; - bool isHiddenByShowDesktop() const override; - double opacity() const override; - - QStringList activities() const override; - QList desktops() const override; - qreal x() const override; - qreal y() const override; - qreal width() const override; - qreal height() const override; - - QSizeF basicUnit() const override; - QRectF frameGeometry() const override; - QRectF bufferGeometry() const override; - QRectF clientGeometry() const override; - - QString caption() const override; - - QRectF expandedGeometry() const override; - Output *screen() const override; - QPointF pos() const override; - QSizeF size() const override; - QRectF rect() const override; - - bool isMovable() const override; - bool isMovableAcrossScreens() const override; - bool isUserMove() const override; - bool isUserResize() const override; - QRectF iconGeometry() const override; - - bool isDesktop() const override; - bool isDock() const override; - bool isToolbar() const override; - bool isMenu() const override; - bool isNormalWindow() const override; - bool isSpecialWindow() const override; - bool isDialog() const override; - bool isSplash() const override; - bool isUtility() const override; - bool isDropdownMenu() const override; - bool isPopupMenu() const override; - bool isTooltip() const override; - bool isNotification() const override; - bool isCriticalNotification() const override; - bool isAppletPopup() const override; - bool isOnScreenDisplay() const override; - bool isComboBox() const override; - bool isDNDIcon() const override; - bool skipsCloseAnimation() const override; - - bool acceptsFocus() const override; - bool keepAbove() const override; - bool keepBelow() const override; - bool isModal() const override; - bool isPopupWindow() const override; - bool isOutline() const override; - bool isLockScreen() const override; - - SurfaceInterface *surface() const override; - bool isFullScreen() const override; - bool isUnresponsive() const override; - - QRectF contentsRect() const override; - bool decorationHasAlpha() const override; - QIcon icon() const override; - QString windowClass() const override; - NET::WindowType windowType() const override; - bool isSkipSwitcher() const override; - QString windowRole() const override; - - bool isManaged() const override; - bool isWaylandClient() const override; - bool isX11Client() const override; - - pid_t pid() const override; - qlonglong windowId() const override; - QUuid internalId() const override; - - QRectF decorationInnerRect() const override; - KDecoration2::Decoration *decoration() const override; - QByteArray readProperty(long atom, long type, int format) const override; - void deleteProperty(long atom) const override; - - EffectWindow *findModal() override; - EffectWindow *transientFor() override; - EffectWindowList mainWindows() const override; - - void minimize() override; - void unminimize() override; - void closeWindow() override; - - QWindow *internalWindow() const override; - - const Window *window() const; - Window *window(); - - WindowItem *windowItem() const; // internal - - void elevate(bool elevate); - - void setData(int role, const QVariant &data) override; - QVariant data(int role) const override; - -private: - void refVisible(const EffectWindowVisibleRef *holder) override; - void unrefVisible(const EffectWindowVisibleRef *holder) override; - - Window *m_window; - WindowItem *m_windowItem; // This one is used only during paint pass. - QHash dataMap; - bool managed = false; - bool m_waylandWindow; - bool m_x11Window; -}; - -class EffectWindowGroupImpl - : public EffectWindowGroup -{ -public: - explicit EffectWindowGroupImpl(Group *g); - EffectWindowList members() const override; - -private: - Group *group; -}; - class EffectFrameQuickScene : public OffscreenQuickScene { Q_OBJECT @@ -583,24 +438,4 @@ inline xcb_connection_t *EffectsHandlerImpl::xcbConnection() const return kwinApp()->x11Connection(); } -inline EffectWindowGroupImpl::EffectWindowGroupImpl(Group *g) - : group(g) -{ -} - -inline WindowItem *EffectWindowImpl::windowItem() const -{ - return m_windowItem; -} - -inline const Window *EffectWindowImpl::window() const -{ - return m_window; -} - -inline Window *EffectWindowImpl::window() -{ - return m_window; -} - } // namespace diff --git a/src/group.cpp b/src/group.cpp index 7509e758c1..5f795e732a 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -9,7 +9,6 @@ */ #include "group.h" -#include "effects.h" #include "workspace.h" #include "x11window.h" @@ -35,7 +34,7 @@ Group::Group(xcb_window_t leader_P) leader_info = std::make_unique(kwinApp()->x11Connection(), leader_P, kwinApp()->x11RootWindow(), NET::Properties(), NET::WM2StartupId); } - effect_group = std::make_unique(this); + effect_group = std::make_unique(this); workspace()->addGroup(this); } diff --git a/src/group.h b/src/group.h index 9b733051a8..5cae3c1083 100644 --- a/src/group.h +++ b/src/group.h @@ -16,7 +16,7 @@ namespace KWin { -class EffectWindowGroupImpl; +class EffectWindowGroup; class X11Window; class Group @@ -37,7 +37,7 @@ public: xcb_timestamp_t userTime() const; void ref(); void deref(); - EffectWindowGroupImpl *effectGroup(); + EffectWindowGroup *effectGroup(); private: void startupIdChanged(); @@ -47,7 +47,7 @@ private: std::unique_ptr leader_info; xcb_timestamp_t user_time; int refcount; - std::unique_ptr effect_group; + std::unique_ptr effect_group; }; inline xcb_window_t Group::leader() const @@ -75,7 +75,7 @@ inline xcb_timestamp_t Group::userTime() const return user_time; } -inline EffectWindowGroupImpl *Group::effectGroup() +inline EffectWindowGroup *Group::effectGroup() { return effect_group.get(); } diff --git a/src/libkwineffects/kwineffects.cpp b/src/libkwineffects/kwineffects.cpp index 72f6e6a189..50e18228dc 100644 --- a/src/libkwineffects/kwineffects.cpp +++ b/src/libkwineffects/kwineffects.cpp @@ -11,7 +11,12 @@ #include "libkwineffects/kwineffects.h" #include "core/output.h" +#include "group.h" +#include "internalwindow.h" +#include "scene/windowitem.h" #include "virtualdesktops.h" +#include "waylandwindow.h" +#include "x11window.h" #include "config-kwin.h" @@ -32,6 +37,34 @@ namespace KWin { +static QByteArray readWindowProperty(xcb_window_t win, xcb_atom_t atom, xcb_atom_t type, int format) +{ + if (win == XCB_WINDOW_NONE) { + return QByteArray(); + } + uint32_t len = 32768; + for (;;) { + Xcb::Property prop(false, win, atom, XCB_ATOM_ANY, 0, len); + if (prop.isNull()) { + // get property failed + return QByteArray(); + } + if (prop->bytes_after > 0) { + len *= 2; + continue; + } + return prop.toByteArray(format, type); + } +} + +static void deleteWindowProperty(xcb_window_t win, long int atom) +{ + if (win == XCB_WINDOW_NONE) { + return; + } + xcb_delete_property(kwinApp()->x11Connection(), win, atom); +} + void WindowPrePaintData::setTranslucent() { mask |= Effect::PAINT_WINDOW_TRANSLUCENT; @@ -636,25 +669,120 @@ EffectsHandler *effects = nullptr; class Q_DECL_HIDDEN EffectWindow::Private { public: - Private(EffectWindow *q); + Private(EffectWindow *q, WindowItem *windowItem); EffectWindow *q; + Window *m_window; + WindowItem *m_windowItem; // This one is used only during paint pass. + QHash dataMap; + bool managed = false; + bool m_waylandWindow; + bool m_x11Window; }; -EffectWindow::Private::Private(EffectWindow *q) +EffectWindow::Private::Private(EffectWindow *q, WindowItem *windowItem) : q(q) + , m_window(windowItem->window()) + , m_windowItem(windowItem) { } -EffectWindow::EffectWindow() - : d(new Private(this)) +EffectWindow::EffectWindow(WindowItem *windowItem) + : d(new Private(this, windowItem)) { + // Deleted windows are not managed. So, when windowClosed signal is + // emitted, effects can't distinguish managed windows from unmanaged + // windows(e.g. combo box popups, popup menus, etc). Save value of the + // managed property during construction of EffectWindow. At that time, + // parent can be Client, XdgShellClient, or Unmanaged. So, later on, when + // an instance of Deleted becomes parent of the EffectWindow, effects + // can still figure out whether it is/was a managed window. + d->managed = d->m_window->isClient(); + + d->m_waylandWindow = qobject_cast(d->m_window) != nullptr; + d->m_x11Window = qobject_cast(d->m_window) != nullptr; + + connect(d->m_window, &Window::windowShown, this, [this]() { + Q_EMIT windowShown(this); + }); + connect(d->m_window, &Window::windowHidden, this, [this]() { + Q_EMIT windowHidden(this); + }); + connect(d->m_window, &Window::maximizedChanged, this, [this]() { + const MaximizeMode mode = d->m_window->maximizeMode(); + Q_EMIT windowMaximizedStateChanged(this, mode & MaximizeHorizontal, mode & MaximizeVertical); + }); + connect(d->m_window, &Window::maximizedAboutToChange, this, [this](MaximizeMode m) { + Q_EMIT windowMaximizedStateAboutToChange(this, m & MaximizeHorizontal, m & MaximizeVertical); + }); + connect(d->m_window, &Window::frameGeometryAboutToChange, this, [this]() { + Q_EMIT windowFrameGeometryAboutToChange(this); + }); + connect(d->m_window, &Window::interactiveMoveResizeStarted, this, [this]() { + Q_EMIT windowStartUserMovedResized(this); + }); + connect(d->m_window, &Window::interactiveMoveResizeStepped, this, [this](const QRectF &geometry) { + Q_EMIT windowStepUserMovedResized(this, geometry); + }); + connect(d->m_window, &Window::interactiveMoveResizeFinished, this, [this]() { + Q_EMIT windowFinishUserMovedResized(this); + }); + connect(d->m_window, &Window::opacityChanged, this, [this](Window *window, qreal oldOpacity) { + Q_EMIT windowOpacityChanged(this, oldOpacity, window->opacity()); + }); + connect(d->m_window, &Window::minimizedChanged, this, [this]() { + if (d->m_window->isMinimized()) { + Q_EMIT windowMinimized(this); + } else { + Q_EMIT windowUnminimized(this); + } + }); + connect(d->m_window, &Window::modalChanged, this, [this]() { + Q_EMIT windowModalityChanged(this); + }); + connect(d->m_window, &Window::frameGeometryChanged, this, [this](const QRectF &oldGeometry) { + Q_EMIT windowFrameGeometryChanged(this, oldGeometry); + }); + connect(d->m_window, &Window::damaged, this, [this]() { + Q_EMIT windowDamaged(this); + }); + connect(d->m_window, &Window::unresponsiveChanged, this, [this](bool unresponsive) { + Q_EMIT windowUnresponsiveChanged(this, unresponsive); + }); + connect(d->m_window, &Window::keepAboveChanged, this, [this]() { + Q_EMIT windowKeepAboveChanged(this); + }); + connect(d->m_window, &Window::keepBelowChanged, this, [this]() { + Q_EMIT windowKeepBelowChanged(this); + }); + connect(d->m_window, &Window::fullScreenChanged, this, [this]() { + Q_EMIT windowFullScreenChanged(this); + }); + connect(d->m_window, &Window::visibleGeometryChanged, this, [this]() { + Q_EMIT windowExpandedGeometryChanged(this); + }); + connect(d->m_window, &Window::decorationChanged, this, [this]() { + Q_EMIT windowDecorationChanged(this); + }); + connect(d->m_window, &Window::desktopsChanged, this, [this]() { + Q_EMIT windowDesktopsChanged(this); + }); } EffectWindow::~EffectWindow() { } +Window *EffectWindow::window() const +{ + return d->m_window; +} + +WindowItem *EffectWindow::windowItem() const +{ + return d->m_windowItem; +} + bool EffectWindow::isOnActivity(const QString &activity) const { const QStringList _activities = activities(); @@ -708,14 +836,319 @@ bool EffectWindow::isVisible() const && isOnCurrentActivity(); } +void EffectWindow::refVisible(const EffectWindowVisibleRef *holder) +{ + d->m_windowItem->refVisible(holder->reason()); +} + +void EffectWindow::unrefVisible(const EffectWindowVisibleRef *holder) +{ + d->m_windowItem->unrefVisible(holder->reason()); +} + +void EffectWindow::addRepaint(const QRect &r) +{ + d->m_windowItem->scheduleRepaint(QRegion(r)); +} + +void EffectWindow::addRepaintFull() +{ + d->m_windowItem->scheduleRepaint(d->m_windowItem->boundingRect()); +} + +void EffectWindow::addLayerRepaint(const QRect &r) +{ + d->m_windowItem->scheduleRepaint(d->m_windowItem->mapFromGlobal(r)); +} + +const EffectWindowGroup *EffectWindow::group() const +{ + if (auto c = qobject_cast(d->m_window)) { + return c->group()->effectGroup(); + } + return nullptr; // TODO +} + +void EffectWindow::refWindow() +{ + if (d->m_window->isDeleted()) { + return d->m_window->ref(); + } + Q_UNREACHABLE(); // TODO +} + +void EffectWindow::unrefWindow() +{ + if (d->m_window->isDeleted()) { + return d->m_window->unref(); + } + Q_UNREACHABLE(); // TODO +} + +Output *EffectWindow::screen() const +{ + return d->m_window->output(); +} + +#define WINDOW_HELPER(rettype, prototype, toplevelPrototype) \ + rettype EffectWindow::prototype() const \ + { \ + return d->m_window->toplevelPrototype(); \ + } + +WINDOW_HELPER(double, opacity, opacity) +WINDOW_HELPER(qreal, x, x) +WINDOW_HELPER(qreal, y, y) +WINDOW_HELPER(qreal, width, width) +WINDOW_HELPER(qreal, height, height) +WINDOW_HELPER(QPointF, pos, pos) +WINDOW_HELPER(QSizeF, size, size) +WINDOW_HELPER(QRectF, frameGeometry, frameGeometry) +WINDOW_HELPER(QRectF, bufferGeometry, bufferGeometry) +WINDOW_HELPER(QRectF, clientGeometry, clientGeometry) +WINDOW_HELPER(QRectF, expandedGeometry, visibleGeometry) +WINDOW_HELPER(QRectF, rect, rect) +WINDOW_HELPER(bool, isDesktop, isDesktop) +WINDOW_HELPER(bool, isDock, isDock) +WINDOW_HELPER(bool, isToolbar, isToolbar) +WINDOW_HELPER(bool, isMenu, isMenu) +WINDOW_HELPER(bool, isNormalWindow, isNormalWindow) +WINDOW_HELPER(bool, isDialog, isDialog) +WINDOW_HELPER(bool, isSplash, isSplash) +WINDOW_HELPER(bool, isUtility, isUtility) +WINDOW_HELPER(bool, isDropdownMenu, isDropdownMenu) +WINDOW_HELPER(bool, isPopupMenu, isPopupMenu) +WINDOW_HELPER(bool, isTooltip, isTooltip) +WINDOW_HELPER(bool, isNotification, isNotification) +WINDOW_HELPER(bool, isCriticalNotification, isCriticalNotification) +WINDOW_HELPER(bool, isAppletPopup, isAppletPopup) +WINDOW_HELPER(bool, isOnScreenDisplay, isOnScreenDisplay) +WINDOW_HELPER(bool, isComboBox, isComboBox) +WINDOW_HELPER(bool, isDNDIcon, isDNDIcon) +WINDOW_HELPER(bool, isDeleted, isDeleted) +WINDOW_HELPER(QString, windowRole, windowRole) +WINDOW_HELPER(QStringList, activities, activities) +WINDOW_HELPER(bool, skipsCloseAnimation, skipsCloseAnimation) +WINDOW_HELPER(SurfaceInterface *, surface, surface) +WINDOW_HELPER(bool, isPopupWindow, isPopupWindow) +WINDOW_HELPER(bool, isOutline, isOutline) +WINDOW_HELPER(bool, isLockScreen, isLockScreen) +WINDOW_HELPER(pid_t, pid, pid) +WINDOW_HELPER(QUuid, internalId, internalId) +WINDOW_HELPER(bool, isMinimized, isMinimized) +WINDOW_HELPER(bool, isHidden, isHidden) +WINDOW_HELPER(bool, isHiddenByShowDesktop, isHiddenByShowDesktop) +WINDOW_HELPER(bool, isModal, isModal) +WINDOW_HELPER(bool, isFullScreen, isFullScreen) +WINDOW_HELPER(bool, keepAbove, keepAbove) +WINDOW_HELPER(bool, keepBelow, keepBelow) +WINDOW_HELPER(QString, caption, caption) +WINDOW_HELPER(bool, isMovable, isMovable) +WINDOW_HELPER(bool, isMovableAcrossScreens, isMovableAcrossScreens) +WINDOW_HELPER(bool, isUserMove, isInteractiveMove) +WINDOW_HELPER(bool, isUserResize, isInteractiveResize) +WINDOW_HELPER(QRectF, iconGeometry, iconGeometry) +WINDOW_HELPER(bool, isSpecialWindow, isSpecialWindow) +WINDOW_HELPER(bool, acceptsFocus, wantsInput) +WINDOW_HELPER(QIcon, icon, icon) +WINDOW_HELPER(bool, isSkipSwitcher, skipSwitcher) +WINDOW_HELPER(bool, decorationHasAlpha, decorationHasAlpha) +WINDOW_HELPER(bool, isUnresponsive, unresponsive) +WINDOW_HELPER(QList, desktops, desktops) + +#undef WINDOW_HELPER + +qlonglong EffectWindow::windowId() const +{ + if (X11Window *x11Window = qobject_cast(d->m_window)) { + return x11Window->window(); + } + return 0; +} + +QString EffectWindow::windowClass() const +{ + return d->m_window->resourceName() + QLatin1Char(' ') + d->m_window->resourceClass(); +} + +QRectF EffectWindow::contentsRect() const +{ + return QRectF(d->m_window->clientPos(), d->m_window->clientSize()); +} + +NET::WindowType EffectWindow::windowType() const +{ + return d->m_window->windowType(); +} + +QSizeF EffectWindow::basicUnit() const +{ + if (auto window = qobject_cast(d->m_window)) { + return window->basicUnit(); + } + return QSize(1, 1); +} + +QRectF EffectWindow::decorationInnerRect() const +{ + return d->m_window->rect() - d->m_window->frameMargins(); +} + +KDecoration2::Decoration *EffectWindow::decoration() const +{ + return d->m_window->decoration(); +} + +QByteArray EffectWindow::readProperty(long atom, long type, int format) const +{ + auto x11Window = qobject_cast(d->m_window); + if (!x11Window) { + return QByteArray(); + } + if (!kwinApp()->x11Connection()) { + return QByteArray(); + } + return readWindowProperty(x11Window->window(), atom, type, format); +} + +void EffectWindow::deleteProperty(long int atom) const +{ + auto x11Window = qobject_cast(d->m_window); + if (!x11Window) { + return; + } + if (kwinApp()->x11Connection()) { + deleteWindowProperty(x11Window->window(), atom); + } +} + +EffectWindow *EffectWindow::findModal() +{ + Window *modal = d->m_window->findModal(); + if (modal) { + return modal->effectWindow(); + } + + return nullptr; +} + +EffectWindow *EffectWindow::transientFor() +{ + Window *transientFor = d->m_window->transientFor(); + if (transientFor) { + return transientFor->effectWindow(); + } + + return nullptr; +} + +QWindow *EffectWindow::internalWindow() const +{ + if (auto window = qobject_cast(d->m_window)) { + return window->handle(); + } + return nullptr; +} + +template +EffectWindowList getMainWindows(T *c) +{ + const auto mainwindows = c->mainWindows(); + EffectWindowList ret; + ret.reserve(mainwindows.size()); + std::transform(std::cbegin(mainwindows), std::cend(mainwindows), + std::back_inserter(ret), + [](auto window) { + return window->effectWindow(); + }); + return ret; +} + +EffectWindowList EffectWindow::mainWindows() const +{ + return getMainWindows(d->m_window); +} + +void EffectWindow::setData(int role, const QVariant &data) +{ + if (!data.isNull()) { + d->dataMap[role] = data; + } else { + d->dataMap.remove(role); + } + Q_EMIT effects->windowDataChanged(this, role); +} + +QVariant EffectWindow::data(int role) const +{ + return d->dataMap.value(role); +} + +void EffectWindow::elevate(bool elevate) +{ + effects->setElevatedWindow(this, elevate); +} + +void EffectWindow::minimize() +{ + if (d->m_window->isClient()) { + d->m_window->setMinimized(true); + } +} + +void EffectWindow::unminimize() +{ + if (d->m_window->isClient()) { + d->m_window->setMinimized(false); + } +} + +void EffectWindow::closeWindow() +{ + if (d->m_window->isClient()) { + d->m_window->closeWindow(); + } +} + +bool EffectWindow::isManaged() const +{ + return d->managed; +} + +bool EffectWindow::isWaylandClient() const +{ + return d->m_waylandWindow; +} + +bool EffectWindow::isX11Client() const +{ + return d->m_x11Window; +} + //**************************************** // EffectWindowGroup //**************************************** +EffectWindowGroup::EffectWindowGroup(Group *group) + : m_group(group) +{ +} + EffectWindowGroup::~EffectWindowGroup() { } +EffectWindowList EffectWindowGroup::members() const +{ + const auto memberList = m_group->members(); + EffectWindowList ret; + ret.reserve(memberList.size()); + std::transform(std::cbegin(memberList), std::cend(memberList), std::back_inserter(ret), [](auto window) { + return window->effectWindow(); + }); + return ret; +} + /*************************************************************** WindowQuad ***************************************************************/ diff --git a/src/libkwineffects/kwineffects.h b/src/libkwineffects/kwineffects.h index b429271847..fa810e3beb 100644 --- a/src/libkwineffects/kwineffects.h +++ b/src/libkwineffects/kwineffects.h @@ -73,8 +73,11 @@ class EffectWindowGroup; class EffectFrame; class EffectFramePrivate; class OffscreenQuickView; +class Group; class Output; class Effect; +class Window; +class WindowItem; class WindowQuad; class WindowQuadList; class WindowPrePaintData; @@ -1989,29 +1992,29 @@ public: PAINT_DISABLED_BY_ACTIVITY = 1 << 3, }; - explicit EffectWindow(); + explicit EffectWindow(WindowItem *windowItem); ~EffectWindow() override; - Q_SCRIPTABLE virtual void addRepaint(const QRect &r) = 0; + Q_SCRIPTABLE void addRepaint(const QRect &r); Q_SCRIPTABLE void addRepaint(int x, int y, int w, int h); - Q_SCRIPTABLE virtual void addRepaintFull() = 0; - Q_SCRIPTABLE virtual void addLayerRepaint(const QRect &r) = 0; + Q_SCRIPTABLE void addRepaintFull(); + Q_SCRIPTABLE void addLayerRepaint(const QRect &r); Q_SCRIPTABLE void addLayerRepaint(int x, int y, int w, int h); - virtual void refWindow() = 0; - virtual void unrefWindow() = 0; + void refWindow(); + void unrefWindow(); - virtual bool isDeleted() const = 0; - virtual bool isHidden() const = 0; - virtual bool isHiddenByShowDesktop() const = 0; + bool isDeleted() const; + bool isHidden() const; + bool isHiddenByShowDesktop() const; - virtual bool isMinimized() const = 0; - virtual double opacity() const = 0; + bool isMinimized() const; + double opacity() const; bool isOnCurrentActivity() const; Q_SCRIPTABLE bool isOnActivity(const QString &id) const; bool isOnAllActivities() const; - virtual QStringList activities() const = 0; + QStringList activities() const; Q_SCRIPTABLE bool isOnDesktop(KWin::VirtualDesktop *desktop) const; bool isOnCurrentDesktop() const; @@ -2021,24 +2024,24 @@ public: * a length of 1, on Wayland can be any subset. * If the list is empty it means the window is on all desktops */ - virtual QList desktops() const = 0; + QList desktops() const; - virtual qreal x() const = 0; - virtual qreal y() const = 0; - virtual qreal width() const = 0; - virtual qreal height() const = 0; + qreal x() const; + qreal y() const; + qreal width() const; + qreal height() const; /** * By how much the window wishes to grow/shrink at least. Usually QSize(1,1). * MAY BE DISOBEYED BY THE WM! It's only for information, do NOT rely on it at all. */ - virtual QSizeF basicUnit() const = 0; + QSizeF basicUnit() const; /** * Returns the geometry of the window excluding server-side and client-side * drop-shadows. * * @since 5.18 */ - virtual QRectF frameGeometry() const = 0; + QRectF frameGeometry() const; /** * Returns the geometry of the pixmap or buffer attached to this window. * @@ -2049,181 +2052,181 @@ public: * * @since 5.18 */ - virtual QRectF bufferGeometry() const = 0; - virtual QRectF clientGeometry() const = 0; + QRectF bufferGeometry() const; + QRectF clientGeometry() const; /** * Geometry of the window including decoration and potentially shadows. * May be different from geometry() if the window has a shadow. * @since 4.9 */ - virtual QRectF expandedGeometry() const = 0; - virtual Output *screen() const = 0; - virtual QPointF pos() const = 0; - virtual QSizeF size() const = 0; - virtual QRectF rect() const = 0; - virtual bool isMovable() const = 0; - virtual bool isMovableAcrossScreens() const = 0; - virtual bool isUserMove() const = 0; - virtual bool isUserResize() const = 0; - virtual QRectF iconGeometry() const = 0; + QRectF expandedGeometry() const; + Output *screen() const; + QPointF pos() const; + QSizeF size() const; + QRectF rect() const; + bool isMovable() const; + bool isMovableAcrossScreens() const; + bool isUserMove() const; + bool isUserResize() const; + QRectF iconGeometry() const; /** * Geometry of the actual window contents inside the whole (including decorations) window. */ - virtual QRectF contentsRect() const = 0; + QRectF contentsRect() const; /** * Geometry of the transparent rect in the decoration. * May be different from contentsRect() if the decoration is extended into the client area. * @since 4.5 */ - virtual QRectF decorationInnerRect() const = 0; + QRectF decorationInnerRect() const; bool hasDecoration() const; - virtual bool decorationHasAlpha() const = 0; + bool decorationHasAlpha() const; /** * Returns the decoration * @since 5.25 */ - virtual KDecoration2::Decoration *decoration() const = 0; - virtual QByteArray readProperty(long atom, long type, int format) const = 0; - virtual void deleteProperty(long atom) const = 0; + KDecoration2::Decoration *decoration() const; + QByteArray readProperty(long atom, long type, int format) const; + void deleteProperty(long atom) const; - virtual QString caption() const = 0; - virtual QIcon icon() const = 0; - virtual QString windowClass() const = 0; - virtual QString windowRole() const = 0; - virtual const EffectWindowGroup *group() const = 0; + QString caption() const; + QIcon icon() const; + QString windowClass() const; + QString windowRole() const; + const EffectWindowGroup *group() const; /** * Returns whether the window is a desktop background window (the one with wallpaper). * See _NET_WM_WINDOW_TYPE_DESKTOP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isDesktop() const = 0; + bool isDesktop() const; /** * Returns whether the window is a dock (i.e. a panel). * See _NET_WM_WINDOW_TYPE_DOCK at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isDock() const = 0; + bool isDock() const; /** * Returns whether the window is a standalone (detached) toolbar window. * See _NET_WM_WINDOW_TYPE_TOOLBAR at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isToolbar() const = 0; + bool isToolbar() const; /** * Returns whether the window is a torn-off menu. * See _NET_WM_WINDOW_TYPE_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isMenu() const = 0; + bool isMenu() const; /** * Returns whether the window is a "normal" window, i.e. an application or any other window * for which none of the specialized window types fit. * See _NET_WM_WINDOW_TYPE_NORMAL at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isNormalWindow() const = 0; // normal as in 'NET::Normal or NET::Unknown non-transient' + bool isNormalWindow() const; // normal as in 'NET::Normal or NET::Unknown non-transient' /** * Returns whether the window is any of special windows types (desktop, dock, splash, ...), * i.e. window types that usually don't have a window frame and the user does not use window * management (moving, raising,...) on them. */ - virtual bool isSpecialWindow() const = 0; + bool isSpecialWindow() const; /** * Returns whether the window is a dialog window. * See _NET_WM_WINDOW_TYPE_DIALOG at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isDialog() const = 0; + bool isDialog() const; /** * Returns whether the window is a splashscreen. Note that many (especially older) applications * do not support marking their splash windows with this type. * See _NET_WM_WINDOW_TYPE_SPLASH at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isSplash() const = 0; + bool isSplash() const; /** * Returns whether the window is a utility window, such as a tool window. * See _NET_WM_WINDOW_TYPE_UTILITY at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isUtility() const = 0; + bool isUtility() const; /** * Returns whether the window is a dropdown menu (i.e. a popup directly or indirectly open * from the applications menubar). * See _NET_WM_WINDOW_TYPE_DROPDOWN_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isDropdownMenu() const = 0; + bool isDropdownMenu() const; /** * Returns whether the window is a popup menu (that is not a torn-off or dropdown menu). * See _NET_WM_WINDOW_TYPE_POPUP_MENU at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isPopupMenu() const = 0; // a context popup, not dropdown, not torn-off + bool isPopupMenu() const; // a context popup, not dropdown, not torn-off /** * Returns whether the window is a tooltip. * See _NET_WM_WINDOW_TYPE_TOOLTIP at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isTooltip() const = 0; + bool isTooltip() const; /** * Returns whether the window is a window with a notification. * See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isNotification() const = 0; + bool isNotification() const; /** * Returns whether the window is a window with a critical notification. * using the non-standard _KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION */ - virtual bool isCriticalNotification() const = 0; + bool isCriticalNotification() const; /** * Returns whether the window is a window used for applet popups. */ - virtual bool isAppletPopup() const = 0; + bool isAppletPopup() const; /** * Returns whether the window is an on screen display window * using the non-standard _KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY */ - virtual bool isOnScreenDisplay() const = 0; + bool isOnScreenDisplay() const; /** * Returns whether the window is a combobox popup. * See _NET_WM_WINDOW_TYPE_COMBO at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isComboBox() const = 0; + bool isComboBox() const; /** * Returns whether the window is a Drag&Drop icon. * See _NET_WM_WINDOW_TYPE_DND at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual bool isDNDIcon() const = 0; + bool isDNDIcon() const; /** * Returns the NETWM window type * See https://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ - virtual NET::WindowType windowType() const = 0; + NET::WindowType windowType() const; /** * Returns whether the window is managed by KWin (it has control over its placement and other * aspects, as opposed to override-redirect windows that are entirely handled by the application). */ - virtual bool isManaged() const = 0; // whether it's managed or override-redirect + bool isManaged() const; // whether it's managed or override-redirect /** * Returns whether or not the window can accept keyboard focus. */ - virtual bool acceptsFocus() const = 0; + bool acceptsFocus() const; /** * Returns whether or not the window is kept above all other windows. */ - virtual bool keepAbove() const = 0; + bool keepAbove() const; /** * Returns whether the window is kept below all other windows. */ - virtual bool keepBelow() const = 0; + bool keepBelow() const; - virtual bool isModal() const = 0; - Q_SCRIPTABLE virtual KWin::EffectWindow *findModal() = 0; - Q_SCRIPTABLE virtual KWin::EffectWindow *transientFor() = 0; - Q_SCRIPTABLE virtual KWin::EffectWindowList mainWindows() const = 0; + bool isModal() const; + Q_SCRIPTABLE KWin::EffectWindow *findModal(); + Q_SCRIPTABLE KWin::EffectWindow *transientFor(); + Q_SCRIPTABLE KWin::EffectWindowList mainWindows() const; /** * Returns whether the window should be excluded from window switching effects. * @since 4.5 */ - virtual bool isSkipSwitcher() const = 0; + bool isSkipSwitcher() const; void setMinimized(bool minimize); - virtual void minimize() = 0; - virtual void unminimize() = 0; - Q_SCRIPTABLE virtual void closeWindow() = 0; + void minimize(); + void unminimize(); + Q_SCRIPTABLE void closeWindow(); /** * @since 4.11 @@ -2233,62 +2236,62 @@ public: /** * @since 5.0 */ - virtual bool skipsCloseAnimation() const = 0; + bool skipsCloseAnimation() const; /** * @since 5.5 */ - virtual SurfaceInterface *surface() const = 0; + SurfaceInterface *surface() const; /** * @since 5.6 */ - virtual bool isFullScreen() const = 0; + bool isFullScreen() const; /** * @since 5.10 */ - virtual bool isUnresponsive() const = 0; + bool isUnresponsive() const; /** * @since 5.15 */ - virtual bool isWaylandClient() const = 0; + bool isWaylandClient() const; /** * @since 5.15 */ - virtual bool isX11Client() const = 0; + bool isX11Client() const; /** * @since 5.15 */ - virtual bool isPopupWindow() const = 0; + bool isPopupWindow() const; /** * @since 5.16 */ - virtual QWindow *internalWindow() const = 0; + QWindow *internalWindow() const; /** * @since 5.16 */ - virtual bool isOutline() const = 0; + bool isOutline() const; /** * @since 5.22 */ - virtual bool isLockScreen() const = 0; + bool isLockScreen() const; /** * @since 5.18 */ - virtual pid_t pid() const = 0; + pid_t pid() const; /** * @since 5.21 */ - virtual qlonglong windowId() const = 0; + qlonglong windowId() const; /** * Returns the internal id of the window that uniquely identifies it. The main difference * between internalId() and windowId() is that the latter one works as expected only on X11, @@ -2297,7 +2300,7 @@ public: * Note that the internaId() has special meaning only to kwin. * @since 5.24 */ - virtual QUuid internalId() const = 0; + QUuid internalId() const; /** * Can be used to by effects to store arbitrary data in the EffectWindow. @@ -2305,8 +2308,12 @@ public: * Invoking this method will emit the signal EffectsHandler::windowDataChanged. * @see EffectsHandler::windowDataChanged */ - Q_SCRIPTABLE virtual void setData(int role, const QVariant &data) = 0; - Q_SCRIPTABLE virtual QVariant data(int role) const = 0; + Q_SCRIPTABLE void setData(int role, const QVariant &data); + Q_SCRIPTABLE QVariant data(int role) const; + + Window *window() const; + WindowItem *windowItem() const; + void elevate(bool elevate); Q_SIGNALS: /** @@ -2489,8 +2496,8 @@ Q_SIGNALS: protected: friend EffectWindowVisibleRef; - virtual void refVisible(const EffectWindowVisibleRef *holder) = 0; - virtual void unrefVisible(const EffectWindowVisibleRef *holder) = 0; + void refVisible(const EffectWindowVisibleRef *holder); + void unrefVisible(const EffectWindowVisibleRef *holder); private: class Private; @@ -2618,8 +2625,13 @@ private: class KWIN_EXPORT EffectWindowGroup { public: + explicit EffectWindowGroup(Group *group); virtual ~EffectWindowGroup(); - virtual EffectWindowList members() const = 0; + + EffectWindowList members() const; + +private: + Group *m_group; }; struct GLVertex2D diff --git a/src/scene/windowitem.cpp b/src/scene/windowitem.cpp index faf56dbe71..ba09efa1df 100644 --- a/src/scene/windowitem.cpp +++ b/src/scene/windowitem.cpp @@ -5,7 +5,6 @@ */ #include "scene/windowitem.h" -#include "effects.h" #include "internalwindow.h" #include "scene/decorationitem.h" #include "scene/shadowitem.h" @@ -55,7 +54,7 @@ WindowItem::WindowItem(Window *window, Scene *scene, Item *parent) connect(window, &Window::stackingOrderChanged, this, &WindowItem::updateStackingOrder); updateStackingOrder(); - m_effectWindow = std::make_unique(this); + m_effectWindow = std::make_unique(this); } WindowItem::~WindowItem() @@ -82,7 +81,7 @@ Window *WindowItem::window() const return m_window; } -EffectWindowImpl *WindowItem::effectWindow() const +EffectWindow *WindowItem::effectWindow() const { return m_effectWindow.get(); } diff --git a/src/scene/windowitem.h b/src/scene/windowitem.h index f3e15ec386..442ebdda7a 100644 --- a/src/scene/windowitem.h +++ b/src/scene/windowitem.h @@ -17,7 +17,7 @@ namespace KWin { class Window; class DecorationItem; -class EffectWindowImpl; +class EffectWindow; class InternalWindow; class Shadow; class ShadowItem; @@ -48,7 +48,7 @@ public: DecorationItem *decorationItem() const; ShadowItem *shadowItem() const; Window *window() const; - EffectWindowImpl *effectWindow() const; + EffectWindow *effectWindow() const; void refVisible(int reason); void unrefVisible(int reason); @@ -79,7 +79,7 @@ private: std::unique_ptr m_surfaceItem; std::unique_ptr m_decorationItem; std::unique_ptr m_shadowItem; - std::unique_ptr m_effectWindow; + std::unique_ptr m_effectWindow; std::optional m_elevation; int m_forceVisibleByHiddenCount = 0; int m_forceVisibleByDesktopCount = 0; diff --git a/src/scene/workspacescene.cpp b/src/scene/workspacescene.cpp index 8a9009c27a..0bb20d203e 100644 --- a/src/scene/workspacescene.cpp +++ b/src/scene/workspacescene.cpp @@ -460,13 +460,13 @@ void WorkspaceScene::paintWindow(const RenderTarget &renderTarget, const RenderV } // the function that'll be eventually called by paintWindow() above -void WorkspaceScene::finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindowImpl *w, int mask, const QRegion ®ion, WindowPaintData &data) +void WorkspaceScene::finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) { effects->drawWindow(renderTarget, viewport, w, mask, region, data); } // will be eventually called from drawWindow() -void WorkspaceScene::finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindowImpl *w, int mask, const QRegion ®ion, WindowPaintData &data) +void WorkspaceScene::finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) { m_renderer->renderItem(renderTarget, viewport, w->windowItem(), mask, region, data); } diff --git a/src/scene/workspacescene.h b/src/scene/workspacescene.h index 8158dbd571..c6f4821d4a 100644 --- a/src/scene/workspacescene.h +++ b/src/scene/workspacescene.h @@ -32,7 +32,7 @@ class DecoratedClientImpl; class DecorationRenderer; class Deleted; class DragAndDropIconItem; -class EffectWindowImpl; +class EffectWindow; class GLTexture; class Item; class RenderLoop; @@ -99,11 +99,11 @@ protected: void preparePaintSimpleScreen(); void paintSimpleScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion); // called after all effects had their paintWindow() called - void finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindowImpl *w, int mask, const QRegion ®ion, WindowPaintData &data); + void finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data); // shared implementation, starts painting the window void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, WindowItem *w, int mask, const QRegion ®ion); // called after all effects had their drawWindow() called - void finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindowImpl *w, int mask, const QRegion ®ion, WindowPaintData &data); + void finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data); // saved data for 2nd pass of optimized screen painting struct Phase2Data diff --git a/src/window.cpp b/src/window.cpp index ff8d6a9761..3d0c61853f 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -276,12 +276,12 @@ void Window::updateShadow() } } -EffectWindowImpl *Window::effectWindow() +EffectWindow *Window::effectWindow() { return m_windowItem ? m_windowItem->effectWindow() : nullptr; } -const EffectWindowImpl *Window::effectWindow() const +const EffectWindow *Window::effectWindow() const { return m_windowItem ? m_windowItem->effectWindow() : nullptr; } diff --git a/src/window.h b/src/window.h index aa0a35bd89..e7b59097b3 100644 --- a/src/window.h +++ b/src/window.h @@ -43,7 +43,7 @@ class SurfaceInterface; class Group; class Output; class ClientMachine; -class EffectWindowImpl; +class EffectWindow; class Tile; class Scene; class Shadow; @@ -754,8 +754,8 @@ public: qreal opacity() const; virtual bool setupCompositing(); virtual void finishCompositing(); - EffectWindowImpl *effectWindow(); - const EffectWindowImpl *effectWindow() const; + EffectWindow *effectWindow(); + const EffectWindow *effectWindow() const; SurfaceItem *surfaceItem() const; WindowItem *windowItem() const; /**