9#include <QtWaylandCompositor/QWaylandCompositor>
10#include <QtWaylandCompositor/QWaylandSurface>
12#include <QtWaylandCompositor/QWaylandResource>
14#if QT_CONFIG(wayland_compositor_quick)
15# include "qwaylandqtshellintegration_p.h"
18#include <QtWaylandCompositor/QWaylandResource>
20#include "compositor_api/qwaylandseat.h"
22#include <QtWaylandCompositor/private/qwaylandutils_p.h>
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
53
54QWaylandQtShell::QWaylandQtShell()
55 : QWaylandCompositorExtensionTemplate<QWaylandQtShell>(*
new QWaylandQtShellPrivate())
59QWaylandQtShell::QWaylandQtShell(QWaylandCompositor *compositor)
60 : QWaylandCompositorExtensionTemplate<QWaylandQtShell>(compositor, *
new QWaylandQtShellPrivate())
64bool QWaylandQtShell::moveChromeToFront(QWaylandQtShellChrome *chrome)
67 for (
int i = 0; i < d->m_chromes.size(); ++i) {
68 if (d->m_chromes.at(i) == chrome) {
70 QWaylandQtShellChrome *currentActive = d->m_chromes.first();
71 d->m_chromes.move(i, 0);
73 currentActive->deactivate();
82void QWaylandQtShell::registerChrome(QWaylandQtShellChrome *chrome)
85 if (moveChromeToFront(chrome))
88 QWaylandQtShellChrome *currentActive = d->m_chromes.isEmpty() ?
nullptr : d->m_chromes.first();
90 d->m_chromes.prepend(chrome);
93 if (currentActive !=
nullptr)
94 currentActive->deactivate();
96 connect(chrome, &QWaylandQtShellChrome::activated,
this, &QWaylandQtShell::chromeActivated);
97 connect(chrome, &QWaylandQtShellChrome::deactivated,
this, &QWaylandQtShell::chromeDeactivated);
100void QWaylandQtShell::unregisterChrome(QWaylandQtShellChrome *chrome)
102 Q_D(QWaylandQtShell);
104 chrome->disconnect(
this);
105 int index = d->m_chromes.indexOf(chrome);
107 d->m_chromes.removeAt(index);
108 if (index == 0 && d->m_chromes.size() > 0)
109 d->m_chromes.at(0)->activate();
113void QWaylandQtShell::chromeActivated()
115 QWaylandQtShellChrome *c = qobject_cast<QWaylandQtShellChrome *>(sender());
117 moveChromeToFront(c);
121void QWaylandQtShell::chromeDeactivated()
123 Q_D(QWaylandQtShell);
124 QWaylandQtShellChrome *c = qobject_cast<QWaylandQtShellChrome *>(sender());
125 if (d->m_chromes.size() > 1 && d->m_chromes.at(0) == c) {
126 d->m_chromes.move(0, 1);
127 d->m_chromes.at(0)->activate();
128 }
else if (d->m_chromes.size() == 1) {
129 d->m_chromes.at(0)->activate();
133void QWaylandQtShell::initialize()
135 Q_D(QWaylandQtShell);
136 QWaylandCompositorExtensionTemplate::initialize();
138 QWaylandCompositor *compositor =
static_cast<QWaylandCompositor *>(extensionContainer());
140 qWarning() <<
"Failed to find QWaylandCompositor when initializing QWaylandQtShell";
144 d->init(compositor->display(), 1);
147const struct wl_interface *QWaylandQtShell::interface()
149 return QWaylandQtShellPrivate::interface();
153
154
155QByteArray QWaylandQtShell::interfaceName()
157 return QWaylandQtShellPrivate::interfaceName();
161
162
163
164
165
166
167
170
171
172
173
174
176QWaylandQtShellPrivate::QWaylandQtShellPrivate()
180void QWaylandQtShellPrivate::unregisterQtShellSurface(QWaylandQtShellSurface *qtShellSurface)
182 Q_UNUSED(qtShellSurface)
185void QWaylandQtShellPrivate::zqt_shell_v1_surface_create(QtWaylandServer::zqt_shell_v1::Resource *resource, wl_resource *surfaceResource, uint32_t id)
187 Q_Q(QWaylandQtShell);
188 QWaylandSurface *surface = QWaylandSurface::fromResource(surfaceResource);
190 if (!surface->setRole(QWaylandQtShellSurface::role(), resource->handle, ZQT_SHELL_V1_ERROR_ROLE))
193 QWaylandResource qtShellSurfaceResource(wl_resource_create(resource->client(), &zqt_shell_surface_v1_interface,
194 wl_resource_get_version(resource->handle), id));
196 emit q->qtShellSurfaceRequested(surface, qtShellSurfaceResource);
198 QWaylandQtShellSurface *qtShellSurface = QWaylandQtShellSurface::fromResource(qtShellSurfaceResource.resource());
201 qtShellSurface =
new QWaylandQtShellSurface(q, surface, qtShellSurfaceResource);
203 emit q->qtShellSurfaceCreated(qtShellSurface);
206QWaylandSurfaceRole QWaylandQtShellSurfacePrivate::s_role(
"qt_shell_surface");
209
210
211
212
213
214
215
216
217
218
219
220
221
222
225
226
227
228
229
230
231
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
251QWaylandQtShellSurface::QWaylandQtShellSurface()
252 : QWaylandShellSurfaceTemplate<QWaylandQtShellSurface>(*
new QWaylandQtShellSurfacePrivate())
256QWaylandQtShellSurface::QWaylandQtShellSurface(QWaylandQtShell *application, QWaylandSurface *surface,
const QWaylandResource &resource)
257 : QWaylandShellSurfaceTemplate<QWaylandQtShellSurface>(*
new QWaylandQtShellSurfacePrivate())
259 initialize(application, surface, resource);
263
264
265
266
267
268void QWaylandQtShellSurface::initialize(QWaylandQtShell *qtShell, QWaylandSurface *surface,
const QWaylandResource &resource)
270 Q_D(QWaylandQtShellSurface);
272 d->m_qtShell = qtShell;
273 d->m_surface = surface;
275 connect(d->m_surface, &QWaylandSurface::damaged,
this, &QWaylandQtShellSurface::surfaceCommitted);
277 d->init(resource.resource());
278 setExtensionContainer(surface);
280 emit surfaceChanged();
282 QWaylandCompositorExtension::initialize();
286
287
288
289
292
293
294
295
296QWaylandSurface *QWaylandQtShellSurface::surface()
const
298 Q_D(
const QWaylandQtShellSurface);
302QWaylandQtShell *QWaylandQtShellSurface::shell()
const
304 Q_D(
const QWaylandQtShellSurface);
309
310
311
312
315
316
317
318
319QPoint QWaylandQtShellSurface::windowPosition()
const
321 Q_D(
const QWaylandQtShellSurface);
322 return d->m_windowGeometry.topLeft();
325void QWaylandQtShellSurface::setWindowPosition(
const QPoint &position)
327 Q_D(QWaylandQtShellSurface);
330 d->send_set_position(UINT32_MAX, position.x(), position.y());
331 d->send_configure(UINT32_MAX);
333 d->m_windowGeometry.moveTopLeft(position);
334 d->m_positionSet =
true;
335 emit positionAutomaticChanged();
336 emit windowGeometryChanged();
340
341
342
343
346
347
348
349
350QRect QWaylandQtShellSurface::windowGeometry()
const
352 Q_D(
const QWaylandQtShellSurface);
353 return d->m_windowGeometry;
357
358
359
360
363
364
365
366
367
368QSize QWaylandQtShellSurface::minimumSize()
const
370 Q_D(
const QWaylandQtShellSurface);
371 return d->m_minimumSize;
375
376
377
378
381
382
383
384
385
386QSize QWaylandQtShellSurface::maximumSize()
const
388 Q_D(
const QWaylandQtShellSurface);
389 return d->m_maximumSize;
393
394
395
396
397
398
399void QWaylandQtShellSurface::requestWindowGeometry(uint windowState,
const QRect &windowGeometry)
401 Q_D(QWaylandQtShellSurface);
402 if (!windowGeometry.isValid())
405 d->configure(windowState, windowGeometry);
408void QWaylandQtShellSurfacePrivate::configure(uint windowState,
const QRect &newGeometry)
410 QWaylandCompositor *compositor = m_surface !=
nullptr ? m_surface->compositor() :
nullptr;
412 qWarning() <<
"Failed to find QWaylandCompositor when configuring QWaylandQtShell";
416 uint32_t serial = compositor->nextSerial();
417 m_pendingConfigures[serial] = {windowState, newGeometry};
419 send_set_position(serial, newGeometry.x(), newGeometry.y());
420 send_resize(serial, newGeometry.width(), newGeometry.height());
421 send_set_window_state(serial, windowState & ~Qt::WindowActive);
422 send_configure(serial);
425void QWaylandQtShellSurface::setFrameMargins(
const QMargins &margins)
427 Q_D(QWaylandQtShellSurface);
428 if (d->m_frameMargins == margins)
431 d->m_frameMargins = margins;
432 d->updateFrameMargins();
434 emit frameMarginChanged();
438
439
440
441
444
445
446
447
448void QWaylandQtShellSurface::setFrameMarginLeft(
int left)
450 Q_D(QWaylandQtShellSurface);
451 if (d->m_frameMargins.left() == left)
454 d->m_frameMargins.setLeft(left);
455 d->updateFrameMargins();
457 emit frameMarginChanged();
460int QWaylandQtShellSurface::frameMarginLeft()
const
462 Q_D(
const QWaylandQtShellSurface);
463 return d->m_frameMargins.left();
467
468
469
470
473
474
475
476
477void QWaylandQtShellSurface::setFrameMarginRight(
int right)
479 Q_D(QWaylandQtShellSurface);
480 if (d->m_frameMargins.right() == right)
483 d->m_frameMargins.setRight(right);
484 d->updateFrameMargins();
486 emit frameMarginChanged();
489int QWaylandQtShellSurface::frameMarginRight()
const
491 Q_D(
const QWaylandQtShellSurface);
492 return d->m_frameMargins.right();
496
497
498
499
502
503
504
505
506void QWaylandQtShellSurface::setFrameMarginTop(
int top)
508 Q_D(QWaylandQtShellSurface);
509 if (d->m_frameMargins.top() == top)
511 d->m_frameMargins.setTop(top);
512 d->updateFrameMargins();
514 emit frameMarginChanged();
517int QWaylandQtShellSurface::frameMarginTop()
const
519 Q_D(
const QWaylandQtShellSurface);
520 return d->m_frameMargins.top();
524
525
526
527
530
531
532
533
534void QWaylandQtShellSurface::setFrameMarginBottom(
int bottom)
536 Q_D(QWaylandQtShellSurface);
537 if (d->m_frameMargins.bottom() == bottom)
539 d->m_frameMargins.setBottom(bottom);
540 d->updateFrameMargins();
542 emit frameMarginChanged();
546
547
548
549
550
551
552
553
554bool QWaylandQtShellSurface::positionAutomatic()
const
556 Q_D(
const QWaylandQtShellSurface);
557 return !d->m_positionSet;
560int QWaylandQtShellSurface::frameMarginBottom()
const
562 Q_D(
const QWaylandQtShellSurface);
563 return d->m_frameMargins.bottom();
567
568
569
570
573
574
575
576
577uint QWaylandQtShellSurface::windowFlags()
const
579 Q_D(
const QWaylandQtShellSurface);
580 return d->m_windowFlags;
584
585
586
587
588void QWaylandQtShellSurface::sendClose()
590 Q_D(QWaylandQtShellSurface);
595
596
597
598
601
602
603
604
605QString QWaylandQtShellSurface::windowTitle()
const
607 Q_D(
const QWaylandQtShellSurface);
608 return d->m_windowTitle;
612
613
614
615
616
617
618
619
622
623
624
625
626
627
628
629
630
631
632void QWaylandQtShellSurface::setActive(
bool active)
634 Q_D(QWaylandQtShellSurface);
635 if (d->m_active == active)
638 d->m_active = active;
639 QWaylandCompositor *compositor = d->m_surface ? d->m_surface->compositor() :
nullptr;
640 QWaylandSeat *seat = compositor ? compositor->defaultSeat() :
nullptr;
642 seat->setKeyboardFocus(surface());
643 emit activeChanged();
646bool QWaylandQtShellSurface::active()
const
648 Q_D(
const QWaylandQtShellSurface);
653
654
655
656
657
658
659
660
661
662
663
664
665
666
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685void QWaylandQtShellSurface::setCapabilities(CapabilityFlags capabilities)
687 Q_D(QWaylandQtShellSurface);
688 if (d->m_capabilities == capabilities)
691 d->m_capabilities = capabilities;
692 d->send_set_capabilities(capabilities);
694 emit capabilitiesChanged();
697QWaylandQtShellSurface::CapabilityFlags QWaylandQtShellSurface::capabilities()
const
699 Q_D(
const QWaylandQtShellSurface);
700 return d->m_capabilities;
704
705
706
707
708
709
710
713
714
715
716
717
718
719
720
721uint QWaylandQtShellSurface::windowState()
const
723 Q_D(
const QWaylandQtShellSurface);
724 return d->m_windowState;
727void QWaylandQtShellSurface::surfaceCommitted()
729 Q_D(QWaylandQtShellSurface);
730 if (d->m_lastAckedConfigure < UINT32_MAX) {
731 QRect targetRect = d->m_windowGeometry;
732 uint windowState = d->m_windowState;
733 for (
auto it = d->m_pendingConfigures.begin(); it != d->m_pendingConfigures.end(); ) {
734 if (it.key() == d->m_lastAckedConfigure) {
735 targetRect = it.value().second;
736 windowState = it.value().first;
739 if (it.key() <= d->m_lastAckedConfigure)
740 it = d->m_pendingConfigures.erase(it);
745 if (d->m_windowState != windowState) {
746 d->m_windowState = windowState;
747 emit windowStateChanged();
750 if (d->m_windowGeometry != targetRect) {
751 d->m_windowGeometry = targetRect;
752 d->m_positionSet =
true;
753 emit positionAutomaticChanged();
754 emit windowGeometryChanged();
757 d->m_lastAckedConfigure = UINT32_MAX;
758 d->m_pendingPosition = QPoint{};
759 d->m_pendingPositionValid =
false;
760 d->m_pendingSize = QSize{};
762 QRect oldRect = d->m_windowGeometry;
763 if (d->m_pendingPositionValid) {
764 d->m_windowGeometry.moveTopLeft(d->m_pendingPosition);
765 d->m_pendingPosition = QPoint{};
766 d->m_pendingPositionValid =
false;
767 d->m_positionSet =
true;
768 emit positionAutomaticChanged();
771 if (d->m_pendingSize.isValid()) {
772 d->m_windowGeometry.setSize(d->m_pendingSize);
773 d->m_pendingSize = QSize{};
776 if (d->m_windowGeometry != oldRect)
777 emit windowGeometryChanged();
782
783
784
785const wl_interface *QWaylandQtShellSurface::interface()
787 return QWaylandQtShellSurfacePrivate::interface();
790QByteArray QWaylandQtShellSurface::interfaceName()
792 return QWaylandQtShellSurfacePrivate::interfaceName();
796
797
798
799QWaylandSurfaceRole *QWaylandQtShellSurface::role()
801 return &QWaylandQtShellSurfacePrivate::s_role;
805
806
807
808QWaylandQtShellSurface *QWaylandQtShellSurface::fromResource(wl_resource *resource)
810 if (
auto p = QtWayland::fromResource<QWaylandQtShellSurfacePrivate *>(resource))
815#if QT_CONFIG(wayland_compositor_quick)
816QWaylandQuickShellIntegration *QWaylandQtShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item)
818 return new QtWayland::QtShellIntegration(item);
823
824
825void QWaylandQtShellSurface::initialize()
827 QWaylandShellSurfaceTemplate::initialize();
830QWaylandQtShellSurfacePrivate::QWaylandQtShellSurfacePrivate()
834void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_ack_configure(Resource *resource, uint32_t serial)
837 Q_Q(QWaylandQtShellSurface);
838 if (serial < UINT32_MAX)
839 m_lastAckedConfigure = serial;
842 if (m_windowState & Qt::WindowMinimized)
843 q->surfaceCommitted();
846void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_reposition(Resource *resource, int32_t x, int32_t y)
850 m_pendingPosition = QPoint(x, y);
851 m_pendingPositionValid =
true;
852 m_lastAckedConfigure = UINT32_MAX;
855void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_size(Resource *resource, int32_t width, int32_t height)
859 m_pendingSize = QSize(width, height);
860 m_lastAckedConfigure = UINT32_MAX;
863void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_minimum_size(Resource *resource, int32_t width, int32_t height)
866 Q_Q(QWaylandQtShellSurface);
867 m_minimumSize = QSize{width, height};
868 emit q->minimumSizeChanged();
871void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_maximum_size(Resource *resource, int32_t width, int32_t height)
874 Q_Q(QWaylandQtShellSurface);
875 m_maximumSize = QSize{width, height};
876 emit q->maximumSizeChanged();
879void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_destroy_resource(QtWaylandServer::zqt_shell_surface_v1::Resource *resource)
882 Q_Q(QWaylandQtShellSurface);
883 QWaylandQtShellPrivate::get(m_qtShell)->unregisterQtShellSurface(q);
887void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_destroy(QtWaylandServer::zqt_shell_surface_v1::Resource *resource)
889 wl_resource_destroy(resource->handle);
892void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_window_flags(Resource *resource, uint32_t flags)
895 Q_Q(QWaylandQtShellSurface);
896 m_windowFlags = flags;
897 emit q->windowFlagsChanged();
900void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_change_window_state(Resource *resource, uint32_t state)
903 Q_Q(QWaylandQtShellSurface);
904 uint oldWindowState = m_windowState;
905 m_windowState = state & ~Qt::WindowActive;
907 if (oldWindowState != m_windowState)
908 emit q->windowStateChanged();
911void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_start_system_resize(Resource *resource, uint32_t serial, uint32_t edge)
915 Q_Q(QWaylandQtShellSurface);
916 emit q->startResize(Qt::Edges(edge));
919void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_start_system_move(Resource *resource, uint32_t serial)
923 Q_Q(QWaylandQtShellSurface);
927void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_set_window_title(Resource *resource,
928 const QString &title)
931 Q_Q(QWaylandQtShellSurface);
932 m_windowTitle = title;
933 emit q->windowTitleChanged();
936void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_request_activate(Resource *resource)
940 Q_Q(QWaylandQtShellSurface);
944 auto view = m_surface->primaryView();
945 auto item = view ? qobject_cast<QWaylandQuickItem *>(view->renderObject()) :
nullptr;
947 item->forceActiveFocus();
951void QWaylandQtShellSurfacePrivate::updateFrameMargins()
953 send_set_frame_margins(m_frameMargins.left(), m_frameMargins.right(),
954 m_frameMargins.top(), m_frameMargins.bottom());
958void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_raise(Resource *resource)
961 Q_Q(QWaylandQtShellSurface);
962 emit q->raiseRequested();
965void QWaylandQtShellSurfacePrivate::zqt_shell_surface_v1_lower(Resource *resource)
968 Q_Q(QWaylandQtShellSurface);
969 emit q->lowerRequested();
974#include "moc_qwaylandqtshell_p.cpp"