1- // SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
1+ // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
22//
33// SPDX-License-Identifier: GPL-3.0-or-later
44
1717#include < xcb/xcb.h>
1818#include < xcb/xcb_ewmh.h>
1919#include < xcb/xcb_icccm.h>
20- #include < xcb/shape.h>
2120
2221DS_BEGIN_NAMESPACE
2322
@@ -30,11 +29,16 @@ LayerShellEmulation::LayerShellEmulation(QWindow* window, QObject *parent)
3029{
3130 onLayerChanged ();
3231 connect (m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this , &LayerShellEmulation::onLayerChanged);
32+ connect (m_window, &QWindow::visibleChanged, this , [this ](bool ) {
33+ onLayerChanged ();
34+ });
35+ connect (m_window, &QWindow::visibilityChanged, this , [this ](QWindow::Visibility) {
36+ onLayerChanged ();
37+ });
3338
3439 onPositionChanged ();
3540 connect (m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this , &LayerShellEmulation::onPositionChanged);
3641 connect (m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this , &LayerShellEmulation::onPositionChanged);
37- connect (m_dlayerShellWindow, &DLayerShellWindow::geometryHintsChanged, this , &LayerShellEmulation::onPositionChanged);
3842
3943 onExclusionZoneChanged ();
4044 m_exclusionZoneChangedTimer.setSingleShot (true );
@@ -72,9 +76,6 @@ LayerShellEmulation::LayerShellEmulation(QWindow* window, QObject *parent)
7276 onScopeChanged ();
7377 connect (m_dlayerShellWindow, &DLayerShellWindow::scopeChanged, this , &LayerShellEmulation::onScopeChanged);
7478
75- onInputRegionChanged ();
76- connect (m_dlayerShellWindow, &DLayerShellWindow::inputRegionChanged, this , &LayerShellEmulation::onInputRegionChanged);
77-
7879 // connect(m_dlayerShellWindow, &DS_NAMESPACE::DLayerShellWindow::keyboardInteractivityChanged, this, &LayerShellEmulation::onKeyboardInteractivityChanged);
7980}
8081
@@ -90,6 +91,10 @@ LayerShellEmulation::LayerShellEmulation(QWindow* window, QObject *parent)
9091void LayerShellEmulation::onLayerChanged ()
9192{
9293 auto xcbWindow = dynamic_cast <QNativeInterface::Private::QXcbWindow*>(m_window->handle ());
94+ if (!xcbWindow) {
95+ return ;
96+ }
97+
9398 switch (m_dlayerShellWindow->layer ()) {
9499 case DLayerShellWindow::LayerBackground: {
95100 m_window->setFlags (m_window->flags () & ~Qt::WindowStaysOnBottomHint);
@@ -122,30 +127,17 @@ void LayerShellEmulation::onPositionChanged()
122127{
123128 auto anchors = m_dlayerShellWindow->anchors ();
124129 auto screen = m_window->screen ();
125- if (!screen) {
126- return ;
127- }
128-
129- int targetWidth = m_window->width ();
130- int targetHeight = m_window->height ();
131- if (m_dlayerShellWindow->preferredWidth () > 0 ) {
132- targetWidth = m_dlayerShellWindow->preferredWidth ();
133- }
134- if (m_dlayerShellWindow->preferredHeight () > 0 ) {
135- targetHeight = m_dlayerShellWindow->preferredHeight ();
136- }
137-
138130 auto screenRect = screen->geometry ();
139- auto x = screenRect.left () + (screenRect.width () - targetWidth ) / 2 ;
140- auto y = screenRect.top () + (screenRect.height () - targetHeight ) / 2 ;
131+ auto x = screenRect.left () + (screenRect.width () - m_window-> width () ) / 2 ;
132+ auto y = screenRect.top () + (screenRect.height () - m_window-> height () ) / 2 ;
141133 if (anchors & DLayerShellWindow::AnchorRight) {
142134 // https://doc.qt.io/qt-6/qrect.html#right
143- x = (screen->geometry ().right () + 1 - targetWidth - m_dlayerShellWindow->rightMargin ());
135+ x = (screen->geometry ().right () + 1 - m_window-> width () - m_dlayerShellWindow->rightMargin ());
144136 }
145137
146138 if (anchors & DLayerShellWindow::AnchorBottom) {
147139 // https://doc.qt.io/qt-6/qrect.html#bottom
148- y = (screen->geometry ().bottom () + 1 - targetHeight - m_dlayerShellWindow->bottomMargin ());
140+ y = (screen->geometry ().bottom () + 1 - m_window-> height () - m_dlayerShellWindow->bottomMargin ());
149141 }
150142 if (anchors & DLayerShellWindow::AnchorLeft) {
151143 x = (screen->geometry ().left () + m_dlayerShellWindow->leftMargin ());
@@ -154,7 +146,7 @@ void LayerShellEmulation::onPositionChanged()
154146 y = (screen->geometry ().top () + m_dlayerShellWindow->topMargin ());
155147 }
156148
157- QRect rect (x, y, targetWidth, targetHeight );
149+ QRect rect (x, y, m_window-> width (), m_window-> height () );
158150
159151 const bool horizontallyConstrained = anchors.testFlags ({DLayerShellWindow::AnchorLeft, DLayerShellWindow::AnchorRight});
160152 const bool verticallyConstrained = anchors.testFlags ({DLayerShellWindow::AnchorTop, DLayerShellWindow::AnchorBottom});
@@ -168,9 +160,8 @@ void LayerShellEmulation::onPositionChanged()
168160 rect.setHeight (screen->geometry ().height () - m_dlayerShellWindow->topMargin () - m_dlayerShellWindow->bottomMargin ());
169161 }
170162
171- if (m_window->geometry () != rect) {
172- m_window->setGeometry (rect);
173- }
163+ m_window->setGeometry (rect);
164+ onLayerChanged ();
174165}
175166
176167/* *
@@ -325,41 +316,6 @@ void LayerShellEmulation::onScopeChanged()
325316 qCDebug (layershell) << " Set WM_CLASS for window" << m_window->winId () << " wm_class:" << wmClassData;
326317}
327318
328- void LayerShellEmulation::onInputRegionChanged ()
329- {
330- auto *x11Application = qGuiApp->nativeInterface <QNativeInterface::QX11Application>();
331- if (!x11Application || !m_window->winId () || !m_dlayerShellWindow) {
332- return ;
333- }
334-
335- if (m_dlayerShellWindow->inputRegion ().isNull ()) {
336- // Reset input region (no shape constraint)
337- xcb_shape_mask (x11Application->connection (), XCB_SHAPE_SO_SET , XCB_SHAPE_SK_INPUT , m_window->winId (), 0 , 0 , XCB_NONE );
338- xcb_flush (x11Application->connection ());
339- return ;
340- }
341-
342- QRegion region = m_dlayerShellWindow->inputRegion ();
343- qreal scaleFactor = qGuiApp->devicePixelRatio ();
344-
345- QVector<xcb_rectangle_t > rects;
346- for (const QRect &r : region) {
347- xcb_rectangle_t rect;
348- rect.x = r.x () * scaleFactor;
349- rect.y = r.y () * scaleFactor;
350- rect.width = r.width () * scaleFactor;
351- rect.height = r.height () * scaleFactor;
352- rects.append (rect);
353- }
354-
355- // Set the input shape via XCB
356- // If rects vector is empty, the window will become completely transparent to input clicks (unclickable)
357- xcb_shape_rectangles (x11Application->connection (), XCB_SHAPE_SO_SET , XCB_SHAPE_SK_INPUT ,
358- XCB_CLIP_ORDERING_UNSORTED , m_window->winId (), 0 , 0 ,
359- rects.size (), rects.data ());
360- xcb_flush (x11Application->connection ());
361- }
362-
363319// void X11Emulation::onKeyboardInteractivityChanged()
364320// {
365321// // kwin no implentation on wayland
0 commit comments