12#include "compositor.h"
20#include <xcb/composite.h>
22#if XCB_COMPOSITE_MAJOR_VERSION > 0 || XCB_COMPOSITE_MINOR_VERSION >= 3
23#define KWIN_HAVE_XCOMPOSITE_OVERLAY
34 , m_window(XCB_WINDOW_NONE)
44 Q_ASSERT(m_window == XCB_WINDOW_NONE);
51#ifdef KWIN_HAVE_XCOMPOSITE_OVERLAY
53 if (overlay.isNull()) {
56 m_window = overlay->overlay_win;
57 if (m_window == XCB_WINDOW_NONE) {
68 Q_ASSERT(m_window != XCB_WINDOW_NONE);
70 setNoneBackgroundPixmap(m_window);
71 if (m_size.isValid()) {
72 setShape(QRect(0, 0, m_size.width(), m_size.height()));
74 if (
window != XCB_WINDOW_NONE) {
75 setNoneBackgroundPixmap(
window);
78 const uint32_t eventMask = XCB_EVENT_MASK_VISIBILITY_CHANGE;
79 xcb_change_window_attributes(
connection(), m_window, XCB_CW_EVENT_MASK, &eventMask);
82void OverlayWindowX11::setupInputShape(xcb_window_t window)
84 xcb_shape_rectangles(
connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED,
window, 0, 0, 0,
nullptr);
87void OverlayWindowX11::setNoneBackgroundPixmap(xcb_window_t window)
89 const uint32_t mask = XCB_BACK_PIXMAP_NONE;
90 xcb_change_window_attributes(
connection(),
window, XCB_CW_BACK_PIXMAP, &mask);
95 Q_ASSERT(m_window != XCB_WINDOW_NONE);
106 Q_ASSERT(m_window != XCB_WINDOW_NONE);
109 const QSize &s = m_size;
110 setShape(QRect(0, 0, s.width(), s.height()));
117 if (reg == m_shape) {
120 const QList<xcb_rectangle_t> xrects = Xcb::regionToRects(reg);
121 xcb_shape_rectangles(
connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
122 m_window, 0, 0, xrects.count(), xrects.data());
123 setupInputShape(m_window);
130 if (m_window == XCB_WINDOW_NONE) {
133 const uint32_t geometry[2] = {
134 static_cast<uint32_t
>(size.width()),
135 static_cast<uint32_t
>(size.height())};
136 xcb_configure_window(
connection(), m_window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, geometry);
137 setShape(QRegion(0, 0, size.width(), size.height()));
152 if (m_window == XCB_WINDOW_NONE) {
156 xcb_rectangle_t rec = {0, 0,
static_cast<uint16_t
>(m_size.width()),
static_cast<uint16_t
>(m_size.height())};
157 xcb_shape_rectangles(
connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, m_window, 0, 0, 1, &rec);
158 xcb_shape_rectangles(
connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, m_window, 0, 0, 1, &rec);
159#ifdef KWIN_HAVE_XCOMPOSITE_OVERLAY
160 xcb_composite_release_overlay_window(
connection(), m_window);
162 m_window = XCB_WINDOW_NONE;
173 const uint8_t eventType =
event->response_type & ~0x80;
174 if (eventType == XCB_EXPOSE) {
175 const auto *expose =
reinterpret_cast<xcb_expose_event_t *
>(
event);
177 || (m_window != XCB_WINDOW_NONE && expose->window == m_window)) {
180 }
else if (eventType == XCB_VISIBILITY_NOTIFY) {
181 const auto *visibility =
reinterpret_cast<xcb_visibility_notify_event_t *
>(
event);
182 if (m_window != XCB_WINDOW_NONE && visibility->window == m_window) {
184 setVisibility((visibility->state != XCB_VISIBILITY_FULLY_OBSCURED));
186 if (!was_visible && m_visible) {
188 compositor->scene()->addRepaintFull();
189 QTimer::singleShot(2000, compositor, [compositor]() {
190 if (compositor->compositing()) {
191 compositor->scene()->addRepaintFull();
WorkspaceScene * scene() const
static Compositor * self()
bool event(xcb_generic_event_t *event) override
void destroy() override
Destroys XComposite overlay window.
xcb_window_t window() const override
void resize(const QSize &size) override
~OverlayWindowX11() override
void setShape(const QRegion ®)
bool create() override
Creates XComposite overlay window, call initOverlay() and resize afterwards.
void setup(xcb_window_t window) override
Init overlay and the destination window in it.
OverlayWindowX11(X11StandaloneBackend *backend)
void setVisibility(bool visible) override
bool isVisible() const override
void scheduleRepaint(Item *item=nullptr)
void addRepaint(const QRegion ®ion)
RenderLoop * renderLoop() const
static Extensions * self()
KWIN_EXPORT xcb_window_t rootWindow()
KWIN_EXPORT xcb_connection_t * connection()