diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index 4f24b46ece..1ea9891732 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -148,13 +148,22 @@ MyAvatar::MyAvatar(RigPointer rig) :
     auto player = DependencyManager::get<Deck>();
     auto recorder = DependencyManager::get<Recorder>();
     connect(player.data(), &Deck::playbackStateChanged, [=] {
-        if (player->isPlaying()) {
+        bool isPlaying = player->isPlaying();
+        if (isPlaying) {
             auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
             if (recordingInterface->getPlayFromCurrentLocation()) {
                 setRecordingBasis();
             }
         } else {
             clearRecordingBasis();
+            useFullAvatarURL(_fullAvatarURLFromPreferences, _fullAvatarModelName);
+        }
+
+        auto audioIO = DependencyManager::get<AudioClient>();
+        audioIO->setIsPlayingBackRecording(isPlaying);
+
+        if (_rig) {
+            _rig->setEnableAnimations(!isPlaying);
         }
     });
 
@@ -180,8 +189,8 @@ MyAvatar::MyAvatar(RigPointer rig) :
 
         if (recordingInterface->getPlayerUseSkeletonModel() && dummyAvatar.getSkeletonModelURL().isValid() &&
             (dummyAvatar.getSkeletonModelURL() != getSkeletonModelURL())) {
-            // FIXME
-            //myAvatar->useFullAvatarURL()
+
+            setSkeletonModelURL(dummyAvatar.getSkeletonModelURL());
         }
 
         if (recordingInterface->getPlayerUseDisplayName() && dummyAvatar.getDisplayName() != getDisplayName()) {
@@ -204,6 +213,11 @@ MyAvatar::MyAvatar(RigPointer rig) :
             // head orientation
             _headData->setLookAtPosition(headData->getLookAtPosition());
         }
+
+        auto jointData = dummyAvatar.getRawJointData();
+        if (jointData.length() > 0 && _rig) {
+            _rig->copyJointsFromJointData(jointData);
+        }
     });
 
     connect(rig.get(), SIGNAL(onLoadComplete()), this, SIGNAL(onLoadComplete()));
@@ -471,7 +485,9 @@ void MyAvatar::simulate(float deltaTime) {
     {
         PerformanceTimer perfTimer("joints");
         // copy out the skeleton joints from the model
-        _rig->copyJointsIntoJointData(_jointData);
+        if (_rigEnabled) {
+            _rig->copyJointsIntoJointData(_jointData);
+        }
     }
 
     {
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index d94d1088e2..4f86256a2f 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -485,6 +485,7 @@ private:
     std::unordered_set<int> _headBoneSet;
     RigPointer _rig;
     bool _prevShouldDrawHead;
+    bool _rigEnabled { true };
 
     bool _enableDebugDrawDefaultPose { false };
     bool _enableDebugDrawAnimPose { false };
diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp
index ac16b16c1d..07462e9878 100644
--- a/libraries/animation/src/Rig.cpp
+++ b/libraries/animation/src/Rig.cpp
@@ -483,6 +483,10 @@ void Rig::setEnableInverseKinematics(bool enable) {
     _enableInverseKinematics = enable;
 }
 
+void Rig::setEnableAnimations(bool enable) {
+    _enabledAnimations = enable;
+}
+
 AnimPose Rig::getAbsoluteDefaultPose(int index) const {
     if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) {
         return _absoluteDefaultPoses[index];
@@ -907,7 +911,7 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
 
     setModelOffset(rootTransform);
 
-    if (_animNode) {
+    if (_animNode && _enabledAnimations) {
         PerformanceTimer perfTimer("handleTriggers");
 
         updateAnimationStateHandlers();
diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h
index aa091fe10c..78a669b249 100644
--- a/libraries/animation/src/Rig.h
+++ b/libraries/animation/src/Rig.h
@@ -210,6 +210,7 @@ public:
     void computeAvatarBoundingCapsule(const FBXGeometry& geometry, float& radiusOut, float& heightOut, glm::vec3& offsetOut) const;
 
     void setEnableInverseKinematics(bool enable);
+    void setEnableAnimations(bool enable);
 
     const glm::mat4& getGeometryToRigTransform() const { return _geometryToRigTransform; }
 
@@ -314,6 +315,7 @@ protected:
     int32_t _numOverrides { 0 };
     bool _lastEnableInverseKinematics { true };
     bool _enableInverseKinematics { true };
+    bool _enabledAnimations { true };
 
     mutable uint32_t _jointNameWarningCount { 0 };
 
diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp
index 081d74a5aa..bd141cfb12 100644
--- a/libraries/audio-client/src/AudioClient.cpp
+++ b/libraries/audio-client/src/AudioClient.cpp
@@ -39,13 +39,10 @@
 #include <plugins/CodecPlugin.h>
 #include <plugins/PluginManager.h>
 #include <udt/PacketHeaders.h>
-#include <PositionalAudioStream.h>
 #include <SettingHandle.h>
 #include <SharedUtil.h>
-#include <UUID.h>
 #include <Transform.h>
 
-#include "PositionalAudioStream.h"
 #include "AudioClientLogging.h"
 #include "AudioLogging.h"
 
@@ -294,12 +291,12 @@ QString friendlyNameForAudioDevice(IMMDevice* pEndpoint) {
     IPropertyStore* pPropertyStore;
     pEndpoint->OpenPropertyStore(STGM_READ, &pPropertyStore);
     pEndpoint->Release();
-    pEndpoint = NULL;
+    pEndpoint = nullptr;
     PROPVARIANT pv;
     PropVariantInit(&pv);
     HRESULT hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &pv);
     pPropertyStore->Release();
-    pPropertyStore = NULL;
+    pPropertyStore = nullptr;
     deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal);
     if (!IsWindows8OrGreater()) {
         // Windows 7 provides only the 31 first characters of the device name.
@@ -313,9 +310,9 @@ QString friendlyNameForAudioDevice(IMMDevice* pEndpoint) {
 QString AudioClient::friendlyNameForAudioDevice(wchar_t* guid) {
     QString deviceName;
     HRESULT hr = S_OK;
-    CoInitialize(NULL);
-    IMMDeviceEnumerator* pMMDeviceEnumerator = NULL;
-    CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator);
+    CoInitialize(nullptr);
+    IMMDeviceEnumerator* pMMDeviceEnumerator = nullptr;
+    CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator);
     IMMDevice* pEndpoint;
     hr = pMMDeviceEnumerator->GetDevice(guid, &pEndpoint);
     if (hr == E_NOTFOUND) {
@@ -325,7 +322,7 @@ QString AudioClient::friendlyNameForAudioDevice(wchar_t* guid) {
         deviceName = ::friendlyNameForAudioDevice(pEndpoint);
     }
     pMMDeviceEnumerator->Release();
-    pMMDeviceEnumerator = NULL;
+    pMMDeviceEnumerator = nullptr;
     CoUninitialize();
     return deviceName;
 }
@@ -968,8 +965,7 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
 }
 
 void AudioClient::handleAudioInput() {
-
-    if (!_inputDevice) {
+    if (!_inputDevice || _isPlayingBackRecording) {
         return;
     }
 
diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h
index 453444ccdd..5619051eaf 100644
--- a/libraries/audio-client/src/AudioClient.h
+++ b/libraries/audio-client/src/AudioClient.h
@@ -147,6 +147,8 @@ public:
     void setPositionGetter(AudioPositionGetter positionGetter) { _positionGetter = positionGetter; }
     void setOrientationGetter(AudioOrientationGetter orientationGetter) { _orientationGetter = orientationGetter; }
 
+    void setIsPlayingBackRecording(bool isPlayingBackRecording) { _isPlayingBackRecording = isPlayingBackRecording; }
+
     Q_INVOKABLE void setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 scale);
 
     void checkDevices();
@@ -369,10 +371,12 @@ private:
     QVector<QString> _inputDevices;
     QVector<QString> _outputDevices;
 
-    bool _hasReceivedFirstPacket = false;
+    bool _hasReceivedFirstPacket { false };
 
     QVector<AudioInjector*> _activeLocalAudioInjectors;
 
+    bool _isPlayingBackRecording { false };
+
     CodecPluginPointer _codec;
     QString _selectedCodecName;
     Encoder* _encoder { nullptr }; // for outbound mic stream
diff --git a/libraries/audio/src/AudioInjectorOptions.cpp b/libraries/audio/src/AudioInjectorOptions.cpp
index 1a92697828..0af74a796c 100644
--- a/libraries/audio/src/AudioInjectorOptions.cpp
+++ b/libraries/audio/src/AudioInjectorOptions.cpp
@@ -91,4 +91,4 @@ void injectorOptionsFromScriptValue(const QScriptValue& object, AudioInjectorOpt
             qCWarning(audio) << "Unknown audio injector option:" << it.name();
         }
     }
- }
\ No newline at end of file
+}
diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp
index 6a01c2930c..c1dd60a3b0 100644
--- a/libraries/avatars/src/AvatarData.cpp
+++ b/libraries/avatars/src/AvatarData.cpp
@@ -37,6 +37,7 @@
 #include <ShapeInfo.h>
 #include <AudioHelpers.h>
 #include <Profile.h>
+#include <VariantMapToScriptValue.h>
 
 #include "AvatarLogging.h"
 
@@ -2379,3 +2380,37 @@ std::priority_queue<AvatarPriority> AvatarData::sortAvatars(
     }
     return sortedAvatars;
 }
+
+QScriptValue AvatarEntityMapToScriptValue(QScriptEngine* engine, const AvatarEntityMap& value) {
+    QScriptValue obj = engine->newObject();
+    for (auto entityID : value.keys()) {
+        QByteArray entityProperties = value.value(entityID);
+        QJsonDocument jsonEntityProperties = QJsonDocument::fromBinaryData(entityProperties);
+        if (!jsonEntityProperties.isObject()) {
+            qCDebug(avatars) << "bad AvatarEntityData in AvatarEntityMap" << QString(entityProperties.toHex());
+        }
+        
+        QVariant variantEntityProperties = jsonEntityProperties.toVariant();
+        QVariantMap entityPropertiesMap = variantEntityProperties.toMap();
+        QScriptValue scriptEntityProperties = variantMapToScriptValue(entityPropertiesMap, *engine);
+        
+        QString key = entityID.toString();
+        obj.setProperty(key, scriptEntityProperties);
+    }
+    return obj;
+}
+
+void AvatarEntityMapFromScriptValue(const QScriptValue& object, AvatarEntityMap& value) {
+    QScriptValueIterator itr(object);
+    while (itr.hasNext()) {
+        itr.next();
+        QUuid EntityID = QUuid(itr.name());
+        
+        QScriptValue scriptEntityProperties = itr.value();
+        QVariant variantEntityProperties = scriptEntityProperties.toVariant();
+        QJsonDocument jsonEntityProperties = QJsonDocument::fromVariant(variantEntityProperties);
+        QByteArray binaryEntityProperties = jsonEntityProperties.toBinaryData();
+        
+        value[EntityID] = binaryEntityProperties;
+    }
+}
diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h
index 3797132274..12209d9c31 100644
--- a/libraries/avatars/src/AvatarData.h
+++ b/libraries/avatars/src/AvatarData.h
@@ -46,6 +46,7 @@ typedef unsigned long long quint64;
 #include <QVariantMap>
 #include <QVector>
 #include <QtScript/QScriptable>
+#include <QtScript/QScriptValueIterator>
 #include <QReadWriteLock>
 
 #include <JointData.h>
@@ -847,6 +848,11 @@ Q_DECLARE_METATYPE(RayToAvatarIntersectionResult)
 QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, const RayToAvatarIntersectionResult& results);
 void RayToAvatarIntersectionResultFromScriptValue(const QScriptValue& object, RayToAvatarIntersectionResult& results);
 
+Q_DECLARE_METATYPE(AvatarEntityMap)
+
+QScriptValue AvatarEntityMapToScriptValue(QScriptEngine* engine, const AvatarEntityMap& value);
+void AvatarEntityMapFromScriptValue(const QScriptValue& object, AvatarEntityMap& value);
+
 // faux joint indexes (-1 means invalid)
 const int SENSOR_TO_WORLD_MATRIX_INDEX = 65534; // -2
 const int CONTROLLER_RIGHTHAND_INDEX = 65533; // -3
diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp
index f1ff4c4686..83f2f5ccc0 100644
--- a/libraries/script-engine/src/ScriptEngine.cpp
+++ b/libraries/script-engine/src/ScriptEngine.cpp
@@ -576,6 +576,7 @@ void ScriptEngine::init() {
     qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
     qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
     qScriptRegisterMetaType(this, RayToAvatarIntersectionResultToScriptValue, RayToAvatarIntersectionResultFromScriptValue);
+    qScriptRegisterMetaType(this, AvatarEntityMapToScriptValue, AvatarEntityMapFromScriptValue);
     qScriptRegisterSequenceMetaType<QVector<QUuid>>(this);
     qScriptRegisterSequenceMetaType<QVector<EntityItemID>>(this);
 
diff --git a/libraries/script-engine/src/TabletScriptingInterface.cpp b/libraries/script-engine/src/TabletScriptingInterface.cpp
index d66bb4d2f6..32bd7f422e 100644
--- a/libraries/script-engine/src/TabletScriptingInterface.cpp
+++ b/libraries/script-engine/src/TabletScriptingInterface.cpp
@@ -366,6 +366,7 @@ void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaS
     }
 
     if (root) {
+        removeButtonsFromHomeScreen();
         QMetaObject::invokeMethod(root, "loadSource", Q_ARG(const QVariant&, QVariant(WEB_VIEW_SOURCE_URL)));
         QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true)));
         QMetaObject::invokeMethod(root, "loadWebUrl", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectedJavaScriptUrl)));
diff --git a/scripts/developer/utilities/record/recorder.js b/scripts/developer/utilities/record/recorder.js
index 083037461d..0e335116d5 100644
--- a/scripts/developer/utilities/record/recorder.js
+++ b/scripts/developer/utilities/record/recorder.js
@@ -12,14 +12,14 @@
 HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
 Script.include("/~/system/libraries/toolBars.js");
 
-var recordingFile = "recording.rec";
+var recordingFile = "recording.hfr";
 
 function setPlayerOptions() {
     Recording.setPlayFromCurrentLocation(true);
     Recording.setPlayerUseDisplayName(false);
     Recording.setPlayerUseAttachments(false);
     Recording.setPlayerUseHeadModel(false);
-    Recording.setPlayerUseSkeletonModel(false);
+    Recording.setPlayerUseSkeletonModel(true);
 }
 
 var windowDimensions = Controller.getViewportDimensions();
@@ -142,7 +142,6 @@ function setupTimer() {
         backgroundAlpha: 1.0,
         visible: true
     });
-
 }
 
 function updateTimer() {
@@ -272,7 +271,7 @@ function mousePressEvent(event) {
         }
     } else if (loadIcon === toolBar.clicked(clickedOverlay)) {
         if (!Recording.isRecording() && !Recording.isPlaying()) {
-            recordingFile = Window.browse("Load recorcding from file", ".", "Recordings (*.hfr *.rec *.HFR *.REC)");
+            recordingFile = Window.browse("Load recording from file", ".", "Recordings (*.hfr *.rec *.HFR *.REC)");
             if (!(recordingFile === "null" || recordingFile === null || recordingFile === "")) {
                 Recording.loadRecording(recordingFile);
             }
@@ -345,5 +344,3 @@ Script.scriptEnding.connect(scriptEnding);
 
 // Should be called last to put everything into position
 moveUI();
-
-
diff --git a/scripts/system/audio.js b/scripts/system/audio.js
index c0fdb43b40..6e7e95d659 100644
--- a/scripts/system/audio.js
+++ b/scripts/system/audio.js
@@ -16,19 +16,51 @@
 var TABLET_BUTTON_NAME = "AUDIO";
 var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
 
+var MUTE_ICONS = {
+    icon: "icons/tablet-icons/mic-mute-i.svg",
+    activeIcon: "icons/tablet-icons/mic-mute-a.svg"
+};
+
+var UNMUTE_ICONS = {
+    icon: "icons/tablet-icons/mic-unmute-i.svg",
+    activeIcon: "icons/tablet-icons/mic-unmute-a.svg"
+};
+
 function onMuteToggled() {
-    button.editProperties({ isActive: AudioDevice.getMuted() });
+    if (AudioDevice.getMuted()) {
+        button.editProperties(MUTE_ICONS);
+    } else {
+        button.editProperties(UNMUTE_ICONS);
+    }
 }
-function onClicked(){
-    var entity = HMD.tabletID;
-    Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) });
-    tablet.gotoMenuScreen("Audio");
+
+var shouldActivateButton = false;
+var onAudioScreen = false;
+
+function onClicked() {
+    if (onAudioScreen) {
+        // for toolbar-mode: go back to home screen, this will close the window.
+        tablet.gotoHomeScreen();
+    } else {
+        var entity = HMD.tabletID;
+        Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) });
+        shouldActivateButton = true;
+        tablet.gotoMenuScreen("Audio");
+        onAudioScreen = true;
+    }
+}
+
+function onScreenChanged(type, url) {
+    // for toolbar mode: change button to active when window is first openend, false otherwise.
+    button.editProperties({isActive: shouldActivateButton});
+    shouldActivateButton = false;
+    onAudioScreen = false;
 }
 
 var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
 var button = tablet.addButton({
-    icon: "icons/tablet-icons/mic-unmute-i.svg",
-    activeIcon: "icons/tablet-icons/mic-mute-a.svg",
+    icon: AudioDevice.getMuted() ? MUTE_ICONS.icon : UNMUTE_ICONS.icon,
+    activeIcon: AudioDevice.getMuted() ? MUTE_ICONS.activeIcon : UNMUTE_ICONS.activeIcon,
     text: TABLET_BUTTON_NAME,
     sortOrder: 1
 });
@@ -36,10 +68,12 @@ var button = tablet.addButton({
 onMuteToggled();
 
 button.clicked.connect(onClicked);
+tablet.screenChanged.connect(onScreenChanged);
 AudioDevice.muteToggled.connect(onMuteToggled);
 
 Script.scriptEnding.connect(function () {
     button.clicked.disconnect(onClicked);
+    tablet.screenChanged.disconnect(onScreenChanged);
     AudioDevice.muteToggled.disconnect(onMuteToggled);
     tablet.removeButton(button);
 });
diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js
index 95c05c2717..ea76490b7b 100644
--- a/scripts/system/controllers/handControllerGrab.js
+++ b/scripts/system/controllers/handControllerGrab.js
@@ -1233,7 +1233,13 @@ function MyController(hand) {
         });
         if (grabbableEntities.length > 0) {
             if (!this.grabPointIntersectsEntity) {
-                Controller.triggerHapticPulse(1, 20, this.hand);
+                // don't do haptic pulse for tablet
+                var nonTabletEntities = grabbableEntities.filter(function(entityID) {
+                    return entityID != HMD.tabletID && entityID != HMD.homeButtonID;
+                });
+                if (nonTabletEntities.length > 0) {
+                    Controller.triggerHapticPulse(1, 20, this.hand);
+                }
                 this.grabPointIntersectsEntity = true;
                 this.grabPointSphereOn();
             }
diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js
index 0990440801..367ef05aea 100644
--- a/scripts/system/libraries/WebTablet.js
+++ b/scripts/system/libraries/WebTablet.js
@@ -49,24 +49,30 @@ function calcSpawnInfo(hand, height) {
         var handController = getControllerWorldLocation(hand, true);
         var controllerPosition = handController.position;
 
-        // compute the angle of the chord with length (height / 2)
-        var theta = Math.asin(height / (2 * Vec3.distance(headPos, controllerPosition)));
+        // base of the tablet is slightly above controller position
+        var TABLET_BASE_DISPLACEMENT = {x: 0, y: 0.1, z: 0};
+        var tabletBase = Vec3.sum(controllerPosition, TABLET_BASE_DISPLACEMENT);
 
-        // then we can use this angle to rotate the vector between the HMD position and the center of the tablet.
-        // this vector, u, will become our new look at direction.
-        var d = Vec3.normalize(Vec3.subtract(headPos, controllerPosition));
+        var d = Vec3.subtract(headPos, tabletBase);
+        var theta = Math.acos(d.y / Vec3.length(d));
+        d.y = 0;
+        if (Vec3.length(d) < 0.0001) {
+            d = {x: 1, y: 0, z: 0};
+        } else {
+            d = Vec3.normalize(d);
+        }
         var w = Vec3.normalize(Vec3.cross(Y_AXIS, d));
-        var q = Quat.angleAxis(theta * (180 / Math.PI), w);
+        var ANGLE_OFFSET = 25;
+        var q = Quat.angleAxis(theta * (180 / Math.PI) - (90 - ANGLE_OFFSET), w);
         var u = Vec3.multiplyQbyV(q, d);
 
         // use u to compute a full lookAt quaternion.
-        var lookAtRot = Quat.lookAt(controllerPosition, Vec3.sum(controllerPosition, u), Y_AXIS);
-
-        // adjust the tablet position by a small amount.
-        var yDisplacement = (height / 2) + 0.1;
+        var lookAtRot = Quat.lookAt(tabletBase, Vec3.sum(tabletBase, u), Y_AXIS);
+        var yDisplacement = (height / 2);
         var zDisplacement = 0.05;
         var tabletOffset = Vec3.multiplyQbyV(lookAtRot, {x: 0, y: yDisplacement, z: zDisplacement});
-        finalPosition = Vec3.sum(controllerPosition, tabletOffset);
+        finalPosition = Vec3.sum(tabletBase, tabletOffset);
+
         return {
             position: finalPosition,
             rotation: lookAtRot
diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js
index c5ce5a634b..68da7696be 100644
--- a/scripts/system/marketplaces/marketplaces.js
+++ b/scripts/system/marketplaces/marketplaces.js
@@ -52,10 +52,16 @@ function onMessageBoxClosed(id, button) {
 
 Window.messageBoxClosed.connect(onMessageBoxClosed);
 
+var shouldActivateButton = false;
+var onMarketplaceScreen = false;
+
 function showMarketplace() {
     UserActivityLogger.openedMarketplace();
 
+    shouldActivateButton = true;
     tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
+    onMarketplaceScreen = true;
+
     tablet.webEventReceived.connect(function (message) {
 
         if (message === GOTO_DIRECTORY) {
@@ -98,15 +104,10 @@ function showMarketplace() {
     });
 }
 
-function toggleMarketplace() {
-    var entity = HMD.tabletID;
-    Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
-    showMarketplace();
-}
-
 var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
 var marketplaceButton = tablet.addButton({
     icon: "icons/tablet-icons/market-i.svg",
+    activeIcon: "icons/tablet-icons/market-a.svg",
     text: "MARKET",
     sortOrder: 9
 });
@@ -117,16 +118,30 @@ function onCanWriteAssetsChanged() {
 }
 
 function onClick() {
-    toggleMarketplace();
+    if (onMarketplaceScreen) {
+        // for toolbar-mode: go back to home screen, this will close the window.
+        tablet.gotoHomeScreen();
+    } else {
+        var entity = HMD.tabletID;
+        Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
+        showMarketplace();
+    }
+}
+
+function onScreenChanged(type, url) {
+    // for toolbar mode: change button to active when window is first openend, false otherwise.
+    marketplaceButton.editProperties({isActive: shouldActivateButton});
+    shouldActivateButton = false;
+    onMarketplaceScreen = false;
 }
 
 marketplaceButton.clicked.connect(onClick);
+tablet.screenChanged.connect(onScreenChanged);
 Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
 
 Script.scriptEnding.connect(function () {
-    if (tablet) {
-        tablet.removeButton(marketplaceButton);
-    }
+    tablet.removeButton(marketplaceButton);
+    tablet.screenChanged.disconnect(onScreenChanged);
     Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
 });
 
diff --git a/scripts/system/menu.js b/scripts/system/menu.js
index 13c6ce1e0d..1d5f8bccd6 100644
--- a/scripts/system/menu.js
+++ b/scripts/system/menu.js
@@ -10,26 +10,46 @@
 //
 
 var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
-//var HOME_BUTTON_TEXTURE = Script.resourcesPath() + "meshes/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
+// var HOME_BUTTON_TEXTURE = Script.resourcesPath() + "meshes/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
 
 (function() {
     var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
     var button = tablet.addButton({
         icon: "icons/tablet-icons/menu-i.svg",
+        activeIcon: "icons/tablet-icons/menu-a.svg",
         text: "MENU",
         sortOrder: 3
     });
 
+    var shouldActivateButton = false;
+    var onMenuScreen = false;
+
     function onClicked() {
-        var entity = HMD.tabletID;
-        Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
-        tablet.gotoMenuScreen();
+        if (onMenuScreen) {
+            // for toolbar-mode: go back to home screen, this will close the window.
+            tablet.gotoHomeScreen();
+        } else {
+            var entity = HMD.tabletID;
+            Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
+            shouldActivateButton = true;
+            tablet.gotoMenuScreen();
+            onMenuScreen = true;
+        }
+    }
+
+    function onScreenChanged(type, url) {
+        // for toolbar mode: change button to active when window is first openend, false otherwise.
+        button.editProperties({isActive: shouldActivateButton});
+        shouldActivateButton = false;
+        onMenuScreen = false;
     }
 
     button.clicked.connect(onClicked);
+    tablet.screenChanged.connect(onScreenChanged);
 
     Script.scriptEnding.connect(function () {
         button.clicked.disconnect(onClicked);
         tablet.removeButton(button);
+        tablet.screenChanged.disconnect(onScreenChanged);
     });
 }());
diff --git a/scripts/system/pal.js b/scripts/system/pal.js
index d47544e0f0..36ecc1f084 100644
--- a/scripts/system/pal.js
+++ b/scripts/system/pal.js
@@ -477,23 +477,17 @@ var button;
 var buttonName = "PEOPLE";
 var tablet = null;
 
-function onTabletScreenChanged(type, url) {
-    if (type !== "QML" || url !== "../Pal.qml") {
-        off();
-    }
-}
-
 function startup() {
     tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
     button = tablet.addButton({
         text: buttonName,
         icon: "icons/tablet-icons/people-i.svg",
+        activeIcon: "icons/tablet-icons/people-a.svg",
         sortOrder: 7
     });
     tablet.fromQml.connect(fromQml);
     button.clicked.connect(onTabletButtonClicked);
     tablet.screenChanged.connect(onTabletScreenChanged);
-
     Users.usernameFromIDReply.connect(usernameFromIDReply);
     Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
     Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
@@ -524,17 +518,39 @@ function off() {
     Users.requestsDomainListData = false;
 }
 
+var onPalScreen = false;
+var shouldActivateButton = false;
+
 function onTabletButtonClicked() {
-    tablet.loadQMLSource("../Pal.qml");
-    Users.requestsDomainListData = true;
-    populateUserList();
-    isWired = true;
-    Script.update.connect(updateOverlays);
-    Controller.mousePressEvent.connect(handleMouseEvent);
-    Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
-    triggerMapping.enable();
-    triggerPressMapping.enable();
-    audioTimer = createAudioInterval(conserveResources ? AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS : AUDIO_LEVEL_UPDATE_INTERVAL_MS);
+    if (onPalScreen) {
+        // for toolbar-mode: go back to home screen, this will close the window.
+        tablet.gotoHomeScreen();
+    } else {
+        shouldActivateButton = true;
+        tablet.loadQMLSource("../Pal.qml");
+        onPalScreen = true;
+        Users.requestsDomainListData = true;
+        populateUserList();
+        isWired = true;
+        Script.update.connect(updateOverlays);
+        Controller.mousePressEvent.connect(handleMouseEvent);
+        Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
+        triggerMapping.enable();
+        triggerPressMapping.enable();
+        audioTimer = createAudioInterval(conserveResources ? AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS : AUDIO_LEVEL_UPDATE_INTERVAL_MS);
+    }
+}
+
+function onTabletScreenChanged(type, url) {
+    // for toolbar mode: change button to active when window is first openend, false otherwise.
+    button.editProperties({isActive: shouldActivateButton});
+    shouldActivateButton = false;
+    onPalScreen = false;
+
+    // disable sphere overlays when not on pal screen.
+    if (type !== "QML" || url !== "../Pal.qml") {
+        off();
+    }
 }
 
 //
@@ -621,14 +637,12 @@ function shutdown() {
     button.clicked.disconnect(onTabletButtonClicked);
     tablet.removeButton(button);
     tablet.screenChanged.disconnect(onTabletScreenChanged);
-
     Users.usernameFromIDReply.disconnect(usernameFromIDReply);
     Window.domainChanged.disconnect(clearLocalQMLDataAndClosePAL);
     Window.domainConnectionRefused.disconnect(clearLocalQMLDataAndClosePAL);
     Messages.subscribe(CHANNEL);
     Messages.messageReceived.disconnect(receiveMessage);
     Users.avatarDisconnected.disconnect(avatarDisconnected);
-
     off();
 }
 
diff --git a/scripts/system/tablet-goto.js b/scripts/system/tablet-goto.js
index 6c3e12cd9b..eb95d9d8a3 100644
--- a/scripts/system/tablet-goto.js
+++ b/scripts/system/tablet-goto.js
@@ -14,10 +14,27 @@
 (function() { // BEGIN LOCAL_SCOPE
     var gotoQmlSource = "TabletAddressDialog.qml";
     var buttonName = "GOTO";
+    var onGotoScreen = false;
+    var shouldActivateButton = false;
 
-    function onClicked(){
-        tablet.loadQMLSource(gotoQmlSource);
+    function onClicked() {
+        if (onGotoScreen) {
+            // for toolbar-mode: go back to home screen, this will close the window.
+            tablet.gotoHomeScreen();
+        } else {
+            shouldActivateButton = true;
+            tablet.loadQMLSource(gotoQmlSource);
+            onGotoScreen = true;
+        }
     }
+
+    function onScreenChanged(type, url) {
+        // for toolbar mode: change button to active when window is first openend, false otherwise.
+        button.editProperties({isActive: shouldActivateButton});
+        shouldActivateButton = false;
+        onGotoScreen = false;
+    }
+
     var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
     var button = tablet.addButton({
         icon: "icons/tablet-icons/goto-i.svg",
@@ -27,12 +44,12 @@
     });
 
     button.clicked.connect(onClicked);
+    tablet.screenChanged.connect(onScreenChanged);
 
     Script.scriptEnding.connect(function () {
         button.clicked.disconnect(onClicked);
-        if (tablet) {
-            tablet.removeButton(button);
-        }
+        tablet.removeButton(button);
+        tablet.screenChanged.disconnect(onScreenChanged);
     });
 
 }()); // END LOCAL_SCOPE
diff --git a/scripts/system/tablet-users.js b/scripts/system/tablet-users.js
index ce50c4686d..8e89ac74b7 100644
--- a/scripts/system/tablet-users.js
+++ b/scripts/system/tablet-users.js
@@ -1,7 +1,7 @@
 "use strict";
 
 //
-//  users.js
+//  tablet-users.js
 //
 //  Created by Faye Li on 18 Jan 2017.
 //  Copyright 2017 High Fidelity, Inc.
@@ -36,16 +36,34 @@
     var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
     var button = tablet.addButton({
         icon: "icons/tablet-icons/users-i.svg",
+        activeIcon: "icons/tablet-icons/users-a.svg",
         text: "USERS",
         sortOrder: 11
     });
 
+    var onUsersScreen = false;
+    var shouldActivateButton = false;
+
     function onClicked() {
-        var tabletEntity = HMD.tabletID;
-        if (tabletEntity) {
-            Entities.editEntity(tabletEntity, {textures: JSON.stringify({"tex.close" : HOME_BUTTON_TEXTURE})});
+        if (onUsersScreen) {
+            // for toolbar-mode: go back to home screen, this will close the window.
+            tablet.gotoHomeScreen();
+        } else {
+            var tabletEntity = HMD.tabletID;
+            if (tabletEntity) {
+                Entities.editEntity(tabletEntity, {textures: JSON.stringify({"tex.close" : HOME_BUTTON_TEXTURE})});
+            }
+            shouldActivateButton = true;
+            tablet.gotoWebScreen(USERS_URL);
+            onUsersScreen = true;
         }
-        tablet.gotoWebScreen(USERS_URL);
+    }
+
+    function onScreenChanged() {
+        // for toolbar mode: change button to active when window is first openend, false otherwise.
+        button.editProperties({isActive: shouldActivateButton});
+        shouldActivateButton = false;
+        onUsersScreen = false;
     }
 
     function onWebEventReceived(event) {
@@ -88,12 +106,13 @@
                 // update your visibility (all, friends, or none)
                 myVisibility = event.data.visibility;
                 GlobalServices.findableBy = myVisibility;
-            } 
+            }
         }
     }
 
     button.clicked.connect(onClicked);
     tablet.webEventReceived.connect(onWebEventReceived);
+    tablet.screenChanged.connect(onScreenChanged);
 
     function cleanup() {
         button.clicked.disconnect(onClicked);