From ed6407d2bddb15fa3db5d4e52d899f0bafba4b6d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 16 Aug 2019 21:07:34 +1200 Subject: [PATCH 01/12] Fix callback functions' display in JSDoc --- tools/jsdoc/hifi-jsdoc-template/tmpl/container.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/jsdoc/hifi-jsdoc-template/tmpl/container.tmpl b/tools/jsdoc/hifi-jsdoc-template/tmpl/container.tmpl index 3796bab632..451ed4d01a 100644 --- a/tools/jsdoc/hifi-jsdoc-template/tmpl/container.tmpl +++ b/tools/jsdoc/hifi-jsdoc-template/tmpl/container.tmpl @@ -239,7 +239,7 @@ - + Date: Fri, 16 Aug 2019 10:57:03 -0700 Subject: [PATCH 02/12] Avatar sitting bug fixes * Added seatedToIdle transition, to make transition quicker to better match the capsule physics. * Made switching into and out of instantly set animVar for the animation graph, previously it was delayed by 100 ms. * Created "isNotSeated" anim var for exiting the seated state. * MyAvatar::beginSit & MyAvatar::endSit no longer calls goToPosition, instead MyAvatar::slamPosition is called. * MyAvatar::slamPosition will cause the AvatarTransit class to NOT play the teleport anticipation/reaction animation. Note: This does not prevent other clients from interpolating the position when entering the seat, but it prevents the teleport reaction animation from playing. * Disable leg IK in HMD mode while seated. --- .../resources/avatar/avatar-animation.json | 81 +++++++------------ interface/src/avatar/MyAvatar.cpp | 22 +++-- libraries/animation/src/Rig.cpp | 18 ++++- .../src/avatars-renderer/Avatar.cpp | 20 +++-- .../src/avatars-renderer/Avatar.h | 1 + 5 files changed, 75 insertions(+), 67 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index b23e1c74d9..29fed17ed6 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -3935,6 +3935,19 @@ }, "id": "LANDRUN", "type": "clip" + }, + { + "children": [ + ], + "data": { + "endFrame": 105, + "loopFlag": false, + "startFrame": 100, + "timeScale": 1, + "url": "qrc:///avatar/animations/idle.fbx" + }, + "id": "seatedToIdle", + "type": "clip" } ], "data": { @@ -3951,60 +3964,8 @@ "interpType": "snapshotPrev", "transitions": [ { - "state": "idle", - "var": "isNotMoving" - }, - { - "state": "WALKFWD", - "var": "isMovingForward" - }, - { - "state": "WALKBWD", - "var": "isMovingBackward" - }, - { - "state": "STRAFERIGHT", - "var": "isMovingRight" - }, - { - "state": "STRAFELEFT", - "var": "isMovingLeft" - }, - { - "state": "turnRight", - "var": "isTurningRight" - }, - { - "state": "turnLeft", - "var": "isTurningLeft" - }, - { - "state": "fly", - "var": "isFlying" - }, - { - "state": "takeoffStand", - "var": "isTakeoffStand" - }, - { - "state": "TAKEOFFRUN", - "var": "isTakeoffRun" - }, - { - "state": "inAirStand", - "var": "isInAirStand" - }, - { - "state": "INAIRRUN", - "var": "isInAirRun" - }, - { - "state": "strafeRightHmd", - "var": "isMovingRightHmd" - }, - { - "state": "strafeLeftHmd", - "var": "isMovingLeftHmd" + "state": "seatedToIdle", + "var": "isNotSeated" } ] }, @@ -4886,6 +4847,18 @@ "var": "landRunOnDone" } ] + }, + { + "id": "seatedToIdle", + "interpDuration": 10, + "interpTarget": 1, + "interpType": "snapshotPrev", + "transitions": [ + { + "state": "idle", + "var": "seatedToIdleOnDone" + } + ] } ] }, diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 28f6644d7f..0ff2e055b7 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -6245,31 +6245,43 @@ void MyAvatar::setSitDriveKeysStatus(bool enabled) { } void MyAvatar::beginSit(const glm::vec3& position, const glm::quat& rotation) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "beginSit", Q_ARG(glm::vec3, position), Q_ARG(glm::quat, rotation)); + return; + } + _characterController.setSeated(true); - setCollisionsEnabled(false); + setCollisionsEnabled(false); setHMDLeanRecenterEnabled(false); // Disable movement setSitDriveKeysStatus(false); centerBody(); int hipIndex = getJointIndex("Hips"); clearPinOnJoint(hipIndex); - goToLocation(position, true, rotation, false, false); pinJoint(hipIndex, position, rotation); } void MyAvatar::endSit(const glm::vec3& position, const glm::quat& rotation) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "endSit", Q_ARG(glm::vec3, position), Q_ARG(glm::quat, rotation)); + return; + } + if (_characterController.getSeated()) { clearPinOnJoint(getJointIndex("Hips")); _characterController.setSeated(false); setCollisionsEnabled(true); setHMDLeanRecenterEnabled(true); centerBody(); - goToLocation(position, true, rotation, false, false); + slamPosition(position); + setWorldOrientation(rotation); + + // the jump key is used to exit the chair. We add a delay here to prevent + // the avatar from jumping right as they exit the chair. float TIME_BEFORE_DRIVE_ENABLED_MS = 150.0f; QTimer::singleShot(TIME_BEFORE_DRIVE_ENABLED_MS, [this]() { // Enable movement again setSitDriveKeysStatus(true); }); } - -} \ No newline at end of file +} diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index d0204219ac..211c54def8 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1144,6 +1144,11 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER; } + // Skip hysterisis timer for sit transitions. + if (_desiredState == RigRole::Seated || _state == RigRole::Seated) { + _desiredStateAge = STATE_CHANGE_HYSTERESIS_TIMER; + } + if ((_desiredStateAge >= STATE_CHANGE_HYSTERESIS_TIMER) && _desiredState != _state) { _state = _desiredState; _desiredStateAge = 0.0f; @@ -1223,6 +1228,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInAirRun", false); _animVars.set("isNotInAir", true); _animVars.set("isSeated", false); + _animVars.set("isNotSeated", true); } else if (_state == RigRole::Turn) { if (turningSpeed > 0.0f) { @@ -1252,6 +1258,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInAirRun", false); _animVars.set("isNotInAir", true); _animVars.set("isSeated", false); + _animVars.set("isNotSeated", true); } else if (_state == RigRole::Idle) { // default anim vars to notMoving and notTurning @@ -1274,6 +1281,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInAirRun", false); _animVars.set("isNotInAir", true); _animVars.set("isSeated", false); + _animVars.set("isNotSeated", true); } else if (_state == RigRole::Hover) { // flying. @@ -1296,6 +1304,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInAirRun", false); _animVars.set("isNotInAir", true); _animVars.set("isSeated", false); + _animVars.set("isNotSeated", true); } else if (_state == RigRole::Takeoff) { // jumping in-air @@ -1326,6 +1335,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInAirRun", false); _animVars.set("isNotInAir", false); _animVars.set("isSeated", false); + _animVars.set("isNotSeated", true); } else if (_state == RigRole::InAir) { // jumping in-air @@ -1345,6 +1355,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isTakeoffRun", false); _animVars.set("isNotTakeoff", true); _animVars.set("isSeated", false); + _animVars.set("isNotSeated", true); bool inAirRun = forwardSpeed > 0.1f; if (inAirRun) { @@ -1386,6 +1397,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos _animVars.set("isInAirRun", false); _animVars.set("isNotInAir", true); _animVars.set("isSeated", true); + _animVars.set("isNotSeated", false); } t += deltaTime; @@ -1821,8 +1833,10 @@ void Rig::updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabl int hipsIndex = indexOfJoint("Hips"); const float KNEE_POLE_VECTOR_BLEND_FACTOR = 0.85f; - if (headEnabled) { - // always do IK if head is enabled + bool isSeated = _state == RigRole::Seated; + + if (headEnabled && !isSeated) { + // enable leg IK if head is enabled and we arent sitting down. _animVars.set("leftFootIKEnabled", true); _animVars.set("rightFootIKEnabled", true); } else { diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index a7e4a0ae9f..0038f46761 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -131,7 +131,7 @@ AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& av } else { _lastPosition = avatarPosition; _status = Status::ABORT_TRANSIT; - } + } } _lastPosition = avatarPosition; _status = updatePosition(deltaTime); @@ -143,11 +143,18 @@ AvatarTransit::Status AvatarTransit::update(float deltaTime, const glm::vec3& av return _status; } +void AvatarTransit::slamPosition(const glm::vec3& avatarPosition) { + // used to instantly teleport between two points without triggering a change in status. + _lastPosition = avatarPosition; + _endPosition = avatarPosition; +} + void AvatarTransit::reset() { _lastPosition = _endPosition; _currentPosition = _endPosition; _isActive = false; } + void AvatarTransit::start(float deltaTime, const glm::vec3& startPosition, const glm::vec3& endPosition, const AvatarTransit::TransitConfig& config) { _startPosition = startPosition; _endPosition = endPosition; @@ -192,8 +199,8 @@ AvatarTransit::Status AvatarTransit::updatePosition(float deltaTime) { status = Status::PRE_TRANSIT; if (_currentTime == 0) { status = Status::STARTED; - } - } else if (nextTime < _totalTime - _postTransitTime){ + } + } else if (nextTime < _totalTime - _postTransitTime) { status = Status::TRANSITING; if (_currentTime <= _preTransitTime) { status = Status::START_TRANSIT; @@ -519,10 +526,10 @@ void Avatar::relayJointDataToChildren() { * * "avatar" or ""The rate at which the avatar is updated even if not in view. * "avatarInView"The rate at which the avatar is updated if in view. - * "skeletonModel"The rate at which the skeleton model is being updated, even if there are no + * "skeletonModel"The rate at which the skeleton model is being updated, even if there are no * joint data available. * "jointData"The rate at which joint data are being updated. - * ""When no rate name is specified, the "avatar" update rate is + * ""When no rate name is specified, the "avatar" update rate is * provided. * * @@ -557,6 +564,7 @@ void Avatar::slamPosition(const glm::vec3& newPosition) { _positionDeltaAccumulator = glm::vec3(0.0f); setWorldVelocity(glm::vec3(0.0f)); _lastVelocity = glm::vec3(0.0f); + _transit.slamPosition(newPosition); } void Avatar::updateAttitude(const glm::quat& orientation) { @@ -1533,7 +1541,7 @@ void Avatar::setModelURLFinished(bool success) { QMetaObject::invokeMethod(_skeletonModel.get(), "setURL", Qt::QueuedConnection, Q_ARG(QUrl, AvatarData::defaultFullAvatarModelUrl())); } else { - qCWarning(avatars_renderer) << "Avatar model failed to load... attempts:" + qCWarning(avatars_renderer) << "Avatar model failed to load... attempts:" << _skeletonModel->getResourceDownloadAttempts() << "out of:" << MAX_SKELETON_DOWNLOAD_ATTEMPTS; } } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index ee0fb6f433..7bb15ecbf7 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -93,6 +93,7 @@ public: AvatarTransit() {}; Status update(float deltaTime, const glm::vec3& avatarPosition, const TransitConfig& config); + void slamPosition(const glm::vec3& avatarPosition); Status getStatus() { return _status; } bool isActive() { return _isActive; } glm::vec3 getCurrentPosition() { return _currentPosition; } From 150b4e45d42dc4dff21c7121066833f0dfb1283e Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 16 Aug 2019 17:30:28 -0700 Subject: [PATCH 03/12] More robust handling of the avatar verify-failed property --- interface/src/avatar/MyAvatar.h | 3 +++ interface/src/commerce/Wallet.cpp | 7 ++++++- .../src/avatars-renderer/Avatar.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 13 +++++++++++++ libraries/avatars/src/AvatarData.h | 2 +- libraries/avatars/src/AvatarHashMap.cpp | 4 ---- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index ad45df892b..bb6f036533 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1866,6 +1866,9 @@ public: // also clears internal reaction triggers void updateRigControllerParameters(Rig::ControllerParameters& params); + // Don't substitute verify-fail: + virtual const QUrl& getSkeletonModelURL() const override { return _skeletonModelURL; } + public slots: /**jsdoc diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 5af7a357b0..c449874117 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -830,9 +830,14 @@ void Wallet::handleChallengeOwnershipPacket(QSharedPointer pack } void Wallet::sendChallengeOwnershipResponses() { - if (_pendingChallenges.size() == 0 || getSalt().length() == 0) { + if (_pendingChallenges.size() == 0) { return; } + if (getSalt().length() == 0) { + qCDebug(commerce) << "Not responding to ownership challenge due to missing Wallet salt"; + return; + } + auto nodeList = DependencyManager::get(); EC_KEY* ec = readKeys(keyFilePath()); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index a7e4a0ae9f..9d88dd47ea 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1511,7 +1511,7 @@ void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { } indicateLoadingStatus(LoadingStatus::LoadModel); - _skeletonModel->setURL(_skeletonModelURL); + _skeletonModel->setURL(getSkeletonModelURL()); } void Avatar::setModelURLFinished(bool success) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 7d5f38db40..72bead6e74 100755 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1988,6 +1988,7 @@ void AvatarData::processAvatarIdentity(QDataStream& packetStream, bool& identity if (flagValue != _verificationFailed) { _verificationFailed = flagValue; identityChanged = true; + setSkeletonModelURL(_skeletonModelURL); } if (identity.attachmentData != _attachmentData) { @@ -2016,6 +2017,18 @@ QUrl AvatarData::getWireSafeSkeletonModelURL() const { return QUrl(); } } + +static const QString VERIFY_FAIL_MODEL { "/meshes/verifyFailed.fst" }; + +const QUrl& AvatarData::getSkeletonModelURL() const { + if (_verificationFailed) { + static QUrl VERIFY_FAIL_MODEL_URL = PathUtils::resourcesUrl(VERIFY_FAIL_MODEL); + return VERIFY_FAIL_MODEL_URL; + } else { + return _skeletonModelURL; + } +} + QByteArray AvatarData::packSkeletonData() const { // Send an avatar trait packet with the skeleton data before the mesh is loaded int avatarDataSize = 0; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 20c5b1900d..59a2e2a53e 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1205,7 +1205,7 @@ public: QByteArray identityByteArray(bool setIsReplicated = false) const; QUrl getWireSafeSkeletonModelURL() const; - const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } + virtual const QUrl& getSkeletonModelURL() const; const QString& getDisplayName() const { return _displayName; } const QString& getSessionDisplayName() const { return _sessionDisplayName; } diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 0c7054424f..d0b315b524 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -330,10 +330,6 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer bool displayNameChanged = false; // In this case, the "sendingNode" is the Avatar Mixer. avatar->processAvatarIdentity(avatarIdentityStream, identityChanged, displayNameChanged); - if (avatar->isCertifyFailed() && identityUUID != EMPTY) { - qCDebug(avatars) << "Avatar" << avatar->getSessionDisplayName() << "marked as VERIFY-FAILED"; - avatar->setSkeletonModelURL(PathUtils::resourcesUrl(VERIFY_FAIL_MODEL)); - } _replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged); } } From 2fafb6822db237b58f417cd1d77b7da8b6bb4237 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 16 Aug 2019 18:03:20 -0700 Subject: [PATCH 04/12] Remove identity-resend hack - shouldn't be required now --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index d874100ca2..46ca51219d 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -157,11 +157,6 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis ++simpleReceivedIt; } - if (bytesWritten > 0 && sendingAvatar->isCertifyFailed()) { - // Resend identity packet if certification failed: - sendingAvatar->setNeedsIdentityUpdate(); - } - // enumerate the received instanced trait versions auto instancedReceivedIt = lastReceivedVersions.instancedCBegin(); while (instancedReceivedIt != lastReceivedVersions.instancedCEnd()) { From dbb964d4156996a2975b5695f13ba8c8a0403427 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 17 Aug 2019 16:56:01 +1200 Subject: [PATCH 05/12] Report type of callback as "function" in JSDoc --- tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl b/tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl index 8c78643b3e..d101a036f1 100644 --- a/tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl +++ b/tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl @@ -13,7 +13,10 @@ var self = this; + } ?> + +
Type: + From 11f8387a5a2c3670338c5033ef09a6833b69538a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 17 Aug 2019 16:56:35 +1200 Subject: [PATCH 06/12] Fix typo noticed in passing --- tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl b/tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl index d101a036f1..8db1df8a77 100644 --- a/tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl +++ b/tools/jsdoc/hifi-jsdoc-template/tmpl/method.tmpl @@ -66,7 +66,7 @@ var self = this; - +
Type:
  • From abad9868ae5ec9e7d5f911f34fa634850b4d23b3 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 19 Aug 2019 12:12:10 -0700 Subject: [PATCH 07/12] Log when avatar data becomes avatar-failed --- libraries/avatars/src/AvatarData.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 72bead6e74..c03f9430be 100755 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1989,7 +1989,10 @@ void AvatarData::processAvatarIdentity(QDataStream& packetStream, bool& identity _verificationFailed = flagValue; identityChanged = true; setSkeletonModelURL(_skeletonModelURL); - } + if (_verificationFailed) { + qCDebug(avatars) << "Avatar" << getSessionDisplayName() << "marked as VERIFY-FAILED"; + } + }; if (identity.attachmentData != _attachmentData) { setAttachmentData(identity.attachmentData); From 8097ecef11de7eeeb155416cfa013e9b4fa84d50 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 19 Aug 2019 15:44:06 -0700 Subject: [PATCH 08/12] Fix cmd-leftclick not working correctly on Mac OS On Mac OS, Cmd+LeftClick is treated as a RightClick (more specifically, it seems to be Cmd+RightClick without the modifier being dropped). Starting in Qt 5.12, only on Mac, the MouseButtonRelease event for these mouse presses are sent to the top level QWidgetWindow, but are not propagated further. The change here gets around this problem by capturing these pseudo-RightClicks, and re-emitting them as "pure" RightClicks. --- interface/src/Application.cpp | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1803b5e19f..2a310df7f5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4235,12 +4235,43 @@ bool Application::event(QEvent* event) { } bool Application::eventFilter(QObject* object, QEvent* event) { + auto eventType = event->type(); - if (_aboutToQuit && event->type() != QEvent::DeferredDelete && event->type() != QEvent::Destroy) { + if (_aboutToQuit && eventType != QEvent::DeferredDelete && eventType != QEvent::Destroy) { return true; } - auto eventType = event->type(); +#if defined(Q_OS_MAC) + // On Mac OS, Cmd+LeftClick is treated as a RightClick (more specifically, it seems to + // be Cmd+RightClick without the modifier being dropped). Starting in Qt 5.12, only + // on Mac, the MouseButtonRelease event for these mouse presses is sent to the top + // level QWidgetWindow, but are not propagated further. This means that the Application + // will see a MouseButtonPress, but no MouseButtonRelease, causing the client to get + // stuck in "mouse-look." The cause of the problem is in the way QWidgetWindow processes + // events where QMouseEvent::button() is not equal to QMouseEvent::buttons(). In this case + // QMouseEvent::button() is Qt::RightButton, while QMouseEvent::buttons() is (correctly?) + // Qt::LeftButton. + // + // The change here gets around this problem by capturing these + // pseudo-RightClicks, and re-emitting them as "pure" RightClicks, where + // QMouseEvent::button() == QMouseEvent::buttons() == Qt::RightButton. + // + if (eventType == QEvent::MouseButtonPress) { + auto mouseEvent = static_cast(event); + if (mouseEvent->button() == Qt::RightButton + && mouseEvent->buttons() == Qt::LeftButton + && mouseEvent->modifiers() == Qt::MetaModifier) { + + QMouseEvent* newEvent = new QMouseEvent( + QEvent::MouseButtonPress, mouseEvent->localPos(), mouseEvent->windowPos(), + mouseEvent->screenPos(), Qt::RightButton, Qt::MouseButtons(Qt::RightButton), + mouseEvent->modifiers()); + QApplication::postEvent(object, newEvent); + return true; + } + } +#endif + if (eventType == QEvent::KeyPress || eventType == QEvent::KeyRelease || eventType == QEvent::MouseMove) { getRefreshRateManager().resetInactiveTimer(); } From 78edfb9af947ccb4a354e7888e2e481edeb63204 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 19 Aug 2019 17:22:38 -0700 Subject: [PATCH 09/12] Remove 'About' tab from Settings --- .../simplifiedUI/settingsApp/SettingsApp.qml | 14 - .../simplifiedUI/settingsApp/about/About.qml | 332 ------------------ .../settingsApp/about/images/logo.png | Bin 16487 -> 0 bytes 3 files changed, 346 deletions(-) delete mode 100644 interface/resources/qml/hifi/simplifiedUI/settingsApp/about/About.qml delete mode 100644 interface/resources/qml/hifi/simplifiedUI/settingsApp/about/images/logo.png diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml index ecc8bac2a7..c9857afcec 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml @@ -17,8 +17,6 @@ import "./audio" as AudioSettings import "./general" as GeneralSettings import "./vr" as VrSettings import "./dev" as DevSettings -import "./about" as AboutSettings - Rectangle { property string activeTabView: "generalTabView" id: root @@ -86,10 +84,6 @@ Rectangle { tabTitle: "VR" tabViewName: "vrTabView" } - ListElement { - tabTitle: "About" - tabViewName: "aboutTabView" - } ListElement { tabTitle: "Dev" tabViewName: "devTabView" @@ -190,12 +184,6 @@ Rectangle { anchors.fill: parent } - AboutSettings.About { - id: aboutTabViewContainer - visible: activeTabView === "aboutTabView" - anchors.fill: parent - } - SimplifiedControls.VerticalScrollBar { parent: { if (activeTabView === "generalTabView") { @@ -206,8 +194,6 @@ Rectangle { vrTabViewContainer } else if (activeTabView === "devTabView") { devTabViewContainer - } else if (activeTabView === "aboutTabView") { - aboutTabViewContainer } } } diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/about/About.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/about/About.qml deleted file mode 100644 index 89cccb8ecd..0000000000 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/about/About.qml +++ /dev/null @@ -1,332 +0,0 @@ -// -// About.qml -// -// Created by Zach Fox on 2019-06-18 -// Copyright 2019 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -import QtQuick 2.10 -import QtQuick.Controls 2.3 -import "../../simplifiedConstants" as SimplifiedConstants -import "../../simplifiedControls" as SimplifiedControls -import stylesUit 1.0 as HifiStylesUit -import QtQuick.Layouts 1.3 - -Flickable { - id: root - contentWidth: parent.width - contentHeight: aboutColumnLayout.height - clip: true - - onVisibleChanged: { - if (visible) { - root.contentX = 0; - root.contentY = 0; - - // When the user clicks the About tab, refresh the audio I/O model so that - // the delegate Component.onCompleted handlers fire, which will update - // the text that appears in the About screen. - audioOutputDevices.model = undefined; - audioOutputDevices.model = AudioScriptingInterface.devices.output; - audioInputDevices.model = undefined; - audioInputDevices.model = AudioScriptingInterface.devices.input; - } - } - - - SimplifiedConstants.SimplifiedConstants { - id: simplifiedUI - } - - - ColumnLayout { - id: aboutColumnLayout - anchors.left: parent.left - anchors.leftMargin: 26 - anchors.right: parent.right - anchors.rightMargin: 26 - anchors.top: parent.top - spacing: 0 - - Image { - source: "images/logo.png" - Layout.alignment: Qt.AlignHCenter - Layout.topMargin: 16 - Layout.preferredWidth: 160 - Layout.preferredHeight: 120 - fillMode: Image.PreserveAspectFit - mipmap: true - } - - ColumnLayout { - id: platformInfoContainer - Layout.preferredWidth: parent.width - Layout.bottomMargin: 24 - spacing: 0 - - HifiStylesUit.GraphikSemiBold { - text: "Version " + Window.checkVersion() - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - HifiStylesUit.GraphikSemiBold { - text: "Platform Info" - Layout.preferredWidth: parent.width - Layout.topMargin: 8 - Layout.bottomMargin: 8 - height: paintedHeight - size: 22 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - HifiStylesUit.GraphikRegular { - text: "Computer Vendor/Model:" - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - - Component.onCompleted: { - var computer = JSON.parse(PlatformInfo.getComputer()); - var computerVendor = computer.vendor; - if (computerVendor.length === 0) { - computerVendor = "Unknown"; - } - var computerModel = computer.model; - if (computerModel.length === 0) { - computerModel = "Unknown"; - } - - text = "Computer Vendor/Model: " + computerVendor + "/" + computerModel; - } - } - - HifiStylesUit.GraphikRegular { - text: "Profiled Platform Tier: " + PlatformInfo.getTierProfiled() - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - HifiStylesUit.GraphikRegular { - text: "OS Type: " + PlatformInfo.getOperatingSystemType() - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - HifiStylesUit.GraphikRegular { - text: "CPU:" - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - - Component.onCompleted: { - var cpu = JSON.parse(PlatformInfo.getCPU(0)); - var cpuModel = cpu.model; - if (cpuModel.length === 0) { - cpuModel = "Unknown"; - } - - text = "CPU: " + cpuModel; - } - } - - HifiStylesUit.GraphikRegular { - text: "# CPUs: " + PlatformInfo.getNumCPUs() - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - HifiStylesUit.GraphikRegular { - text: "# CPU Cores: " + PlatformInfo.getNumLogicalCores() - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - HifiStylesUit.GraphikRegular { - text: "RAM: " + PlatformInfo.getTotalSystemMemoryMB() + " MB" - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - HifiStylesUit.GraphikRegular { - text: "GPU: " - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - - Component.onCompleted: { - var gpu = JSON.parse(PlatformInfo.getGPU(PlatformInfo.getMasterGPU())); - var gpuModel = gpu.model; - if (gpuModel.length === 0) { - gpuModel = "Unknown"; - } - - text = "GPU: " + gpuModel; - } - } - - HifiStylesUit.GraphikRegular { - text: "VR Hand Controllers: " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None")) - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - // This is a bit of a hack to get the name of the currently-selected audio input device - // in the current mode (Desktop or VR). The reason this is necessary is because it seems to me like - // the only way one can get a human-readable list of the audio I/O devices is by using a ListView - // and grabbing the names from the AudioScriptingInterface; you can't do it using a ListModel. - // See `AudioDevices.h`, specifically the comment above the declaration of `QVariant data()`. - ListView { - id: audioInputDevices - visible: false - property string selectedInputDeviceName - Layout.preferredWidth: parent.width - Layout.preferredHeight: contentItem.height - interactive: false - delegate: Item { - Component.onCompleted: { - if (HMD.active && selectedHMD) { - audioInputDevices.selectedInputDeviceName = model.devicename - } else if (!HMD.active && selectedDesktop) { - audioInputDevices.selectedInputDeviceName = model.devicename - } - } - } - } - - HifiStylesUit.GraphikRegular { - text: "Audio Input: " + audioInputDevices.selectedInputDeviceName - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - - // This is a bit of a hack to get the name of the currently-selected audio output device - // in the current mode (Desktop or VR). The reason this is necessary is because it seems to me like - // the only way one can get a human-readable list of the audio I/O devices is by using a ListView - // and grabbing the names from the AudioScriptingInterface; you can't do it using a ListModel. - // See `AudioDevices.h`, specifically the comment above the declaration of `QVariant data()`. - ListView { - id: audioOutputDevices - visible: false - property string selectedOutputDeviceName - Layout.preferredWidth: parent.width - Layout.preferredHeight: contentItem.height - interactive: false - delegate: Item { - Component.onCompleted: { - if (HMD.active && selectedHMD) { - audioOutputDevices.selectedOutputDeviceName = model.devicename - } else if (!HMD.active && selectedDesktop) { - audioOutputDevices.selectedOutputDeviceName = model.devicename - } - } - } - } - - HifiStylesUit.GraphikRegular { - text: "Audio Output: " + audioOutputDevices.selectedOutputDeviceName - Layout.preferredWidth: parent.width - height: paintedHeight - size: 16 - color: simplifiedUI.colors.text.white - wrapMode: Text.Wrap - } - - SimplifiedControls.Button { - Layout.topMargin: 8 - width: 200 - height: 32 - text: "Copy to Clipboard" - temporaryText: "Copied!" - - onClicked: { - Window.copyToClipboard(root.buildPlatformInfoTextToCopy()); - showTemporaryText(); - } - } - } - } - - function buildPlatformInfoTextToCopy() { - var textToCopy = "**About Interface**\n"; - textToCopy += "Interface Version: " + Window.checkVersion() + "\n"; - textToCopy += "\n**Platform Info**\n"; - - var computer = JSON.parse(PlatformInfo.getComputer()); - var computerVendor = computer.vendor; - if (computerVendor.length === 0) { - computerVendor = "Unknown"; - } - var computerModel = computer.model; - if (computerModel.length === 0) { - computerModel = "Unknown"; - } - - textToCopy += "Computer Vendor/Model: " + computerVendor + "/" + computerModel + "\n"; - textToCopy += "Profiled Platform Tier: " + PlatformInfo.getTierProfiled() + "\n"; - textToCopy += "OS Type: " + PlatformInfo.getOperatingSystemType() + "\n"; - - var cpu = JSON.parse(PlatformInfo.getCPU(0)); - var cpuModel = cpu.model; - if (cpuModel.length === 0) { - cpuModel = "Unknown"; - } - - textToCopy += "CPU: " + cpuModel + "\n"; - textToCopy += "# CPUs: " + PlatformInfo.getNumCPUs() + "\n"; - textToCopy += "# CPU Cores: " + PlatformInfo.getNumLogicalCores() + "\n"; - textToCopy += "RAM: " + PlatformInfo.getTotalSystemMemoryMB() + " MB\n"; - - var gpu = JSON.parse(PlatformInfo.getGPU(PlatformInfo.getMasterGPU())); - var gpuModel = gpu.model; - if (gpuModel.length === 0) { - gpuModel = "Unknown"; - } - - textToCopy += "GPU: " + gpuModel + "\n"; - textToCopy += "VR Hand Controllers: " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None")) + "\n"; - textToCopy += "Audio Input: " + audioInputDevices.selectedInputDeviceName + "\n"; - textToCopy += "Audio Output: " + audioOutputDevices.selectedOutputDeviceName + "\n"; - - textToCopy += "\n**All Platform Info**\n"; - textToCopy += JSON.stringify(JSON.parse(PlatformInfo.getPlatform()), null, 4); - - return textToCopy; - } -} diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/about/images/logo.png b/interface/resources/qml/hifi/simplifiedUI/settingsApp/about/images/logo.png deleted file mode 100644 index d480da86ddc13c61dee02443563bfed4022ecdbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16487 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 From 0cc28c58ae60b55ae9b69ffd58dd09eb672c8775 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 20 Aug 2019 10:54:58 -0700 Subject: [PATCH 10/12] DEV-415: Implement Support tab in Help app --- .../qml/hifi/simplifiedUI/helpApp/HelpApp.qml | 13 +++ .../helpApp/support/HelpSupport.qml | 85 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 interface/resources/qml/hifi/simplifiedUI/helpApp/support/HelpSupport.qml diff --git a/interface/resources/qml/hifi/simplifiedUI/helpApp/HelpApp.qml b/interface/resources/qml/hifi/simplifiedUI/helpApp/HelpApp.qml index d8238d35cf..0ebbe49963 100644 --- a/interface/resources/qml/hifi/simplifiedUI/helpApp/HelpApp.qml +++ b/interface/resources/qml/hifi/simplifiedUI/helpApp/HelpApp.qml @@ -16,6 +16,7 @@ import stylesUit 1.0 as HifiStylesUit import "./controls" as HelpControls import "./faq" as HelpFAQ import "./about" as HelpAbout +import "./support" as HelpSupport Rectangle { property string activeTabView: "controlsTabView" @@ -59,6 +60,10 @@ Rectangle { tabTitle: "Controls" tabViewName: "controlsTabView" } + ListElement { + tabTitle: "Support" + tabViewName: "supportTabView" + } ListElement { tabTitle: "FAQ" tabViewName: "faqTabView" @@ -139,6 +144,12 @@ Rectangle { anchors.fill: parent } + HelpSupport.HelpSupport { + id: supportTabViewContainer + visible: activeTabView === "supportTabView" + anchors.fill: parent + } + HelpFAQ.HelpFAQ { id: faqTabViewContainer visible: activeTabView === "faqTabView" @@ -159,6 +170,8 @@ Rectangle { parent: { if (activeTabView === "controlsTabView") { controlsTabViewContainer + } else if (activeTabView === "supportTabView") { + supportTabViewContainer } else if (activeTabView === "faqTabView") { faqTabViewContainer } else if (activeTabView === "aboutTabView") { diff --git a/interface/resources/qml/hifi/simplifiedUI/helpApp/support/HelpSupport.qml b/interface/resources/qml/hifi/simplifiedUI/helpApp/support/HelpSupport.qml new file mode 100644 index 0000000000..31b9593f09 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/helpApp/support/HelpSupport.qml @@ -0,0 +1,85 @@ +// +// HelpSupport.qml +// +// Created by Zach Fox on 2019-08-20 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.10 +import QtQuick.Controls 2.3 +import "../../simplifiedConstants" as SimplifiedConstants +import "../../simplifiedControls" as SimplifiedControls +import stylesUit 1.0 as HifiStylesUit +import QtQuick.Layouts 1.3 + +Item { + id: root + width: parent.width + height: parent.height + + + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + + Image { + id: accent + source: "../images/accent2.svg" + anchors.left: parent.left + anchors.top: parent.top + width: 83 + height: 156 + transform: Scale { + xScale: -1 + origin.x: accent.width / 2 + origin.y: accent.height / 2 + } + } + + + ColumnLayout { + anchors.left: parent.left + anchors.leftMargin: 26 + anchors.right: parent.right + anchors.rightMargin: 26 + anchors.top: parent.top + spacing: 0 + + HifiStylesUit.GraphikSemiBold { + text: "Support" + Layout.preferredWidth: parent.width + Layout.preferredHeight: paintedHeight + Layout.topMargin: 16 + size: 22 + color: simplifiedUI.colors.text.white + } + + HifiStylesUit.GraphikRegular { + text: "You can quickly get the support that you need by clicking the button below." + Layout.preferredWidth: parent.width + Layout.preferredHeight: paintedHeight + Layout.topMargin: 8 + size: 18 + wrapMode: Text.Wrap + color: simplifiedUI.colors.text.white + } + + SimplifiedControls.Button { + Layout.topMargin: 8 + width: 200 + height: 32 + text: "CONTACT SUPPORT" + temporaryText: "Opening browser..." + + onClicked: { + Qt.openUrlExternally("https://www.highfidelity.com/knowledge/kb-tickets/new"); + } + } + } + + signal sendToScript(var message); +} From bb97b4f8664f547cdf50ce6260f951715cad33ac Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 20 Aug 2019 11:17:05 -0700 Subject: [PATCH 11/12] Fix BUGZ-1303: Make 'View All Controls' go to knowledge base --- .../qml/hifi/simplifiedUI/helpApp/controls/HelpControls.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/simplifiedUI/helpApp/controls/HelpControls.qml b/interface/resources/qml/hifi/simplifiedUI/helpApp/controls/HelpControls.qml index 01c5187aa5..b4f7bd76c0 100644 --- a/interface/resources/qml/hifi/simplifiedUI/helpApp/controls/HelpControls.qml +++ b/interface/resources/qml/hifi/simplifiedUI/helpApp/controls/HelpControls.qml @@ -88,7 +88,7 @@ Flickable { temporaryText: "Viewing!" onClicked: { - Qt.openUrlExternally("http://docs.highfidelity.com/explore/get-started/desktop.html"); + Qt.openUrlExternally("https://www.highfidelity.com/knowledge/get-around"); } } } From 780a081d16fd826836309229295453a6b1a54bb8 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 20 Aug 2019 12:05:00 -0700 Subject: [PATCH 12/12] Remove unused TabletAddressDialog internal property, fixing BUGZ-1294 --- interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index 1342e55b5d..fdb05c8a35 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -225,10 +225,6 @@ StackView { verticalCenter: addressLineContainer.verticalCenter; } - onFocusChanged: { - addressBarDialog.raised = focus; - } - onTextChanged: { updateLocationText(text.length > 0); }