{"id":16654747,"url":"https://github.com/zuzu-typ/winput","last_synced_at":"2025-06-29T09:34:28.891Z","repository":{"id":34920885,"uuid":"138437195","full_name":"Zuzu-Typ/winput","owner":"Zuzu-Typ","description":"winput Python extention - capture and send keyboard and mouse input on Windows","archived":false,"fork":false,"pushed_at":"2022-07-16T10:22:49.000Z","size":42,"stargazers_count":28,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-18T03:08:31.709Z","etag":null,"topics":["capture","extension","input","keyboard","keyboard-hooks","mouse","mouse-tracking","pyhook","python","record-keyboard","recording","send","simple","user32","windows"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Zuzu-Typ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-23T22:18:14.000Z","updated_at":"2024-11-13T15:54:57.000Z","dependencies_parsed_at":"2022-09-10T08:21:33.487Z","dependency_job_id":null,"html_url":"https://github.com/Zuzu-Typ/winput","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zuzu-Typ%2Fwinput","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zuzu-Typ%2Fwinput/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zuzu-Typ%2Fwinput/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zuzu-Typ%2Fwinput/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Zuzu-Typ","download_url":"https://codeload.github.com/Zuzu-Typ/winput/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244829527,"owners_count":20517319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["capture","extension","input","keyboard","keyboard-hooks","mouse","mouse-tracking","pyhook","python","record-keyboard","recording","send","simple","user32","windows"],"created_at":"2024-10-12T09:50:56.117Z","updated_at":"2025-06-29T09:34:28.882Z","avatar_url":"https://github.com/Zuzu-Typ.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# winput\n\nwinput provides a simple Python interface for capturing or sending keyboard and mouse input on Windows. It wraps functions from `user32.dll` so you can listen to events or automate input.\n\n\u003e **Warning**\n\u003e Do not record a user's input without their permission.\n\n  \n## About winput  \n**winput must not be used to record the user's input without their consent\\!**  \n**winput** is supposed to **replace** the outdated extension [PyHook](https://pypi.org/project/pyHook/)\\.  \n  \n## Installation\n\nInstall from PyPI:\n\n    pip install winput\n\n## Basic usage\n  \nTo use winput in a script, you have to import the package `winput` using  \n\n    import winput\n  \nor a wildcard import:  \n\n    from winput import *\n  \n  \n\nHere is a minimal example that prints every pressed key until Escape is hit:\n\n```python\nimport winput\n\n\ndef on_key(event: winput.KeyboardEvent) -\u003e int:\n    print(event.vkCode)\n    if event.vkCode == winput.VK_ESCAPE:\n        return winput.WP_STOP\n\nwinput.hook_keyboard(on_key)\nwinput.wait_messages()\nwinput.unhook_keyboard()\n```\n\nSee the [examples](examples/) directory for more scripts.\n\n  \n#### Capturing mouse input  \nThere are two ways you can get input from the mouse\\.  \n1\\. You can get the current position of the mouse cursor using  \n\n    get_mouse_pos() -\u003e (x, y)\n  \n  \n2\\. You can hook onto the Windows message system to receive an Event every time   \nthe state of the mouse changes:  \n\n    hook_mouse( callback_function )\n  \nThe function will be supplied with a **MouseEvent** as it's only argument\\.  \n\n    class MouseEvent:\n        position        # [length-2-tuple] the screen coordinates at which the event occured\n        action          # [int] which type of event occured - can be any of the mouse-wParams (see below)\n        time            # [int] time in ms since system startup\n        additional_data # [int] information for specific mouse events (which X-Button, amount of mouse-wheel-movement)\n        type            # [string] = \"MouseEvent\"\n  \nYou **have to run a message loop** to use a hook\\! \\(see **\\[Running a message loop\\]** below\\)  \n  \nRemember to unhook when you're done capturing by using:  \n\n    unhook_mouse()\n  \n  \nThe following mouse\\-wParams exist:  \n\n    \n    WM_MOUSEMOVE    = 0x0200 # the mouse has been moved\n    \n    WM_LBUTTONDOWN  = 0x0201 # left mouse button pressed\n    WM_LBTTONUP     = 0x0202 # left mouse button released\n    \n    WM_RBUTTONDOWN  = 0x0204 # right mouse button pressed\n    WM_RBUTTONUP    = 0x0205 # right mouse button released\n    \n    WM_MBUTTONDOWN  = 0x0207 # middle mouse button pressed\n    WM_MBUTTONUP    = 0x0208 # middle mouse button released\n    \n    WM_MOUSEWHEEL   = 0x020A # mouse wheel moved\n    WM_MOUSEHWHEEL  = 0x020E # mouse wheel moved (horizontal)\n    \n    WM_XBUTTONDOWN  = 0x020B # extra button pressed\n    WM_XBUTTONUP    = 0x020C # extra button released\n    \n  \n  \n  \n#### Capturing keyboard input  \nIf you want to monitor keyboard input you also have to hook onto the Windows message system\\.  \n\n    hook_keyboard( callback_function )\n  \nThe function will be supplied with a **KeyboardEvent** as it's only argument\\.  \n\n    class KeyboardEvent:\n        action  # [int] which type of event occured - can be any of the keyboard-wParams\n        vkCode  # [int] virtual key code -- which key has been pressed\n        time    # [int] time in ms since system startup\n        type    # [string] = \"KeyboardEvent\"\n  \nYou **have to run a message loop** to use a hook\\! \\(see *Running a message loop* below\\)  \n  \nAgain, remember to unhook when you're done capturing by using:  \n\n    unhook_keyboard()\n  \n  \nThe following keyboard\\-wParams exist:  \n\n    \n    WM_KEYDOWN      = 0x0100 # key pressed\n    WM_KEYUP        = 0x0101 # key released\n    \n    WM_SYSKEYDOWN   = 0x0104 # system-key pressed\n    WM_SYSKEYUP     = 0x0105 # system-key released\n    \n  \n\n#### Return values for callback functions\nThe callback (hook) functions mentioned above are expected to return a **flag**.\nThe following flags exist:\n\nFlag | Value | Meaning\n-----|-------|--------\n`WP_CONTINUE` | `0x00` | Continue normally\n`WP_UNHOOK` | `0x01` | Remove this hook\n`WP_STOP` | `0x02` | Stops the message loop\n`WP_DONT_PASS_INPUT_ON` | `0x04` | Does not call any other hooks (i.e. input isn't passed on to other programs)\n\nIf the callback function returns `None`, `WP_CONTINUE` is assumed.  \n  \n**WARNING:** Using `WP_DONT_PASS_INPUT_ON` will also prevent the inputs to be passed on to Windows. If you do this for a mouse hook, the mouse will **not move** and you might loose control over your computer. Same goes for keyboard hooks. The keyboard events will **not be passed on** to the rest of your system. You may loose control over your computer.\n\n\n#### Running a message loop  \nIf you're using a hook, you have to keep updating the Windows messages\\.  \nYou can either do this by using   \n\n    wait_messages()\n  \nto enter an infinite message loop, which you can stop by calling  \n\n    stop()\n  \n  \nOr you can have your own loop that repeatedly \\(at least 100x per second\\) calls  \n\n    get_message()\n  \n  \n  \n#### Virtual Key Codes \\(VK codes\\)  \nVirtual key codes or vk\\_codes are numerical representations of given keys\\.  \nTo get a list of all virtual key codes, take a look over [here](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes)\\.  \nAll VK codes are members of the main `winput` module and the submodule `winput.vk_codes`\\.  \nIf you want to import all the VK codes without performing a package\\-wide wildcard import, you can use  \n\n    from winput.vk_codes import *\n  \n  \nYou can also convert the virtual key codes to a literal representation using a predefined dict\\.  \n\n    vk_code_dict.get(vk_code, \"VK_UNKNOWN\") -\u003e string\n  \n  \n  \n#### Sending mouse input  \nTo set the position of the mouse cursor, you can use  \n\n    set_mouse_pos(x, y)\n  \n  \nTo make sure this also works with high DPI values, please use the DPI awareness functions below\\.  \n  \nTo move the mouse cursor by a given amount, you can use  \n\n    move_mouse(dx, dy)\n  \n  \nA mouse button can be pressed using  \n\n    press_mouse_button(mouse_button)\n  \nand released using  \n\n    release_mouse_button(mouse_button)\n  \nor pressed and released using  \n\n    click_mouse_button(mouse_button)\n  \n  \nThe following mouse buttons exist:  \n\n    \n    LEFT_MOUSE_BUTTON   = LMB   = 1\n    RIGHT_MOUSE_BUTTON  = RMB   = 2\n    MIDDLE_MOUSE_BUTTON = MMB   = 4\n    EXTRA_MOUSE_BUTTON1 = XMB1  = 8\n    EXTRA_MOUSE_BUTTON2 = XMB2  = 16\n  \n  \nThe mousewheel can be moved using  \n`move_mousewheel(amount[, horizontal = False])`  \n  \n#### Sending keyboard input  \nTo press a key, you can use  \n\n    press_key(vk_code)\n  \nto release it, you can use  \n\n    release_key(vk_code)\n  \nand to press and release it, you can use  \n\n    click_key(vk_code)\n  \n  \n  \n#### DPI awareness  \nTo make the process running winput DPI aware, use the following function:  \n\n    set_DPI_aware(per_monitor=True)\n  \n  \nTo get the DPI scaling factor for a given window handle \\(HWND\\), use  \n\n    get_window_scaling_factor(hwnd)\n  \n  \n### Example  \n#### Capturing the mouse and keyboard  \n```Python\nimport winput\n\ndef mouse_callback( event ):\n    if event.action == winput.WM_LBUTTONDOWN:\n        print(\"Left mouse button press at {}\".format( event.position ))\n    \ndef keyboard_callback( event ):\n    if event.vkCode == winput.VK_ESCAPE: # quit on pressing escape\n        return winput.WP_STOP\n        # alternatively you could also call:\n        # winput.stop()\n        \nprint(\"Press escape to quit\")\n    \n# hook input    \nwinput.hook_mouse( mouse_callback )\nwinput.hook_keyboard( keyboard_callback )\n\n# enter message loop\nwinput.wait_messages()\n\n# remove input hook\nwinput.unhook_mouse()\nwinput.unhook_keyboard()\n``` \n\n#### Capturing keyboard without passthrough\n```Python\nimport winput\n\ndef keyboard_callback(event : winput.KeyboardEvent) -\u003e int:\n  if event.key == winput.VK_ESCAPE:\n    print(\"quitting\")\n    return winput.WP_UNHOOK | winput.WP_STOP\n\t\n  print(winput.vk_code_dict.get(event.key, \"VK_UNKNOWN\"))\n  \n  return winput.WP_DONT_PASS_INPUT_ON\n  \nwinput.hook_keyboard(keyboard_callback)\nwinput.wait_messages()\n```\n\n  \n#### Sending input  \n\n```Python\nimport winput\nfrom winput.vk_codes import *\n\nimport time\n\ndef slow_click(vk_code): # delay each keypress by 1/10 of a second\n    time.sleep(0.1)\n    winput.click_key(vk_code)\n\n# open the RUN menu (WIN + R)\nwinput.press_key(VK_LWIN)\nwinput.click_key(VK_R)\nwinput.release_key(VK_LWIN)\n\ntime.sleep(0.5)\n\n# enter \"notepad.exe\"\nslow_click(VK_N)\nslow_click(VK_O)\nslow_click(VK_T)\nslow_click(VK_E)\nslow_click(VK_P)\nslow_click(VK_A)\nslow_click(VK_D)\nslow_click(VK_OEM_PERIOD)\nslow_click(VK_E)\nslow_click(VK_X)\nslow_click(VK_E)\nslow_click(VK_RETURN)\n\ntime.sleep(1)\n\n# enter \"hello world\"\nslow_click(VK_H)\nslow_click(VK_E)\nslow_click(VK_L)\nslow_click(VK_L)\nslow_click(VK_O)\nslow_click(VK_SPACE)\nslow_click(VK_W)\nslow_click(VK_O)\nslow_click(VK_R)\nslow_click(VK_L)\nslow_click(VK_D)\n```\n  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzuzu-typ%2Fwinput","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzuzu-typ%2Fwinput","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzuzu-typ%2Fwinput/lists"}