You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
797 lines
26 KiB
797 lines
26 KiB
5 years ago
|
Metadata-Version: 2.1
|
||
|
Name: pynput
|
||
|
Version: 1.6.8
|
||
|
Summary: Monitor and control user input devices
|
||
|
Home-page: https://github.com/moses-palmer/pynput
|
||
|
Author: Moses Palmér
|
||
|
Author-email: moses.palmer@gmail.com
|
||
|
License: LGPLv3
|
||
|
Keywords: control mouse,mouse input,control keyboard,keyboard input
|
||
|
Platform: UNKNOWN
|
||
|
Classifier: Development Status :: 5 - Production/Stable
|
||
|
Classifier: Intended Audience :: Developers
|
||
|
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
|
||
|
Classifier: Operating System :: MacOS :: MacOS X
|
||
|
Classifier: Operating System :: Microsoft :: Windows :: Windows NT/2000
|
||
|
Classifier: Operating System :: POSIX
|
||
|
Classifier: Programming Language :: Python
|
||
|
Classifier: Programming Language :: Python :: 2.7
|
||
|
Classifier: Programming Language :: Python :: 3.4
|
||
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||
|
Classifier: Topic :: System :: Monitoring
|
||
|
Requires-Dist: six
|
||
|
Requires-Dist: python-xlib (>=0.17) ; "linux" in sys_platform
|
||
|
Requires-Dist: enum34 ; python_version == "2.7"
|
||
|
Requires-Dist: pyobjc-framework-Quartz (>=3.0) ; sys_platform == "darwin"
|
||
|
|
||
|
pynput
|
||
|
======
|
||
|
|
||
|
This library allows you to control and monitor input devices.
|
||
|
|
||
|
Currently, mouse and keyboard input and monitoring are supported.
|
||
|
|
||
|
See `here <https://pynput.readthedocs.io/en/latest/>`_ for the full
|
||
|
documentation.
|
||
|
|
||
|
|
||
|
Controlling the mouse
|
||
|
---------------------
|
||
|
|
||
|
Use ``pynput.mouse.Controller`` like this::
|
||
|
|
||
|
from pynput.mouse import Button, Controller
|
||
|
|
||
|
mouse = Controller()
|
||
|
|
||
|
# Read pointer position
|
||
|
print('The current pointer position is {0}'.format(
|
||
|
mouse.position))
|
||
|
|
||
|
# Set pointer position
|
||
|
mouse.position = (10, 20)
|
||
|
print('Now we have moved it to {0}'.format(
|
||
|
mouse.position))
|
||
|
|
||
|
# Move pointer relative to current position
|
||
|
mouse.move(5, -5)
|
||
|
|
||
|
# Press and release
|
||
|
mouse.press(Button.left)
|
||
|
mouse.release(Button.left)
|
||
|
|
||
|
# Double click; this is different from pressing and releasing
|
||
|
# twice on Mac OSX
|
||
|
mouse.click(Button.left, 2)
|
||
|
|
||
|
# Scroll two steps down
|
||
|
mouse.scroll(0, 2)
|
||
|
|
||
|
|
||
|
Monitoring the mouse
|
||
|
--------------------
|
||
|
|
||
|
Use ``pynput.mouse.Listener`` like this::
|
||
|
|
||
|
from pynput import mouse
|
||
|
|
||
|
def on_move(x, y):
|
||
|
print('Pointer moved to {0}'.format(
|
||
|
(x, y)))
|
||
|
|
||
|
def on_click(x, y, button, pressed):
|
||
|
print('{0} at {1}'.format(
|
||
|
'Pressed' if pressed else 'Released',
|
||
|
(x, y)))
|
||
|
if not pressed:
|
||
|
# Stop listener
|
||
|
return False
|
||
|
|
||
|
def on_scroll(x, y, dx, dy):
|
||
|
print('Scrolled {0} at {1}'.format(
|
||
|
'down' if dy < 0 else 'up',
|
||
|
(x, y)))
|
||
|
|
||
|
# Collect events until released
|
||
|
with mouse.Listener(
|
||
|
on_move=on_move,
|
||
|
on_click=on_click,
|
||
|
on_scroll=on_scroll) as listener:
|
||
|
listener.join()
|
||
|
|
||
|
# ...or, in a non-blocking fashion:
|
||
|
listener = mouse.Listener(
|
||
|
on_move=on_move,
|
||
|
on_click=on_click,
|
||
|
on_scroll=on_scroll)
|
||
|
listener.start()
|
||
|
|
||
|
A mouse listener is a ``threading.Thread``, and all callbacks will be invoked
|
||
|
from the thread.
|
||
|
|
||
|
Call ``pynput.mouse.Listener.stop`` from anywhere, raise ``StopException`` or
|
||
|
return ``False`` from a callback to stop the listener.
|
||
|
|
||
|
When using the non-blocking version above, the current thread will continue
|
||
|
executing. This might be necessary when integrating with other GUI frameworks
|
||
|
that incorporate a main-loop, but when run from a script, this will cause the
|
||
|
program to terminate immediately.
|
||
|
|
||
|
|
||
|
The mouse listener thread
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
The listener callbacks are invoked directly from an operating thread on some
|
||
|
platforms, notably *Windows*.
|
||
|
|
||
|
This means that long running procedures and blocking operations should not be
|
||
|
invoked from the callback, as this risks freezing input for all processes.
|
||
|
|
||
|
A possible workaround is to just dispatch incoming messages to a queue, and let
|
||
|
a separate thread handle them.
|
||
|
|
||
|
|
||
|
Handling mouse listener errors
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
If a callback handler raises an exception, the listener will be stopped. Since
|
||
|
callbacks run in a dedicated thread, the exceptions will not automatically be
|
||
|
reraised.
|
||
|
|
||
|
To be notified about callback errors, call ``Thread.join`` on the listener
|
||
|
instance::
|
||
|
|
||
|
from pynput import mouse
|
||
|
|
||
|
class MyException(Exception): pass
|
||
|
|
||
|
def on_click(x, y, button, pressed):
|
||
|
if button == mouse.Button.left:
|
||
|
raise MyException(button)
|
||
|
|
||
|
# Collect events until released
|
||
|
with mouse.Listener(
|
||
|
on_click=on_click) as listener:
|
||
|
try:
|
||
|
listener.join()
|
||
|
except MyException as e:
|
||
|
print('{0} was clicked'.format(e.args[0]))
|
||
|
|
||
|
|
||
|
Toggling event listening for the mouse listener
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Once ``pynput.mouse.Listener.stop`` has been called, the listener cannot be
|
||
|
restarted, since listeners are instances of ``threading.Thread``.
|
||
|
|
||
|
If your application requires toggling listening events, you must either add an
|
||
|
internal flag to ignore events when not required, or create a new listener when
|
||
|
resuming listening.
|
||
|
|
||
|
|
||
|
Synchronous event listening for the mouse listener
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
To simplify scripting, synchronous event listening is supported through the
|
||
|
utility class ``pynput.mouse.Events``. This class supports reading single
|
||
|
events in a non-blocking fashion, as well as iterating over all events.
|
||
|
|
||
|
To read a single event, use the following code::
|
||
|
|
||
|
from pynput import mouse
|
||
|
|
||
|
# The event listener will be running in this block
|
||
|
with mouse.Events() as events:
|
||
|
# Block at most one second
|
||
|
event = events.get(1.0)
|
||
|
if event is None:
|
||
|
print('You did not interact with the mouse within one second')
|
||
|
else:
|
||
|
print('Received event {}'.format(event))
|
||
|
|
||
|
To iterate over mouse events, use the following code::
|
||
|
|
||
|
from pynput import mouse
|
||
|
|
||
|
# The event listener will be running in this block
|
||
|
with mouse.Events() as events:
|
||
|
for event in events:
|
||
|
if event.button == mouse.Button.right:
|
||
|
break
|
||
|
else:
|
||
|
print('Received event {}'.format(event))
|
||
|
|
||
|
Please note that the iterator method does not support non-blocking operation,
|
||
|
so it will wait for at least one mouse event.
|
||
|
|
||
|
The events will be instances of the inner classes found in
|
||
|
``pynput.mouse.Events``.
|
||
|
|
||
|
|
||
|
Ensuring consistent coordinates between listener and controller on Windows
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Recent versions of _Windows_ support running legacy applications scaled when
|
||
|
the system scaling has been increased beyond 100%. This allows old applications
|
||
|
to scale, albeit with a blurry look, and avoids tiny, unusable user interfaces.
|
||
|
|
||
|
This scaling is unfortunately inconsistently applied to a mouse listener and a
|
||
|
controller: the listener will receive physical coordinates, but the controller
|
||
|
has to work with scaled coordinates.
|
||
|
|
||
|
This can be worked around by telling Windows that your application is DPI
|
||
|
aware. This is a process global setting, so _pynput_ cannot do it
|
||
|
automatically. Do enable DPI awareness, run the following code::
|
||
|
|
||
|
import ctypes
|
||
|
|
||
|
|
||
|
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||
|
|
||
|
ctypes.windll.shcore.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)
|
||
|
|
||
|
|
||
|
Controlling the keyboard
|
||
|
------------------------
|
||
|
|
||
|
Use ``pynput.keyboard.Controller`` like this::
|
||
|
|
||
|
from pynput.keyboard import Key, Controller
|
||
|
|
||
|
keyboard = Controller()
|
||
|
|
||
|
# Press and release space
|
||
|
keyboard.press(Key.space)
|
||
|
keyboard.release(Key.space)
|
||
|
|
||
|
# Type a lower case A; this will work even if no key on the
|
||
|
# physical keyboard is labelled 'A'
|
||
|
keyboard.press('a')
|
||
|
keyboard.release('a')
|
||
|
|
||
|
# Type two upper case As
|
||
|
keyboard.press('A')
|
||
|
keyboard.release('A')
|
||
|
with keyboard.pressed(Key.shift):
|
||
|
keyboard.press('a')
|
||
|
keyboard.release('a')
|
||
|
|
||
|
# Type 'Hello World' using the shortcut type method
|
||
|
keyboard.type('Hello World')
|
||
|
|
||
|
|
||
|
Monitoring the keyboard
|
||
|
-----------------------
|
||
|
|
||
|
Use ``pynput.keyboard.Listener`` like this::
|
||
|
|
||
|
from pynput import keyboard
|
||
|
|
||
|
def on_press(key):
|
||
|
try:
|
||
|
print('alphanumeric key {0} pressed'.format(
|
||
|
key.char))
|
||
|
except AttributeError:
|
||
|
print('special key {0} pressed'.format(
|
||
|
key))
|
||
|
|
||
|
def on_release(key):
|
||
|
print('{0} released'.format(
|
||
|
key))
|
||
|
if key == keyboard.Key.esc:
|
||
|
# Stop listener
|
||
|
return False
|
||
|
|
||
|
# Collect events until released
|
||
|
with keyboard.Listener(
|
||
|
on_press=on_press,
|
||
|
on_release=on_release) as listener:
|
||
|
listener.join()
|
||
|
|
||
|
# ...or, in a non-blocking fashion:
|
||
|
listener = keyboard.Listener(
|
||
|
on_press=on_press,
|
||
|
on_release=on_release)
|
||
|
listener.start()
|
||
|
|
||
|
A keyboard listener is a ``threading.Thread``, and all callbacks will be
|
||
|
invoked from the thread.
|
||
|
|
||
|
Call ``pynput.keyboard.Listener.stop`` from anywhere, raise ``StopException``
|
||
|
or return ``False`` from a callback to stop the listener.
|
||
|
|
||
|
The ``key`` parameter passed to callbacks is a ``pynput.keyboard.Key``, for
|
||
|
special keys, a ``pynput.keyboard.KeyCode`` for normal alphanumeric keys, or
|
||
|
just ``None`` for unknown keys.
|
||
|
|
||
|
When using the non-blocking version above, the current thread will continue
|
||
|
executing. This might be necessary when integrating with other GUI frameworks
|
||
|
that incorporate a main-loop, but when run from a script, this will cause the
|
||
|
program to terminate immediately.
|
||
|
|
||
|
|
||
|
The keyboard listener thread
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
The listener callbacks are invoked directly from an operating thread on some
|
||
|
platforms, notably *Windows*.
|
||
|
|
||
|
This means that long running procedures and blocking operations should not be
|
||
|
invoked from the callback, as this risks freezing input for all processes.
|
||
|
|
||
|
A possible workaround is to just dispatch incoming messages to a queue, and let
|
||
|
a separate thread handle them.
|
||
|
|
||
|
|
||
|
Handling keyboard listener errors
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
If a callback handler raises an exception, the listener will be stopped. Since
|
||
|
callbacks run in a dedicated thread, the exceptions will not automatically be
|
||
|
reraised.
|
||
|
|
||
|
To be notified about callback errors, call ``Thread.join`` on the listener
|
||
|
instance::
|
||
|
|
||
|
from pynput import keyboard
|
||
|
|
||
|
class MyException(Exception): pass
|
||
|
|
||
|
def on_press(key):
|
||
|
if key == keyboard.Key.esc:
|
||
|
raise MyException(key)
|
||
|
|
||
|
# Collect events until released
|
||
|
with keyboard.Listener(
|
||
|
on_press=on_press) as listener:
|
||
|
try:
|
||
|
listener.join()
|
||
|
except MyException as e:
|
||
|
print('{0} was pressed'.format(e.args[0]))
|
||
|
|
||
|
|
||
|
Toggling event listening for the keyboard listener
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Once ``pynput.keyboard.Listener.stop`` has been called, the listener cannot be
|
||
|
restarted, since listeners are instances of ``threading.Thread``.
|
||
|
|
||
|
If your application requires toggling listening events, you must either add an
|
||
|
internal flag to ignore events when not required, or create a new listener when
|
||
|
resuming listening.
|
||
|
|
||
|
|
||
|
Synchronous event listening for the keyboard listener
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
To simplify scripting, synchronous event listening is supported through the
|
||
|
utility class ``pynput.keyboard.Events``. This class supports reading single
|
||
|
events in a non-blocking fashion, as well as iterating over all events.
|
||
|
|
||
|
To read a single event, use the following code::
|
||
|
|
||
|
from pynput import keyboard
|
||
|
|
||
|
# The event listener will be running in this block
|
||
|
with keyboard.Events() as events:
|
||
|
# Block at most one second
|
||
|
event = events.get(1.0)
|
||
|
if event is None:
|
||
|
print('You did not press a key within one second')
|
||
|
else:
|
||
|
print('Received event {}'.format(event))
|
||
|
|
||
|
To iterate over keyboard events, use the following code::
|
||
|
|
||
|
from pynput import keyboard
|
||
|
|
||
|
# The event listener will be running in this block
|
||
|
with keyboard.Events() as events:
|
||
|
for event in events:
|
||
|
if event.key == keyboard.Key.esc:
|
||
|
break
|
||
|
else:
|
||
|
print('Received event {}'.format(event))
|
||
|
|
||
|
Please note that the iterator method does not support non-blocking operation,
|
||
|
so it will wait for at least one keyboard event.
|
||
|
|
||
|
The events will be instances of the inner classes found in
|
||
|
``pynput.keyboard.Events``.
|
||
|
|
||
|
|
||
|
Global hotkeys
|
||
|
~~~~~~~~~~~~~~
|
||
|
|
||
|
A common use case for keyboard monitors is reacting to global hotkeys. Since a
|
||
|
listener does not maintain any state, hotkeys involving multiple keys must
|
||
|
store this state somewhere.
|
||
|
|
||
|
*pynput* provides the class ``pynput.keyboard.HotKey`` for this purpose. It
|
||
|
contains two methods to update the state, designed to be easily interoperable
|
||
|
with a keyboard listener: ``pynput.keyboard.HotKey.press`` and
|
||
|
``pynput.keyboard.HotKey.release`` which can be directly passed as listener
|
||
|
callbacks.
|
||
|
|
||
|
The intended usage is as follows::
|
||
|
|
||
|
from pynput import keyboard
|
||
|
|
||
|
def on_activate():
|
||
|
print('Global hotkey activated!')
|
||
|
|
||
|
def for_canonical(f):
|
||
|
return lambda k: f(l.canonical(k))
|
||
|
|
||
|
hotkey = keyboard.HotKey(
|
||
|
keyboard.HotKey.parse('<ctrl>+<alt>+h'),
|
||
|
on_activate)
|
||
|
with keyboard.Listener(
|
||
|
on_press=for_canonical(hotkey.press),
|
||
|
on_release=for_canonical(hotkey.release)) as l:
|
||
|
l.join()
|
||
|
|
||
|
This will create a hotkey, and then use a listener to update its state. Once
|
||
|
all the specified keys are pressed simultaneously, ``on_activate`` will be
|
||
|
invoked.
|
||
|
|
||
|
Note that keys are passed through ``pynput.keyboard.Listener.canonical`` before
|
||
|
being passed to the ``HotKey`` instance. This is to remove any modifier state
|
||
|
from the key events, and to normalise modifiers with more than one physical
|
||
|
button.
|
||
|
|
||
|
The method ``pynput.keyboard.HotKey.parse`` is a convenience function to
|
||
|
transform shortcut strings to key collections. Please see its documentation for
|
||
|
more information.
|
||
|
|
||
|
To register a number of global hotkeys, use the convenience class
|
||
|
``pynput.keyboard.GlobalHotKeys``::
|
||
|
|
||
|
from pynput import keyboard
|
||
|
|
||
|
def on_activate_h():
|
||
|
print('<ctrl>+<alt>+h pressed')
|
||
|
|
||
|
def on_activate_i():
|
||
|
print('<ctrl>+<alt>+i pressed')
|
||
|
|
||
|
with keyboard.GlobalHotKeys({
|
||
|
'<ctrl>+<alt>+h': on_activate_h,
|
||
|
'<ctrl>+<alt>+i': on_activate_i}) as h:
|
||
|
h.join()
|
||
|
|
||
|
|
||
|
Release Notes
|
||
|
=============
|
||
|
|
||
|
v1.6.8 (2020-02-28) - Various fixes
|
||
|
-----------------------------------
|
||
|
* Updated documentation.
|
||
|
* Corrected lint warnings and tests.
|
||
|
* Do not use internal types in ``argtypes`` for ``win32`` functions; this
|
||
|
renders them uncallable for other code running in the same runtime.
|
||
|
* Include scan codes in events on *Windows*. Thanks to *bhudax*!
|
||
|
* Correctly apply transformation to scroll event values on *Windows*. Thanks
|
||
|
to *DOCCA0*!
|
||
|
|
||
|
|
||
|
v1.6.7 (2020-02-17) - Various fixes
|
||
|
-----------------------------------
|
||
|
* Corrected infinite scrolling on *macOS* when providing non-integer deltas.
|
||
|
Thanks to *Iván Munsuri Ibáñez*!
|
||
|
* Corrected controller and listener handling of media keys on *macOS*. Thanks
|
||
|
to *Iván Munsuri Ibáñez*!
|
||
|
|
||
|
|
||
|
v1.6.6 (2020-01-23) - Corrected hot key documentation
|
||
|
-----------------------------------------------------
|
||
|
* The code examples for the simple ``pynput.keyboard.HotKey`` now work. Thanks
|
||
|
to *jfongattw*!
|
||
|
|
||
|
|
||
|
v1.6.5 (2020-01-08) - Corrected media key mappings
|
||
|
--------------------------------------------------
|
||
|
* Corrected media key mappings on *macOS*. Thanks to *Luis Nachtigall*!
|
||
|
|
||
|
|
||
|
v1.6.4 (2020-01-03) - Corrected imports yet again
|
||
|
-------------------------------------------------
|
||
|
* Corrected imports for keyboard Controller. Thanks to *rhystedstone*!
|
||
|
|
||
|
|
||
|
v1.6.3 (2019-12-28) - Corrected imports again
|
||
|
---------------------------------------------
|
||
|
* Corrected imports for keyboard Controller. Thanks to *Matt Iversen*!
|
||
|
|
||
|
|
||
|
v1.6.2 (2019-12-28) - Corrected imports
|
||
|
---------------------------------------
|
||
|
* Corrected imports for keyboard Controller. Thanks to *Matt Iversen*!
|
||
|
|
||
|
|
||
|
v1.6.1 (2019-12-27) - Corrections for *Windows*
|
||
|
-----------------------------------------------
|
||
|
* Corrected global hotkeys on *Windows*.
|
||
|
* Corrected pressed / released state for keyboard listener on *Windows*.
|
||
|
Thanks to *segalion*!
|
||
|
|
||
|
v1.6.0 (2019-12-11) - Global Hotkeys
|
||
|
------------------------------------
|
||
|
* Added support for global hotkeys.
|
||
|
* Added support for streaming listener events synchronously.
|
||
|
|
||
|
|
||
|
v1.5.2 (2019-12-06) - Corrected media key names for *Xorg*
|
||
|
----------------------------------------------------------
|
||
|
* Removed media flag from *Xorg* keys.
|
||
|
|
||
|
|
||
|
v1.5.1 (2019-12-06) - Corrected media key names for *macOS*
|
||
|
-----------------------------------------------------------
|
||
|
* Corrected attribute names for media keys on *macOS*. Thanks to *ah3243*!
|
||
|
|
||
|
|
||
|
v1.5.0 (2019-12-04) - Various improvements
|
||
|
------------------------------------------
|
||
|
* Corrected keyboard listener on *Windows*. Thanks to *akiratakasaki*,
|
||
|
*segalion*, *SpecialCharacter*!
|
||
|
* Corrected handling of some special keys, including arrow keys, when combined
|
||
|
with modifiers on *Windows*. Thanks to *tuessetr*!
|
||
|
* Updated documentation to include information about DPI scaling on *Windows*.
|
||
|
Thanks to *david-szarka*!
|
||
|
* Added experimental support for media keys. Thanks to *ShivamJoker*,
|
||
|
*StormTersteeg*!
|
||
|
|
||
|
|
||
|
v1.4.5 (2019-11-05) - Corrected errors on *Python 3.8*
|
||
|
------------------------------------------------------
|
||
|
* Corrected errors about using `in` operator for enums on *Python 3.8* on
|
||
|
*macOS*.
|
||
|
|
||
|
|
||
|
v1.4.4 (2019-09-24) - Actually corrected keyboard listener on macOS
|
||
|
-------------------------------------------------------------------
|
||
|
* Included commit to correctly fall back on
|
||
|
``CGEventKeyboardGetUnicodeString``.
|
||
|
* Corrected deprecation warnings about ``Enum`` usage on *Python 3.8*.
|
||
|
|
||
|
|
||
|
v1.4.3 (2019-09-24) - Corrected keyboard listener on macOS again
|
||
|
----------------------------------------------------------------
|
||
|
* Correctly fall back on ``CGEventKeyboardGetUnicodeString``.
|
||
|
* Updated documentation.
|
||
|
|
||
|
|
||
|
v1.4.2 (2019-03-22) - Corrected keyboard listener on macOS
|
||
|
----------------------------------------------------------
|
||
|
* Use ``CGEventKeyboardGetUnicodeString`` in *macOS* keyboard listener to send
|
||
|
correct characters.
|
||
|
* Include keysym instead of key code in *Xorg* keyboard listener.
|
||
|
* Corrected logging to not include expected ``StopException``.
|
||
|
* Updated and corrected documentation.
|
||
|
|
||
|
|
||
|
v1.4.1 (2018-09-07) - Logging
|
||
|
-----------------------------
|
||
|
* Log unhandled exceptions raised by listener callbacks.
|
||
|
|
||
|
|
||
|
v1.4 (2018-07-03) - Event suppression
|
||
|
-------------------------------------
|
||
|
* Added possibility to fully suppress events when listening.
|
||
|
* Added support for typing some control characters.
|
||
|
* Added support for mouse drag events on *OSX*. Thanks to *jungledrum*!
|
||
|
* Include the key code in keyboard listener events.
|
||
|
* Correctly handle the numeric key pad on *Xorg* with *num lock* active.
|
||
|
Thanks to *TheoRet*!
|
||
|
* Corrected handling of current thread keyboard layout on *Windows*. Thanks to
|
||
|
*Schmettaling*!
|
||
|
* Corrected stopping of listeners on *Xorg*.
|
||
|
* Corrected import of ``Xlib.keysymdef.xkb`` on *Xorg*. Thanks to *Glandos*!
|
||
|
|
||
|
|
||
|
v1.3.10 (2018-02-05) - Do not crash under *Xephyr*
|
||
|
--------------------------------------------------
|
||
|
* Do not crash when ``Xlib.display.Display.get_input_focus`` returns an
|
||
|
integer, as it may when running under *Xephyr*. Thanks to *Eli Skeggs*!
|
||
|
|
||
|
|
||
|
v1.3.9 (2018-01-12) - Correctly handle the letter *A* on *OSX*
|
||
|
--------------------------------------------------------------
|
||
|
* Corrected check for virtual key code when generating keyboard events on
|
||
|
*OSX*. This fixes an issue where pressing *A* with *shift* explicitly pressed
|
||
|
would still type a miniscule letter.
|
||
|
|
||
|
|
||
|
v1.3.8 (2017-12-08) - Do not crash on some keyboard layouts on *OSX*
|
||
|
--------------------------------------------------------------------
|
||
|
* Fall back on a different method to retrieve the keyboard layout on *OSX*.
|
||
|
This helps for some keyboard layouts, such as *Chinese*. Thanks to
|
||
|
*haoflynet*!
|
||
|
|
||
|
|
||
|
v1.3.7 (2017-08-23) - *Xorg* corrections
|
||
|
----------------------------------------
|
||
|
* Include mouse buttons up to *30* for *Xorg*.
|
||
|
|
||
|
|
||
|
v1.3.6 (2017-08-13) - *win32* corrections
|
||
|
-----------------------------------------
|
||
|
* Corrected double delivery of fake keyboard events on *Windows*.
|
||
|
* Corrected handling of synthetic unicode keys on *Windows*.
|
||
|
|
||
|
|
||
|
v1.3.5 (2017-06-07) - Corrected dependencies again
|
||
|
--------------------------------------------------
|
||
|
* Reverted changes in *1.3.3*.
|
||
|
* Corrected platform specifier for *Python 2* on *Linux*.
|
||
|
|
||
|
|
||
|
v1.3.4 (2017-06-05) - *Xorg* corrections
|
||
|
----------------------------------------
|
||
|
* Corrected bounds check for values on *Xorg*.
|
||
|
|
||
|
|
||
|
v1.3.3 (2017-06-05) - Make dependencies non-optional
|
||
|
----------------------------------------------------
|
||
|
* Made platform depdendencies non-optional.
|
||
|
|
||
|
|
||
|
v1.3.2 (2017-05-15) - Fix for button click on Mac
|
||
|
-------------------------------------------------
|
||
|
* Corrected regression from previous release where button clicks would
|
||
|
crash the *Mac* mouse listener.
|
||
|
|
||
|
|
||
|
v1.3.1 (2017-05-12) - Fixes for unknown buttons on Linux
|
||
|
--------------------------------------------------------
|
||
|
* Fall back on `Button.unknown` for unknown mouse buttons in *Xorg* mouse
|
||
|
listener.
|
||
|
|
||
|
|
||
|
v1.3 (2017-04-10) - Platform specific features
|
||
|
----------------------------------------------
|
||
|
* Added ability to stop event propagation on *Windows*. This will prevent
|
||
|
events from reaching other applications.
|
||
|
* Added ability to ignore events on *Windows*. This is a workaround for systems
|
||
|
where the keyboard monitor interferes with normal keyboard events.
|
||
|
* Added ability to modify events on *OSX*. This allows intercepting and
|
||
|
altering input events before they reach other applications.
|
||
|
* Corrected crash on *OSX* when some types of third party input sources are
|
||
|
installed.
|
||
|
|
||
|
|
||
|
v1.2 (2017-01-06) - Improved error handling
|
||
|
-------------------------------------------
|
||
|
* Allow catching exceptions thrown from listener callbacks. This changes the
|
||
|
API, as joining a listener now potentially raises unhandled exceptions,
|
||
|
and unhandled exceptions will stop listeners.
|
||
|
* Added support for the numeric keypad on *Linux*.
|
||
|
* Improved documentation.
|
||
|
* Thanks to *jollysean* and *gilleswijnker* for their input!
|
||
|
|
||
|
|
||
|
v1.1.7 (2017-01-02) - Handle middle button on Windows
|
||
|
-----------------------------------------------------
|
||
|
* Listen for and dispatch middle button mouse clicks on *Windows*.
|
||
|
|
||
|
|
||
|
v1.1.6 (2016-11-24) - Corrected context manager for pressing keys
|
||
|
-----------------------------------------------------------------
|
||
|
* Corrected bug in ``pynput.keyboard.Controller.pressed`` which caused it to
|
||
|
never release the key. Many thanks to Toby Southwell!
|
||
|
|
||
|
|
||
|
v1.1.5 (2016-11-17) - Corrected modifier key combinations on Linux
|
||
|
------------------------------------------------------------------
|
||
|
* Corrected handling of modifier keys to allow them to be composable on
|
||
|
*Linux*.
|
||
|
|
||
|
|
||
|
v1.1.4 (2016-10-30) - Small bugfixes
|
||
|
------------------------------------
|
||
|
* Corrected error generation when ``GetKeyboardState`` fails.
|
||
|
* Make sure to apply shift state to borrowed keys on *X*.
|
||
|
* Use *pylint*.
|
||
|
|
||
|
|
||
|
v1.1.3 (2016-09-27) - Changed Xlib backend library
|
||
|
--------------------------------------------------
|
||
|
* Changed *Xlib* library.
|
||
|
|
||
|
|
||
|
v1.1.2 (2016-09-26) - Added missing type for Python 2
|
||
|
-----------------------------------------------------
|
||
|
* Added missing ``LPDWORD`` for *Python 2* on *Windows*.
|
||
|
|
||
|
|
||
|
v1.1.1 (2016-09-26) - Fixes for listeners and controllers on Windows
|
||
|
--------------------------------------------------------------------
|
||
|
* Corrected keyboard listener on *Windows*. Modifier keys and other keys
|
||
|
changing the state of the keyboard are now handled correctly.
|
||
|
* Corrected mouse click and release on *Windows*.
|
||
|
* Corrected code samples.
|
||
|
|
||
|
|
||
|
v1.1 (2016-06-22) - Simplified usage on Linux
|
||
|
---------------------------------------------
|
||
|
* Propagate import errors raised on Linux to help troubleshoot missing
|
||
|
``Xlib`` module.
|
||
|
* Declare ``python3-xlib`` as dependency on *Linux* for *Python 3*.
|
||
|
|
||
|
|
||
|
v1.0.6 (2016-04-19) - Universal wheel
|
||
|
-------------------------------------
|
||
|
* Make sure to build a universal wheel for all python versions.
|
||
|
|
||
|
|
||
|
v1.0.5 (2016-04-11) - Fixes for dragging on OSX
|
||
|
-----------------------------------------------
|
||
|
* Corrected dragging on *OSX*.
|
||
|
* Added scroll speed constant for *OSX* to correct slow scroll speed.
|
||
|
|
||
|
|
||
|
v1.0.4 (2016-04-11) - Fixes for clicking and scrolling on Windows
|
||
|
-----------------------------------------------------------------
|
||
|
* Corrected name of mouse input field when sending click and scroll events.
|
||
|
|
||
|
|
||
|
v1.0.3 (2016-04-05) - Fixes for Python 3 on Windows
|
||
|
---------------------------------------------------
|
||
|
* Corrected use of ``ctypes`` on Windows.
|
||
|
|
||
|
|
||
|
v1.0.2 (2016-04-03) - Fixes for thread identifiers
|
||
|
--------------------------------------------------
|
||
|
* Use thread identifiers to identify threads, not Thread instances.
|
||
|
|
||
|
|
||
|
v1.0.1 (2016-04-03) - Fixes for Python 3
|
||
|
----------------------------------------
|
||
|
* Corrected bugs which prevented the library from being used on *Python 3*.
|
||
|
|
||
|
|
||
|
v1.0 (2016-02-28) - Stable Release
|
||
|
----------------------------------
|
||
|
* Changed license to *LGPL*.
|
||
|
* Corrected minor bugs and inconsistencies.
|
||
|
* Corrected and extended documentation.
|
||
|
|
||
|
|
||
|
v0.6 (2016-02-08) - Keyboard Monitor
|
||
|
------------------------------------
|
||
|
* Added support for monitoring the keyboard.
|
||
|
* Corrected wheel packaging.
|
||
|
* Corrected deadlock when stopping a listener in some cases on *X*.
|
||
|
* Corrected key code constants on *Mac OSX*.
|
||
|
* Do not intercept events on *Mac OSX*.
|
||
|
|
||
|
|
||
|
v0.5.1 (2016-01-26) - Do not die on dead keys
|
||
|
---------------------------------------------
|
||
|
* Corrected handling of dead keys.
|
||
|
* Corrected documentation.
|
||
|
|
||
|
|
||
|
v0.5 (2016-01-18) - Keyboard Modifiers
|
||
|
--------------------------------------
|
||
|
* Added support for modifiers.
|
||
|
|
||
|
|
||
|
v0.4 (2015-12-22) - Keyboard Controller
|
||
|
---------------------------------------
|
||
|
* Added keyboard controller.
|
||
|
|
||
|
|
||
|
v0.3 (2015-12-22) - Cleanup
|
||
|
---------------------------
|
||
|
* Moved ``pynput.mouse.Controller.Button`` to top-level.
|
||
|
|
||
|
|
||
|
v0.2 (2015-10-28) - Initial Release
|
||
|
-----------------------------------
|
||
|
* Support for controlling the mouse on *Linux*, *Mac OSX* and *Windows*.
|
||
|
* Support for monitoring the mouse on *Linux*, *Mac OSX* and *Windows*.
|
||
|
|
||
|
|