Key releases missed and key registered as pressed across multiple trials

OS: (Mac +) Win
PsychoPy version 2024.2.4 Py 3.8
Standard Standalone Installation? (y/n) y
Do you want it to also run online? (y/n) n
What are you trying to achieve?:

I have a routine in my experiment in which participants use up/down/left/right buttons to move a cursor on screen and a confirm button to choose a location. I want the cursor to move whenever a key is pressed and stop moving when it isn’t.

This is working, the issue is that sometimes some movement keys get stuck: even when I release the key, PsychoPy records it as being pressed (I see the print statement print out the key on every frame) and the cursor keeps moving in that direction until I press confirm (=end routine). On the next trial, if I press the same key again the same thing happens (for many trials, unclear why/when it stops).

This happens both on my local laptop and the windows machine I run the experiment on. I am not entirely sure what triggers it, but I think it has to do with pressing multiple keys at once.

What did you try to make it work?:
Adding an if statement checking if kb.getState(key): in the loop through the keys seems to solve the issue on my Mac, but it leads to an error on the Windows machine, which is where I need the experiment to run (error related to KbCheck behind the scenes requiring a device_id, which is not available on win Psychtoolbox-3 - KbCheck).

The routine has 2 images (background image and cursor) and a code component. Below are the relevant parts of the code component.

Begin routine:

kb.clock.reset()  # reset timer
kb.clearEvents(eventType='keyboard') # remove all previous key presses

Each frame:

# listen for keys
keys = kb.getKeys(keyList=[key_left, key_right, key_up, key_down, key_confirm, 'q'], waitRelease=False, clear=False)

if keys: # if a key is being pressed
    # ========= allows to quit experiment by pressing Q =========
    if 'q' in keys:
        endExpNow = True
    # ========= if press confirm, end trial =========
    elif key_confirm in keys:
        continueRoutine = False
    # ========= Update movement for each directional key -- single speed =========
    else:
        cursor_pos_new = deepcopy(cursor_pos)
        # move for each pressed key
        for key in keys:
            # if kb.getState(key):
            print('pressed', key.name, key.rt)
            if key == key_left:
                cursor_pos_new[0] += -1 * speed
            if key == key_right:
                cursor_pos_new[0] += 1 * speed
            if key == key_up:
                cursor_pos_new[1] += 1 * speed
            if key == key_down:
                cursor_pos_new[1] += -1 * speed

            # Prevent moving out of bounds
            distance_to_center = math.sqrt(cursor_pos_new[0]**2 + cursor_pos_new[1]**2)
            if distance_to_center <= max_radius:
                cursor_pos[0] = cursor_pos_new[0]
                cursor_pos[1] = cursor_pos_new[1]

            # save sequence of pressed keys (even if the cursor is not moved because of bounds)
            keypress_log.append({'key': key.name, 'time': key.rt})
            # save cursor path
            cursor_path.append({'time': key.rt, 'x': cursor_pos[0], 'y': cursor_pos[1]}) 

End routine:

kb.clearEvents()

Link to the most relevant existing thread you have found:
The issue is similar to the one here, but I don’t think it has been answered: Key release event missed occasionally

What specifically went wrong when you tried that?:
Error message on Win machine for kb.getState()

Psychtoolbox/hid.py line 141
Return PsychHID( KbCheck", Self device id, scan_Lis) AttributeError: keyboard object has no attribute device_id

I would really appreciate any help!