Skip to content

POC: event handling using await #98

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

POC: event handling using await #98

wants to merge 1 commit into from

Conversation

almarklein
Copy link
Member

@almarklein almarklein commented Jun 29, 2025

This is a proof of concept for an idea to allow users to handle events using await. An event handling workflow can then be written as a single async function, which can be much easier than listening to multiple events and maintaining state across the handlers.

Example implementing drag:

@canvas.add_event_task
async def foo(for_event):
    while True:

        # Wait for pointer down
        event = await for_event("pointer_down")

        # Does this select the current position of the active block?
        width, height = canvas.get_logical_size()
        x = int(w * event["x"] / width)
        y = int(h * event["y"] / height)
        if [x, y] != currentpos:
            print("nope", x, y)
            continue

        # Move until pointer up
        while True:
            event = await for_event("pointer_move", "pointer_up")
            if event["event_type"] == "pointer_up":
                break

            width, height = canvas.get_logical_size()
            x = int(w * event["x"] / width)
            y = int(h * event["y"] / height)
            print(x, y)
            currentpos[:] = x, y

The use-case that triggered me to think about this more is the lasso tool in FPL: fastplotlib/fastplotlib#837

I'm curious to what @Korijn thinks of this idea from a design/API perspective, and what users like @kushalkolar, @hmaarrfk, @claydugo, @kingbedjed think of writing handlers this way. I think it should be an alternative to add_event_handler, not replace it.

Some notes regarding async:

  • Yes, this works with any backend.
  • Yes, you can also await sleep(), but you should from rendercanvas.asyncs import sleep to make it portable.
  • Although, if you know the underlying loop is asyncio, you can do any asyncio stuff :)

Some caveats:

  • If an exception occurs in the task, it stops the task completely, unless you add a try except.

Some ideas:

  • The argument into the function can be the for_event() instead of the emitted object (see example above).
  • Use canvas.add_event_task("pointer_down", func) so the task is initiated for every mouse down, avoiding one while loop.
  • Maybe could write this as a generator instead of a an async function to make it feel more 'confined' to events.

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

Successfully merging this pull request may close these issues.

1 participant
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy