custom modal operator event timing
There are two events for keyboard keys: When you push the key down and when you release it.
event.value is 'PRESS' or 'RELEASE'.
Run this code in Text Editor, put your mouse over 3D View and hit Spacebar.
Search for Simple Modal View3D Operator and run it, then press some keys.
import bpy
import blf


def draw_callback_px(self, context):

    font_id = 0  # XXX, need to find out how best to get this.

    # draw some text
    blf.position(font_id, 15, 30, 0)
    blf.size(font_id, 20, 72)
    blf.draw(font_id, self.key)



class ModalDrawOperator(bpy.types.Operator):
    &quot;&quot;&quot;Draw a line with the mouse&quot;&quot;&quot;
    bl_idname = &quot;view3d.modal_operator&quot;
    bl_label = &quot;Simple Modal View3D Operator&quot;

    def modal(self, context, event):

        mod = []
        if event.shift:
            mod.append(&quot;Shift&quot;)
        if event.alt:
            mod.append(&quot;Alt&quot;)
        if event.ctrl:
            mod.append(&quot;Ctrl&quot;)

        if mod:
            mod = &quot;[%s]&quot; % &quot;+&quot;.join(mod)
        else:
            mod = &quot;&quot;

        context.area.header_text_set(&quot;%s %s - %s&quot; % (mod, event.type, event.value))

        if event.unicode:
            self.key += event.unicode
            context.area.tag_redraw()

        elif event.type in {'RET', 'NUMPAD_ENTER', 'BACK_SPACE', 'DEL'}:
            self.key = &quot;&quot;
            context.area.tag_redraw()

        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            context.area.tag_redraw()
            context.area.header_text_set(None)
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        if context.area.type == 'VIEW_3D':
            # the arguments we pass the the callback
            args = (self, context)
            # Add the region OpenGL drawing callback
            # draw in view space with 'POST_VIEW' and 'PRE_VIEW'
            self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')

            self.key = &quot;&quot;

            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, &quot;View3D not found, cannot run operator&quot;)
            return {'CANCELLED'}


def register():
    bpy.utils.register_class(ModalDrawOperator)


def unregister():
    bpy.utils.unregister_class(ModalDrawOperator)

if __name__ == &quot;__main__&quot;:
    register()