@@ -24,63 +24,35 @@ QWaylandLayerShellSurface::QWaylandLayerShellSurface(QtWayland::zwlr_layer_shell
2424 , QtWayland::zwlr_layer_surface_v1()
2525 , m_dlayerShellWindow(DLayerShellWindow::get(window->window ()))
2626{
27-
2827 wl_output *output = nullptr ;
2928 if (m_dlayerShellWindow->screenConfiguration () == DLayerShellWindow::ScreenFromQWindow) {
30- auto waylandScreen = dynamic_cast <QtWaylandClient::QWaylandScreen*>(window->window ()->screen ()->handle ());
31- connect (window->window (), &QWindow::screenChanged, this , [window](){
32- window->reset ();
33- // make sure window has been cleaned completed
34- QMetaObject::invokeMethod (
35- window,
36- [window]() {
37- window->reinit ();
38- },
39- Qt::QueuedConnection);
40- });
41- if (!waylandScreen) {
29+ output = currentOutput ();
30+ connect (window->window (), &QWindow::screenChanged, this , &QWaylandLayerShellSurface::scheduleRecreate);
31+ if (!output) {
4232 qCWarning (layershellsurface) << " failed to get screen for wayland" ;
43- } else {
44- output = waylandScreen->output ();
4533 }
4634 }
4735
4836 init (shell->get_layer_surface (window->waylandSurface ()->object (), output, m_dlayerShellWindow->layer (), m_dlayerShellWindow->scope ()));
37+ m_output = output;
4938
50- set_layer (m_dlayerShellWindow->layer ());
51- connect (m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this , [this , window](){
52- set_layer (m_dlayerShellWindow->layer ());
53- window->waylandSurface ()->commit ();
54- });
39+ applyLayer ();
40+ connect (m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this , &QWaylandLayerShellSurface::applyLayer);
5541
5642 set_anchor (m_dlayerShellWindow->anchors ());
57- connect (m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this ,[this , window](){
58- trySetAnchorsAndSize ();
59- });
43+ connect (m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this , &QWaylandLayerShellSurface::trySetAnchorsAndSize);
6044
61- set_exclusive_zone (m_dlayerShellWindow->exclusionZone ());
62- connect (m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, this ,[this , window](){
63- set_exclusive_zone (m_dlayerShellWindow->exclusionZone ());
64- window->waylandSurface ()->commit ();
65- });
45+ applyExclusiveZone ();
46+ connect (m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, this , &QWaylandLayerShellSurface::applyExclusiveZone);
6647
67- set_margin (m_dlayerShellWindow->topMargin (), m_dlayerShellWindow->rightMargin (), m_dlayerShellWindow->bottomMargin (), m_dlayerShellWindow->leftMargin ());
68- connect (m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this , [this ](){
69- set_margin (m_dlayerShellWindow->topMargin (), m_dlayerShellWindow->rightMargin (), m_dlayerShellWindow->bottomMargin (), m_dlayerShellWindow->leftMargin ());
70- });
48+ applyMargins ();
49+ connect (m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this , &QWaylandLayerShellSurface::applyMargins);
7150
72- set_keyboard_interactivity (m_dlayerShellWindow->keyboardInteractivity ());
73- connect (m_dlayerShellWindow, &DLayerShellWindow::keyboardInteractivityChanged, this , [this , window](){
74- set_keyboard_interactivity (m_dlayerShellWindow->keyboardInteractivity ());
75- window->waylandSurface ()->commit ();
76- });
51+ applyKeyboardInteractivity ();
52+ connect (m_dlayerShellWindow, &DLayerShellWindow::keyboardInteractivityChanged, this , &QWaylandLayerShellSurface::applyKeyboardInteractivity);
7753
78- auto applyInputRegion = [this , window]() {
79- window->window ()->setMask (m_dlayerShellWindow->inputRegion ());
80- window->waylandSurface ()->commit ();
81- };
82-
83- connect (m_dlayerShellWindow, &DLayerShellWindow::inputRegionChanged, this , applyInputRegion);
54+ applyInputRegion ();
55+ connect (m_dlayerShellWindow, &DLayerShellWindow::inputRegionChanged, this , &QWaylandLayerShellSurface::applyInputRegion);
8456
8557 calcAndSetRequestSize (window->surfaceSize ());
8658
@@ -101,6 +73,33 @@ void QWaylandLayerShellSurface::zwlr_layer_surface_v1_closed()
10173 }
10274}
10375
76+ QtWaylandClient::QWaylandWindow *QWaylandLayerShellSurface::waylandWindow ()
77+ {
78+ return window ();
79+ }
80+
81+ QWindow *QWaylandLayerShellSurface::windowHandle ()
82+ {
83+ auto currentWindow = waylandWindow ();
84+ return currentWindow ? currentWindow->window () : nullptr ;
85+ }
86+
87+ QtWaylandClient::QWaylandScreen *QWaylandLayerShellSurface::waylandScreen ()
88+ {
89+ auto currentWindowHandle = windowHandle ();
90+ if (!currentWindowHandle || !currentWindowHandle->screen ()) {
91+ return nullptr ;
92+ }
93+
94+ return dynamic_cast <QtWaylandClient::QWaylandScreen *>(currentWindowHandle->screen ()->handle ());
95+ }
96+
97+ wl_output *QWaylandLayerShellSurface::currentOutput ()
98+ {
99+ auto currentWaylandScreen = waylandScreen ();
100+ return currentWaylandScreen ? currentWaylandScreen->output () : nullptr ;
101+ }
102+
104103void QWaylandLayerShellSurface::calcAndSetRequestSize (QSize requestSize)
105104{
106105 auto anchors = m_dlayerShellWindow->anchors ();
@@ -128,10 +127,45 @@ void QWaylandLayerShellSurface::trySetAnchorsAndSize()
128127 if (!anchorsSizeConflict ()) {
129128 set_anchor (m_dlayerShellWindow->anchors ());
130129 set_size (m_requestSize.width (), m_requestSize.height ());
131- window ()-> waylandSurface ()-> commit ();
130+ scheduleCommit ();
132131 }
133132}
134133
134+ void QWaylandLayerShellSurface::applyLayer ()
135+ {
136+ set_layer (m_dlayerShellWindow->layer ());
137+ scheduleCommit ();
138+ }
139+
140+ void QWaylandLayerShellSurface::applyExclusiveZone ()
141+ {
142+ set_exclusive_zone (m_dlayerShellWindow->exclusionZone ());
143+ scheduleCommit ();
144+ }
145+
146+ void QWaylandLayerShellSurface::applyMargins ()
147+ {
148+ set_margin (m_dlayerShellWindow->topMargin (), m_dlayerShellWindow->rightMargin (), m_dlayerShellWindow->bottomMargin (), m_dlayerShellWindow->leftMargin ());
149+ scheduleCommit ();
150+ }
151+
152+ void QWaylandLayerShellSurface::applyKeyboardInteractivity ()
153+ {
154+ set_keyboard_interactivity (m_dlayerShellWindow->keyboardInteractivity ());
155+ scheduleCommit ();
156+ }
157+
158+ void QWaylandLayerShellSurface::applyInputRegion ()
159+ {
160+ auto currentWindowHandle = windowHandle ();
161+ if (!currentWindowHandle) {
162+ return ;
163+ }
164+
165+ currentWindowHandle->setMask (m_dlayerShellWindow->inputRegion ());
166+ scheduleCommit ();
167+ }
168+
135169void QWaylandLayerShellSurface::zwlr_layer_surface_v1_configure (uint32_t serial, uint32_t width, uint32_t height)
136170{
137171 ack_configure (serial);
@@ -164,6 +198,71 @@ void QWaylandLayerShellSurface::setWindowGeometry(const QRect &geometry)
164198 trySetAnchorsAndSize ();
165199}
166200
201+ void QWaylandLayerShellSurface::commitWindowState ()
202+ {
203+ auto currentWaylandWindow = waylandWindow ();
204+ if (!currentWaylandWindow || !currentWaylandWindow->waylandSurface ()) {
205+ return ;
206+ }
207+
208+ currentWaylandWindow->waylandSurface ()->commit ();
209+ }
210+
211+ void QWaylandLayerShellSurface::flushCommit ()
212+ {
213+ m_commitScheduled = false ;
214+ commitWindowState ();
215+ }
216+
217+ void QWaylandLayerShellSurface::scheduleCommit ()
218+ {
219+ if (m_commitScheduled) {
220+ return ;
221+ }
222+
223+ m_commitScheduled = true ;
224+ QMetaObject::invokeMethod (this , &QWaylandLayerShellSurface::flushCommit, Qt::QueuedConnection);
225+ }
226+
227+ void QWaylandLayerShellSurface::recreateWindow ()
228+ {
229+ auto currentWaylandWindow = waylandWindow ();
230+ if (!currentWaylandWindow) {
231+ return ;
232+ }
233+
234+ currentWaylandWindow->reset ();
235+ QMetaObject::invokeMethod (currentWaylandWindow, &QtWaylandClient::QWaylandWindow::reinit, Qt::QueuedConnection);
236+ }
237+
238+ void QWaylandLayerShellSurface::flushRecreate ()
239+ {
240+ m_recreateScheduled = false ;
241+ recreateWindow ();
242+ }
243+
244+ void QWaylandLayerShellSurface::scheduleRecreate ()
245+ {
246+ auto currentWindowHandle = windowHandle ();
247+ if (!currentWindowHandle) {
248+ return ;
249+ }
250+
251+ const auto output = currentOutput ();
252+ if (!output) {
253+ qCWarning (layershellsurface) << " failed to get screen for wayland" ;
254+ return ;
255+ }
256+
257+ if (output == m_output || m_recreateScheduled) {
258+ return ;
259+ }
260+
261+ m_output = output;
262+ m_recreateScheduled = true ;
263+ QMetaObject::invokeMethod (this , &QWaylandLayerShellSurface::flushRecreate, Qt::QueuedConnection);
264+ }
265+
167266void QWaylandLayerShellSurface::attachPopup (QtWaylandClient::QWaylandShellSurface *popup)
168267{
169268 std::any anyRole = popup->surfaceRole ();
0 commit comments