Client: Add safer fromObject function to scanner
Makes the scanner produce generated static functions such as QtWaylandClient::wl_surface *wl_surface::fromObject(struct ::wl_surface *object); Which casts from the wayland-scanner generated types, such as struct ::wl_surface *, to types types generated by qtwaylandscanner, but performs a check to see if the listener is set to the wrapper class first (at least for interfaces with events). This lets us easily fix crashes in a couple of places where we receive events with wayland objects that we didn't create. Also adds nullptr checks whenever we use the fromWlSurface() and fromWlOutput() functions to handle failed conversions. Task-number: QTBUG-73801 Fixes: QTBUG-74085 Change-Id: I9f33c31c7d1a939ccb3ebbbcb0eb67af10037237 Reviewed-by: Jaroslaw Kubik <jarek@froglogic.com> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> (cherry picked from commit c6476ae915b8ac64121d379274363227b1c300ff) Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@liri.io>
This commit is contained in:
parent
37377fc044
commit
0b803993e7
@ -154,9 +154,13 @@ void QWaylandDataDevice::data_device_drop()
|
||||
|
||||
void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer *id)
|
||||
{
|
||||
m_enterSerial = serial;
|
||||
m_dragWindow = QWaylandWindow::fromWlSurface(surface)->window();
|
||||
auto *dragWaylandWindow = QWaylandWindow::fromWlSurface(surface);
|
||||
if (!dragWaylandWindow)
|
||||
return; // Ignore foreign surfaces
|
||||
|
||||
m_dragWindow = dragWaylandWindow->window();
|
||||
m_dragPoint = calculateDragPosition(x, y, m_dragWindow);
|
||||
m_enterSerial = serial;
|
||||
|
||||
QMimeData *dragData = nullptr;
|
||||
Qt::DropActions supportedActions;
|
||||
|
@ -451,6 +451,9 @@ void QWaylandInputDevice::Pointer::pointer_enter(uint32_t serial, struct wl_surf
|
||||
return;
|
||||
|
||||
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
|
||||
if (!window)
|
||||
return; // Ignore foreign surfaces
|
||||
|
||||
mFocus = window;
|
||||
mSurfacePos = QPointF(wl_fixed_to_double(sx), wl_fixed_to_double(sy));
|
||||
mGlobalPos = window->window()->mapToGlobal(mSurfacePos.toPoint());
|
||||
@ -477,6 +480,10 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
auto *window = QWaylandWindow::fromWlSurface(surface);
|
||||
if (!window)
|
||||
return; // Ignore foreign surfaces
|
||||
|
||||
if (!QWaylandWindow::mouseGrab()) {
|
||||
QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface);
|
||||
window->handleMouseLeave(mParent);
|
||||
@ -852,9 +859,13 @@ void QWaylandInputDevice::Touch::touch_down(uint32_t serial,
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
auto *window = QWaylandWindow::fromWlSurface(surface);
|
||||
if (!window)
|
||||
return; // Ignore foreign surfaces
|
||||
|
||||
mParent->mTime = time;
|
||||
mParent->mSerial = serial;
|
||||
mFocus = QWaylandWindow::fromWlSurface(surface);
|
||||
mFocus = window;
|
||||
mParent->mQDisplay->setLastInputDevice(mParent, serial, mFocus);
|
||||
mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed);
|
||||
}
|
||||
|
@ -70,7 +70,11 @@ void QWaylandQtKeyExtension::zqt_key_v1_key(struct wl_surface *surface,
|
||||
}
|
||||
|
||||
QWaylandInputDevice *dev = inputDevices.first();
|
||||
QWaylandWindow *win = surface ? QWaylandWindow::fromWlSurface(surface) : dev->keyboardFocus();
|
||||
|
||||
auto *win = surface ? QWaylandWindow::fromWlSurface(surface) : nullptr;
|
||||
|
||||
if (!win)
|
||||
win = dev->keyboardFocus();
|
||||
|
||||
if (!win || !win->window()) {
|
||||
qWarning("qt_key_extension: handle_qtkey: No keyboard focus");
|
||||
|
@ -199,8 +199,9 @@ QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window)
|
||||
|
||||
QWaylandScreen *QWaylandScreen::fromWlOutput(::wl_output *output)
|
||||
{
|
||||
auto wlOutput = static_cast<QtWayland::wl_output *>(wl_output_get_user_data(output));
|
||||
return static_cast<QWaylandScreen *>(wlOutput);
|
||||
if (auto *o = QtWayland::wl_output::fromObject(output))
|
||||
return static_cast<QWaylandScreen *>(o);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh)
|
||||
|
@ -982,6 +982,7 @@ bool Scanner::process()
|
||||
printf("\n");
|
||||
printf(" struct ::%s *object() { return m_%s; }\n", interfaceName, interfaceName);
|
||||
printf(" const struct ::%s *object() const { return m_%s; }\n", interfaceName, interfaceName);
|
||||
printf(" static %s *fromObject(struct ::%s *object);\n", interfaceName, interfaceName);
|
||||
printf("\n");
|
||||
printf(" bool isInitialized() const;\n");
|
||||
printf("\n");
|
||||
@ -1110,6 +1111,16 @@ bool Scanner::process()
|
||||
printf(" }\n");
|
||||
printf("\n");
|
||||
|
||||
printf(" %s *%s::fromObject(struct ::%s *object)\n", interfaceName, interfaceName, interfaceName);
|
||||
printf(" {\n");
|
||||
if (hasEvents) {
|
||||
printf(" if (wl_proxy_get_listener((struct ::wl_proxy *)object) != (void *)&m_%s_listener)\n", interfaceName);
|
||||
printf(" return nullptr;\n");
|
||||
}
|
||||
printf(" return static_cast<%s *>(%s_get_user_data(object));\n", interfaceName, interfaceName);
|
||||
printf(" }\n");
|
||||
printf("\n");
|
||||
|
||||
printf(" bool %s::isInitialized() const\n", interfaceName);
|
||||
printf(" {\n");
|
||||
printf(" return m_%s != nullptr;\n", interfaceName);
|
||||
|
Loading…
x
Reference in New Issue
Block a user