diff --git a/src/components/character-controller.js b/src/components/character-controller.js
index 80260e0fcfbf258492e536fa1ab930811cfef1eb..910123ba8bb2f5e54e64037ac478a1ac2e57e577 100644
--- a/src/components/character-controller.js
+++ b/src/components/character-controller.js
@@ -105,6 +105,7 @@ AFRAME.registerComponent("character-controller", {
     const startScale = new THREE.Vector3();
 
     return function(t, dt) {
+      if (!this.el.sceneEl.is("entered")) return;
       const deltaSeconds = dt / 1000;
       const root = this.el.object3D;
       const pivot = this.data.pivot.object3D;
diff --git a/src/components/hand-controls2.js b/src/components/hand-controls2.js
index 4e50b1a500034affe300603340c5af0b8efb925b..534f796c45c304097768d5e486cac12db4d76664 100644
--- a/src/components/hand-controls2.js
+++ b/src/components/hand-controls2.js
@@ -50,6 +50,13 @@ AFRAME.registerComponent("hand-controls2", {
   init() {
     this.pose = POSES.open;
     this.el.setAttribute("visible", false);
+
+    this.connectedController = null;
+
+    this.onControllerConnected = this.onControllerConnected.bind(this);
+    this.onControllerDisconnected = this.onControllerDisconnected.bind(this);
+    this.el.addEventListener("controllerconnected", this.onControllerConnected);
+    this.el.addEventListener("controllerdisconnected", this.onControllerDisconnected);
   },
 
   update(prevData) {
@@ -109,5 +116,17 @@ AFRAME.registerComponent("hand-controls2", {
       this.pose = pose;
     }
     this.el.setAttribute("visible", hasPose);
+  },
+
+  // Show controller when connected
+  onControllerConnected(e) {
+    this.connectedController = e.detail.name;
+    this.el.setAttribute("visible", true);
+  },
+
+  // Hide controller on disconnect
+  onControllerDisconnected() {
+    this.connectedController = null;
+    this.el.setAttribute("visible", false);
   }
 });
diff --git a/src/components/tools/pen.js b/src/components/tools/pen.js
index 7e4b097b0d36ea65f4a39b1040b16828bd566b6d..dd52ca4ab14030ddf064a9d5ae9f0ef9a7d4456a 100644
--- a/src/components/tools/pen.js
+++ b/src/components/tools/pen.js
@@ -140,6 +140,10 @@ AFRAME.registerComponent("pen", {
 
       this.timeSinceLastDraw = time % this.data.drawFrequency;
     }
+
+    if (this.currentDrawing && !grabber) {
+      this._endDraw();
+    }
   },
 
   //helper function to get normal of direction of drawing cross direction to camera
diff --git a/src/hub.html b/src/hub.html
index d003eb06f43938f522d204bc5309d0f21ffc9df0..ce88ff5d12c25bce33f3ddf4ef0b7e46841511a4 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -31,6 +31,7 @@
         personal-space-bubble="debug: false;"
         vr-mode-ui="enabled: false"
         stats-plus="false"
+        action-to-event__mute="path: /actions/muteMic; event: action_mute;"
     >
 
         <a-assets>
diff --git a/src/scene-entry-manager.js b/src/scene-entry-manager.js
index c74cb231eee6ae98eadd3dc6782417a756c44e06..5b62434849bd3427869f741f2cb5fba03e658398 100644
--- a/src/scene-entry-manager.js
+++ b/src/scene-entry-manager.js
@@ -95,6 +95,8 @@ export default class SceneEntryManager {
         this.store.update({ activity: { lastEnteredAt: new Date().toISOString() } });
       });
     })();
+
+    this.scene.addState("entered");
   };
 
   whenSceneLoaded = callback => {
diff --git a/src/systems/userinput/bindings/keyboard-mouse-user.js b/src/systems/userinput/bindings/keyboard-mouse-user.js
index cd610085e64a1ce33a96f91e5bfe58c41983cab9..d38fb69f82063ba778924edd82eac1aadd0a6730 100644
--- a/src/systems/userinput/bindings/keyboard-mouse-user.js
+++ b/src/systems/userinput/bindings/keyboard-mouse-user.js
@@ -109,6 +109,15 @@ export const keyboardMouseUserBindings = {
       dest: { value: paths.actions.cameraDelta },
       xform: xforms.compose_vec2
     },
+    {
+      src: {
+        value: paths.device.keyboard.key("m")
+      },
+      dest: {
+        value: paths.actions.muteMic
+      },
+      xform: xforms.rising
+    },
     {
       src: {
         value: paths.device.keyboard.key("l")
diff --git a/src/systems/userinput/paths.js b/src/systems/userinput/paths.js
index cca20e88d5bff76fcedfb61320725cd156800860..75f655055b4578c0ce38f7781a561955f3ba5100 100644
--- a/src/systems/userinput/paths.js
+++ b/src/systems/userinput/paths.js
@@ -14,6 +14,7 @@ paths.actions.stopGazeTeleport = "/actions/stopTeleport";
 paths.actions.spawnPen = "/actions/spawnPen";
 paths.actions.ensureFrozen = "/actions/ensureFrozen";
 paths.actions.thaw = "/actions/thaw";
+paths.actions.muteMic = "/actions/muteMic";
 paths.actions.cursor = {};
 paths.actions.cursor.pose = "/actions/cursorPose";
 paths.actions.cursor.grab = "/actions/cursorGrab";
diff --git a/src/systems/userinput/userinput.js b/src/systems/userinput/userinput.js
index eb5b16ef0bf666d70d9d400bb3e312c2810c8432..2ffbdca79db0e2d07d464f32ea320fc8cb31c329 100644
--- a/src/systems/userinput/userinput.js
+++ b/src/systems/userinput/userinput.js
@@ -75,8 +75,6 @@ AFRAME.registerSystem("userinput", {
     this.registeredMappings = new Set([keyboardDebuggingBindings]);
     this.xformStates = new Map();
 
-    this.gamepads = [];
-
     const appAwareTouchscreenDevice = new AppAwareTouchscreenDevice();
     const updateBindingsForVRMode = () => {
       const inVRMode = this.el.sceneEl.is("vr-mode");
@@ -103,17 +101,16 @@ AFRAME.registerSystem("userinput", {
     window.addEventListener(
       "gamepadconnected",
       e => {
-        console.log(e.gamepad);
         let gamepadDevice;
-        if (e.gamepad.id === "OpenVR Gamepad") {
-          for (let i = 0; i < this.activeDevices.length; i++) {
-            const activeDevice = this.activeDevices[i];
-            if (activeDevice.gamepad && activeDevice.gamepad === e.gamepad) {
-              console.warn("ignoring gamepad");
-              return; // multiple connect events without a disconnect event
-            }
+        for (let i = 0; i < this.activeDevices.length; i++) {
+          const activeDevice = this.activeDevices[i];
+          if (activeDevice.gamepad && activeDevice.gamepad === e.gamepad) {
+            console.warn("ignoring gamepad", e.gamepad);
+            return; // multiple connect events without a disconnect event
           }
-          if (this.activeDevices) gamepadDevice = new ViveControllerDevice(e.gamepad);
+        }
+        if (e.gamepad.id === "OpenVR Gamepad") {
+          gamepadDevice = new ViveControllerDevice(e.gamepad);
           this.registeredMappings.add(viveUserBindings);
         } else if (e.gamepad.id.startsWith("Oculus Touch")) {
           gamepadDevice = new OculusTouchControllerDevice(e.gamepad);
@@ -132,16 +129,17 @@ AFRAME.registerSystem("userinput", {
           this.registeredMappings.add(gamepadBindings);
         }
         this.activeDevices.add(gamepadDevice);
-        this.gamepads[e.gamepad.index] = gamepadDevice;
       },
       false
     );
     window.addEventListener(
       "gamepaddisconnected",
       e => {
-        if (this.gamepads[e.gamepad.index]) {
-          this.activeDevices.delete(this.gamepads[e.gamepad.index]);
-          delete this.gamepads[e.gamepad.index];
+        for (const device of this.activeDevices) {
+          if (device.gamepad === e.gamepad) {
+            this.activeDevices.delete(device);
+            return;
+          }
         }
       },
       false