client: Move wayland globals into a holding struct

This way all globals get automatically reset by reassigning a default
constructed value to the holder. This way a newly added global will not
be missed in the future.

Change-Id: Id3a62e30427cec9980ea076366e30b419ce1c2c6
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
David Redondo 2023-06-06 16:07:56 +02:00
parent 9a8033ba5a
commit 5abc59af2a
2 changed files with 166 additions and 113 deletions

View File

@ -279,7 +279,7 @@ struct ::wl_region *QWaylandDisplay::createRegion(const QRegion &qregion)
::wl_subsurface *QWaylandDisplay::createSubSurface(QWaylandWindow *window, QWaylandWindow *parent) ::wl_subsurface *QWaylandDisplay::createSubSurface(QWaylandWindow *window, QWaylandWindow *parent)
{ {
if (!mSubCompositor) { if (!mGlobals.subCompositor) {
qCWarning(lcQpaWayland) << "Can't create subsurface, not supported by the compositor."; qCWarning(lcQpaWayland) << "Can't create subsurface, not supported by the compositor.";
return nullptr; return nullptr;
} }
@ -288,18 +288,18 @@ struct ::wl_region *QWaylandDisplay::createRegion(const QRegion &qregion)
Q_ASSERT(parent->wlSurface()); Q_ASSERT(parent->wlSurface());
Q_ASSERT(window->wlSurface()); Q_ASSERT(window->wlSurface());
return mSubCompositor->get_subsurface(window->wlSurface(), parent->wlSurface()); return mGlobals.subCompositor->get_subsurface(window->wlSurface(), parent->wlSurface());
} }
::wp_viewport *QWaylandDisplay::createViewport(QWaylandWindow *window) ::wp_viewport *QWaylandDisplay::createViewport(QWaylandWindow *window)
{ {
if (!mViewporter) { if (!mGlobals.viewporter) {
qCWarning(lcQpaWayland) << "Can't create wp_viewport, not supported by the compositor."; qCWarning(lcQpaWayland) << "Can't create wp_viewport, not supported by the compositor.";
return nullptr; return nullptr;
} }
Q_ASSERT(window->wlSurface()); Q_ASSERT(window->wlSurface());
return mViewporter->get_viewport(window->wlSurface()); return mGlobals.viewporter->get_viewport(window->wlSurface());
} }
QWaylandShellIntegration *QWaylandDisplay::shellIntegration() const QWaylandShellIntegration *QWaylandDisplay::shellIntegration() const
@ -366,9 +366,6 @@ QWaylandDisplay::~QWaylandDisplay(void)
} }
qDeleteAll(mWaitingScreens); qDeleteAll(mWaitingScreens);
#if QT_CONFIG(wayland_datadevice)
mDndSelectionHandler.reset();
#endif
#if QT_CONFIG(cursor) #if QT_CONFIG(cursor)
mCursorThemes.clear(); mCursorThemes.clear();
#endif #endif
@ -376,6 +373,8 @@ QWaylandDisplay::~QWaylandDisplay(void)
if (m_frameEventQueue) if (m_frameEventQueue)
wl_event_queue_destroy(m_frameEventQueue); wl_event_queue_destroy(m_frameEventQueue);
mGlobals = {};
if (mDisplay) if (mDisplay)
wl_display_disconnect(mDisplay); wl_display_disconnect(mDisplay);
} }
@ -432,37 +431,18 @@ void QWaylandDisplay::reconnect()
mShm.reset(); mShm.reset();
mCursorThemes.clear(); mCursorThemes.clear();
mCursor.reset(); mCursor.reset();
mDndSelectionHandler.reset();
mWindowExtension.reset(); mGlobals = GlobalHolder();
mSubCompositor.reset();
mTouchExtension.reset();
mQtKeyExtension.reset();
mWindowManagerIntegration.reset();
mTabletManager.reset();
mPointerGestures.reset();
#if QT_CONFIG(wayland_client_primary_selection)
mPrimarySelectionManager.reset();
#endif
mTextInputMethodManager.reset();
mTextInputManagerv1.reset();
mTextInputManagerv2.reset();
mTextInputManagerv4.reset();
mHardwareIntegration.reset();
mXdgOutputManager.reset();
mViewporter.reset();
mFractionalScaleManager.reset();
mCursorShapeManager.reset();
mXdgToplevelDragManager.reset();
mWaylandIntegration->reset(); mWaylandIntegration->reset();
qDeleteAll(std::exchange(mInputDevices, {})); qDeleteAll(std::exchange(mInputDevices, {}));
mLastInputDevice = nullptr; mLastInputDevice = nullptr;
for (const RegistryGlobal &global : mGlobals) { for (const RegistryGlobal &global : mRegistryGlobals) {
emit globalRemoved(global); emit globalRemoved(global);
} }
mGlobals.clear(); mRegistryGlobals.clear();
mLastInputSerial = 0; mLastInputSerial = 0;
mLastInputWindow.clear(); mLastInputWindow.clear();
@ -646,34 +626,36 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
mInputDevices.append(inputDevice); mInputDevices.append(inputDevice);
#if QT_CONFIG(wayland_datadevice) #if QT_CONFIG(wayland_datadevice)
} else if (interface == QLatin1String(QWaylandDataDeviceManager::interface()->name)) { } else if (interface == QLatin1String(QWaylandDataDeviceManager::interface()->name)) {
mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, version, id)); mGlobals.dndSelectionHandler.reset(new QWaylandDataDeviceManager(this, version, id));
#endif #endif
} else if (interface == QLatin1String(QtWayland::qt_surface_extension::interface()->name)) { } else if (interface == QLatin1String(QtWayland::qt_surface_extension::interface()->name)) {
mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1)); mGlobals.surfaceExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1));
} else if (interface == QLatin1String(QtWayland::wl_subcompositor::interface()->name)) { } else if (interface == QLatin1String(QtWayland::wl_subcompositor::interface()->name)) {
mSubCompositor.reset(new QtWayland::wl_subcompositor(registry, id, 1)); mGlobals.subCompositor.reset(new QtWayland::wl_subcompositor(registry, id, 1));
} else if (interface == QLatin1String(QWaylandTouchExtension::interface()->name)) { } else if (interface == QLatin1String(QWaylandTouchExtension::interface()->name)) {
mTouchExtension.reset(new QWaylandTouchExtension(this, id)); mGlobals.touchExtension.reset(new QWaylandTouchExtension(this, id));
} else if (interface == QLatin1String(QWaylandQtKeyExtension::interface()->name)) { } else if (interface == QLatin1String(QWaylandQtKeyExtension::interface()->name)) {
mQtKeyExtension.reset(new QWaylandQtKeyExtension(this, id)); mGlobals.qtKeyExtension.reset(new QWaylandQtKeyExtension(this, id));
#if QT_CONFIG(tabletevent) #if QT_CONFIG(tabletevent)
} else if (interface == QLatin1String(QWaylandTabletManagerV2::interface()->name)) { } else if (interface == QLatin1String(QWaylandTabletManagerV2::interface()->name)) {
mTabletManager.reset(new QWaylandTabletManagerV2(this, id, qMin(1, int(version)))); mGlobals.tabletManager.reset(new QWaylandTabletManagerV2(this, id, qMin(1, int(version))));
#endif #endif
} else if (interface == QLatin1String(QWaylandPointerGestures::interface()->name)) { } else if (interface == QLatin1String(QWaylandPointerGestures::interface()->name)) {
mPointerGestures.reset(new QWaylandPointerGestures(this, id, 1)); mGlobals.pointerGestures.reset(new QWaylandPointerGestures(this, id, 1));
#if QT_CONFIG(wayland_client_primary_selection) #if QT_CONFIG(wayland_client_primary_selection)
} else if (interface == QLatin1String(QWaylandPrimarySelectionDeviceManagerV1::interface()->name)) { } else if (interface == QLatin1String(QWaylandPrimarySelectionDeviceManagerV1::interface()->name)) {
mPrimarySelectionManager.reset(new QWaylandPrimarySelectionDeviceManagerV1(this, id, 1)); mGlobals.primarySelectionManager.reset(
new QWaylandPrimarySelectionDeviceManagerV1(this, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setPrimarySelectionDevice(mPrimarySelectionManager->createDevice(inputDevice)); inputDevice->setPrimarySelectionDevice(
mGlobals.primarySelectionManager->createDevice(inputDevice));
#endif #endif
} else if (interface == QLatin1String(QtWayland::qt_text_input_method_manager_v1::interface()->name) } else if (interface == QLatin1String(QtWayland::qt_text_input_method_manager_v1::interface()->name)
&& (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) { && (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) {
qCDebug(lcQpaWayland) << "text input: register qt_text_input_method_manager_v1"; qCDebug(lcQpaWayland) << "text input: register qt_text_input_method_manager_v1";
if (mTextInputManagerIndex < INT_MAX) { if (mTextInputManagerIndex < INT_MAX) {
mTextInputManagerv1.reset(); mGlobals.textInputManagerv1.reset();
mTextInputManagerv2.reset(); mGlobals.mTextInputManagerv2.reset();
#if QT_WAYLAND_TEXT_INPUT_V4_WIP #if QT_WAYLAND_TEXT_INPUT_V4_WIP
mTextInputManagerv4.reset(); mTextInputManagerv4.reset();
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP #endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
@ -681,17 +663,21 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
inputDevice->setTextInput(nullptr); inputDevice->setTextInput(nullptr);
} }
mTextInputMethodManager.reset(new QtWayland::qt_text_input_method_manager_v1(registry, id, 1)); mGlobals.textInputMethodManager.reset(
new QtWayland::qt_text_input_method_manager_v1(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInputMethod(new QWaylandTextInputMethod(this, mTextInputMethodManager->get_text_input_method(inputDevice->wl_seat()))); inputDevice->setTextInputMethod(new QWaylandTextInputMethod(
this,
mGlobals.textInputMethodManager->get_text_input_method(
inputDevice->wl_seat())));
mWaylandIntegration->reconfigureInputContext(); mWaylandIntegration->reconfigureInputContext();
mTextInputManagerIndex = mTextInputManagerList.indexOf(interface); mTextInputManagerIndex = mTextInputManagerList.indexOf(interface);
} else if (interface == QLatin1String(QtWayland::zwp_text_input_manager_v1::interface()->name) } else if (interface == QLatin1String(QtWayland::zwp_text_input_manager_v1::interface()->name)
&& (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) { && (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) {
qCDebug(lcQpaWayland) << "text input: register zwp_text_input_v1"; qCDebug(lcQpaWayland) << "text input: register zwp_text_input_v1";
if (mTextInputManagerIndex < INT_MAX) { if (mTextInputManagerIndex < INT_MAX) {
mTextInputMethodManager.reset(); mGlobals.textInputMethodManager.reset();
mTextInputManagerv2.reset(); mGlobals.mTextInputManagerv2.reset();
#if QT_WAYLAND_TEXT_INPUT_V4_WIP #if QT_WAYLAND_TEXT_INPUT_V4_WIP
mTextInputManagerv4.reset(); mTextInputManagerv4.reset();
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP #endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
@ -699,9 +685,11 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
inputDevice->setTextInputMethod(nullptr); inputDevice->setTextInputMethod(nullptr);
} }
mTextInputManagerv1.reset(new QtWayland::zwp_text_input_manager_v1(registry, id, 1)); mGlobals.textInputManagerv1.reset(
new QtWayland::zwp_text_input_manager_v1(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) { for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) {
auto textInput = new QWaylandTextInputv1(this, mTextInputManagerv1->create_text_input()); auto textInput =
new QWaylandTextInputv1(this, mGlobals.textInputManagerv1->create_text_input());
textInput->setSeat(inputDevice->wl_seat()); textInput->setSeat(inputDevice->wl_seat());
inputDevice->setTextInput(textInput); inputDevice->setTextInput(textInput);
} }
@ -712,8 +700,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
&& (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) { && (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) {
qCDebug(lcQpaWayland) << "text input: register zwp_text_input_v2"; qCDebug(lcQpaWayland) << "text input: register zwp_text_input_v2";
if (mTextInputManagerIndex < INT_MAX) { if (mTextInputManagerIndex < INT_MAX) {
mTextInputMethodManager.reset(); mGlobals.textInputMethodManager.reset();
mTextInputManagerv1.reset(); mGlobals.textInputManagerv1.reset();
#if QT_WAYLAND_TEXT_INPUT_V4_WIP #if QT_WAYLAND_TEXT_INPUT_V4_WIP
mTextInputManagerv4.reset(); mTextInputManagerv4.reset();
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP #endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
@ -721,9 +709,11 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
inputDevice->setTextInputMethod(nullptr); inputDevice->setTextInputMethod(nullptr);
} }
mTextInputManagerv2.reset(new QtWayland::zwp_text_input_manager_v2(registry, id, 1)); mGlobals.mTextInputManagerv2.reset(
new QtWayland::zwp_text_input_manager_v2(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(new QWaylandTextInputv2(this, mTextInputManagerv2->get_text_input(inputDevice->wl_seat()))); inputDevice->setTextInput(new QWaylandTextInputv2(
this, mGlobals.mTextInputManagerv2->get_text_input(inputDevice->wl_seat())));
mWaylandIntegration->reconfigureInputContext(); mWaylandIntegration->reconfigureInputContext();
mTextInputManagerIndex = mTextInputManagerList.indexOf(interface); mTextInputManagerIndex = mTextInputManagerList.indexOf(interface);
#if QT_WAYLAND_TEXT_INPUT_V4_WIP #if QT_WAYLAND_TEXT_INPUT_V4_WIP
@ -731,43 +721,48 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
&& (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) { && (mTextInputManagerList.contains(interface) && mTextInputManagerList.indexOf(interface) < mTextInputManagerIndex)) {
qCDebug(lcQpaWayland) << "text input: register zwp_text_input_v4"; qCDebug(lcQpaWayland) << "text input: register zwp_text_input_v4";
if (mTextInputManagerIndex < INT_MAX) { if (mTextInputManagerIndex < INT_MAX) {
mTextInputMethodManager.reset(); mGlobals.textInputMethodManager.reset();
mTextInputManagerv2.reset(); mGlobals.textInputManagerv2.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInputMethod(nullptr); inputDevice->setTextInputMethod(nullptr);
} }
mTextInputManagerv4.reset(new QtWayland::zwp_text_input_manager_v4(registry, id, 1)); mGlobals.textInputManagerv4.reset(
new QtWayland::zwp_text_input_manager_v4(registry, id, 1));
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(new QWaylandTextInputv4(this, mTextInputManagerv4->get_text_input(inputDevice->wl_seat()))); inputDevice->setTextInput(new QWaylandTextInputv4(
this, mGlobals.textInputManagerv4->get_text_input(inputDevice->wl_seat())));
mWaylandIntegration->reconfigureInputContext(); mWaylandIntegration->reconfigureInputContext();
mTextInputManagerIndex = mTextInputManagerList.indexOf(interface); mTextInputManagerIndex = mTextInputManagerList.indexOf(interface);
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP #endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
} else if (interface == QLatin1String(QWaylandHardwareIntegration::interface()->name)) { } else if (interface == QLatin1String(QWaylandHardwareIntegration::interface()->name)) {
bool disableHardwareIntegration = qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_HW_INTEGRATION"); bool disableHardwareIntegration = qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_HW_INTEGRATION");
if (!disableHardwareIntegration) { if (!disableHardwareIntegration) {
mHardwareIntegration.reset(new QWaylandHardwareIntegration(registry, id)); mGlobals.hardwareIntegration.reset(new QWaylandHardwareIntegration(registry, id));
// make a roundtrip here since we need to receive the events sent by // make a roundtrip here since we need to receive the events sent by
// qt_hardware_integration before creating windows // qt_hardware_integration before creating windows
forceRoundTrip(); forceRoundTrip();
} }
} else if (interface == QLatin1String(QWaylandXdgOutputManagerV1::interface()->name)) { } else if (interface == QLatin1String(QWaylandXdgOutputManagerV1::interface()->name)) {
mXdgOutputManager.reset(new QWaylandXdgOutputManagerV1(this, id, version)); mGlobals.xdgOutputManager.reset(new QWaylandXdgOutputManagerV1(this, id, version));
for (auto *screen : std::as_const(mWaitingScreens)) for (auto *screen : std::as_const(mWaitingScreens))
screen->initXdgOutput(xdgOutputManager()); screen->initXdgOutput(xdgOutputManager());
} else if (interface == QLatin1String(QtWayland::wp_fractional_scale_manager_v1::interface()->name)) { } else if (interface == QLatin1String(QtWayland::wp_fractional_scale_manager_v1::interface()->name)) {
mFractionalScaleManager.reset(new QtWayland::wp_fractional_scale_manager_v1(registry, id, 1)); mGlobals.fractionalScaleManager.reset(
new QtWayland::wp_fractional_scale_manager_v1(registry, id, 1));
} else if (interface == QLatin1String("wp_viewporter")) { } else if (interface == QLatin1String("wp_viewporter")) {
mViewporter.reset(new QtWayland::wp_viewporter(registry, id, qMin(1u, version))); mGlobals.viewporter.reset(new QtWayland::wp_viewporter(registry, id, qMin(1u, version)));
} else if (interface == QLatin1String(QtWayland::wp_cursor_shape_manager_v1::interface()->name)) { } else if (interface == QLatin1String(QtWayland::wp_cursor_shape_manager_v1::interface()->name)) {
mCursorShapeManager.reset(new QtWayland::wp_cursor_shape_manager_v1(registry, id, std::min(1u, version))); mGlobals.cursorShapeManager.reset(
new QtWayland::wp_cursor_shape_manager_v1(registry, id, std::min(1u, version)));
} else if ( } else if (
interface == QLatin1String(QtWayland::qt_toplevel_drag_manager_v1::interface()->name)) { interface == QLatin1String(QtWayland::qt_toplevel_drag_manager_v1::interface()->name)) {
mXdgToplevelDragManager.reset(new QtWayland::qt_toplevel_drag_manager_v1(registry, id, 1)); mGlobals.xdgToplevelDragManager.reset(
new QtWayland::qt_toplevel_drag_manager_v1(registry, id, 1));
} }
mGlobals.append(RegistryGlobal(id, interface, version, registry)); mRegistryGlobals.append(RegistryGlobal(id, interface, version, registry));
emit globalAdded(mGlobals.back()); emit globalAdded(mRegistryGlobals.back());
const auto copy = mRegistryListeners; // be prepared for listeners unregistering on notification const auto copy = mRegistryListeners; // be prepared for listeners unregistering on notification
for (Listener l : copy) for (Listener l : copy)
@ -776,8 +771,8 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
void QWaylandDisplay::registry_global_remove(uint32_t id) void QWaylandDisplay::registry_global_remove(uint32_t id)
{ {
for (int i = 0, ie = mGlobals.size(); i != ie; ++i) { for (int i = 0, ie = mRegistryGlobals.size(); i != ie; ++i) {
RegistryGlobal &global = mGlobals[i]; RegistryGlobal &global = mRegistryGlobals[i];
if (global.id == id) { if (global.id == id) {
if (global.interface == QLatin1String(QtWayland::wl_output::interface()->name)) { if (global.interface == QLatin1String(QtWayland::wl_output::interface()->name)) {
for (auto *screen : mWaitingScreens) { for (auto *screen : mWaitingScreens) {
@ -799,13 +794,13 @@ void QWaylandDisplay::registry_global_remove(uint32_t id)
} }
} }
if (global.interface == QLatin1String(QtWayland::zwp_text_input_manager_v1::interface()->name)) { if (global.interface == QLatin1String(QtWayland::zwp_text_input_manager_v1::interface()->name)) {
mTextInputManagerv1.reset(); mGlobals.textInputManagerv1.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(nullptr); inputDevice->setTextInput(nullptr);
mWaylandIntegration->reconfigureInputContext(); mWaylandIntegration->reconfigureInputContext();
} }
if (global.interface == QLatin1String(QtWayland::zwp_text_input_manager_v2::interface()->name)) { if (global.interface == QLatin1String(QtWayland::zwp_text_input_manager_v2::interface()->name)) {
mTextInputManagerv2.reset(); mGlobals.mTextInputManagerv2.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInput(nullptr); inputDevice->setTextInput(nullptr);
mWaylandIntegration->reconfigureInputContext(); mWaylandIntegration->reconfigureInputContext();
@ -819,19 +814,19 @@ void QWaylandDisplay::registry_global_remove(uint32_t id)
} }
#endif // QT_WAYLAND_TEXT_INPUT_V4_WIP #endif // QT_WAYLAND_TEXT_INPUT_V4_WIP
if (global.interface == QLatin1String(QtWayland::qt_text_input_method_manager_v1::interface()->name)) { if (global.interface == QLatin1String(QtWayland::qt_text_input_method_manager_v1::interface()->name)) {
mTextInputMethodManager.reset(); mGlobals.textInputMethodManager.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setTextInputMethod(nullptr); inputDevice->setTextInputMethod(nullptr);
mWaylandIntegration->reconfigureInputContext(); mWaylandIntegration->reconfigureInputContext();
} }
#if QT_CONFIG(wayland_client_primary_selection) #if QT_CONFIG(wayland_client_primary_selection)
if (global.interface == QLatin1String(QtWayland::zwp_primary_selection_device_manager_v1::interface()->name)) { if (global.interface == QLatin1String(QtWayland::zwp_primary_selection_device_manager_v1::interface()->name)) {
mPrimarySelectionManager.reset(); mGlobals.primarySelectionManager.reset();
for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices)) for (QWaylandInputDevice *inputDevice : std::as_const(mInputDevices))
inputDevice->setPrimarySelectionDevice(nullptr); inputDevice->setPrimarySelectionDevice(nullptr);
} }
#endif #endif
emit globalRemoved(mGlobals.takeAt(i)); emit globalRemoved(mRegistryGlobals.takeAt(i));
break; break;
} }
} }
@ -839,7 +834,7 @@ void QWaylandDisplay::registry_global_remove(uint32_t id)
bool QWaylandDisplay::hasRegistryGlobal(QStringView interfaceName) const bool QWaylandDisplay::hasRegistryGlobal(QStringView interfaceName) const
{ {
for (const RegistryGlobal &global : mGlobals) for (const RegistryGlobal &global : mRegistryGlobals)
if (global.interface == interfaceName) if (global.interface == interfaceName)
return true; return true;
@ -850,8 +845,9 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data)
{ {
Listener l = { listener, data }; Listener l = { listener, data };
mRegistryListeners.append(l); mRegistryListeners.append(l);
for (int i = 0, ie = mGlobals.size(); i != ie; ++i) for (int i = 0, ie = mRegistryGlobals.size(); i != ie; ++i)
(*l.listener)(l.data, mGlobals[i].registry, mGlobals[i].id, mGlobals[i].interface, mGlobals[i].version); (*l.listener)(l.data, mRegistryGlobals[i].registry, mRegistryGlobals[i].id,
mRegistryGlobals[i].interface, mRegistryGlobals[i].version);
} }
void QWaylandDisplay::removeListener(RegistryListener listener, void *data) void QWaylandDisplay::removeListener(RegistryListener listener, void *data)

View File

@ -135,27 +135,75 @@ public:
QWaylandInputDevice *defaultInputDevice() const; QWaylandInputDevice *defaultInputDevice() const;
QWaylandInputDevice *currentInputDevice() const { return defaultInputDevice(); } QWaylandInputDevice *currentInputDevice() const { return defaultInputDevice(); }
#if QT_CONFIG(wayland_datadevice) #if QT_CONFIG(wayland_datadevice)
QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler.get(); } QWaylandDataDeviceManager *dndSelectionHandler() const
{
return mGlobals.dndSelectionHandler.get();
}
#endif #endif
#if QT_CONFIG(wayland_client_primary_selection) #if QT_CONFIG(wayland_client_primary_selection)
QWaylandPrimarySelectionDeviceManagerV1 *primarySelectionManager() const { return mPrimarySelectionManager.data(); } QWaylandPrimarySelectionDeviceManagerV1 *primarySelectionManager() const
{
return mGlobals.primarySelectionManager.get();
}
#endif #endif
QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension.data(); } QtWayland::qt_surface_extension *windowExtension() const
{
return mGlobals.surfaceExtension.get();
}
#if QT_CONFIG(tabletevent) #if QT_CONFIG(tabletevent)
QWaylandTabletManagerV2 *tabletManager() const { return mTabletManager.data(); } QWaylandTabletManagerV2 *tabletManager() const
{
return mGlobals.tabletManager.get();
}
#endif #endif
QWaylandPointerGestures *pointerGestures() const { return mPointerGestures.data(); } QWaylandPointerGestures *pointerGestures() const
QWaylandTouchExtension *touchExtension() const { return mTouchExtension.data(); } {
QtWayland::qt_text_input_method_manager_v1 *textInputMethodManager() const { return mTextInputMethodManager.data(); } return mGlobals.pointerGestures.get();
QtWayland::zwp_text_input_manager_v1 *textInputManagerv1() const { return mTextInputManagerv1.data(); } }
QtWayland::zwp_text_input_manager_v2 *textInputManagerv2() const { return mTextInputManagerv2.data(); } QWaylandTouchExtension *touchExtension() const
QtWayland::zwp_text_input_manager_v4 *textInputManagerv4() const { return mTextInputManagerv4.data(); } {
QWaylandHardwareIntegration *hardwareIntegration() const { return mHardwareIntegration.data(); } return mGlobals.touchExtension.get();
QWaylandXdgOutputManagerV1 *xdgOutputManager() const { return mXdgOutputManager.data(); } }
QtWayland::wp_fractional_scale_manager_v1 *fractionalScaleManager() const { return mFractionalScaleManager.data(); } QtWayland::qt_text_input_method_manager_v1 *textInputMethodManager() const
QtWayland::wp_viewporter *viewporter() const { return mViewporter.data(); } {
QtWayland::wp_cursor_shape_manager_v1 *cursorShapeManager() const { return mCursorShapeManager.data();} return mGlobals.textInputMethodManager.get();
QtWayland::qt_toplevel_drag_manager_v1 *xdgToplevelDragManager() const { return mXdgToplevelDragManager.data();} }
QtWayland::zwp_text_input_manager_v1 *textInputManagerv1() const
{
return mGlobals.textInputManagerv1.get();
}
QtWayland::zwp_text_input_manager_v2 *textInputManagerv2() const
{
return mGlobals.mTextInputManagerv2.get();
}
QtWayland::zwp_text_input_manager_v4 *textInputManagerv4() const
{
return mGlobals.textInputManagerv4.get();
}
QWaylandHardwareIntegration *hardwareIntegration() const
{
return mGlobals.hardwareIntegration.get();
}
QWaylandXdgOutputManagerV1 *xdgOutputManager() const
{
return mGlobals.xdgOutputManager.get();
}
QtWayland::wp_fractional_scale_manager_v1 *fractionalScaleManager() const
{
return mGlobals.fractionalScaleManager.get();
}
QtWayland::wp_viewporter *viewporter() const
{
return mGlobals.viewporter.get();
}
QtWayland::wp_cursor_shape_manager_v1 *cursorShapeManager() const
{
return mGlobals.cursorShapeManager.get();
}
QtWayland::qt_toplevel_drag_manager_v1 *xdgToplevelDragManager() const
{
return mGlobals.xdgToplevelDragManager.get();
}
struct RegistryGlobal { struct RegistryGlobal {
uint32_t id; uint32_t id;
@ -165,7 +213,10 @@ public:
RegistryGlobal(uint32_t id_, const QString &interface_, uint32_t version_, struct ::wl_registry *registry_) RegistryGlobal(uint32_t id_, const QString &interface_, uint32_t version_, struct ::wl_registry *registry_)
: id(id_), interface(interface_), version(version_), registry(registry_) { } : id(id_), interface(interface_), version(version_), registry(registry_) { }
}; };
QList<RegistryGlobal> globals() const { return mGlobals; } QList<RegistryGlobal> globals() const
{
return mRegistryGlobals;
}
bool hasRegistryGlobal(QStringView interfaceName) const; bool hasRegistryGlobal(QStringView interfaceName) const;
/* wl_registry_add_listener does not add but rather sets a listener, so this function is used /* wl_registry_add_listener does not add but rather sets a listener, so this function is used
@ -254,38 +305,44 @@ private:
QWaylandCursorTheme *theme() const noexcept QWaylandCursorTheme *theme() const noexcept
{ return found ? position->theme.get() : nullptr; } { return found ? position->theme.get() : nullptr; }
}; };
FindExistingCursorThemeResult findExistingCursorTheme(const QString &name, int pixelSize) const noexcept; FindExistingCursorThemeResult findExistingCursorTheme(const QString &name,
int pixelSize) const noexcept;
QScopedPointer<QWaylandCursor> mCursor; QScopedPointer<QWaylandCursor> mCursor;
#endif #endif
#if QT_CONFIG(wayland_datadevice)
QScopedPointer<QWaylandDataDeviceManager> mDndSelectionHandler;
#endif
QScopedPointer<QtWayland::qt_surface_extension> mWindowExtension;
QScopedPointer<QtWayland::wl_subcompositor> mSubCompositor;
QScopedPointer<QWaylandTouchExtension> mTouchExtension;
QScopedPointer<QWaylandQtKeyExtension> mQtKeyExtension;
QScopedPointer<QWaylandWindowManagerIntegration> mWindowManagerIntegration; QScopedPointer<QWaylandWindowManagerIntegration> mWindowManagerIntegration;
struct GlobalHolder
{
#if QT_CONFIG(wayland_datadevice)
std::unique_ptr<QWaylandDataDeviceManager> dndSelectionHandler;
#endif
std::unique_ptr<QtWayland::qt_surface_extension> surfaceExtension;
std::unique_ptr<QtWayland::wl_subcompositor> subCompositor;
std::unique_ptr<QWaylandTouchExtension> touchExtension;
std::unique_ptr<QWaylandQtKeyExtension> qtKeyExtension;
#if QT_CONFIG(tabletevent) #if QT_CONFIG(tabletevent)
QScopedPointer<QWaylandTabletManagerV2> mTabletManager; std::unique_ptr<QWaylandTabletManagerV2> tabletManager;
#endif #endif
QScopedPointer<QWaylandPointerGestures> mPointerGestures; std::unique_ptr<QWaylandPointerGestures> pointerGestures;
#if QT_CONFIG(wayland_client_primary_selection) #if QT_CONFIG(wayland_client_primary_selection)
QScopedPointer<QWaylandPrimarySelectionDeviceManagerV1> mPrimarySelectionManager; std::unique_ptr<QWaylandPrimarySelectionDeviceManagerV1> primarySelectionManager;
#endif #endif
QScopedPointer<QtWayland::qt_text_input_method_manager_v1> mTextInputMethodManager; std::unique_ptr<QtWayland::qt_text_input_method_manager_v1> textInputMethodManager;
QScopedPointer<QtWayland::zwp_text_input_manager_v1> mTextInputManagerv1; std::unique_ptr<QtWayland::zwp_text_input_manager_v1> textInputManagerv1;
QScopedPointer<QtWayland::zwp_text_input_manager_v2> mTextInputManagerv2; std::unique_ptr<QtWayland::zwp_text_input_manager_v2> mTextInputManagerv2;
QScopedPointer<QtWayland::zwp_text_input_manager_v4> mTextInputManagerv4; std::unique_ptr<QtWayland::zwp_text_input_manager_v4> textInputManagerv4;
QScopedPointer<QWaylandHardwareIntegration> mHardwareIntegration; std::unique_ptr<QWaylandHardwareIntegration> hardwareIntegration;
QScopedPointer<QWaylandXdgOutputManagerV1> mXdgOutputManager; std::unique_ptr<QWaylandXdgOutputManagerV1> xdgOutputManager;
QScopedPointer<QtWayland::wp_viewporter> mViewporter; std::unique_ptr<QtWayland::wp_viewporter> viewporter;
QScopedPointer<QtWayland::wp_fractional_scale_manager_v1> mFractionalScaleManager; std::unique_ptr<QtWayland::wp_fractional_scale_manager_v1> fractionalScaleManager;
QScopedPointer<QtWayland::wp_cursor_shape_manager_v1> mCursorShapeManager; std::unique_ptr<QtWayland::wp_cursor_shape_manager_v1> cursorShapeManager;
QScopedPointer<QtWayland::qt_toplevel_drag_manager_v1> mXdgToplevelDragManager; std::unique_ptr<QtWayland::qt_toplevel_drag_manager_v1> xdgToplevelDragManager;
} mGlobals;
int mFd = -1; int mFd = -1;
int mWritableNotificationFd = -1; int mWritableNotificationFd = -1;
QList<RegistryGlobal> mGlobals; QList<RegistryGlobal> mRegistryGlobals;
uint32_t mLastInputSerial = 0; uint32_t mLastInputSerial = 0;
QWaylandInputDevice *mLastInputDevice = nullptr; QWaylandInputDevice *mLastInputDevice = nullptr;
QPointer<QWaylandWindow> mLastInputWindow; QPointer<QWaylandWindow> mLastInputWindow;