Switch Wayland integration to the new type safe Qt API

This also makes it possible to get a more right seat/serial pair
This commit is contained in:
Ilya Fedin 2023-05-13 23:31:54 +04:00 committed by John Preston
parent e8857f5792
commit be0067a8c7
2 changed files with 37 additions and 62 deletions

View file

@ -13,12 +13,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
#include <QtGui/QWindow> #include <QtGui/QWindow>
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformwindow_p.h>
#include <wayland-client.h> #include <wayland-client.h>
typedef void (*SetWindowMarginsFunc)( using namespace QNativeInterface;
QWindow *window, using namespace QNativeInterface::Private;
const QMargins &margins);
namespace Ui { namespace Ui {
namespace Platform { namespace Platform {
@ -66,14 +65,12 @@ const struct wl_registry_listener WaylandIntegration::Private::RegistryListener
WaylandIntegration::WaylandIntegration() WaylandIntegration::WaylandIntegration()
: _private(std::make_unique<Private>()) { : _private(std::make_unique<Private>()) {
const auto native = QGuiApplication::platformNativeInterface(); const auto native = qApp->nativeInterface<QWaylandApplication>();
if (!native) { if (!native) {
return; return;
} }
const auto display = reinterpret_cast<wl_display*>( const auto display = native->display();
native->nativeResourceForIntegration(QByteArray("wl_display")));
if (!display) { if (!display) {
return; return;
} }
@ -85,7 +82,7 @@ WaylandIntegration::WaylandIntegration()
_private.get()); _private.get());
base::qt_signal_producer( base::qt_signal_producer(
native, qApp,
&QObject::destroyed &QObject::destroyed
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
// too late for standard destructors, just free // too late for standard destructors, just free
@ -108,77 +105,57 @@ bool WaylandIntegration::xdgDecorationSupported() {
} }
bool WaylandIntegration::windowExtentsSupported() { bool WaylandIntegration::windowExtentsSupported() {
const auto native = QGuiApplication::platformNativeInterface(); QWindow window;
if (!native) { window.create();
return false; return window.nativeInterface<QWaylandWindow>();
}
const auto setWindowMargins = reinterpret_cast<SetWindowMarginsFunc>(
reinterpret_cast<void*>(
native->nativeResourceFunctionForWindow("setmargins")));
if (!setWindowMargins) {
return false;
}
return true;
} }
void WaylandIntegration::setWindowExtents( void WaylandIntegration::setWindowExtents(
not_null<QWidget*> widget, not_null<QWidget*> widget,
const QMargins &extents) { const QMargins &extents) {
const auto native = QGuiApplication::platformNativeInterface(); const auto window = widget->windowHandle();
if (!window) {
return;
}
const auto native = window->nativeInterface<QWaylandWindow>();
if (!native) { if (!native) {
return; return;
} }
const auto setWindowMargins = reinterpret_cast<SetWindowMarginsFunc>( native->setCustomMargins(extents);
reinterpret_cast<void*>(
native->nativeResourceFunctionForWindow("setmargins")));
if (!setWindowMargins) {
return;
}
setWindowMargins(widget->windowHandle(), extents);
} }
void WaylandIntegration::unsetWindowExtents(not_null<QWidget*> widget) { void WaylandIntegration::unsetWindowExtents(not_null<QWidget*> widget) {
const auto native = QGuiApplication::platformNativeInterface(); const auto window = widget->windowHandle();
if (!window) {
return;
}
const auto native = window->nativeInterface<QWaylandWindow>();
if (!native) { if (!native) {
return; return;
} }
const auto setWindowMargins = reinterpret_cast<SetWindowMarginsFunc>( native->setCustomMargins(QMargins());
reinterpret_cast<void*>(
native->nativeResourceFunctionForWindow("setmargins")));
if (!setWindowMargins) {
return;
}
setWindowMargins(widget->windowHandle(), QMargins());
} }
void WaylandIntegration::showWindowMenu( void WaylandIntegration::showWindowMenu(
not_null<QWidget*> widget, not_null<QWidget*> widget,
const QPoint &point) { const QPoint &point) {
const auto native = QGuiApplication::platformNativeInterface(); const auto window = widget->windowHandle();
if (!native) { if (!window) {
return; return;
} }
const auto toplevel = reinterpret_cast<xdg_toplevel*>( const auto native = qApp->nativeInterface<QWaylandApplication>();
native->nativeResourceForWindow( const auto nativeWindow = window->nativeInterface<QWaylandWindow>();
QByteArray("xdg_toplevel"), if (!native || !nativeWindow) {
widget->windowHandle())); return;
}
const auto seat = reinterpret_cast<wl_seat*>(
native->nativeResourceForIntegration(QByteArray("wl_seat")));
const auto serial = uint32_t(reinterpret_cast<quintptr>(
native->nativeResourceForIntegration(QByteArray("serial"))));
const auto toplevel = nativeWindow->surfaceRole<xdg_toplevel>();
const auto seat = native->lastInputSeat();
if (!toplevel || !seat) { if (!toplevel || !seat) {
return; return;
} }
@ -186,7 +163,7 @@ void WaylandIntegration::showWindowMenu(
xdg_toplevel_show_window_menu( xdg_toplevel_show_window_menu(
toplevel, toplevel,
seat, seat,
serial, native->lastInputSerial(),
point.x(), point.x(),
point.y()); point.y());
} }

View file

@ -323,12 +323,10 @@ void PopupMenu::validateCompositingSupport() {
std::max(_st.shadow.extend.bottom(), additional.bottom())); std::max(_st.shadow.extend.bottom(), additional.bottom()));
_extents = _padding - (additional - _additionalMenuExtents); _extents = _padding - (additional - _additionalMenuExtents);
} }
if (windowHandle()) { if (_extents.isNull()) {
if (_extents.isNull()) { Platform::UnsetWindowExtents(this);
Platform::UnsetWindowExtents(this); } else {
} else { Platform::SetWindowExtents(this, _extents);
Platform::SetWindowExtents(this, _extents);
}
} }
_scroll->moveToLeft(_padding.left(), _padding.top()); _scroll->moveToLeft(_padding.left(), _padding.top());
handleMenuResize(); handleMenuResize();