diff --git a/src/components/cursor-controller.js b/src/components/cursor-controller.js
index d4d282011a1c52d2d68beb1150bfdf4abc9fa884..e42d1ba6a703d62e480033fdd669a630ecc824fc 100644
--- a/src/components/cursor-controller.js
+++ b/src/components/cursor-controller.js
@@ -1,5 +1,4 @@
 import { paths } from "../systems/userinput/paths";
-import { sets } from "../systems/userinput/sets";
 /**
  * Manages targeting and physical cursor location. Has the following responsibilities:
  *
@@ -18,24 +17,25 @@ AFRAME.registerComponent("cursor-controller", {
     cursorColorHovered: { default: "#2F80ED" },
     cursorColorUnhovered: { default: "#FFFFFF" },
     rayObject: { type: "selector" },
-    drawLine: { default: false },
+    drawLine: { default: true },
     objects: { default: "" }
   },
 
   init: function() {
     this.enabled = true;
-    this.currentDistanceMod = 0;
-    this.mousePos = new THREE.Vector2();
-    this.data.cursor.setAttribute("material", { color: this.data.cursorColorUnhovered });
 
-    this._handleCursorLoaded = this._handleCursorLoaded.bind(this);
-    this.data.cursor.addEventListener("loaded", this._handleCursorLoaded);
+    this.data.cursor.addEventListener(
+      "loaded",
+      () => {
+        this.data.cursor.object3DMap.mesh.renderOrder = window.APP.RENDER_ORDER.CURSOR;
+      },
+      { once: true }
+    );
 
     // raycaster state
+    this.setDirty = this.setDirty.bind(this);
     this.targets = [];
-    this.intersection = null;
     this.raycaster = new THREE.Raycaster();
-    this.setDirty = this.setDirty.bind(this);
     this.dirty = true;
     this.distance = this.data.far;
   },
@@ -98,153 +98,64 @@ AFRAME.registerComponent("cursor-controller", {
     const cameraPos = new THREE.Vector3();
     return function() {
       if (this.dirty) {
-        this.populateEntities(this.data.objects, this.targets); // touchscreen cares about this.targets
+        // app aware devices cares about this.targets so we must update it even if cursor is not enabled
+        this.populateEntities(this.data.objects, this.targets);
         this.dirty = false;
       }
 
       const userinput = AFRAME.scenes[0].systems.userinput;
-      if (!this.enabled) {
-        userinput.deactivate(sets.cursorHoveringOnPen);
-        userinput.deactivate(sets.cursorHoveringOnInteractable);
+      const cursorPose = userinput.readFrameValueAtPath(paths.actions.cursor.pose);
+
+      this.setCursorVisibility(this.enabled && !!cursorPose);
+
+      if (!this.enabled || !cursorPose) {
         return;
       }
 
+      let intersection;
       const isGrabbing = this.data.cursor.components["super-hands"].state.has("grab-start");
       if (!isGrabbing) {
-        const cursorPose = userinput.readFrameValueAtPath(paths.actions.cursor.pose);
-        if (cursorPose) {
-          rawIntersections.length = 0;
-          this.raycaster.ray.origin = cursorPose.position;
-          this.raycaster.ray.direction = cursorPose.direction;
-          this.raycaster.intersectObjects(this.targets, true, rawIntersections);
-          const intersection = rawIntersections.find(x => x.object.el);
-          this.intersection = intersection;
-          const isHoveringOnPen = intersection && intersection.object.el.matches(".pen, .pen *");
-          const isHoveringOnInteractable =
-            intersection && intersection.object.el.matches(".interactable, .interactable *");
-          userinput[isHoveringOnPen ? "activate" : "deactivate"](sets.cursorHoveringOnPen);
-          userinput[isHoveringOnInteractable ? "activate" : "deactivate"](sets.cursorHoveringOnInteractable);
-        } else {
-          userinput.deactivate(sets.cursorHoveringOnPen);
-          userinput.deactivate(sets.cursorHoveringOnInteractable);
-        }
+        rawIntersections.length = 0;
+        this.raycaster.ray.origin = cursorPose.position;
+        this.raycaster.ray.direction = cursorPose.direction;
+        this.raycaster.intersectObjects(this.targets, true, rawIntersections);
+        intersection = rawIntersections.find(x => x.object.el);
+        this.emitIntersectionEvents(this.prevIntersection, intersection);
+        this.prevIntersection = intersection;
+        this.distance = intersection ? intersection.distance : this.data.far;
       }
 
-      const { cursor, near, far, drawLine, camera } = this.data;
-      const intersection = this.intersection;
-      this.emitIntersectionEvents(this.prevIntersection, intersection);
-      this.prevIntersection = intersection;
-      this.data.cursor.setAttribute("material", {
-        color: intersection ? this.data.cursorColorHovered : this.data.cursorColorUnhovered
-      });
-      if (intersection) {
-        this.distance = intersection.distance;
-      } else {
-        this.distance = this.data.far;
-      }
-
-      const cursorPose = userinput.readFrameValueAtPath(paths.actions.cursor.pose);
-      this.setCursorVisibility(!!cursorPose);
-      if (isGrabbing) {
-        if (userinput.readFrameValueAtPath(paths.actions.cursor.drop)) {
-          this.endInteraction();
-        }
-      }
-      if (!cursorPose) {
-        return;
-      }
+      const { cursor, near, far, drawLine, camera, cursorColorHovered, cursorColorUnhovered } = this.data;
 
-      const cursorPosition = cursor.object3D.position;
-      if (isGrabbing) {
-        const cursorModDelta = userinput.readFrameValueAtPath(paths.actions.cursor.modDelta);
-        if (cursorModDelta) {
-          this.changeDistanceMod(cursorModDelta);
-        }
-        cursorPosition
-          .copy(cursorPose.position)
-          .addScaledVector(cursorPose.direction, THREE.Math.clamp(this.distance - this.currentDistanceMod, near, far));
-      } else {
-        this.currentDistanceMod = 0;
-        if (intersection) {
-          cursorPosition.copy(intersection.point);
-        } else {
-          cursorPosition.copy(cursorPose.position).addScaledVector(cursorPose.direction, far);
-        }
+      const cursorModDelta = userinput.readFrameValueAtPath(paths.actions.cursor.modDelta);
+      if (isGrabbing && cursorModDelta) {
+        this.distance = THREE.Math.clamp(this.distance - cursorModDelta, near, far);
       }
+      cursor.object3D.position.copy(cursorPose.position).addScaledVector(cursorPose.direction, this.distance);
+      // The cursor will always be oriented towards the player about its Y axis, so objects held by the cursor will rotate towards the player.
+      camera.object3D.getWorldPosition(cameraPos);
+      cameraPos.y = cursor.object3D.position.y;
+      cursor.object3D.lookAt(cameraPos);
 
+      this.data.cursor.setAttribute("material", {
+        color: intersection || isGrabbing ? cursorColorHovered : cursorColorUnhovered
+      });
       if (drawLine) {
         this.el.setAttribute("line", {
           start: cursorPose.position.clone(),
           end: cursor.object3D.position.clone()
         });
       }
-
-      // The cursor will always be oriented towards the player about its Y axis, so objects held by the cursor will rotate towards the player.
-      camera.object3D.getWorldPosition(cameraPos);
-      cameraPos.y = cursor.object3D.position.y;
-      cursor.object3D.lookAt(cameraPos);
-
-      if (!isGrabbing) {
-        if (userinput.readFrameValueAtPath(paths.actions.cursor.grab)) {
-          this.startInteraction();
-        }
-      }
     };
   })(),
 
-  updateDistanceAndTargetType: function() {},
-
   setCursorVisibility: function(visible) {
     this.data.cursor.setAttribute("visible", visible);
     this.el.setAttribute("line", { visible: visible && this.data.drawLine });
   },
 
-  isInteracting: function() {
-    return;
-  },
-
-  startInteraction: function() {
-    const userinput = AFRAME.scenes[0].systems.userinput;
-    this.data.cursor.emit("cursor-grab", {});
-    const isGrabbing = this.data.cursor.components["super-hands"].state.has("grab-start");
-    if (isGrabbing) {
-      userinput.activate(sets.cursorHoldingInteractable);
-    }
-  },
-
-  endInteraction: function() {
-    const userinput = AFRAME.scenes[0].systems.userinput;
-    this.data.cursor.emit("cursor-release", {});
-    const isGrabbing = this.data.cursor.components["super-hands"].state.has("grab-start");
-    if (!isGrabbing) {
-      userinput.deactivate(sets.cursorHoldingInteractable);
-    }
-  },
-
-  moveCursor: function(x, y) {
-    this.mousePos.set(x, y);
-  },
-
-  changeDistanceMod: function(delta) {
-    const { near, far } = this.data;
-    const targetDistanceMod = this.currentDistanceMod + delta;
-    const moddedDistance = this.distance - targetDistanceMod;
-    if (moddedDistance > far || moddedDistance < near) {
-      return false;
-    }
-
-    this.currentDistanceMod = targetDistanceMod;
-    return true;
-  },
-
-  _handleCursorLoaded: function() {
-    this.data.cursor.object3DMap.mesh.renderOrder = window.APP.RENDER_ORDER.CURSOR;
-    this.data.cursor.removeEventListener("loaded", this._handleCursorLoaded);
-  },
-
   remove: function() {
-    this.emitIntersectionEvents(this.intersection, null);
-    this.intersection = null;
-    this.data.cursor.removeEventListener("loaded", this._handleCursorLoaded);
+    this.emitIntersectionEvents(this.prevIntersection, null);
+    delete this.prevIntersection;
   }
 });
diff --git a/src/hub.html b/src/hub.html
index 46b335b32c2e36d35d04b7e04bb48c224181325f..78fa01ad5bfc6d703a2109b7758e11865ac57887 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -300,6 +300,8 @@
                 dragDropEndButtons: cursor-release, primary_hand_release, secondary_hand_release;
                 activateStartButtons: secondary-cursor-grab, secondary_hand_grab, next_color, previous_color, increase_radius, decrease_radius, scroll_up, scroll_down, scroll_left, scroll_right;
                 activateEndButtons: secondary-cursor-release, secondary_hand_release, vertical_scroll_release, horizontal_scroll_release, thumb_up;"
+            action-to-event__grab="path: /actions/cursorGrab; event: cursor-grab"
+            action-to-event__drop="path: /actions/cursorDrop; event: cursor-release"
         ></a-sphere>
 
         <!-- Player Rig -->
diff --git a/src/systems/userinput/resolve-action-sets.js b/src/systems/userinput/resolve-action-sets.js
index 18a945daaf7a41e4230394a8178e150a78696787..557fedba9c580a039489b0742098e2f54148f73e 100644
--- a/src/systems/userinput/resolve-action-sets.js
+++ b/src/systems/userinput/resolve-action-sets.js
@@ -80,41 +80,58 @@ export function updateActionSetsBasedOnSuperhands() {
     !cursorGrabbing &&
     !rightHandState.has("grab-start");
 
+  // Cursor
+  if (rightHandTeleporting || rightHandHovering || rightHandGrabbing) {
+    cursorController.disable();
+  } else {
+    cursorController.enable();
+  }
+
   const cursorHoveringOnInteractable =
+    cursorController.enabled &&
     !rightHandTeleporting &&
     !rightHandHovering &&
     !rightHandGrabbing &&
     cursorHand.has("hover-start") &&
     cursorHand.get("hover-start").matches(".interactable, .interactable *");
   const cursorHoveringOnCamera =
+    cursorController.enabled &&
     !rightTeleporter.active &&
     !rightHandHovering &&
     !rightHandGrabbing &&
     (cursorHand.has("hover-start") && cursorHand.get("hover-start").matches(".icamera, .icamera *"));
   const cursorHoveringOnUI =
+    cursorController.enabled &&
     !rightHandTeleporting &&
     !rightHandHovering &&
     !rightHandGrabbing &&
     (cursorHand.has("hover-start") && cursorHand.get("hover-start").matches(".ui, .ui *"));
   const cursorHoveringOnPen =
+    cursorController.enabled &&
     !rightHandTeleporting &&
     !rightHandHovering &&
     !rightHandGrabbing &&
     cursorHand.has("hover-start") &&
     cursorHand.get("hover-start").matches(".pen, .pen *");
   const cursorHoldingInteractable =
+    cursorController.enabled &&
     !rightHandTeleporting &&
     cursorHand.has("grab-start") &&
     cursorHand.get("grab-start").matches(".interactable, .interactable *");
   const cursorHoldingPen =
-    !rightHandTeleporting && cursorHand.has("grab-start") && cursorHand.get("grab-start").matches(".pen, .pen *");
+    cursorController.enabled &&
+    !rightHandTeleporting &&
+    cursorHand.has("grab-start") &&
+    cursorHand.get("grab-start").matches(".pen, .pen *");
 
   const cursorHoldingCamera =
+    cursorController.enabled &&
     !rightTeleporter.active &&
     cursorHand.has("grab-start") &&
     cursorHand.get("grab-start").matches(".icamera, .icamera *");
 
   const cursorHoveringOnNothing =
+    cursorController.enabled &&
     !rightHandTeleporting &&
     !rightHandHovering &&
     !rightHandGrabbing &&
@@ -122,12 +139,6 @@ export function updateActionSetsBasedOnSuperhands() {
     !cursorHand.has("grab-start") &&
     !cursorHoveringOnUI;
 
-  if (rightHandTeleporting || rightHandHovering || rightHandGrabbing) {
-    cursorController.disable();
-  } else {
-    cursorController.enable();
-  }
-
   const userinput = AFRAME.scenes[0].systems.userinput;
   userinput.toggleActive(sets.leftHandHoveringOnInteractable, leftHandHoveringOnInteractable);
   userinput.toggleActive(sets.leftHandHoveringOnPen, leftHandHoveringOnPen);