Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FR: ability to pause KeyProcessor #1910

Open
eight04 opened this issue Aug 25, 2024 · 1 comment
Open

FR: ability to pause KeyProcessor #1910

eight04 opened this issue Aug 25, 2024 · 1 comment

Comments

@eight04
Copy link

eight04 commented Aug 25, 2024

I want to implement typeahead in a full screen app.

For example: if the user types a key while a list is loading, the key shouldn't be processed until the list is loaded and the item is focused.

# suppose the user types `nfoo\nbar\n` on a todo list

@kb.add("n") # create a new todo
async def _(event):
  app.key_processor.pause()

  await some_tasks()

  p = await prepare_and_focus_prompt()
  app.key_processor.resume()
  name = await p.readline(on_accept=app.key_processor.pause)
  # we have to pause key_processor immediately after `\n` so `bar\n` can be kept in `input_queue`

  await some_tasks()

  p2 = await prepare_and_focus_prompt()
  app.key_processor.resume() # now `bar` would be processed by the second prompt.
  desc = await p2.readline(on_accept=app.key_processor.pause)

  # back to the list and resume key_processor
  await create_item(name, desc)
  await load_and_focus_list()
  app.key_processor.resume() # any keys after `\n` should go to list window

Currently this is what I do:

  1. Configure asyncio to run tasks eagerly: asyncio.get_running_loop().set_task_factory(asyncio.eager_task_factory)
  2. Modify app._default_bindings to add an <any> handler, which will catch all unhandled keys.
  3. Before loading the list, focus a dummy window so key presses can be cought by (2)
  4. After the list is ready, focus the list item and send those keys to app.key_processor.feed_multiple.
  5. Call key_processor.process_keys. However, you have to call it via aynscio.get_running_loop().call_later(0.1, app.key_processor.process_keys) or the app will freeze. I have no idea why.

I also noticed that there is an input.detach function. However, it doesn't work in a key binding handler since keys typed are already sent to key_processor.input_queue.

@eight04
Copy link
Author

eight04 commented Aug 25, 2024

5. aynscio.get_running_loop().call_later(0.1, app.key_processor.process_keys)

It seems that it has to execute after app.after_render event?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant