Merge branch 'master' of https://github.com/highfidelity/hifi into light

This commit is contained in:
samcake 2017-12-06 10:21:45 -08:00
commit 1efddb8260
10 changed files with 92 additions and 137 deletions

View file

@ -65,21 +65,23 @@ var EventBridge;
// we need to listen to events that might precede the addition of this elements. // 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?) // 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() { setTimeout(function() {
EventBridge.forceHtmlAudioOutputDeviceUpdate(); EventBridge.forceHtmlAudioOutputDeviceUpdate();
}, 1200); }, 1200);
}; }, false);
document.onclick = function(){
document.addEventListener("click",function(){
setTimeout(function() { setTimeout(function() {
EventBridge.forceHtmlAudioOutputDeviceUpdate(); EventBridge.forceHtmlAudioOutputDeviceUpdate();
}, 1200); }, 1200);
}; }, false);
document.onchange = function(){
document.addEventListener("change",function(){
setTimeout(function() { setTimeout(function() {
EventBridge.forceHtmlAudioOutputDeviceUpdate(); EventBridge.forceHtmlAudioOutputDeviceUpdate();
}, 1200); }, 1200);
}; }, false);
tempEventBridge._callbacks.forEach(function (callback) { tempEventBridge._callbacks.forEach(function (callback) {
EventBridge.scriptEventReceived.connect(callback); EventBridge.scriptEventReceived.connect(callback);

View file

@ -206,16 +206,6 @@ Item {
root.isPasswordField = (focus && passphraseField.echoMode === TextInput.Password); 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: { onAccepted: {
submitPassphraseInputButton.enabled = false; submitPassphraseInputButton.enabled = false;
commerce.setPassphrase(passphraseField.text); commerce.setPassphrase(passphraseField.text);
@ -362,25 +352,6 @@ Item {
right: parent.right; 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 { HifiControlsUit.Keyboard {
id: keyboard; id: keyboard;
raised: HMD.mounted && root.keyboardRaised; raised: HMD.mounted && root.keyboardRaised;

View file

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

View file

@ -667,25 +667,6 @@ Rectangle {
right: parent.right; 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 { HifiControlsUit.Keyboard {
id: keyboard; id: keyboard;
raised: HMD.mounted && root.keyboardRaised; raised: HMD.mounted && root.keyboardRaised;

View file

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

View file

@ -321,6 +321,16 @@ Wallet::Wallet() {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
getWalletStatus(); 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 { class AudioHandler : public QObject, QRunnable {
Q_OBJECT Q_OBJECT
public: public:
AudioHandler(QObject* container, const QString& deviceName, int runDelayMs = 0, QObject* parent = nullptr) : QObject(parent) { AudioHandler(QSharedPointer<OffscreenQmlSurface> surface, const QString& deviceName, QObject* parent = nullptr) : QObject(parent) {
_container = container;
_newTargetDevice = deviceName; _newTargetDevice = deviceName;
_runDelayMs = runDelayMs; _surface = surface;
setAutoDelete(true); setAutoDelete(true);
QThreadPool::globalInstance()->start(this); if (deviceName.size() > 0) {
QThreadPool::globalInstance()->start(this);
}
} }
virtual ~AudioHandler() { virtual ~AudioHandler() {
qDebug() << "Audio Handler Destroyed"; qDebug() << "Audio Handler Destroyed";
} }
void run() override { void run() override {
if (_newTargetDevice.isEmpty()) { if (!_surface.isNull() && _surface->getRootItem() && !_surface->getCleaned()) {
return; for (auto player : _surface->getRootItem()->findChildren<QMediaPlayer*>()) {
} auto mediaState = player->state();
if (_runDelayMs > 0) { QMediaService *svc = player->service();
QThread::msleep(_runDelayMs); if (nullptr == svc) {
} return;
auto audioIO = DependencyManager::get<AudioClient>(); }
QString deviceName = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName(); QAudioOutputSelectorControl *out = qobject_cast<QAudioOutputSelectorControl *>
for (auto player : _container->findChildren<QMediaPlayer*>()) { (svc->requestControl(QAudioOutputSelectorControl_iid));
auto mediaState = player->state(); if (nullptr == out) {
QMediaService *svc = player->service(); return;
if (nullptr == svc) { }
return; QString deviceOuput;
} auto outputs = out->availableOutputs();
QAudioOutputSelectorControl *out = qobject_cast<QAudioOutputSelectorControl *> for (int i = 0; i < outputs.size(); i++) {
(svc->requestControl(QAudioOutputSelectorControl_iid)); QString output = outputs[i];
if (nullptr == out) { QString description = out->outputDescription(output);
return; if (description == _newTargetDevice) {
} deviceOuput = output;
QString deviceOuput; break;
auto outputs = out->availableOutputs(); }
for (int i = 0; i < outputs.size(); i++) { }
QString output = outputs[i]; out->setActiveOutput(deviceOuput);
QString description = out->outputDescription(output); svc->releaseControl(out);
if (description == deviceName) { // if multimedia was paused, it will start playing automatically after changing audio device
deviceOuput = output; // this will reset it back to a paused state
break; 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: private:
QString _newTargetDevice; QString _newTargetDevice;
QObject* _container; QSharedPointer<OffscreenQmlSurface> _surface;
int _runDelayMs;
}; };
class OffscreenTextures { class OffscreenTextures {
@ -502,6 +497,7 @@ QOpenGLContext* OffscreenQmlSurface::getSharedContext() {
} }
void OffscreenQmlSurface::cleanup() { void OffscreenQmlSurface::cleanup() {
_isCleaned = true;
_canvas->makeCurrent(); _canvas->makeCurrent();
_renderControl->invalidate(); _renderControl->invalidate();
@ -600,6 +596,7 @@ OffscreenQmlSurface::OffscreenQmlSurface() {
OffscreenQmlSurface::~OffscreenQmlSurface() { OffscreenQmlSurface::~OffscreenQmlSurface() {
QObject::disconnect(&_updateTimer); QObject::disconnect(&_updateTimer);
disconnectAudioOutputTimer();
QObject::disconnect(qApp); QObject::disconnect(qApp);
cleanup(); cleanup();
@ -613,6 +610,15 @@ OffscreenQmlSurface::~OffscreenQmlSurface() {
void OffscreenQmlSurface::onAboutToQuit() { void OffscreenQmlSurface::onAboutToQuit() {
_paused = true; _paused = true;
QObject::disconnect(&_updateTimer); QObject::disconnect(&_updateTimer);
disconnectAudioOutputTimer();
}
void OffscreenQmlSurface::disconnectAudioOutputTimer() {
if (_audioOutputUpdateTimer.isActive()) {
_audioOutputUpdateTimer.stop();
}
QObject::disconnect(&_audioOutputUpdateTimer);
} }
void OffscreenQmlSurface::create() { 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, // 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. // a timer with a small interval is used to get better performance.
QObject::connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick); QObject::connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
@ -699,10 +713,11 @@ void OffscreenQmlSurface::forceQmlAudioOutputDeviceUpdate() {
QMetaObject::invokeMethod(this, "forceQmlAudioOutputDeviceUpdate", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "forceQmlAudioOutputDeviceUpdate", Qt::QueuedConnection);
} else { } else {
auto audioIO = DependencyManager::get<AudioClient>(); auto audioIO = DependencyManager::get<AudioClient>();
QString deviceName = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName(); _currentAudioOutputDevice = audioIO->getActiveAudioDevice(QAudio::AudioOutput).deviceName();
int waitForAudioQmlMs = 500; if (_audioOutputUpdateTimer.isActive()) {
// The audio device need to be change using oth _audioOutputUpdateTimer.stop();
new AudioHandler(_rootItem, deviceName, waitForAudioQmlMs); }
_audioOutputUpdateTimer.start();
} }
} }

View file

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

View file

@ -62,7 +62,7 @@
this.pointingAtTablet = function(controllerData) { this.pointingAtTablet = function(controllerData) {
var rayPick = controllerData.rayPicks[this.hand]; 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() { this.getOtherModule = function() {

View file

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