FocusBehavior already does all of this, see https://github.com/kivy/kivy/blob/master/kivy/uix/behaviors.py#L639