8#include <QtWaylandCompositor/QWaylandCompositor>
9#include <QtWaylandCompositor/QWaylandSurface>
11#include <QtWaylandCompositor/QWaylandResource>
13#if QT_CONFIG(wayland_compositor_quick)
14# include "qwaylandqtshellintegration_p.h"
17#include <QtWaylandCompositor/QWaylandResource>
19#include "compositor_api/qwaylandseat.h"
21#include <QtWaylandCompositor/private/qwaylandutils_p.h>
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53QWaylandQtShell::QWaylandQtShell()
54 : QWaylandCompositorExtensionTemplate<QWaylandQtShell>(*
new QWaylandQtShellPrivate())
58QWaylandQtShell::QWaylandQtShell(QWaylandCompositor *compositor)
59 : QWaylandCompositorExtensionTemplate<QWaylandQtShell>(compositor, *
new QWaylandQtShellPrivate())
63bool QWaylandQtShell::moveChromeToFront(QWaylandQtShellChrome *chrome)
66 for (
int i = 0; i < d->m_chromes.size(); ++i) {
67 if (d->m_chromes.at(i) == chrome) {
69 QWaylandQtShellChrome *currentActive = d->m_chromes.first();
70 d->m_chromes.move(i, 0);
72 currentActive->deactivate();
81void QWaylandQtShell::registerChrome(QWaylandQtShellChrome *chrome)
84 if (moveChromeToFront(chrome))
87 QWaylandQtShellChrome *currentActive = d->m_chromes.isEmpty() ?
nullptr : d->m_chromes.first();
89 d->m_chromes.prepend(chrome);
92 if (currentActive !=
nullptr)
93 currentActive->deactivate();
95 connect(chrome, &QWaylandQtShellChrome::activated,
this, &QWaylandQtShell::chromeActivated);
96 connect(chrome, &QWaylandQtShellChrome::deactivated,
this, &QWaylandQtShell::chromeDeactivated);
99void QWaylandQtShell::unregisterChrome(QWaylandQtShellChrome *chrome)
101 Q_D(QWaylandQtShell);
103 chrome->disconnect(
this);
104 int index = d->m_chromes.indexOf(chrome);
106 d->m_chromes.removeAt(index);
107 if (index == 0 && d->m_chromes.size() > 0)
108 d->m_chromes.at(0)->activate();
112void QWaylandQtShell::chromeActivated()
114 QWaylandQtShellChrome *c = qobject_cast<QWaylandQtShellChrome *>(sender());
116 moveChromeToFront(c);
120void QWaylandQtShell::chromeDeactivated()
122 Q_D(QWaylandQtShell);
123 QWaylandQtShellChrome *c = qobject_cast<QWaylandQtShellChrome *>(sender());
124 if (d->m_chromes.size() > 1 && d->m_chromes.at(0) == c) {
125 d->m_chromes.move(0, 1);
126 d->m_chromes.at(0)->activate();
127 }
else if (d->m_chromes.size() == 1) {
128 d->m_chromes.at(0)->activate();
132void QWaylandQtShell::initialize()
134 Q_D(QWaylandQtShell);
135 QWaylandCompositorExtensionTemplate::initialize();
137 QWaylandCompositor *compositor =
static_cast<QWaylandCompositor *>(extensionContainer());
139 qWarning() <<
"Failed to find QWaylandCompositor when initializing QWaylandQtShell";
143 d->init(compositor->display(), 1);
146const struct wl_interface *QWaylandQtShell::interface()
148 return QWaylandQtShellPrivate::interface();
152
153
154QByteArray QWaylandQtShell::interfaceName()
156 return QWaylandQtShellPrivate::interfaceName();
160
161
162
163
164
165
166
169
170
171
172
173
175QWaylandQtShellPrivate::QWaylandQtShellPrivate()
179void QWaylandQtShellPrivate::unregisterQtShellSurface(QWaylandQtShellSurface *qtShellSurface)
181 Q_UNUSED(qtShellSurface)
184void QWaylandQtShellPrivate::zqt_shell_v1_surface_create(QtWaylandServer::zqt_shell_v1::Resource *resource, wl_resource *surfaceResource, uint32_t id)
186 Q_Q(QWaylandQtShell);
187 QWaylandSurface *surface = QWaylandSurface::fromResource(surfaceResource);
189 if (!surface->setRole(QWaylandQtShellSurface::role(), resource->handle, ZQT_SHELL_V1_ERROR_ROLE))
192 QWaylandResource qtShellSurfaceResource(wl_resource_create(resource->client(), &zqt_shell_surface_v1_interface,
193 wl_resource_get_version(resource->handle), id));
195 emit q->qtShellSurfaceRequested(surface, qtShellSurfaceResource);
197 QWaylandQtShellSurface *qtShellSurface = QWaylandQtShellSurface::fromResource(qtShellSurfaceResource.resource());
200 qtShellSurface =
new QWaylandQtShellSurface(q, surface, qtShellSurfaceResource);
202 emit q->qtShellSurfaceCreated(qtShellSurface);
205QWaylandSurfaceRole QWaylandQtShellSurfacePrivate::s_role(
"qt_shell_surface");
208
209
210
211
212
213
214
215
216
217
218
219
220
221
224
225
226
227
228
229
230
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
250QWaylandQtShellSurface::QWaylandQtShellSurface()
251 : QWaylandShellSurfaceTemplate<QWaylandQtShellSurface>(*
new QWaylandQtShellSurfacePrivate())
255QWaylandQtShellSurface::QWaylandQtShellSurface(QWaylandQtShell *application, QWaylandSurface *surface,
const QWaylandResource &resource)
256 : QWaylandShellSurfaceTemplate<QWaylandQtShellSurface>(*
new QWaylandQtShellSurfacePrivate())
258 initialize(application, surface, resource);
262
263
264
265
266
267void QWaylandQtShellSurface::initialize(QWaylandQtShell *qtShell, QWaylandSurface *surface,
const QWaylandResource &resource)
269 Q_D(QWaylandQtShellSurface);
271 d->m_qtShell = qtShell;
272 d->m_surface = surface;
274 connect(d->m_surface, &QWaylandSurface::damaged,
this, &QWaylandQtShellSurface::surfaceCommitted);
276 d->init(resource.resource());
277 setExtensionContainer(surface);
279 emit surfaceChanged();
281 QWaylandCompositorExtension::initialize();
285
286
287
288
291
292
293
294
295QWaylandSurface *QWaylandQtShellSurface::surface()
const
297 Q_D(
const QWaylandQtShellSurface);
301QWaylandQtShell *QWaylandQtShellSurface::shell()
const
303 Q_D(
const QWaylandQtShellSurface);
308
309
310
311
314
315
316
317
318QPoint QWaylandQtShellSurface::windowPosition()
const
320 Q_D(
const QWaylandQtShellSurface);
321 return d->m_windowGeometry.topLeft();
324void QWaylandQtShellSurface::setWindowPosition(
const QPoint &position)
326 Q_D(QWaylandQtShellSurface);
329 d->send_set_position(UINT32_MAX, position.x(), position.y());
330 d->send_configure(UINT32_MAX);
332 d->m_windowGeometry.moveTopLeft(position);
333 d->m_positionSet =
true;
334 emit positionAutomaticChanged();
335 emit windowGeometryChanged();
339
340
341
342
345
346
347
348
349QRect QWaylandQtShellSurface::windowGeometry()
const
351 Q_D(
const QWaylandQtShellSurface);
352 return d->m_windowGeometry;
356
357
358
359
362
363
364
365
366
367QSize QWaylandQtShellSurface::minimumSize()
const
369 Q_D(
const QWaylandQtShellSurface);
370 return d->m_minimumSize;
374
375
376
377
380
381
382
383
384
385QSize QWaylandQtShellSurface::maximumSize()
const
387 Q_D(
const QWaylandQtShellSurface);
388 return d->m_maximumSize;
392
393
394
395
396
397
398void QWaylandQtShellSurface::requestWindowGeometry(uint windowState,
const QRect &windowGeometry)
400 Q_D(QWaylandQtShellSurface);
401 if (!windowGeometry.isValid())
404 d->configure(windowState, windowGeometry);
407void QWaylandQtShellSurfacePrivate::configure(uint windowState,
const QRect &newGeometry)
409 QWaylandCompositor *compositor = m_surface !=
nullptr ? m_surface->compositor() :
nullptr;
411 qWarning() <<
"Failed to find QWaylandCompositor when configuring QWaylandQtShell";
415 uint32_t serial = compositor->nextSerial();
416 m_pendingConfigures[serial] = qMakePair(windowState, newGeometry);
418 send_set_position(serial, newGeometry.x(), newGeometry.y());
419 send_resize(serial, newGeometry.width(), newGeometry.height());
420 send_set_window_state(serial, windowState & ~Qt::WindowActive);
421 send_configure(serial);
424void QWaylandQtShellSurface::setFrameMargins(
const QMargins &margins)
426 Q_D(QWaylandQtShellSurface);
427 if (d->m_frameMargins == margins)
430 d->m_frameMargins = margins;
431 d->updateFrameMargins();
433 emit frameMarginChanged();
437
438
439
440
443
444
445
446
447void QWaylandQtShellSurface::setFrameMarginLeft(
int left)
449 Q_D(QWaylandQtShellSurface);
450 if (d->m_frameMargins.left() == left)
453 d->m_frameMargins.setLeft(left);
454 d->updateFrameMargins();
456 emit frameMarginChanged();
459int QWaylandQtShellSurface::frameMarginLeft()
const
461 Q_D(
const QWaylandQtShellSurface);
462 return d->m_frameMargins.left();
466
467
468
469
472
473
474
475
476void QWaylandQtShellSurface::setFrameMarginRight(
int right)
478 Q_D(QWaylandQtShellSurface);
479 if (d->m_frameMargins.right() == right)
482 d->m_frameMargins.setRight(right);
483 d->updateFrameMargins();
485 emit frameMarginChanged();
488int QWaylandQtShellSurface::frameMarginRight()
const
490 Q_D(
const QWaylandQtShellSurface);
491 return d->m_frameMargins.right();
495
496
497
498
501
502
503
504
505void QWaylandQtShellSurface::setFrameMarginTop(
int top)
507 Q_D(QWaylandQtShellSurface);
508 if (d->m_frameMargins.top() == top)
510 d->m_frameMargins.setTop(top);
511 d->updateFrameMargins();
513 emit frameMarginChanged();
516int QWaylandQtShellSurface::frameMarginTop()
const
518 Q_D(
const QWaylandQtShellSurface);
519 return d->m_frameMargins.top();
523
524
525
526
529
530
531
532
533void QWaylandQtShellSurface::setFrameMarginBottom(
int bottom)
535 Q_D(QWaylandQtShellSurface);
536 if (d->m_frameMargins.bottom() == bottom)
538 d->m_frameMargins.setBottom(bottom);
539 d->updateFrameMargins();
541 emit frameMarginChanged();
545
546
547
548
549
550
551
552
553bool QWaylandQtShellSurface::positionAutomatic()
const
555 Q_D(
const QWaylandQtShellSurface);
556 return !d->m_positionSet;
559int QWaylandQtShellSurface::frameMarginBottom()
const
561 Q_D(
const QWaylandQtShellSurface);
562 return d->m_frameMargins.bottom();
566
567
568
569
572
573
574
575
576uint QWaylandQtShellSurface::windowFlags()
const
578 Q_D(
const QWaylandQtShellSurface);
579 return d->m_windowFlags;
583
584
585
586
587void QWaylandQtShellSurface::sendClose()
589 Q_D(QWaylandQtShellSurface);
594
595
596
597
600
601
602
603
604QString QWaylandQtShellSurface::windowTitle()
const
606 Q_D(
const QWaylandQtShellSurface);
607 return d->m_windowTitle;
611
612
613
614
615
616
617
618
621
622
623
624
625
626
627
628
629
630
631void QWaylandQtShellSurface::setActive(
bool active)
633 Q_D(QWaylandQtShellSurface);
634 if (d->m_active == active)
637 d->m_active = active;
638 QWaylandCompositor *compositor = d->m_surface ? d->m_surface->compositor() :
nullptr;
639 QWaylandSeat *seat = compositor ? compositor->defaultSeat() :
nullptr;
641 seat->setKeyboardFocus(surface());
642 emit activeChanged();
645bool QWaylandQtShellSurface::active()
const
647 Q_D(
const QWaylandQtShellSurface);
652
653
654
655
656
657
658
659
660
661
662
663
664
665
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684void QWaylandQtShellSurface::setCapabilities(CapabilityFlags capabilities)
686 Q_D(QWaylandQtShellSurface);
687 if (d->m_capabilities == capabilities)
690 d->m_capabilities = capabilities;
691 d->send_set_capabilities(capabilities);
693 emit capabilitiesChanged();
696QWaylandQtShellSurface::CapabilityFlags QWaylandQtShellSurface::capabilities()
const
698 Q_D(
const QWaylandQtShellSurface);
699 return d->m_capabilities;
703
704
705
706
707
708
709
712
713
714
715
716
717
718
719
720uint QWaylandQtShellSurface::windowState()
const
722 Q_D(
const QWaylandQtShellSurface);
723 return d->m_windowState;
726void QWaylandQtShellSurface::surfaceCommitted()
728 Q_D(QWaylandQtShellSurface);
729 if (d->m_lastAckedConfigure < UINT32_MAX) {
730 QRect targetRect = d->m_windowGeometry;
731 uint windowState = d->m_windowState;
732 for (
auto it = d->m_pendingConfigures.begin(); it != d->m_pendingConfigures.end(); ) {
733 if (it.key() == d->m_lastAckedConfigure) {
734 targetRect = it.value().second;
735 windowState = it.value().first;
738 if (it.key() <= d->m_lastAckedConfigure)
739 it = d->m_pendingConfigures.erase(it);
744 if (d->m_windowState != windowState) {
745 d->m_windowState = windowState;
746 emit windowStateChanged();
749 if (d->m_windowGeometry != targetRect) {
750 d->m_windowGeometry = targetRect;
751 d->m_positionSet =
true;
752 emit positionAutomaticChanged();
753 emit windowGeometryChanged();
756 d->m_lastAckedConfigure = UINT32_MAX;
757 d->m_pendingPosition = QPoint{};
758 d->m_pendingPositionValid =
false;
759 d->m_pendingSize = QSize{};
761 QRect oldRect = d->m_windowGeometry;
762 if (d->m_pendingPositionValid) {
763 d->m_windowGeometry.moveTopLeft(d->m_pendingPosition);
764 d->m_pendingPosition = QPoint{};
765 d->m_pendingPositionValid =
false;
766 d->m_positionSet =
true;
767 emit positionAutomaticChanged();
770 if (d->m_pendingSize.isValid()) {
771 d->m_windowGeometry.setSize(d->m_pendingSize);
772 d->m_pendingSize = QSize{};
775 if (d->m_windowGeometry != oldRect)
776 emit windowGeometryChanged();
781
782
783
784const wl_interface *QWaylandQtShellSurface::interface()
786 return QWaylandQtShellSurfacePrivate::interface();
789QByteArray QWaylandQtShellSurface::interfaceName()
791 return QWaylandQtShellSurfacePrivate::interfaceName();
795
796
797
798QWaylandSurfaceRole *QWaylandQtShellSurface::role()
800 return &QWaylandQtShellSurfacePrivate::s_role;
804
805
806
807QWaylandQtShellSurface *QWaylandQtShellSurface::fromResource(wl_resource *resource)
809 if (
auto p = QtWayland::fromResource<QWaylandQtShellSurfacePrivate *>(resource))
814#if QT_CONFIG(wayland_compositor_quick)
815QWaylandQuickShellIntegration *QWaylandQtShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item)
817 return new QtWayland::QtShellIntegration(item);
822
823
824void QWaylandQtShellSurface::initialize()
826 QWaylandShellSurfaceTemplate::initialize();
829QWaylandQtShellSurfacePrivate::QWaylandQtShellSurfacePrivate()
833void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_ack_configure(Resource *resource, uint32_t serial)
836 Q_Q(QWaylandQtShellSurface);
837 if (serial < UINT32_MAX)
838 m_lastAckedConfigure = serial;
841 if (m_windowState & Qt::WindowMinimized)
842 q->surfaceCommitted();
845void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_reposition(Resource *resource, int32_t x, int32_t y)
849 m_pendingPosition = QPoint(x, y);
850 m_pendingPositionValid =
true;
851 m_lastAckedConfigure = UINT32_MAX;
854void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_size(Resource *resource, int32_t width, int32_t height)
858 m_pendingSize = QSize(width, height);
859 m_lastAckedConfigure = UINT32_MAX;
862void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_minimum_size(Resource *resource, int32_t width, int32_t height)
865 Q_Q(QWaylandQtShellSurface);
866 m_minimumSize = QSize{width, height};
867 emit q->minimumSizeChanged();
870void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_maximum_size(Resource *resource, int32_t width, int32_t height)
873 Q_Q(QWaylandQtShellSurface);
874 m_maximumSize = QSize{width, height};
875 emit q->maximumSizeChanged();
878void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_destroy_resource(QtWaylandServer::zqt_shell_surface_v1::Resource *resource)
881 Q_Q(QWaylandQtShellSurface);
882 QWaylandQtShellPrivate::get(m_qtShell)->unregisterQtShellSurface(q);
886void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_destroy(QtWaylandServer::zqt_shell_surface_v1::Resource *resource)
888 wl_resource_destroy(resource->handle);
891void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_window_flags(Resource *resource, uint32_t flags)
894 Q_Q(QWaylandQtShellSurface);
895 m_windowFlags = flags;
896 emit q->windowFlagsChanged();
899void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_change_window_state(Resource *resource, uint32_t state)
902 Q_Q(QWaylandQtShellSurface);
903 uint oldWindowState = m_windowState;
904 m_windowState = state & ~Qt::WindowActive;
906 if (oldWindowState != m_windowState)
907 emit q->windowStateChanged();
910void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_start_system_resize(Resource *resource, uint32_t serial, uint32_t edge)
914 Q_Q(QWaylandQtShellSurface);
915 emit q->startResize(Qt::Edges(edge));
918void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_start_system_move(Resource *resource, uint32_t serial)
922 Q_Q(QWaylandQtShellSurface);
926void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_window_title(Resource *resource,
927 const QString &title)
930 Q_Q(QWaylandQtShellSurface);
931 m_windowTitle = title;
932 emit q->windowTitleChanged();
935void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_request_activate(Resource *resource)
939 Q_Q(QWaylandQtShellSurface);
943 auto view = m_surface->primaryView();
944 auto item = view ? qobject_cast<QWaylandQuickItem *>(view->renderObject()) :
nullptr;
946 item->forceActiveFocus();
950void QWaylandQtShellSurfacePrivate::updateFrameMargins()
952 send_set_frame_margins(m_frameMargins.left(), m_frameMargins.right(),
953 m_frameMargins.top(), m_frameMargins.bottom());
957void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_raise(Resource *resource)
960 Q_Q(QWaylandQtShellSurface);
961 emit q->raiseRequested();
964void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_lower(Resource *resource)
967 Q_Q(QWaylandQtShellSurface);
968 emit q->lowerRequested();
973#include "moc_qwaylandqtshell_p.cpp"