Merge branch 'master' of github.com:highfidelity/hifi into fix-collision-mask-for-children

This commit is contained in:
Dante Ruiz 2017-12-05 15:48:45 -08:00
commit 36aa0ae476
15 changed files with 118 additions and 153 deletions

View file

@ -65,21 +65,23 @@ var EventBridge;
// we need to listen to events that might precede the addition of this elements.
// A more robust hack will be to add a setInterval that look for DOM changes every 100-300 ms (low performance?)
window.onload = function(){
window.addEventListener("load",function(event) {
setTimeout(function() {
EventBridge.forceHtmlAudioOutputDeviceUpdate();
}, 1200);
};
document.onclick = function(){
}, false);
document.addEventListener("click",function(){
setTimeout(function() {
EventBridge.forceHtmlAudioOutputDeviceUpdate();
}, 1200);
};
document.onchange = function(){
}, false);
document.addEventListener("change",function(){
setTimeout(function() {
EventBridge.forceHtmlAudioOutputDeviceUpdate();
}, 1200);
};
}, false);
tempEventBridge._callbacks.forEach(function (callback) {
EventBridge.scriptEventReceived.connect(callback);

View file

@ -12,9 +12,9 @@
var MAX_WARNINGS = 3;
var numWarnings = 0;
var isWindowFocused = true;
var isKeyboardRaised = false;
var isNumericKeyboard = false;
var isPasswordField = false;
window.isKeyboardRaised = false;
window.isNumericKeyboard = false;
window.isPasswordField = false;
function shouldSetPasswordField() {
var nodeType = document.activeElement.type;
@ -62,7 +62,7 @@
var passwordField = shouldSetPasswordField();
if (isWindowFocused &&
(keyboardRaised !== isKeyboardRaised || numericKeyboard !== isNumericKeyboard || passwordField !== isPasswordField)) {
(keyboardRaised !== window.isKeyboardRaised || numericKeyboard !== window.isNumericKeyboard || passwordField !== window.isPasswordField)) {
if (typeof EventBridge !== "undefined" && EventBridge !== null) {
EventBridge.emitWebEvent(
@ -75,20 +75,20 @@
}
}
if (!isKeyboardRaised) {
if (!window.isKeyboardRaised) {
scheduleBringToView(250); // Allow time for keyboard to be raised in QML.
// 2DO: should it be rather done from 'client area height changed' event?
}
isKeyboardRaised = keyboardRaised;
isNumericKeyboard = numericKeyboard;
isPasswordField = passwordField;
window.isKeyboardRaised = keyboardRaised;
window.isNumericKeyboard = numericKeyboard;
window.isPasswordField = passwordField;
}
}, POLL_FREQUENCY);
window.addEventListener("click", function () {
var keyboardRaised = shouldRaiseKeyboard();
if(keyboardRaised && isKeyboardRaised) {
if (keyboardRaised && window.isKeyboardRaised) {
scheduleBringToView(150);
}
});
@ -99,7 +99,7 @@
window.addEventListener("blur", function () {
isWindowFocused = false;
isKeyboardRaised = false;
isNumericKeyboard = false;
window.isKeyboardRaised = false;
window.isNumericKeyboard = false;
});
})();

View file

@ -206,16 +206,6 @@ Item {
root.isPasswordField = (focus && passphraseField.echoMode === TextInput.Password);
}
MouseArea {
anchors.fill: parent;
onClicked: {
root.keyboardRaised = true;
root.isPasswordField = (passphraseField.echoMode === TextInput.Password);
mouse.accepted = false;
}
}
onAccepted: {
submitPassphraseInputButton.enabled = false;
commerce.setPassphrase(passphraseField.text);
@ -362,25 +352,6 @@ Item {
right: parent.right;
}
Image {
id: lowerKeyboardButton;
z: 999;
source: "images/lowerKeyboard.png";
anchors.right: keyboard.right;
anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
height: 50;
width: 60;
MouseArea {
anchors.fill: parent;
onClicked: {
root.keyboardRaised = false;
}
}
}
HifiControlsUit.Keyboard {
id: keyboard;
raised: HMD.mounted && root.keyboardRaised;

View file

@ -82,17 +82,6 @@ Item {
if (focus) {
var hidePassword = (currentPassphraseField.echoMode === TextInput.Password);
sendSignalToWallet({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword});
} else if (!passphraseFieldAgain.focus) {
sendSignalToWallet({method: 'walletSetup_lowerKeyboard', isPasswordField: false});
}
}
MouseArea {
anchors.fill: parent;
onPressed: {
var hidePassword = (currentPassphraseField.echoMode === TextInput.Password);
sendSignalToWallet({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword});
mouse.accepted = false;
}
}
@ -115,21 +104,10 @@ Item {
activeFocusOnPress: true;
activeFocusOnTab: true;
MouseArea {
anchors.fill: parent;
onPressed: {
var hidePassword = (passphraseField.echoMode === TextInput.Password);
sendSignalToWallet({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword});
mouse.accepted = false;
}
}
onFocusChanged: {
if (focus) {
var hidePassword = (passphraseField.echoMode === TextInput.Password);
sendMessageToLightbox({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword});
} else if (!passphraseFieldAgain.focus) {
sendMessageToLightbox({method: 'walletSetup_lowerKeyboard', isPasswordField: false});
}
}
@ -151,21 +129,10 @@ Item {
activeFocusOnPress: true;
activeFocusOnTab: true;
MouseArea {
anchors.fill: parent;
onPressed: {
var hidePassword = (passphraseFieldAgain.echoMode === TextInput.Password);
sendSignalToWallet({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword});
mouse.accepted = false;
}
}
onFocusChanged: {
if (focus) {
var hidePassword = (passphraseFieldAgain.echoMode === TextInput.Password);
sendMessageToLightbox({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword});
} else if (!passphraseField.focus) {
sendMessageToLightbox({method: 'walletSetup_lowerKeyboard', isPasswordField: false});
}
}

View file

@ -47,6 +47,7 @@ Rectangle {
} else if (walletStatus === 1) {
if (root.activeView !== "walletSetup") {
root.activeView = "walletSetup";
commerce.resetLocalWalletOnly();
}
} else if (walletStatus === 2) {
if (root.activeView !== "passphraseModal") {
@ -666,25 +667,6 @@ Rectangle {
right: parent.right;
}
Image {
id: lowerKeyboardButton;
z: 999;
source: "images/lowerKeyboard.png";
anchors.right: keyboard.right;
anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
height: 50;
width: 60;
MouseArea {
anchors.fill: parent;
onClicked: {
root.keyboardRaised = false;
}
}
}
HifiControlsUit.Keyboard {
id: keyboard;
raised: HMD.mounted && root.keyboardRaised;

View file

@ -68,6 +68,7 @@ Item {
Connections {
target: GlobalServices
onMyUsernameChanged: {
transactionHistoryModel.clear();
usernameText.text = Account.username;
}
}

View file

@ -371,7 +371,7 @@ Item {
Item {
id: securityImageTip;
visible: false;
visible: !root.hasShownSecurityImageTip && root.activeView === "step_3";
z: 999;
anchors.fill: root;
@ -421,7 +421,6 @@ Item {
text: "Got It";
onClicked: {
root.hasShownSecurityImageTip = true;
securityImageTip.visible = false;
passphraseSelection.focusFirstTextField();
}
}
@ -439,9 +438,6 @@ Item {
onVisibleChanged: {
if (visible) {
commerce.getWalletAuthenticatedStatus();
if (!root.hasShownSecurityImageTip) {
securityImageTip.visible = true;
}
}
}
@ -732,6 +728,7 @@ Item {
text: "Finish";
onClicked: {
root.visible = false;
root.hasShownSecurityImageTip = false;
sendSignalToWallet({method: 'walletSetup_finished', referrer: root.referrer ? root.referrer : ""});
}
}

View file

@ -128,6 +128,11 @@ void QmlCommerce::reset() {
wallet->reset();
}
void QmlCommerce::resetLocalWalletOnly() {
auto wallet = DependencyManager::get<Wallet>();
wallet->reset();
}
void QmlCommerce::account() {
auto ledger = DependencyManager::get<Ledger>();
ledger->account();

View file

@ -65,6 +65,7 @@ protected:
Q_INVOKABLE void history();
Q_INVOKABLE void generateKeyPair();
Q_INVOKABLE void reset();
Q_INVOKABLE void resetLocalWalletOnly();
Q_INVOKABLE void account();
Q_INVOKABLE void certificateInfo(const QString& certificateId);

View file

@ -321,6 +321,16 @@ Wallet::Wallet() {
auto accountManager = DependencyManager::get<AccountManager>();
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
getWalletStatus();
_publicKeys.clear();
if (_securityImage) {
delete _securityImage;
}
_securityImage = nullptr;
// tell the provider we got nothing
updateImageProvider();
_passphrase->clear();
});
}

View file

@ -121,63 +121,58 @@ uint64_t uvec2ToUint64(const uvec2& v) {
class AudioHandler : public QObject, QRunnable {
Q_OBJECT
public:
AudioHandler(QObject* container, const QString& deviceName, int runDelayMs = 0, QObject* parent = nullptr) : QObject(parent) {
_container = container;
AudioHandler(QSharedPointer<OffscreenQmlSurface> surface, const QString& deviceName, QObject* parent = nullptr) : QObject(parent) {
_newTargetDevice = deviceName;
_runDelayMs = runDelayMs;
_surface = surface;
setAutoDelete(true);
QThreadPool::globalInstance()->start(this);
if (deviceName.size() > 0) {
QThreadPool::globalInstance()->start(this);
}
}
virtual ~AudioHandler() {
qDebug() << "Audio Handler Destroyed";
}
void run() override {
if (_newTargetDevice.isEmpty()) {
return;
}
if (_runDelayMs > 0) {
QThread::msleep(_runDelayMs);
}
auto audioIO = DependencyManager::get<AudioClient>();
QString deviceName = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName();
for (auto player : _container->findChildren<QMediaPlayer*>()) {
auto mediaState = player->state();
QMediaService *svc = player->service();
if (nullptr == svc) {
return;
}
QAudioOutputSelectorControl *out = qobject_cast<QAudioOutputSelectorControl *>
(svc->requestControl(QAudioOutputSelectorControl_iid));
if (nullptr == out) {
return;
}
QString deviceOuput;
auto outputs = out->availableOutputs();
for (int i = 0; i < outputs.size(); i++) {
QString output = outputs[i];
QString description = out->outputDescription(output);
if (description == deviceName) {
deviceOuput = output;
break;
if (!_surface.isNull() && _surface->getRootItem() && !_surface->getCleaned()) {
for (auto player : _surface->getRootItem()->findChildren<QMediaPlayer*>()) {
auto mediaState = player->state();
QMediaService *svc = player->service();
if (nullptr == svc) {
return;
}
QAudioOutputSelectorControl *out = qobject_cast<QAudioOutputSelectorControl *>
(svc->requestControl(QAudioOutputSelectorControl_iid));
if (nullptr == out) {
return;
}
QString deviceOuput;
auto outputs = out->availableOutputs();
for (int i = 0; i < outputs.size(); i++) {
QString output = outputs[i];
QString description = out->outputDescription(output);
if (description == _newTargetDevice) {
deviceOuput = output;
break;
}
}
out->setActiveOutput(deviceOuput);
svc->releaseControl(out);
// if multimedia was paused, it will start playing automatically after changing audio device
// this will reset it back to a paused state
if (mediaState == QMediaPlayer::State::PausedState) {
player->pause();
}
else if (mediaState == QMediaPlayer::State::StoppedState) {
player->stop();
}
}
out->setActiveOutput(deviceOuput);
svc->releaseControl(out);
// if multimedia was paused, it will start playing automatically after changing audio device
// this will reset it back to a paused state
if (mediaState == QMediaPlayer::State::PausedState) {
player->pause();
} else if (mediaState == QMediaPlayer::State::StoppedState) {
player->stop();
}
}
qDebug() << "QML Audio changed to " << deviceName;
qDebug() << "QML Audio changed to " << _newTargetDevice;
}
private:
QString _newTargetDevice;
QObject* _container;
int _runDelayMs;
QSharedPointer<OffscreenQmlSurface> _surface;
};
class OffscreenTextures {
@ -502,6 +497,7 @@ QOpenGLContext* OffscreenQmlSurface::getSharedContext() {
}
void OffscreenQmlSurface::cleanup() {
_isCleaned = true;
_canvas->makeCurrent();
_renderControl->invalidate();
@ -600,6 +596,7 @@ OffscreenQmlSurface::OffscreenQmlSurface() {
OffscreenQmlSurface::~OffscreenQmlSurface() {
QObject::disconnect(&_updateTimer);
disconnectAudioOutputTimer();
QObject::disconnect(qApp);
cleanup();
@ -613,6 +610,15 @@ OffscreenQmlSurface::~OffscreenQmlSurface() {
void OffscreenQmlSurface::onAboutToQuit() {
_paused = true;
QObject::disconnect(&_updateTimer);
disconnectAudioOutputTimer();
}
void OffscreenQmlSurface::disconnectAudioOutputTimer() {
if (_audioOutputUpdateTimer.isActive()) {
_audioOutputUpdateTimer.stop();
}
QObject::disconnect(&_audioOutputUpdateTimer);
}
void OffscreenQmlSurface::create() {
@ -671,6 +677,14 @@ void OffscreenQmlSurface::create() {
}
});
// Setup the update of the QML media components with the current audio output device
QObject::connect(&_audioOutputUpdateTimer, &QTimer::timeout, this, [this]() {
new AudioHandler(sharedFromThis(), _currentAudioOutputDevice);
});
int waitForAudioQmlMs = 200;
_audioOutputUpdateTimer.setInterval(waitForAudioQmlMs);
_audioOutputUpdateTimer.setSingleShot(true);
// When Quick says there is a need to render, we will not render immediately. Instead,
// a timer with a small interval is used to get better performance.
QObject::connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
@ -699,10 +713,11 @@ void OffscreenQmlSurface::forceQmlAudioOutputDeviceUpdate() {
QMetaObject::invokeMethod(this, "forceQmlAudioOutputDeviceUpdate", Qt::QueuedConnection);
} else {
auto audioIO = DependencyManager::get<AudioClient>();
QString deviceName = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName();
int waitForAudioQmlMs = 500;
// The audio device need to be change using oth
new AudioHandler(_rootItem, deviceName, waitForAudioQmlMs);
_currentAudioOutputDevice = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName();
if (_audioOutputUpdateTimer.isActive()) {
_audioOutputUpdateTimer.stop();
}
_audioOutputUpdateTimer.start();
}
}

View file

@ -40,7 +40,7 @@ class QQuickItem;
using QmlContextCallback = std::function<void(QQmlContext*, QObject*)>;
class OffscreenQmlSurface : public QObject {
class OffscreenQmlSurface : public QObject, public QEnableSharedFromThis<OffscreenQmlSurface> {
Q_OBJECT
Q_PROPERTY(bool focusText READ isFocusText NOTIFY focusTextChanged)
public:
@ -75,6 +75,7 @@ public:
void pause();
void resume();
bool isPaused() const;
bool getCleaned() { return _isCleaned; }
void setBaseUrl(const QUrl& baseUrl);
QQuickItem* getRootItem();
@ -116,6 +117,7 @@ public slots:
void changeAudioOutputDevice(const QString& deviceName, bool isHtmlUpdate = false);
void forceHtmlAudioOutputDeviceUpdate();
void forceQmlAudioOutputDeviceUpdate();
signals:
void audioOutputDeviceChanged(const QString& deviceName);
@ -147,6 +149,7 @@ private:
void render();
void cleanup();
QJsonObject getGLContextData();
void disconnectAudioOutputTimer();
private slots:
void updateQuick();
@ -170,6 +173,9 @@ private:
uint64_t _lastRenderTime { 0 };
uvec2 _size;
QTimer _audioOutputUpdateTimer;
QString _currentAudioOutputDevice;
// Texture management
TextureAndFence _latestTextureAndFence { 0, 0 };
@ -177,6 +183,7 @@ private:
bool _polish { true };
bool _paused { true };
bool _focusText { false };
bool _isCleaned{ false };
uint8_t _maxFps { 60 };
MouseTranslator _mouseTranslator { [](const QPointF& p) { return p.toPoint(); } };
QWindow* _proxyWindow { nullptr };

View file

@ -62,7 +62,7 @@
this.pointingAtTablet = function(controllerData) {
var rayPick = controllerData.rayPicks[this.hand];
return (rayPick.objectID === HMD.tabletScreenID || rayPick.objectID === HMD.homeButtonID);
return (HMD.tabletScreenID && HMD.homeButtonID && (rayPick.objectID === HMD.tabletScreenID || rayPick.objectID === HMD.homeButtonID));
};
this.getOtherModule = function() {

View file

@ -81,7 +81,8 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
};
this.otherHandIsParent = function(props) {
return this.getOtherModule().thisHandIsParent(props);
var otherModule = this.getOtherModule();
return (otherModule.thisHandIsParent(props) && otherModule.grabbing);
};
this.startNearParentingGrabEntity = function (controllerData, targetProps) {

View file

@ -15,6 +15,9 @@ function setUpKeyboardControl() {
var KEYBOARD_HEIGHT = 200;
function raiseKeyboard() {
window.isKeyboardRaised = true;
window.isNumericKeyboard = this.type === "number";
if (lowerTimer !== null) {
clearTimeout(lowerTimer);
lowerTimer = null;
@ -35,6 +38,9 @@ function setUpKeyboardControl() {
}
function doLowerKeyboard() {
window.isKeyboardRaised = false;
window.isNumericKeyboard = false;
EventBridge.emitWebEvent("_LOWER_KEYBOARD");
lowerTimer = null;
isRaised = false;