void keyPressedHelper(KeyboardKey sender)
        {
            var model = this.layout?.keyForView(sender);

            if (model != null)
            {
                this.keyPressed(model);

                // auto exit from special char subkeyboard;
                if (model.type == Key.KeyType.Space || model.type == Key.KeyType.Return)
                {
                    this.currentMode = 0;
                }
                else if (model.lowercaseOutput == "'")
                {
                    this.currentMode = 0;
                }
                else if (model.type == Key.KeyType.Character)
                {
                    this.currentMode = 0;
                }

                // auto period on double space;
                // TODO: timeout;

                this.handleAutoPeriod(model);
                // TODO: reset context;
            }

            this.setCapsIfNeeded();
        }
 void showPopup(KeyboardKey sender)
 {
     if (sender == this.keyWithDelayedPopup)
     {
         this.popupDelayTimer.Invalidate();
     }
     sender.showPopup();
 }
 void modeChangeTapped(KeyboardKey sender)
 {
     if (layout.viewToModel.ContainsKey(sender))
     {
         var toMode = this.layout.viewToModel[sender].toMode;
         this.currentMode = toMode;
     }
 }
        void advanceTapped(KeyboardKey sender)
        {
            this.forwardingView.resetTrackedViews();
            this.shiftStartingState  = null;
            this.shiftWasMultitapped = false;

            this.AdvanceToNextInputMode();
        }
        void backspaceDown(KeyboardKey sender)
        {
            this.cancelBackspaceTimers();


            this.TextDocumentProxy.DeleteBackward();
            this.setCapsIfNeeded();

            // trigger for subsequent deletes;
            this.backspaceDelayTimer = NSTimer.CreateScheduledTimer(backspaceDelay - backspaceRepeat, (t) => backspaceDelayCallback());
        }
        void hidePopupDelay(KeyboardKey sender)
        {
            this.popupDelayTimer?.Invalidate();


            if (sender != this.keyWithDelayedPopup)
            {
                this.keyWithDelayedPopup?.hidePopup();
                this.keyWithDelayedPopup = sender;
            }

            if (sender.popup != null)
            {
                this.popupDelayTimer = NSTimer.CreateScheduledTimer((double)0.05, (t) => hidePopupCallback());
            }
        }
        void shiftUp(KeyboardKey sender)
        {
            if (this.shiftWasMultitapped)
            {
                // do nothing;
            }
            else
            {
                var shiftStartingState = this.shiftStartingState;
                if (shiftStartingState != null)
                {
                    if (!shiftStartingState.Value.uppercase())
                    {
                        // handled by shiftDown;
                    }
                    else
                    {
                        switch (this.shiftState)
                        {
                        case ShiftState.Disabled:
                            this.shiftState = ShiftState.Enabled;
                            break;

                        case ShiftState.Enabled:
                            this.shiftState = ShiftState.Disabled;
                            break;

                        case ShiftState.Locked:
                            this.shiftState = ShiftState.Disabled;
                            break;
                        }
                        var btn = sender.shape as ShiftShape;
                        if (btn != null)
                        {
                            btn.withLock = false;
                        }
                    }
                }
            }

            this.shiftStartingState  = null;
            this.shiftWasMultitapped = false;
        }
        void shiftDoubleTapped(KeyboardKey sender)
        {
            this.shiftWasMultitapped = true;


            switch (this.shiftState)
            {
            case ShiftState.Disabled:
                this.shiftState = ShiftState.Locked;
                break;

            case ShiftState.Enabled:
                this.shiftState = ShiftState.Locked;
                break;

            case ShiftState.Locked:
                this.shiftState = ShiftState.Disabled;
                break;
            }
        }
        void shiftDown(KeyboardKey sender)
        {
            this.shiftStartingState = this.shiftState;
            var shiftStartingState = this.shiftStartingState;

            if (shiftStartingState != null)
            {
                if (shiftStartingState.Value.uppercase())
                {
                    // handled by shiftUp;
                    return;
                }
                else
                {
                    switch (this.shiftState)
                    {
                    case ShiftState.Disabled:
                        this.shiftState = ShiftState.Enabled;
                        break;

                    case ShiftState.Enabled:
                        this.shiftState = ShiftState.Disabled;
                        break;

                    case ShiftState.Locked:
                        this.shiftState = ShiftState.Disabled;
                        break;
                    }
                    var btn = sender.shape as ShiftShape;
                    if (btn != null)
                    {
                        btn.withLock = false;
                    }
                }
            }
        }
 void unHighlightKey(KeyboardKey sender)
 {
     sender.Highlighted = false;
 }
 void highlightKey(KeyboardKey sender)
 {
     sender.Highlighted = true;
 }
 void hidePopupCallback()
 {
     this.keyWithDelayedPopup?.hidePopup();
     this.keyWithDelayedPopup = null;
     this.popupDelayTimer     = null;
 }
 void backspaceUp(KeyboardKey sender)
 {
     this.cancelBackspaceTimers();
 }