Changeset View
Changeset View
Standalone View
Standalone View
src/server/seat_interface.cpp
Show First 20 Lines • Show All 240 Lines • ▼ Show 20 Line(s) | 240 | { | |||
---|---|---|---|---|---|
241 | return interfacesForSurface(surface, pointers); | 241 | return interfacesForSurface(surface, pointers); | ||
242 | } | 242 | } | ||
243 | 243 | | |||
244 | QVector<KeyboardInterface *> SeatInterface::Private::keyboardsForSurface(SurfaceInterface *surface) const | 244 | QVector<KeyboardInterface *> SeatInterface::Private::keyboardsForSurface(SurfaceInterface *surface) const | ||
245 | { | 245 | { | ||
246 | return interfacesForSurface(surface, keyboards); | 246 | return interfacesForSurface(surface, keyboards); | ||
247 | } | 247 | } | ||
248 | 248 | | |||
249 | TouchInterface *SeatInterface::Private::touchForSurface(SurfaceInterface *surface) const | 249 | QVector<TouchInterface *> SeatInterface::Private::touchsForSurface(SurfaceInterface *surface) const | ||
250 | { | 250 | { | ||
251 | return interfaceForSurface(surface, touchs); | 251 | return interfacesForSurface(surface, touchs); | ||
252 | } | 252 | } | ||
253 | 253 | | |||
254 | DataDeviceInterface *SeatInterface::Private::dataDeviceForSurface(SurfaceInterface *surface) const | 254 | DataDeviceInterface *SeatInterface::Private::dataDeviceForSurface(SurfaceInterface *surface) const | ||
255 | { | 255 | { | ||
256 | return interfaceForSurface(surface, dataDevices); | 256 | return interfaceForSurface(surface, dataDevices); | ||
257 | } | 257 | } | ||
258 | 258 | | |||
259 | TextInputInterface *SeatInterface::Private::textInputForSurface(SurfaceInterface *surface) const | 259 | TextInputInterface *SeatInterface::Private::textInputForSurface(SurfaceInterface *surface) const | ||
▲ Show 20 Lines • Show All 286 Lines • ▼ Show 20 Line(s) | 543 | { | |||
546 | auto clientConnection = display->getConnection(client); | 546 | auto clientConnection = display->getConnection(client); | ||
547 | touch->create(clientConnection, qMin(wl_resource_get_version(resource), s_touchVersion), id); | 547 | touch->create(clientConnection, qMin(wl_resource_get_version(resource), s_touchVersion), id); | ||
548 | if (!touch->resource()) { | 548 | if (!touch->resource()) { | ||
549 | wl_resource_post_no_memory(resource); | 549 | wl_resource_post_no_memory(resource); | ||
550 | delete touch; | 550 | delete touch; | ||
551 | return; | 551 | return; | ||
552 | } | 552 | } | ||
553 | touchs << touch; | 553 | touchs << touch; | ||
554 | if (touchInterface.focus.surface && touchInterface.focus.surface->client() == clientConnection) { | 554 | if (globalTouch.focus.surface && globalTouch.focus.surface->client() == clientConnection) { | ||
555 | // this is a touch for the currently focused touch surface | 555 | // this is a touch for the currently focused touch surface | ||
556 | if (!touchInterface.focus.touch) { | 556 | globalTouch.focus.touchs << touch; | ||
557 | touchInterface.focus.touch = touch; | 557 | if (!globalTouch.ids.isEmpty()) { | ||
558 | if (!touchInterface.ids.isEmpty()) { | | |||
559 | // TODO: send out all the points | 558 | // TODO: send out all the points | ||
560 | } | 559 | } | ||
561 | } | 560 | } | ||
562 | } | | |||
563 | QObject::connect(touch, &QObject::destroyed, q, | 561 | QObject::connect(touch, &QObject::destroyed, q, | ||
564 | [touch,this] { | 562 | [touch,this] { | ||
565 | touchs.removeAt(touchs.indexOf(touch)); | 563 | touchs.removeAt(touchs.indexOf(touch)); | ||
566 | if (touchInterface.focus.touch == touch) { | 564 | globalTouch.focus.touchs.removeOne(touch); | ||
567 | touchInterface.focus.touch = nullptr; | | |||
568 | } | | |||
569 | } | 565 | } | ||
570 | ); | 566 | ); | ||
571 | emit q->touchCreated(touch); | 567 | emit q->touchCreated(touch); | ||
572 | } | 568 | } | ||
573 | 569 | | |||
574 | QString SeatInterface::name() const | 570 | QString SeatInterface::name() const | ||
575 | { | 571 | { | ||
576 | Q_D(); | 572 | Q_D(); | ||
▲ Show 20 Lines • Show All 672 Lines • ▼ Show 20 Line(s) | 1244 | if (d->keys.focus.keyboards.isEmpty()) { | |||
1249 | return nullptr; | 1245 | return nullptr; | ||
1250 | } | 1246 | } | ||
1251 | return d->keys.focus.keyboards.first(); | 1247 | return d->keys.focus.keyboards.first(); | ||
1252 | } | 1248 | } | ||
1253 | 1249 | | |||
1254 | void SeatInterface::cancelTouchSequence() | 1250 | void SeatInterface::cancelTouchSequence() | ||
1255 | { | 1251 | { | ||
1256 | Q_D(); | 1252 | Q_D(); | ||
1257 | if (d->touchInterface.focus.touch) { | 1253 | for (auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) { | ||
1258 | d->touchInterface.focus.touch->cancel(); | 1254 | (*it)->cancel(); | ||
1259 | } | 1255 | } | ||
1260 | d->touchInterface.ids.clear(); | 1256 | d->globalTouch.ids.clear(); | ||
1261 | } | 1257 | } | ||
1262 | 1258 | | |||
1263 | TouchInterface *SeatInterface::focusedTouch() const | 1259 | TouchInterface *SeatInterface::focusedTouch() const | ||
1264 | { | 1260 | { | ||
1265 | Q_D(); | 1261 | Q_D(); | ||
1266 | return d->touchInterface.focus.touch; | 1262 | if (d->globalTouch.focus.touchs.isEmpty()) { | ||
1263 | return nullptr; | ||||
1264 | } | ||||
1265 | return d->globalTouch.focus.touchs.first(); | ||||
1267 | } | 1266 | } | ||
1268 | 1267 | | |||
1269 | SurfaceInterface *SeatInterface::focusedTouchSurface() const | 1268 | SurfaceInterface *SeatInterface::focusedTouchSurface() const | ||
1270 | { | 1269 | { | ||
1271 | Q_D(); | 1270 | Q_D(); | ||
1272 | return d->touchInterface.focus.surface; | 1271 | return d->globalTouch.focus.surface; | ||
1273 | } | 1272 | } | ||
1274 | 1273 | | |||
1275 | QPointF SeatInterface::focusedTouchSurfacePosition() const | 1274 | QPointF SeatInterface::focusedTouchSurfacePosition() const | ||
1276 | { | 1275 | { | ||
1277 | Q_D(); | 1276 | Q_D(); | ||
1278 | return d->touchInterface.focus.offset; | 1277 | return d->globalTouch.focus.offset; | ||
1279 | } | 1278 | } | ||
1280 | 1279 | | |||
1281 | bool SeatInterface::isTouchSequence() const | 1280 | bool SeatInterface::isTouchSequence() const | ||
1282 | { | 1281 | { | ||
1283 | Q_D(); | 1282 | Q_D(); | ||
1284 | return !d->touchInterface.ids.isEmpty(); | 1283 | return !d->globalTouch.ids.isEmpty(); | ||
1285 | } | 1284 | } | ||
1286 | 1285 | | |||
1287 | void SeatInterface::setFocusedTouchSurface(SurfaceInterface *surface, const QPointF &surfacePosition) | 1286 | void SeatInterface::setFocusedTouchSurface(SurfaceInterface *surface, const QPointF &surfacePosition) | ||
1288 | { | 1287 | { | ||
1289 | if (isTouchSequence()) { | 1288 | if (isTouchSequence()) { | ||
1290 | // changing surface not allowed during a touch sequence | 1289 | // changing surface not allowed during a touch sequence | ||
1291 | return; | 1290 | return; | ||
1292 | } | 1291 | } | ||
1293 | Q_D(); | 1292 | Q_D(); | ||
1294 | if (d->touchInterface.focus.surface) { | 1293 | if (d->globalTouch.focus.surface) { | ||
1295 | disconnect(d->touchInterface.focus.destroyConnection); | 1294 | disconnect(d->globalTouch.focus.destroyConnection); | ||
1296 | } | 1295 | } | ||
1297 | d->touchInterface.focus = Private::Touch::Focus(); | 1296 | d->globalTouch.focus = Private::Touch::Focus(); | ||
1298 | d->touchInterface.focus.surface = surface; | 1297 | d->globalTouch.focus.surface = surface; | ||
1299 | d->touchInterface.focus.offset = surfacePosition; | 1298 | d->globalTouch.focus.offset = surfacePosition; | ||
1300 | TouchInterface *t = d->touchForSurface(surface); | 1299 | d->globalTouch.focus.touchs = d->touchsForSurface(surface); | ||
1301 | if (t && !t->resource()) { | 1300 | if (d->globalTouch.focus.surface) { | ||
1302 | t = nullptr; | 1301 | d->globalTouch.focus.destroyConnection = connect(surface, &QObject::destroyed, this, | ||
1303 | } | | |||
1304 | d->touchInterface.focus.touch = t; | | |||
1305 | if (d->touchInterface.focus.surface) { | | |||
1306 | d->touchInterface.focus.destroyConnection = connect(surface, &QObject::destroyed, this, | | |||
1307 | [this] { | 1302 | [this] { | ||
1308 | Q_D(); | 1303 | Q_D(); | ||
1309 | if (isTouchSequence() && d->touchInterface.focus.touch) { | 1304 | if (isTouchSequence()) { | ||
1310 | // Surface destroyed during touch sequence - send a cancel | 1305 | // Surface destroyed during touch sequence - send a cancel | ||
1311 | d->touchInterface.focus.touch->cancel(); | 1306 | for (auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) { | ||
1307 | (*it)->cancel(); | ||||
1308 | } | ||||
1312 | } | 1309 | } | ||
1313 | d->touchInterface.focus = Private::Touch::Focus(); | 1310 | d->globalTouch.focus = Private::Touch::Focus(); | ||
1314 | } | 1311 | } | ||
1315 | ); | 1312 | ); | ||
1316 | } | 1313 | } | ||
1317 | } | 1314 | } | ||
1318 | 1315 | | |||
1319 | void SeatInterface::setFocusedTouchSurfacePosition(const QPointF &surfacePosition) | 1316 | void SeatInterface::setFocusedTouchSurfacePosition(const QPointF &surfacePosition) | ||
1320 | { | 1317 | { | ||
1321 | Q_D(); | 1318 | Q_D(); | ||
1322 | d->touchInterface.focus.offset = surfacePosition; | 1319 | d->globalTouch.focus.offset = surfacePosition; | ||
1323 | } | 1320 | } | ||
1324 | 1321 | | |||
1325 | qint32 SeatInterface::touchDown(const QPointF &globalPosition) | 1322 | qint32 SeatInterface::touchDown(const QPointF &globalPosition) | ||
1326 | { | 1323 | { | ||
1327 | Q_D(); | 1324 | Q_D(); | ||
1328 | const qint32 id = d->touchInterface.ids.isEmpty() ? 0 : d->touchInterface.ids.last() + 1; | 1325 | const qint32 id = d->globalTouch.ids.isEmpty() ? 0 : d->globalTouch.ids.last() + 1; | ||
1329 | const quint32 serial = display()->nextSerial(); | 1326 | const qint32 serial = display()->nextSerial(); | ||
1330 | if (d->touchInterface.focus.touch && d->touchInterface.focus.surface) { | 1327 | const auto pos = globalPosition - d->globalTouch.focus.offset; | ||
1331 | d->touchInterface.focus.touch->down(id, serial, globalPosition - d->touchInterface.focus.offset); | 1328 | for (auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) { | ||
1332 | } else if (id == 0 && focusedTouchSurface()) { | 1329 | (*it)->down(id, serial, pos); | ||
davidedmundson: what happened to the
if (id == 0 )
which is making sure if you multi touch we only send the… | |||||
romangg: Good catch. Thanks. | |||||
1330 | } | ||||
1331 | | ||||
1333 | #if HAVE_LINUX_INPUT_H | 1332 | #if HAVE_LINUX_INPUT_H | ||
1334 | const QPointF pos = globalPosition - d->touchInterface.focus.offset; | 1333 | if (id == 0 && d->globalTouch.focus.touchs.isEmpty()) { | ||
1334 | // If the client did not bind the touch interface fall back | ||||
1335 | // to at least emulating touch through pointer events. | ||||
1335 | forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, | 1336 | forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, | ||
1336 | [this, pos, serial] (PointerInterface *p) { | 1337 | [this, pos, serial] (PointerInterface *p) { | ||
1337 | wl_pointer_send_enter(p->resource(), serial, | 1338 | wl_pointer_send_enter(p->resource(), serial, | ||
1338 | focusedTouchSurface()->resource(), | 1339 | focusedTouchSurface()->resource(), | ||
1339 | wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); | 1340 | wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); | ||
1340 | wl_pointer_send_motion(p->resource(), timestamp(), | 1341 | wl_pointer_send_motion(p->resource(), timestamp(), | ||
1341 | wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); | 1342 | wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); | ||
1342 | 1343 | | |||
1343 | wl_pointer_send_button(p->resource(), serial, timestamp(), BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); | 1344 | wl_pointer_send_button(p->resource(), serial, timestamp(), BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); | ||
1344 | p->d_func()->sendFrame(); | 1345 | p->d_func()->sendFrame(); | ||
1345 | } | 1346 | } | ||
1346 | ); | 1347 | ); | ||
1347 | #endif | | |||
1348 | } | 1348 | } | ||
1349 | #endif | ||||
1349 | 1350 | | |||
1350 | d->touchInterface.ids << id; | 1351 | d->globalTouch.ids << id; | ||
1351 | return id; | 1352 | return id; | ||
1352 | } | 1353 | } | ||
1353 | 1354 | | |||
1354 | void SeatInterface::touchMove(qint32 id, const QPointF &globalPosition) | 1355 | void SeatInterface::touchMove(qint32 id, const QPointF &globalPosition) | ||
1355 | { | 1356 | { | ||
1356 | Q_D(); | 1357 | Q_D(); | ||
1357 | if (d->touchInterface.focus.touch && d->touchInterface.focus.surface) { | 1358 | Q_ASSERT(d->globalTouch.ids.contains(id)); | ||
If you have a release build Q_ASSERT get completely compiled out and no code will run. davidedmundson: If you have a release build Q_ASSERT get completely compiled out and no code will run.
| |||||
romangg: True, just our dev PCs will suffer. Ok, I will add the assert. | |||||
1358 | d->touchInterface.focus.touch->move(id, globalPosition - d->touchInterface.focus.offset); | 1359 | const auto pos = globalPosition - d->globalTouch.focus.offset; | ||
1359 | } else if (id == 0 && focusedTouchSurface()) { | 1360 | for (auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) { | ||
1360 | const QPointF pos = globalPosition - d->touchInterface.focus.offset; | 1361 | (*it)->move(id, pos); | ||
1362 | } | ||||
1363 | | ||||
1364 | if (id == 0 && d->globalTouch.focus.touchs.isEmpty()) { | ||||
1365 | // Client did not bind touch, fall back to emulating with pointer events. | ||||
1361 | forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, | 1366 | forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, | ||
1362 | [this, pos] (PointerInterface *p) { | 1367 | [this, pos] (PointerInterface *p) { | ||
1363 | wl_pointer_send_motion(p->resource(), timestamp(), | 1368 | wl_pointer_send_motion(p->resource(), timestamp(), | ||
1364 | wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); | 1369 | wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); | ||
1365 | } | 1370 | } | ||
1366 | ); | 1371 | ); | ||
1367 | } | 1372 | } | ||
1368 | } | 1373 | } | ||
1369 | 1374 | | |||
1370 | void SeatInterface::touchUp(qint32 id) | 1375 | void SeatInterface::touchUp(qint32 id) | ||
1371 | { | 1376 | { | ||
1372 | Q_D(); | 1377 | Q_D(); | ||
1373 | Q_ASSERT(d->touchInterface.ids.contains(id)); | 1378 | Q_ASSERT(d->globalTouch.ids.contains(id)); | ||
1374 | if (d->touchInterface.focus.touch && d->touchInterface.focus.surface) { | 1379 | const qint32 serial = display()->nextSerial(); | ||
1375 | d->touchInterface.focus.touch->up(id, display()->nextSerial()); | 1380 | for (auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) { | ||
1376 | } else if (id == 0 && focusedTouchSurface()) { | 1381 | (*it)->up(id, serial); | ||
1382 | } | ||||
1383 | | ||||
1377 | #if HAVE_LINUX_INPUT_H | 1384 | #if HAVE_LINUX_INPUT_H | ||
1385 | if (id == 0 && d->globalTouch.focus.touchs.isEmpty()) { | ||||
1386 | // Client did not bind touch, fall back to emulating with pointer events. | ||||
1378 | const quint32 serial = display()->nextSerial(); | 1387 | const quint32 serial = display()->nextSerial(); | ||
1379 | forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, | 1388 | forEachInterface<PointerInterface>(focusedTouchSurface(), d->pointers, | ||
1380 | [this, serial] (PointerInterface *p) { | 1389 | [this, serial] (PointerInterface *p) { | ||
1381 | wl_pointer_send_button(p->resource(), serial, timestamp(), BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); | 1390 | wl_pointer_send_button(p->resource(), serial, timestamp(), BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); | ||
1382 | } | 1391 | } | ||
1383 | ); | 1392 | ); | ||
1384 | #endif | | |||
1385 | } | 1393 | } | ||
1386 | d->touchInterface.ids.removeAll(id); | 1394 | #endif | ||
1395 | | ||||
1396 | d->globalTouch.ids.remove(id); | ||||
1387 | } | 1397 | } | ||
1388 | 1398 | | |||
1389 | void SeatInterface::touchFrame() | 1399 | void SeatInterface::touchFrame() | ||
1390 | { | 1400 | { | ||
1391 | Q_D(); | 1401 | Q_D(); | ||
1392 | if (d->touchInterface.focus.touch && d->touchInterface.focus.surface) { | 1402 | for (auto it = d->globalTouch.focus.touchs.constBegin(), end = d->globalTouch.focus.touchs.constEnd(); it != end; ++it) { | ||
1393 | d->touchInterface.focus.touch->frame(); | 1403 | (*it)->frame(); | ||
1394 | } | 1404 | } | ||
1395 | } | 1405 | } | ||
1396 | 1406 | | |||
1397 | bool SeatInterface::isDrag() const | 1407 | bool SeatInterface::isDrag() const | ||
1398 | { | 1408 | { | ||
1399 | Q_D(); | 1409 | Q_D(); | ||
1400 | return d->drag.mode != Private::Drag::Mode::None; | 1410 | return d->drag.mode != Private::Drag::Mode::None; | ||
1401 | } | 1411 | } | ||
▲ Show 20 Lines • Show All 127 Lines • Show Last 20 Lines |
what happened to the
if (id == 0 )
which is making sure if you multi touch we only send the first as a mouse event.