diff --git a/overlaywindow.h b/overlaywindow.h --- a/overlaywindow.h +++ b/overlaywindow.h @@ -30,28 +30,22 @@ namespace KWin { class KWIN_EXPORT OverlayWindow { public: - OverlayWindow(); - ~OverlayWindow(); + virtual ~OverlayWindow(); /// Creates XComposite overlay window, call initOverlay() afterwards - bool create(); + virtual bool create() = 0; /// Init overlay and the destination window in it - void setup(xcb_window_t window); - void show(); - void hide(); // hides and resets overlay window - void setShape(const QRegion& reg); - void resize(const QSize &size); + virtual void setup(xcb_window_t window) = 0; + virtual void show() = 0; + virtual void hide() = 0; // hides and resets overlay window + virtual void setShape(const QRegion& reg) = 0; + virtual void resize(const QSize &size) = 0; /// Destroys XComposite overlay window - void destroy(); - xcb_window_t window() const; - bool isVisible() const; - void setVisibility(bool visible); -private: - void setNoneBackgroundPixmap(xcb_window_t window); - void setupInputShape(xcb_window_t window); - bool m_visible; - bool m_shown; // For showOverlay() - QRegion m_shape; - xcb_window_t m_window; + virtual void destroy() = 0; + virtual xcb_window_t window() const = 0; + virtual bool isVisible() const = 0; + virtual void setVisibility(bool visible) = 0; +protected: + OverlayWindow(); }; } // namespace diff --git a/overlaywindow.cpp b/overlaywindow.cpp --- a/overlaywindow.cpp +++ b/overlaywindow.cpp @@ -20,164 +20,13 @@ #include "overlaywindow.h" -#include "kwinglobals.h" -#include "screens.h" -#include "utils.h" -#include "xcbutils.h" - -#include "assert.h" - -#include - -#include -#include -#if XCB_COMPOSITE_MAJOR_VERSION > 0 || XCB_COMPOSITE_MINOR_VERSION >= 3 -#define KWIN_HAVE_XCOMPOSITE_OVERLAY -#endif - namespace KWin { OverlayWindow::OverlayWindow() - : m_visible(true) - , m_shown(false) - , m_window(XCB_WINDOW_NONE) { } OverlayWindow::~OverlayWindow() { } -bool OverlayWindow::create() -{ - assert(m_window == XCB_WINDOW_NONE); - if (!Xcb::Extensions::self()->isCompositeOverlayAvailable()) - return false; - if (!Xcb::Extensions::self()->isShapeInputAvailable()) // needed in setupOverlay() - return false; -#ifdef KWIN_HAVE_XCOMPOSITE_OVERLAY - Xcb::OverlayWindow overlay(rootWindow()); - if (overlay.isNull()) { - return false; - } - m_window = overlay->overlay_win; - if (m_window == XCB_WINDOW_NONE) - return false; - resize(screens()->size()); - return true; -#else - return false; -#endif -} - -void OverlayWindow::setup(xcb_window_t window) -{ - assert(m_window != XCB_WINDOW_NONE); - assert(Xcb::Extensions::self()->isShapeInputAvailable()); - setNoneBackgroundPixmap(m_window); - m_shape = QRegion(); - const QSize &s = screens()->size(); - setShape(QRect(0, 0, s.width(), s.height())); - if (window != XCB_WINDOW_NONE) { - setNoneBackgroundPixmap(window); - setupInputShape(window); - } - const uint32_t eventMask = XCB_EVENT_MASK_VISIBILITY_CHANGE; - xcb_change_window_attributes(connection(), m_window, XCB_CW_EVENT_MASK, &eventMask); -} - -void OverlayWindow::setupInputShape(xcb_window_t window) -{ - xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, window, 0, 0, 0, NULL); -} - -void OverlayWindow::setNoneBackgroundPixmap(xcb_window_t window) -{ - const uint32_t mask = XCB_BACK_PIXMAP_NONE; - xcb_change_window_attributes(connection(), window, XCB_CW_BACK_PIXMAP, &mask); -} - -void OverlayWindow::show() -{ - assert(m_window != XCB_WINDOW_NONE); - if (m_shown) - return; - xcb_map_subwindows(connection(), m_window); - xcb_map_window(connection(), m_window); - m_shown = true; -} - -void OverlayWindow::hide() -{ - assert(m_window != XCB_WINDOW_NONE); - xcb_unmap_window(connection(), m_window); - m_shown = false; - const QSize &s = screens()->size(); - setShape(QRect(0, 0, s.width(), s.height())); -} - -void OverlayWindow::setShape(const QRegion& reg) -{ - // Avoid setting the same shape again, it causes flicker (apparently it is not a no-op - // and triggers something). - if (reg == m_shape) - return; - QVector< QRect > rects = reg.rects(); - xcb_rectangle_t *xrects = new xcb_rectangle_t[rects.count()]; - for (int i = 0; - i < rects.count(); - ++i) { - xrects[ i ].x = rects[ i ].x(); - xrects[ i ].y = rects[ i ].y(); - xrects[ i ].width = rects[ i ].width(); - xrects[ i ].height = rects[ i ].height(); - } - xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, - m_window, 0, 0, rects.count(), xrects); - delete[] xrects; - setupInputShape(m_window); - m_shape = reg; -} - -void OverlayWindow::resize(const QSize &size) -{ - assert(m_window != XCB_WINDOW_NONE); - const uint32_t geometry[2] = { - static_cast(size.width()), - static_cast(size.height()) - }; - xcb_configure_window(connection(), m_window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, geometry); - setShape(QRegion(0, 0, size.width(), size.height())); -} - -bool OverlayWindow::isVisible() const -{ - return m_visible; -} - -void OverlayWindow::setVisibility(bool visible) -{ - m_visible = visible; -} - -void OverlayWindow::destroy() -{ - if (m_window == XCB_WINDOW_NONE) - return; - // reset the overlay shape - const QSize &s = screens()->size(); - xcb_rectangle_t rec = { 0, 0, static_cast(s.width()), static_cast(s.height()) }; - xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, m_window, 0, 0, 1, &rec); - xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, m_window, 0, 0, 1, &rec); -#ifdef KWIN_HAVE_XCOMPOSITE_OVERLAY - xcb_composite_release_overlay_window(connection(), m_window); -#endif - m_window = XCB_WINDOW_NONE; - m_shown = false; -} - -xcb_window_t OverlayWindow::window() const -{ - return m_window; -} - } // namespace KWin diff --git a/platform.h b/platform.h --- a/platform.h +++ b/platform.h @@ -40,6 +40,7 @@ { class Edge; +class OverlayWindow; class OpenGLBackend; class QPainterBackend; class Screens; @@ -301,6 +302,12 @@ m_initialOutputScale = scale; } + /** + * Creates the OverlayWindow required for X11 based compositors. + * Default implementation returns @c nullptr. + **/ + virtual OverlayWindow *createOverlayWindow(); + public Q_SLOTS: void pointerMotion(const QPointF &position, quint32 time); void pointerButtonPressed(quint32 button, quint32 time); diff --git a/platform.cpp b/platform.cpp --- a/platform.cpp +++ b/platform.cpp @@ -23,6 +23,7 @@ #include "composite.h" #include "cursor.h" #include "input.h" +#include "overlaywindow.h" #include "pointer_input.h" #include "scene_opengl.h" #include "screenedge.h" @@ -460,4 +461,9 @@ Q_UNUSED(action) } +OverlayWindow *Platform::createOverlayWindow() +{ + return nullptr; +} + } diff --git a/plugins/platforms/x11/common/eglonxbackend.cpp b/plugins/platforms/x11/common/eglonxbackend.cpp --- a/plugins/platforms/x11/common/eglonxbackend.cpp +++ b/plugins/platforms/x11/common/eglonxbackend.cpp @@ -40,7 +40,7 @@ EglOnXBackend::EglOnXBackend(Display *display) : AbstractEglBackend() - , m_overlayWindow(new OverlayWindow()) + , m_overlayWindow(kwinApp()->platform()->createOverlayWindow()) , surfaceHasSubPost(0) , m_bufferAge(0) , m_usesOverlayWindow(true) diff --git a/plugins/platforms/x11/standalone/CMakeLists.txt b/plugins/platforms/x11/standalone/CMakeLists.txt --- a/plugins/platforms/x11/standalone/CMakeLists.txt +++ b/plugins/platforms/x11/standalone/CMakeLists.txt @@ -5,6 +5,7 @@ x11_platform.cpp screens_xrandr.cpp windowselector.cpp + overlaywindow_x11.cpp ) if(X11_Xinput_FOUND) diff --git a/plugins/platforms/x11/standalone/glxbackend.cpp b/plugins/platforms/x11/standalone/glxbackend.cpp --- a/plugins/platforms/x11/standalone/glxbackend.cpp +++ b/plugins/platforms/x11/standalone/glxbackend.cpp @@ -29,6 +29,7 @@ #include "options.h" #include "overlaywindow.h" #include "composite.h" +#include "platform.h" #include "screens.h" #include "xcbutils.h" // kwin libs @@ -104,7 +105,7 @@ GlxBackend::GlxBackend(Display *display) : OpenGLBackend() - , m_overlayWindow(new OverlayWindow()) + , m_overlayWindow(kwinApp()->platform()->createOverlayWindow()) , window(None) , fbconfig(NULL) , glxWindow(None) diff --git a/overlaywindow.h b/plugins/platforms/x11/standalone/overlaywindow_x11.h copy from overlaywindow.h copy to plugins/platforms/x11/standalone/overlaywindow_x11.h --- a/overlaywindow.h +++ b/plugins/platforms/x11/standalone/overlaywindow_x11.h @@ -18,33 +18,29 @@ along with this program. If not, see . *********************************************************************/ -#ifndef KWIN_OVERLAYWINDOW_H -#define KWIN_OVERLAYWINDOW_H +#ifndef KWIN_OVERLAYWINDOW_X11_H +#define KWIN_OVERLAYWINDOW_X11_H -#include -// xcb -#include - -#include +#include "../../../../overlaywindow.h" namespace KWin { -class KWIN_EXPORT OverlayWindow { +class KWIN_EXPORT OverlayWindowX11 : public OverlayWindow { public: - OverlayWindow(); - ~OverlayWindow(); + OverlayWindowX11(); + ~OverlayWindowX11(); /// Creates XComposite overlay window, call initOverlay() afterwards - bool create(); + bool create() override; /// Init overlay and the destination window in it - void setup(xcb_window_t window); - void show(); - void hide(); // hides and resets overlay window - void setShape(const QRegion& reg); - void resize(const QSize &size); + void setup(xcb_window_t window) override; + void show() override; + void hide() override; // hides and resets overlay window + void setShape(const QRegion& reg) override; + void resize(const QSize &size) override; /// Destroys XComposite overlay window - void destroy(); - xcb_window_t window() const; - bool isVisible() const; - void setVisibility(bool visible); + void destroy() override; + xcb_window_t window() const override; + bool isVisible() const override; + void setVisibility(bool visible) override; private: void setNoneBackgroundPixmap(xcb_window_t window); void setupInputShape(xcb_window_t window); diff --git a/overlaywindow.cpp b/plugins/platforms/x11/standalone/overlaywindow_x11.cpp copy from overlaywindow.cpp copy to plugins/platforms/x11/standalone/overlaywindow_x11.cpp --- a/overlaywindow.cpp +++ b/plugins/platforms/x11/standalone/overlaywindow_x11.cpp @@ -18,7 +18,7 @@ along with this program. If not, see . *********************************************************************/ -#include "overlaywindow.h" +#include "overlaywindow_x11.h" #include "kwinglobals.h" #include "screens.h" @@ -36,18 +36,19 @@ #endif namespace KWin { -OverlayWindow::OverlayWindow() - : m_visible(true) +OverlayWindowX11::OverlayWindowX11() + : OverlayWindow() + , m_visible(true) , m_shown(false) , m_window(XCB_WINDOW_NONE) { } -OverlayWindow::~OverlayWindow() +OverlayWindowX11::~OverlayWindowX11() { } -bool OverlayWindow::create() +bool OverlayWindowX11::create() { assert(m_window == XCB_WINDOW_NONE); if (!Xcb::Extensions::self()->isCompositeOverlayAvailable()) @@ -69,7 +70,7 @@ #endif } -void OverlayWindow::setup(xcb_window_t window) +void OverlayWindowX11::setup(xcb_window_t window) { assert(m_window != XCB_WINDOW_NONE); assert(Xcb::Extensions::self()->isShapeInputAvailable()); @@ -85,18 +86,18 @@ xcb_change_window_attributes(connection(), m_window, XCB_CW_EVENT_MASK, &eventMask); } -void OverlayWindow::setupInputShape(xcb_window_t window) +void OverlayWindowX11::setupInputShape(xcb_window_t window) { xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, window, 0, 0, 0, NULL); } -void OverlayWindow::setNoneBackgroundPixmap(xcb_window_t window) +void OverlayWindowX11::setNoneBackgroundPixmap(xcb_window_t window) { const uint32_t mask = XCB_BACK_PIXMAP_NONE; xcb_change_window_attributes(connection(), window, XCB_CW_BACK_PIXMAP, &mask); } -void OverlayWindow::show() +void OverlayWindowX11::show() { assert(m_window != XCB_WINDOW_NONE); if (m_shown) @@ -106,16 +107,16 @@ m_shown = true; } -void OverlayWindow::hide() +void OverlayWindowX11::hide() { assert(m_window != XCB_WINDOW_NONE); xcb_unmap_window(connection(), m_window); m_shown = false; const QSize &s = screens()->size(); setShape(QRect(0, 0, s.width(), s.height())); } -void OverlayWindow::setShape(const QRegion& reg) +void OverlayWindowX11::setShape(const QRegion& reg) { // Avoid setting the same shape again, it causes flicker (apparently it is not a no-op // and triggers something). @@ -138,7 +139,7 @@ m_shape = reg; } -void OverlayWindow::resize(const QSize &size) +void OverlayWindowX11::resize(const QSize &size) { assert(m_window != XCB_WINDOW_NONE); const uint32_t geometry[2] = { @@ -149,17 +150,17 @@ setShape(QRegion(0, 0, size.width(), size.height())); } -bool OverlayWindow::isVisible() const +bool OverlayWindowX11::isVisible() const { return m_visible; } -void OverlayWindow::setVisibility(bool visible) +void OverlayWindowX11::setVisibility(bool visible) { m_visible = visible; } -void OverlayWindow::destroy() +void OverlayWindowX11::destroy() { if (m_window == XCB_WINDOW_NONE) return; @@ -175,9 +176,10 @@ m_shown = false; } -xcb_window_t OverlayWindow::window() const +xcb_window_t OverlayWindowX11::window() const { return m_window; } } // namespace KWin + diff --git a/plugins/platforms/x11/standalone/x11_platform.h b/plugins/platforms/x11/standalone/x11_platform.h --- a/plugins/platforms/x11/standalone/x11_platform.h +++ b/plugins/platforms/x11/standalone/x11_platform.h @@ -55,6 +55,8 @@ void setupActionForGlobalAccel(QAction *action) override; + OverlayWindow *createOverlayWindow() override; + protected: void doHideCursor() override; void doShowCursor() override; diff --git a/plugins/platforms/x11/standalone/x11_platform.cpp b/plugins/platforms/x11/standalone/x11_platform.cpp --- a/plugins/platforms/x11/standalone/x11_platform.cpp +++ b/plugins/platforms/x11/standalone/x11_platform.cpp @@ -34,6 +34,7 @@ #include "logging.h" #include "screens_xrandr.h" #include "options.h" +#include "overlaywindow_x11.h" #include #include @@ -309,4 +310,9 @@ }); } +OverlayWindow *X11StandalonePlatform::createOverlayWindow() +{ + return new OverlayWindowX11(); +} + } diff --git a/scene_xrender.cpp b/scene_xrender.cpp --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -32,6 +32,7 @@ #include "effects.h" #include "main.h" #include "overlaywindow.h" +#include "platform.h" #include "xcbutils.h" #include "kwinxrenderutils.h" #include "decorations/decoratedclient.h" @@ -109,7 +110,7 @@ //**************************************** X11XRenderBackend::X11XRenderBackend() : XRenderBackend() - , m_overlayWindow(new OverlayWindow()) + , m_overlayWindow(kwinApp()->platform()->createOverlayWindow()) , m_front(XCB_RENDER_PICTURE_NONE) , m_format(0) {