private static void CreateCommandModeObservers(List <IDisposable> observers) { observers.Add(_leapObservable .EnsureOneHande() .Where(f => { var hand = f.Hands[0]; var avgAngl = hand.Fingers.Average(fi => fi.Direction.AngleTo(hand.Direction)); var palmRotation = Math.Abs(hand.Rotation.z); return(avgAngl <= CommandAngleSensetivity && // fingers are in the same plain as hand palmRotation < PalmRotationSensetivity && (Math.Abs(hand.PalmVelocity.y) >= CommandVerticalSensetivity || Math.Abs(hand.PalmVelocity.x) >= CommandHorizontalSensetivity)); // ensured movement }) .Buffer(BufferingWindow) // use Buffer instead of Scan to accumulate multiple values .Select(b => new VelocityInfo(b.Select(f => f.Hands[0].PalmVelocity.x).Sum(), b.Select(f => f.Hands[0].PalmVelocity.y).Sum(), b.Select(f => f.Hands[0].PalmVelocity.z).Sum())) .Subscribe(new PalmVelocityObserver(_modeSwitchSubject))); observers.Add(_leapObservable .EnsureOneHande() .Where(f => { var hand = f.Hands[0]; var rotation = Math.Abs(hand.Rotation.z); var avgAngl = hand.Fingers.Average(fi => fi.Direction.AngleTo(hand.Direction)); // react with opened hand only if (_searchReactionStoped && rotation < PalmRotationSensetivity) { // lets react on palm rotations again. _searchReactionStoped = false; } return(rotation > PalmRotationThreshold && avgAngl <= CommandAngleSensetivity && !_searchReactionStoped); }) .Subscribe(r => { // stop reacting on next to avoid multiple search "hits" _searchReactionStoped = true; WindowsInput.GotoSearch(); })); }