0

I am writing a program in Python on Windows and I want to detect mouse events (eg mouse down, mouse move) on the terminal.

I have tried this solution but it does not detect mouse events, only key events.

I also tried the C code at Microsoft's documentation but the same happens.

However, I tried the textual library and it is able to detect mouse events.

What is going on and how can I detect mouse events on the terminal on Windows using Python?

tovicheung
  • 132
  • 9
  • 1
    "I tried the textual library and it is able to detect mouse events" Ok, so you found a solution to detect mouse events. What's your question then? – Sembei Norimaki May 02 '23 at 12:40
  • The library is too complex for me to adapt my code to. I would like to know the details and implementations on detecting mouse events – tovicheung May 02 '23 at 13:14

1 Answers1

0

After more research I managed to piece together a working solution using snippets from the asciimatics library source code. Hope this helps anyone with the same question

import win32console
import win32file
import win32con

ENABLE_EXTENDED_FLAGS = 0x0080
ENABLE_QUICK_EDIT_MODE = 0x0040

catch_interrupt = False

win_in = win32console.PyConsoleScreenBufferType(
    win32file.CreateFile("CONIN$",
        win32file.GENERIC_READ | win32file.GENERIC_WRITE,
        win32file.FILE_SHARE_READ,
        None,
        win32file.OPEN_ALWAYS,
        0,
        None
    )
)
win_in.SetStdHandle(win32console.STD_INPUT_HANDLE)

in_mode = win_in.GetConsoleMode()
new_mode = (in_mode | win32console.ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS)
new_mode &= ~ENABLE_QUICK_EDIT_MODE
if catch_interrupt:
    # Ignore ctrl-c handlers if specified.
    new_mode &= ~win32console.ENABLE_PROCESSED_INPUT
win_in.SetConsoleMode(new_mode)

try:
    while True:
        if len(win_in.PeekConsoleInput(1)) <= 0:
            continue
        event = win_in.ReadConsoleInput(1)[0]
        if event.EventType == win32console.KEY_EVENT:
            key_code = ord(event.Char)
            print("Processing key: ", key_code)

        elif event.EventType == win32console.MOUSE_EVENT:
            print("Processing mouse: ", event.MousePosition.X, event.MousePosition.Y)
            button = 0
            if event.EventFlags == 0:
                if (event.ButtonState &
                        win32con.FROM_LEFT_1ST_BUTTON_PRESSED != 0):
                    print("left button")
                if (event.ButtonState &
                        win32con.RIGHTMOST_BUTTON_PRESSED != 0):
                    print("right button")
            elif event.EventFlags & win32con.DOUBLE_CLICK != 0:
                print("double click")
finally:
    win_in.SetConsoleMode(in_mode)

Note: I did not want to use any terminal applications framework like textual because it is too complex to adapt my code into, and I would like to learn the logic behind it

tovicheung
  • 132
  • 9