22#include <QtCore/QFileInfo>
23#include <QtCore/QPointer>
24#include <QtCore/QRegularExpression>
25#include <QtGui/QWindow>
27#include <QGuiApplication>
28#include <qpa/qwindowsysteminterface.h>
29#include <QtGui/private/qwindow_p.h>
31#include <QtCore/QDebug>
32#include <QtCore/QThread>
33#include <QtCore/private/qthread_p.h>
35#include <QtWaylandClient/private/qwayland-fractional-scale-v1.h>
43QWaylandWindow *QWaylandWindow::mMouseGrab =
nullptr;
49 , mShellIntegration(
display->shellIntegration())
56 mFrameCallbackTimeout = frameCallbackTimeout;
59 mScale = waylandScreen() ? waylandScreen()->scale() : 1;
63 initializeWlSurface();
66 &QNativeInterface::Private::QWaylandWindow::surfaceCreated);
68 &QNativeInterface::Private::QWaylandWindow::surfaceDestroyed);
81 if (
w->transientParent() ==
parent)
85 if (mMouseGrab ==
this) {
96void QWaylandWindow::initWindow()
102 initializeWlSurface();
109 if (
mScale != preferredScale) {
115 qreal preferredScale = std::max(1.0, mFractionalScale->preferredScale());
116 if (mScale == preferredScale) {
126 window()->requestUpdate();
132 if (shouldCreateSubSurface()) {
137 parent->initializeWlSurface();
138 if (
parent->wlSurface()) {
139 if (::wl_subsurface *subsurface = mDisplay->createSubSurface(
this,
parent))
140 mSubSurfaceWindow =
new QWaylandSubSurface(
this,
parent, subsurface);
142 }
else if (shouldCreateShellSurface()) {
145 mTransientParent = closestTransientParent();
147 mShellSurface = mShellIntegration->createShellSurface(
this);
149 if (mTransientParent) {
151 mTransientParent->addChildPopup(
this);
173 if (domainName.isEmpty()) {
177 for (
int i = 0;
i < domainName.size(); ++
i)
180 mShellSurface->setAppId(appId);
185 mShellSurface->sendProperty(
it.key(),
it.value());
187 qWarning(
"Could not create a shell surface object.");
192 mViewport.reset(
new QWaylandViewport(
display()->createViewport(
this)));
200 else if (mSurface->version() >= 3)
201 mSurface->set_buffer_scale(std::ceil(
scale()));
204 QRect geometry = windowGeometry();
205 QRect defaultGeometry = this->defaultGeometry();
206 if (geometry.
width() <= 0)
208 if (geometry.
height() <= 0)
211 setGeometry_helper(geometry);
214 mShellSurface->requestWindowStates(
window()->windowStates());
215 handleContentOrientationChange(
window()->contentOrientation());
216 mFlags =
window()->flags();
219void QWaylandWindow::initializeWlSurface()
225 connect(mSurface.data(), &QWaylandSurface::screensChanged,
226 this, &QWaylandWindow::handleScreensChanged);
227 mSurface->m_window =
this;
229 emit wlSurfaceCreated();
236 qCWarning(lcQpaWayland) <<
"Cannot set shell integration while there's already a shell surface created";
239 mShellIntegration = shellIntegration;
242bool QWaylandWindow::shouldCreateShellSurface()
const
244 if (!shellIntegration())
247 if (shouldCreateSubSurface())
259bool QWaylandWindow::shouldCreateSubSurface()
const
264void QWaylandWindow::beginFrame()
266 mSurfaceLock.lockForRead();
269void QWaylandWindow::endFrame()
271 mSurfaceLock.unlock();
274void QWaylandWindow::reset()
279 emit wlSurfaceDestroyed();
282 if (mTransientParent)
283 mTransientParent->removeChildPopup(
this);
284 delete mShellSurface;
285 mShellSurface =
nullptr;
286 delete mSubSurfaceWindow;
287 mSubSurfaceWindow =
nullptr;
288 mTransientParent =
nullptr;
291 mFractionalScale.reset();
296 if (mFrameCallback) {
297 wl_callback_destroy(mFrameCallback);
298 mFrameCallback =
nullptr;
301 mFrameCallbackElapsedTimer.invalidate();
302 mWaitingForFrameCallback =
false;
304 if (mFrameCallbackCheckIntervalTimerId != -1) {
305 killTimer(mFrameCallbackCheckIntervalTimerId);
306 mFrameCallbackCheckIntervalTimerId = -1;
309 mFrameCallbackTimedOut =
false;
310 mWaitingToApplyConfigure =
false;
312 mResizeDirty =
false;
317 mQueuedBuffer =
nullptr;
318 mQueuedBufferDamage =
QRegion();
320 mDisplay->handleWindowDestroyed(
this);
325 if (
auto *
s = QWaylandSurface::fromWlSurface(surface))
330WId QWaylandWindow::winId()
const
344 if (mSubSurfaceWindow &&
parent) {
345 delete mSubSurfaceWindow;
358 const QString formatted = formatWindowTitle(
title, separator);
360 const int libwaylandMaxBufferSize = 4096;
364 const int maxLength = libwaylandMaxBufferSize / 3 - 100;
367 if (truncated.size() < formatted.
size()) {
368 qCWarning(lcQpaWayland) <<
"Window titles longer than" <<
maxLength <<
"characters are not supported."
369 <<
"Truncating window title (from" << formatted.
size() <<
"chars)";
371 mShellSurface->setTitle(truncated.toString());
375 mWindowDecoration->update();
383 mWindowDecoration->update();
386QRect QWaylandWindow::defaultGeometry()
const
391void QWaylandWindow::setGeometry_helper(
const QRect &
rect)
393 QSize minimum = windowMinimumSize();
394 QSize maximum = windowMaximumSize();
395 int width = windowGeometry().width();
396 int height = windowGeometry().height();
397 if (minimum.width() <= maximum.width()
398 && minimum.height() <= maximum.height()) {
407 if (mSubSurfaceWindow) {
409 mSubSurfaceWindow->set_position(
rect.x() +
m.left(),
rect.y() +
m.top());
411 QWaylandWindow *parentWindow = mSubSurfaceWindow->parent();
412 if (parentWindow && parentWindow->isExposed()) {
413 QRect parentExposeGeometry(
QPoint(), parentWindow->geometry().size());
414 parentWindow->sendExposeEvent(parentExposeGeometry);
419void QWaylandWindow::setGeometry(
const QRect &
r)
426 setGeometry_helper(
rect);
429 if (mWindowDecorationEnabled)
430 mWindowDecoration->update();
432 if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) {
438 mSentInitialResize =
true;
441 if (isExposed() && !mInResizeFromApplyConfigure && exposeGeometry != mLastExposeGeometry)
442 sendExposeEvent(exposeGeometry);
444 if (mShellSurface && isExposed()) {
445 mShellSurface->setWindowGeometry(windowContentGeometry());
447 mShellSurface->setWindowPosition(windowGeometry().topLeft());
450 if (isOpaque() && mMask.isEmpty())
454void QWaylandWindow::updateViewport()
456 if (!surfaceSize().isEmpty())
457 mViewport->setDestination(surfaceSize());
460void QWaylandWindow::setGeometryFromApplyConfigure(
const QPoint &globalPosition,
const QSize &sizeWithMargins)
462 QMargins margins = clientSideMargins();
465 int widthWithoutMargins =
qMax(sizeWithMargins.
width() - (margins.
left() + margins.
right()), 1);
466 int heightWithoutMargins =
qMax(sizeWithMargins.
height() - (margins.
top() + margins.
bottom()), 1);
468 QRect geometry(positionWithoutMargins,
QSize(widthWithoutMargins, heightWithoutMargins));
470 mInResizeFromApplyConfigure =
true;
471 setGeometry(geometry);
472 mInResizeFromApplyConfigure =
false;
475void QWaylandWindow::repositionFromApplyConfigure(
const QPoint &globalPosition)
477 QMargins margins = clientSideMargins();
480 QRect geometry(positionWithoutMargins, windowGeometry().
size());
481 mInResizeFromApplyConfigure =
true;
482 setGeometry(geometry);
483 mInResizeFromApplyConfigure =
false;
486void QWaylandWindow::resizeFromApplyConfigure(
const QSize &sizeWithMargins,
const QPoint &
offset)
488 QMargins margins = clientSideMargins();
489 int widthWithoutMargins =
qMax(sizeWithMargins.
width() - (margins.
left() + margins.
right()), 1);
490 int heightWithoutMargins =
qMax(sizeWithMargins.
height() - (margins.
top() + margins.
bottom()), 1);
491 QRect geometry(windowGeometry().topLeft(),
QSize(widthWithoutMargins, heightWithoutMargins));
494 mInResizeFromApplyConfigure =
true;
495 setGeometry(geometry);
496 mInResizeFromApplyConfigure =
false;
501 if (!(mShellSurface && mShellSurface->handleExpose(
rect)))
504 qCDebug(lcQpaWayland) <<
"sendExposeEvent: intercepted by shell extension, not sending";
505 mLastExposeGeometry =
rect;
508QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents()
const
512 if (
auto *
screen = mSurface->oldestEnteredScreen())
519void QWaylandWindow::setVisible(
bool visible)
522 if (lastVisible == visible)
524 lastVisible = visible;
529 setGeometry(windowGeometry());
534 sendExposeEvent(
QRect());
540void QWaylandWindow::raise()
543 mShellSurface->raise();
547void QWaylandWindow::lower()
550 mShellSurface->lower();
564 if (mMask.isEmpty()) {
565 mSurface->set_input_region(
nullptr);
570 struct ::wl_region *region = mDisplay->createRegion(mMask);
571 mSurface->set_input_region(region);
572 wl_region_destroy(region);
575 setOpaqueArea(mMask);
581void QWaylandWindow::setAlertState(
bool enabled)
584 mShellSurface->setAlertState(
enabled);
587bool QWaylandWindow::isAlertState()
const
590 return mShellSurface->isAlertState();
595void QWaylandWindow::applyConfigureWhenPossible()
598 if (!mWaitingToApplyConfigure) {
599 mWaitingToApplyConfigure =
true;
604void QWaylandWindow::doApplyConfigure()
606 if (!mWaitingToApplyConfigure)
610 "QWaylandWindow::doApplyConfigure",
"not called from main thread");
613 mShellSurface->applyConfigure();
615 mWaitingToApplyConfigure =
false;
618void QWaylandWindow::doApplyConfigureFromOtherThread()
621 if (!mCanResize || !mWaitingToApplyConfigure)
627void QWaylandWindow::setCanResize(
bool canResize)
630 mCanResize = canResize;
636 if (mWaitingToApplyConfigure) {
644 }
else if (mResizeDirty) {
645 mResizeDirty =
false;
651void QWaylandWindow::applyConfigure()
655 if (mCanResize || !mSentInitialResize)
659 sendRecursiveExposeEvent();
663void QWaylandWindow::sendRecursiveExposeEvent()
670 auto subWindow = subSurface->window();
671 subWindow->sendRecursiveExposeEvent();
678 if (mSurface ==
nullptr)
686 mSurface->attach(
buffer->buffer(),
x,
y);
688 mSurface->attach(
nullptr, 0, 0);
694 attach(
buffer, mOffset.x(), mOffset.y());
701 if (mSurface ==
nullptr)
705 if (mSurface->version() >= 4)
717 mQueuedBufferDamage = damage;
721void QWaylandWindow::handleExpose(
const QRegion ®ion)
725 commit(mQueuedBuffer, mQueuedBufferDamage);
726 mQueuedBuffer =
nullptr;
727 mQueuedBufferDamage =
QRegion();
734 if (
buffer->committed()) {
735 qCDebug(lcWaylandBackingstore) <<
"Buffer already committed, ignoring.";
744 if (mSurface->version() >= 4) {
757void QWaylandWindow::commit()
760 if (mSurface !=
nullptr)
764const wl_callback_listener QWaylandWindow::callbackListener = {
765 [](
void *
data, wl_callback *callback, uint32_t
time) {
768 window->handleFrameCallback(callback);
772void QWaylandWindow::handleFrameCallback(wl_callback* callback)
775 if (!mFrameCallback) {
780 Q_ASSERT(callback == mFrameCallback);
781 wl_callback_destroy(callback);
782 mFrameCallback =
nullptr;
784 mWaitingForFrameCallback =
false;
785 mFrameCallbackElapsedTimer.invalidate();
788 if (mWaitingForUpdateDelivery.testAndSetAcquire(
false,
true)) {
793 mFrameSyncWait.notify_all();
796void QWaylandWindow::doHandleFrameCallback()
798 mWaitingForUpdateDelivery.storeRelease(
false);
799 bool wasExposed = isExposed();
800 mFrameCallbackTimedOut =
false;
801 if (!wasExposed && isExposed())
803 if (wasExposed && hasPendingUpdateRequest())
804 deliverUpdateRequest();
808bool QWaylandWindow::waitForFrameSync(
int timeout)
813 while (mWaitingForFrameCallback && mFrameSyncWait.wait(&mFrameSyncMutex,
deadline)) { }
815 if (mWaitingForFrameCallback) {
816 qCDebug(lcWaylandBackingstore) <<
"Didn't receive frame callback in time, window should now be inexposed";
817 mFrameCallbackTimedOut =
true;
818 mWaitingForUpdate =
false;
819 sendExposeEvent(
QRect());
822 return !mWaitingForFrameCallback;
827 if (mWindowDecorationEnabled)
828 return mWindowDecoration->margins();
829 else if (mShellSurface)
830 return mShellSurface->serverSideFrameMargins();
837 return mWindowDecorationEnabled ? mWindowDecoration->margins() :
QMargins{};
840void QWaylandWindow::setCustomMargins(
const QMargins &margins) {
841 const QMargins oldMargins = mCustomMargins;
842 mCustomMargins = margins;
843 setGeometry(geometry().marginsRemoved(oldMargins).marginsAdded(margins));
849QSize QWaylandWindow::surfaceSize()
const
854QMargins QWaylandWindow::windowContentMargins()
const
858 if (mWindowDecorationEnabled)
859 shadowMargins = mWindowDecoration->margins(QWaylandAbstractDecoration::ShadowsOnly);
861 if (!mCustomMargins.isNull())
862 shadowMargins += mCustomMargins;
864 return shadowMargins;
871QRect QWaylandWindow::windowContentGeometry()
const
873 const QMargins margins = windowContentMargins();
886 const QMargins margins = clientSideMargins();
887 return QPointF(surfacePosition.
x() - margins.
left(), surfacePosition.
y() - margins.
top());
890wl_surface *QWaylandWindow::wlSurface()
893 return mSurface ? mSurface->object() :
nullptr;
898 return mShellSurface;
901std::any QWaylandWindow::_surfaceRole()
const
903 if (mSubSurfaceWindow)
904 return mSubSurfaceWindow->object();
912 return mSubSurfaceWindow;
919 if (platformScreen->isPlaceholder())
927 if (mSurface ==
nullptr || mSurface->version() < 2)
932 switch (orientation) {
937 transform = isPortrait ? WL_OUTPUT_TRANSFORM_270 : WL_OUTPUT_TRANSFORM_NORMAL;
940 transform = isPortrait ? WL_OUTPUT_TRANSFORM_NORMAL : WL_OUTPUT_TRANSFORM_90;
943 transform = isPortrait ? WL_OUTPUT_TRANSFORM_90 : WL_OUTPUT_TRANSFORM_180;
946 transform = isPortrait ? WL_OUTPUT_TRANSFORM_180 : WL_OUTPUT_TRANSFORM_270;
951 mSurface->set_buffer_transform(
transform);
956void QWaylandWindow::setOrientationMask(Qt::ScreenOrientations
mask)
959 mShellSurface->setContentOrientationMask(
mask);
962void QWaylandWindow::setWindowState(Qt::WindowStates
states)
965 mShellSurface->requestWindowStates(
states);
968void QWaylandWindow::setWindowFlags(Qt::WindowFlags
flags)
971 mShellSurface->setWindowFlags(
flags);
977bool QWaylandWindow::createDecoration()
979 if (!mDisplay->supportsWindowDecoration())
982 static bool decorationPluginFailed =
false;
999 if (mSubSurfaceWindow)
1001 if (!mShellSurface || !mShellSurface->wantsDecorations())
1004 bool hadDecoration = mWindowDecorationEnabled;
1006 if (!mWindowDecorationEnabled) {
1007 if (mWindowDecoration) {
1008 delete mWindowDecoration;
1009 mWindowDecoration =
nullptr;
1012 QStringList decorations = QWaylandDecorationFactory::keys();
1013 if (decorations.empty()) {
1014 qWarning() <<
"No decoration plugins available. Running with no decorations.";
1015 decorationPluginFailed =
true;
1021 if (!decorationPluginName.
isEmpty()) {
1023 if (!decorations.contains(targetKey)) {
1024 qWarning() <<
"Requested decoration " << targetKey <<
" not found, falling back to default";
1030 targetKey = decorations.first();
1033 mWindowDecoration = QWaylandDecorationFactory::create(targetKey,
QStringList());
1034 if (!mWindowDecoration) {
1035 qWarning() <<
"Could not create decoration from factory! Running with no decorations.";
1036 decorationPluginFailed =
true;
1039 mWindowDecoration->setWaylandWindow(
this);
1040 mWindowDecorationEnabled =
true;
1043 mWindowDecorationEnabled =
false;
1046 if (hadDecoration != mWindowDecorationEnabled) {
1048 QPoint pos = subsurf->window()->geometry().topLeft();
1050 subsurf->set_position(
pos.x() +
m.left(),
pos.y() +
m.top());
1052 setGeometry(geometry());
1066 return mWindowDecoration;
1071 return mWindowDecorationEnabled ? mWindowDecoration :
nullptr;
1078 if (
w &&
w->shellSurface())
1087 return mTransientParent;
1096 return transientParent;
1107 if (mWindowDecorationEnabled) {
1108 if (mMouseEventsInContentArea)
1113#if QT_CONFIG(cursor)
1114 restoreMouseCursor(inputDevice);
1119 if (mWindowDecorationEnabled) {
1120 handleMouseEventWithDecoration(inputDevice,
e);
1133 e.pixelDelta,
e.angleDelta,
e.modifiers,
1134 e.phase,
e.source,
false);
1141#if QT_CONFIG(cursor)
1144 if (contentGeometry.
contains(
e.local.toPoint()))
1145 restoreMouseCursor(inputDevice);
1150#ifndef QT_NO_GESTURES
1156 if (mGestureState != GestureNotActive)
1157 qCWarning(lcQpaWaylandInput) <<
"Unexpected GestureStarted while already active";
1159 if (mWindowDecorationEnabled && !mMouseEventsInContentArea) {
1161 mGestureState = GestureActiveInDecoration;
1165 mGestureState = GestureActiveInContentArea;
1169 e.local,
e.global,
e.fingers);
1172 if (mGestureState != GestureActiveInContentArea)
1175 if (!
e.delta.isNull()) {
1179 0,
e.delta,
e.local,
e.global,
e.fingers);
1184 if (mGestureState == GestureActiveInDecoration) {
1185 mGestureState = GestureNotActive;
1189 if (mGestureState != GestureActiveInContentArea)
1192 mGestureState = GestureNotActive;
1199 e.local,
e.global,
e.fingers);
1211 if (mGestureState != GestureNotActive)
1212 qCWarning(lcQpaWaylandInput) <<
"Unexpected GestureStarted while already active";
1214 if (mWindowDecorationEnabled && !mMouseEventsInContentArea) {
1216 mGestureState = GestureActiveInDecoration;
1220 mGestureState = GestureActiveInContentArea;
1224 e.local,
e.global,
e.fingers);
1227 if (mGestureState != GestureActiveInContentArea)
1230 if (!
e.delta.isNull()) {
1234 0,
e.delta,
e.local,
e.global,
e.fingers);
1236 if (
e.rotation_delta != 0) {
1241 e.local,
e.global,
e.fingers);
1243 if (
e.scale_delta != 0) {
1248 e.local,
e.global,
e.fingers);
1253 if (mGestureState == GestureActiveInDecoration) {
1254 mGestureState = GestureNotActive;
1258 if (mGestureState != GestureActiveInContentArea)
1261 mGestureState = GestureNotActive;
1268 e.local,
e.global,
e.fingers);
1279 if (!mWindowDecorationEnabled)
1281 return mWindowDecoration->handleTouch(inputDevice, local,
global,
state, mods);
1287 mWindowDecoration->handleMouse(inputDevice,
e.local,
e.global,
e.buttons,
e.modifiers)) {
1288 if (mMouseEventsInContentArea) {
1290 mMouseEventsInContentArea =
false;
1300 if (windowRect.contains(
e.local.toPoint()) || mMousePressedInContentArea !=
Qt::NoButton) {
1301 const QPointF localTranslated = mapFromWlSurface(
e.local);
1302 QPointF globalTranslated =
e.global;
1303 globalTranslated.
setX(globalTranslated.
x() - marg.
left());
1304 globalTranslated.
setY(globalTranslated.
y() - marg.
top());
1305 if (!mMouseEventsInContentArea) {
1306#if QT_CONFIG(cursor)
1307 restoreMouseCursor(inputDevice);
1323 localTranslated, globalTranslated,
1324 e.pixelDelta,
e.angleDelta,
e.modifiers,
1325 e.phase,
e.source,
false);
1332 mMouseEventsInContentArea =
true;
1333 mMousePressedInContentArea =
e.buttons;
1335 if (mMouseEventsInContentArea) {
1337 mMouseEventsInContentArea =
false;
1342void QWaylandWindow::handleScreensChanged()
1346 if (newScreen == mLastReportedScreen)
1349 if (!newScreen->
isPlaceholder() && !newScreen->QPlatformScreen::screen())
1350 mDisplay->forceRoundTrip();
1353 mLastReportedScreen = newScreen;
1357 auto geometry = this->geometry();
1359 setGeometry(geometry);
1362 if (mFractionalScale)
1365 int scale = mLastReportedScreen->isPlaceholder() ? 1 :
static_cast<QWaylandScreen *
>(mLastReportedScreen)->
scale();
1367 if (
scale != mScale) {
1373 else if (mSurface->version() >= 3)
1374 mSurface->set_buffer_scale(std::ceil(mScale));
1380#if QT_CONFIG(cursor)
1383 int fallbackBufferScale = int(devicePixelRatio());
1387void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *
device)
1390 setMouseCursor(
device, *overrideCursor);
1396void QWaylandWindow::requestActivateWindow()
1399 mShellSurface->requestActivate();
1402bool QWaylandWindow::isExposed()
const
1407 if (mFrameCallbackTimedOut)
1411 return mShellSurface->isExposed();
1413 if (mSubSurfaceWindow)
1414 return mSubSurfaceWindow->parent()->isExposed();
1416 return !(shouldCreateShellSurface() || shouldCreateSubSurface());
1419bool QWaylandWindow::isActive()
const
1421 return mDisplay->isWindowActivated(
this);
1426 return devicePixelRatio();
1429qreal QWaylandWindow::devicePixelRatio()
const
1431 return qreal(mScale);
1434bool QWaylandWindow::setMouseGrabEnabled(
bool grab)
1437 qWarning(
"This plugin supports grabbing the mouse only for popup windows");
1441 mMouseGrab = grab ?
this :
nullptr;
1445QWaylandWindow::ToplevelWindowTilingStates QWaylandWindow::toplevelWindowTilingStates()
const
1447 return mLastReportedToplevelWindowTilingStates;
1450void QWaylandWindow::handleToplevelWindowTilingStatesChanged(ToplevelWindowTilingStates
states)
1452 mLastReportedToplevelWindowTilingStates =
states;
1455Qt::WindowStates QWaylandWindow::windowStates()
const
1457 return mLastReportedWindowStates;
1460void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates
states)
1463 Qt::WindowStates statesWithoutActive =
states &
~Qt::WindowActive;
1464 Qt::WindowStates lastStatesWithoutActive = mLastReportedWindowStates &
~Qt::WindowActive;
1466 lastStatesWithoutActive);
1467 mLastReportedWindowStates =
states;
1477 mShellSurface->sendProperty(
name,
value);
1490 return m_properties;
1500 return m_properties.
value(
name, defaultValue);
1505 if (
event->timerId() != mFrameCallbackCheckIntervalTimerId)
1511 bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout);
1512 if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) {
1513 killTimer(mFrameCallbackCheckIntervalTimerId);
1514 mFrameCallbackCheckIntervalTimerId = -1;
1516 if (!mFrameCallbackElapsedTimer.isValid() || !callbackTimerExpired) {
1519 mFrameCallbackElapsedTimer.invalidate();
1522 qCDebug(lcWaylandBackingstore) <<
"Didn't receive frame callback in time, window should now be inexposed";
1523 mFrameCallbackTimedOut =
true;
1524 mWaitingForUpdate =
false;
1525 sendExposeEvent(
QRect());
1528void QWaylandWindow::requestUpdate()
1530 qCDebug(lcWaylandBackingstore) <<
"requestUpdate";
1531 Q_ASSERT(hasPendingUpdateRequest());
1536 if (mWaitingForFrameCallback)
1544 if (mWaitingForUpdate)
1545 qCDebug(lcWaylandBackingstore) <<
"requestUpdate called twice without committing anything";
1553 if (mWaitingForFrameCallback)
1556 if (hasPendingUpdateRequest())
1557 deliverUpdateRequest();
1564void QWaylandWindow::handleUpdate()
1574 if (mWaitingForFrameCallback)
1577 struct ::wl_surface *wrappedSurface =
reinterpret_cast<struct ::wl_surface *
>(wl_proxy_create_wrapper(mSurface->object()));
1578 wl_proxy_set_queue(
reinterpret_cast<wl_proxy *
>(wrappedSurface), mDisplay->frameEventQueue());
1579 mFrameCallback = wl_surface_frame(wrappedSurface);
1580 wl_proxy_wrapper_destroy(wrappedSurface);
1581 wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener,
this);
1582 mWaitingForFrameCallback =
true;
1583 mWaitingForUpdate =
false;
1586 if (mFrameCallbackTimeout > 0) {
1590 if (mWaitingForFrameCallback) {
1591 if (mFrameCallbackCheckIntervalTimerId < 0)
1592 mFrameCallbackCheckIntervalTimerId = startTimer(mFrameCallbackTimeout);
1593 mFrameCallbackElapsedTimer.start();
1599void QWaylandWindow::deliverUpdateRequest()
1601 qCDebug(lcWaylandBackingstore) <<
"deliverUpdateRequest";
1602 mWaitingForUpdate =
true;
1606void QWaylandWindow::addAttachOffset(
const QPoint point)
1611void QWaylandWindow::propagateSizeHints()
1614 mShellSurface->propagateSizeHints();
1617bool QWaylandWindow::startSystemResize(Qt::Edges edges)
1619 if (
auto *seat =
display()->lastInputDevice())
1620 return mShellSurface && mShellSurface->resize(seat, edges);
1626 if (
auto seat =
display()->lastInputDevice())
1631bool QWaylandWindow::isOpaque()
const
1636void QWaylandWindow::setOpaqueArea(
const QRegion &opaqueArea)
1646 mSurface->set_opaque_region(region);
1647 wl_region_destroy(region);
1667void QWaylandWindow::removeChildPopup(QWaylandWindow *
child)
1694#include "moc_qwaylandwindow_p.cpp"
IOBluetoothDevice * device
Type loadRelaxed() const noexcept
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
QString organizationDomain
the Internet domain of the organization that wrote this application
The QCursor class provides a mouse cursor with an arbitrary shape.
State
Specifies the state of this event point.
\inmodule QtCore \reentrant
QString baseName() const
Returns the base name of the file without the path.
static QPlatformNativeInterface * platformNativeInterface()
static QWindowList topLevelWindows()
Returns a list of the top-level windows in the application.
static QCursor * overrideCursor()
Returns the active application override cursor.
static QWindow * focusWindow()
Returns the QWindow that receives events tied to focus, such as key events.
QString desktopFileName
the base name of the desktop entry for this application
The QIcon class provides scalable icons in different modes and states.
constexpr int bottom() const noexcept
Returns the bottom margin.
constexpr int left() const noexcept
Returns the left margin.
constexpr int right() const noexcept
Returns the right margin.
constexpr int top() const noexcept
Returns the top margin.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
constexpr void setY(qreal y) noexcept
Sets the y coordinate of this point to the given finite y coordinate.
constexpr void setX(qreal x) noexcept
Sets the x coordinate of this point to the given finite x coordinate.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr QRect marginsAdded(const QMargins &margins) const noexcept
Returns a rectangle grown by the margins.
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr QRect marginsRemoved(const QMargins &margins) const noexcept
Removes the margins from the rectangle, shrinking it.
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr void setWidth(int w) noexcept
Sets the width of the rectangle to the given width.
constexpr QSize size() const noexcept
Returns the size of the rectangle.
constexpr int width() const noexcept
Returns the width of the rectangle.
constexpr void setHeight(int h) noexcept
Sets the height of the rectangle to the given height.
constexpr void moveTo(int x, int t) noexcept
Moves the rectangle, leaving the top-left corner at the given position (x, y).
The QRegion class specifies a clip region for a painter.
QRegion translated(int dx, int dy) const
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
qsizetype size() const
Returns the number of characters in this string.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QString & append(QChar c)
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
QString & prepend(QChar c)
QAtomicPointer< void > threadId
static QThreadData * get2(QThread *thread)
static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION
static QThread * currentThread()
\qmltype WaylandSurface \instantiates QWaylandSurface \inqmlmodule QtWayland.Compositor
static bool flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
Make Qt Gui process all events on the event queue immediately.
static bool handleGestureEventWithValueAndDelta(QWindow *window, ulong timestamp, const QPointingDevice *device, Qt::NativeGestureType type, qreal value, const QPointF &delta, const QPointF &local, const QPointF &global, int fingerCount=2)
static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen)
static void handleLeaveEvent(QWindow *window)
static bool handleGestureEventWithRealValue(QWindow *window, ulong timestamp, const QPointingDevice *device, Qt::NativeGestureType type, qreal value, const QPointF &local, const QPointF &global, int fingerCount=2)
static bool handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons state, Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
static bool handleCloseEvent(QWindow *window)
static void handleGeometryChange(QWindow *window, const QRect &newRect)
static void handleWindowDevicePixelRatioChanged(QWindow *window)
static bool handleExposeEvent(QWindow *window, const QRegion ®ion)
static bool handleGestureEvent(QWindow *window, ulong timestamp, const QPointingDevice *device, Qt::NativeGestureType type, const QPointF &local, const QPointF &global, int fingerCount=0)
static void handleEnterEvent(QWindow *window, const QPointF &local=QPointF(), const QPointF &global=QPointF())
static bool handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::ScrollPhase phase=Qt::NoScrollPhase, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
static void handleWindowStateChanged(QWindow *window, Qt::WindowStates newState, int oldState=-1)
struct::wl_region * createRegion(const QRegion &qregion)
QtWayland::wp_fractional_scale_manager_v1 * fractionalScaleManager() const
void preferredScaleChanged()
void emitWindowPropertyChanged(QPlatformWindow *window, const QString &name)
virtual void requestXdgActivationToken(quint32 serial)
virtual bool move(QWaylandInputDevice *)
virtual void detachPopup(QWaylandShellSurface *popup)
virtual void attachPopup(QWaylandShellSurface *popup)
virtual void setXdgActivationToken(const QString &token)
virtual std::any surfaceRole() const
virtual void ensureSize()
void wlSurfaceDestroyed()
QWaylandAbstractDecoration * mWindowDecoration
QMargins clientSideMargins() const
QScopedPointer< QWaylandViewport > mViewport
QWaylandDisplay * mDisplay
~QWaylandWindow() override
QWaylandShmBackingStore * mBackingStore
void setXdgActivationToken(const QString &token)
QList< QPointer< QWaylandWindow > > mChildPopups
QScopedPointer< QWaylandSurface > mSurface
QWaylandDisplay * display() const
void requestXdgActivationToken(uint serial) override
QScopedPointer< QWaylandFractionalScale > mFractionalScale
bool isExposed() const override
Returns if this window is exposed in the windowing system.
void deliverUpdateRequest() override
Delivers an QEvent::UpdateRequest event to the window.
void sendExposeEvent(const QRect &rect)
QWaylandShellSurface * mShellSurface
bool startSystemMove() override
Reimplement this method to start a system move operation if the system supports it and return true to...
QSet< QString >::iterator it
struct wl_display * display
Combined button and popup list for selecting options.
static QWaylandWindow * closestShellSurfaceWindow(QWindow *window)
@ InvertedLandscapeOrientation
@ InvertedPortraitOrientation
@ BypassWindowManagerHint
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble top
GLint GLint GLint GLint GLsizei GLsizei GLsizei GLboolean commit
GLbitfield GLuint64 timeout
[4]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLuint GLenum GLenum transform
GLenum GLenum GLenum GLenum GLenum scale
#define Q_ASSERT_X(cond, x, msg)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
Q_GUI_EXPORT QWindowPrivate * qt_window_private(QWindow *window)
QFileInfo fi("c:/temp/foo")
[newstuff]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
QDeadlineTimer deadline(30s)
\inmodule QtCore \reentrant
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent