diff --git a/overlaywindow.cpp b/overlaywindow.cpp
index 91642786e2..ac697519fd 100644
--- a/overlaywindow.cpp
+++ b/overlaywindow.cpp
@@ -20,26 +20,8 @@ along with this program. If not, see .
#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)
{
}
@@ -47,137 +29,4 @@ 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/overlaywindow.h b/overlaywindow.h
index e1ec3ec2f5..0afff215d1 100644
--- a/overlaywindow.h
+++ b/overlaywindow.h
@@ -30,28 +30,22 @@ along with this program. If not, see .
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/platform.cpp b/platform.cpp
index afd3e65532..91ac210c55 100644
--- a/platform.cpp
+++ b/platform.cpp
@@ -23,6 +23,7 @@ along with this program. If not, see .
#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 @@ void Platform::setupActionForGlobalAccel(QAction *action)
Q_UNUSED(action)
}
+OverlayWindow *Platform::createOverlayWindow()
+{
+ return nullptr;
+}
+
}
diff --git a/platform.h b/platform.h
index f27feda837..35392bf5d5 100644
--- a/platform.h
+++ b/platform.h
@@ -40,6 +40,7 @@ namespace KWin
{
class Edge;
+class OverlayWindow;
class OpenGLBackend;
class QPainterBackend;
class Screens;
@@ -301,6 +302,12 @@ public:
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/plugins/platforms/x11/common/eglonxbackend.cpp b/plugins/platforms/x11/common/eglonxbackend.cpp
index 49e23578d0..6eaf518a37 100644
--- a/plugins/platforms/x11/common/eglonxbackend.cpp
+++ b/plugins/platforms/x11/common/eglonxbackend.cpp
@@ -40,7 +40,7 @@ namespace KWin
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
index 98daa12208..c2cc0191a1 100644
--- a/plugins/platforms/x11/standalone/CMakeLists.txt
+++ b/plugins/platforms/x11/standalone/CMakeLists.txt
@@ -5,6 +5,7 @@ set(X11PLATFORM_SOURCES
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
index 438052fb40..ee86434c50 100644
--- a/plugins/platforms/x11/standalone/glxbackend.cpp
+++ b/plugins/platforms/x11/standalone/glxbackend.cpp
@@ -29,6 +29,7 @@ along with this program. If not, see .
#include "options.h"
#include "overlaywindow.h"
#include "composite.h"
+#include "platform.h"
#include "screens.h"
#include "xcbutils.h"
// kwin libs
@@ -104,7 +105,7 @@ bool SwapEventFilter::event(xcb_generic_event_t *event)
GlxBackend::GlxBackend(Display *display)
: OpenGLBackend()
- , m_overlayWindow(new OverlayWindow())
+ , m_overlayWindow(kwinApp()->platform()->createOverlayWindow())
, window(None)
, fbconfig(NULL)
, glxWindow(None)
diff --git a/plugins/platforms/x11/standalone/overlaywindow_x11.cpp b/plugins/platforms/x11/standalone/overlaywindow_x11.cpp
new file mode 100644
index 0000000000..c1e4fe9dae
--- /dev/null
+++ b/plugins/platforms/x11/standalone/overlaywindow_x11.cpp
@@ -0,0 +1,185 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2011 Arthur Arlt
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#include "overlaywindow_x11.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 {
+OverlayWindowX11::OverlayWindowX11()
+ : OverlayWindow()
+ , m_visible(true)
+ , m_shown(false)
+ , m_window(XCB_WINDOW_NONE)
+{
+}
+
+OverlayWindowX11::~OverlayWindowX11()
+{
+}
+
+bool OverlayWindowX11::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 OverlayWindowX11::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 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 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 OverlayWindowX11::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 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 OverlayWindowX11::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 OverlayWindowX11::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 OverlayWindowX11::isVisible() const
+{
+ return m_visible;
+}
+
+void OverlayWindowX11::setVisibility(bool visible)
+{
+ m_visible = visible;
+}
+
+void OverlayWindowX11::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 OverlayWindowX11::window() const
+{
+ return m_window;
+}
+
+} // namespace KWin
+
diff --git a/plugins/platforms/x11/standalone/overlaywindow_x11.h b/plugins/platforms/x11/standalone/overlaywindow_x11.h
new file mode 100644
index 0000000000..2cb562ae55
--- /dev/null
+++ b/plugins/platforms/x11/standalone/overlaywindow_x11.h
@@ -0,0 +1,54 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2011 Arthur Arlt
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*********************************************************************/
+
+#ifndef KWIN_OVERLAYWINDOW_X11_H
+#define KWIN_OVERLAYWINDOW_X11_H
+
+#include "../../../../overlaywindow.h"
+
+namespace KWin {
+class KWIN_EXPORT OverlayWindowX11 : public OverlayWindow {
+public:
+ OverlayWindowX11();
+ ~OverlayWindowX11();
+ /// Creates XComposite overlay window, call initOverlay() afterwards
+ bool create() override;
+ /// Init overlay and the destination window in it
+ 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() 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);
+ bool m_visible;
+ bool m_shown; // For showOverlay()
+ QRegion m_shape;
+ xcb_window_t m_window;
+};
+} // namespace
+
+#endif //KWIN_OVERLAYWINDOW_H
diff --git a/plugins/platforms/x11/standalone/x11_platform.cpp b/plugins/platforms/x11/standalone/x11_platform.cpp
index b6a9150c1e..0a938b20e7 100644
--- a/plugins/platforms/x11/standalone/x11_platform.cpp
+++ b/plugins/platforms/x11/standalone/x11_platform.cpp
@@ -34,6 +34,7 @@ along with this program. If not, see .
#include "logging.h"
#include "screens_xrandr.h"
#include "options.h"
+#include "overlaywindow_x11.h"
#include
#include
@@ -309,4 +310,9 @@ void X11StandalonePlatform::setupActionForGlobalAccel(QAction *action)
});
}
+OverlayWindow *X11StandalonePlatform::createOverlayWindow()
+{
+ return new OverlayWindowX11();
+}
+
}
diff --git a/plugins/platforms/x11/standalone/x11_platform.h b/plugins/platforms/x11/standalone/x11_platform.h
index 7fa55261d8..861b2bf10a 100644
--- a/plugins/platforms/x11/standalone/x11_platform.h
+++ b/plugins/platforms/x11/standalone/x11_platform.h
@@ -55,6 +55,8 @@ public:
void setupActionForGlobalAccel(QAction *action) override;
+ OverlayWindow *createOverlayWindow() override;
+
protected:
void doHideCursor() override;
void doShowCursor() override;
diff --git a/scene_xrender.cpp b/scene_xrender.cpp
index 263c75f14f..ead00b8c5b 100644
--- a/scene_xrender.cpp
+++ b/scene_xrender.cpp
@@ -32,6 +32,7 @@ along with this program. If not, see .
#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 @@ void XRenderBackend::screenGeometryChanged(const QSize &size)
//****************************************
X11XRenderBackend::X11XRenderBackend()
: XRenderBackend()
- , m_overlayWindow(new OverlayWindow())
+ , m_overlayWindow(kwinApp()->platform()->createOverlayWindow())
, m_front(XCB_RENDER_PICTURE_NONE)
, m_format(0)
{