diff --git a/mouse/.gitignore b/mouse/.gitignore
new file mode 100644
index 0000000..7bbc71c
--- /dev/null
+++ b/mouse/.gitignore
@@ -0,0 +1,101 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# dotenv
+.env
+
+# virtualenv
+.venv
+venv/
+ENV/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
diff --git a/mouse/CHANGES.md b/mouse/CHANGES.md
new file mode 100644
index 0000000..e877696
--- /dev/null
+++ b/mouse/CHANGES.md
@@ -0,0 +1,30 @@
+# 0.7.1
+
+- Fixed errors and incorrect information on setup.py.
+- Fixed Windows segfault.
+- Applied pending bug fixes.
+
+
+# 0.7.0
+
+- [All] Fix Windows hook error (#1).
+- [All] Add __main__ module, allowing `python -m mouse` to save and load events.
+
+
+# 0.6.1
+
+- [Windows] Fixed ctypes type-checking error.
+- [All] Misc fixes to release process.
+
+
+# 0.6.0
+
+- Added README and API docs.
+- Bump version to replace old library.
+
+
+# 0.0.1
+
+- Initial release, migrated from `keyboard` package.
+
+
diff --git a/mouse/LICENSE.txt b/mouse/LICENSE.txt
new file mode 100644
index 0000000..4f3cb7b
--- /dev/null
+++ b/mouse/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016 Lucas Boppre Niehues
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/mouse/Makefile b/mouse/Makefile
new file mode 100644
index 0000000..b2f750a
--- /dev/null
+++ b/mouse/Makefile
@@ -0,0 +1,18 @@
+test: tests
+tests:
+ python2 -m coverage run -m mouse._mouse_tests
+ python2 -m coverage run -am mouse._mouse_tests
+ python -m coverage run -am mouse._mouse_tests
+ python -m coverage run -am mouse._mouse_tests
+ python -m coverage report && coverage3 html
+
+build: tests mouse setup.py
+ python ../docstring2markdown/docstring2markdown.py mouse "https://github.com/boppreh/mouse/blob/master" > README.md
+ find . \( -name "*.py" -o -name "*.sh" -o -name "* .md" \) -exec dos2unix {} \;
+ python setup.py sdist --format=zip bdist_wheel --universal bdist_wininst && twine check dist/*
+
+release:
+ python make_release.py
+
+clean:
+ rm -rfv dist build coverage_html_report mouse.egg-info
\ No newline at end of file
diff --git a/mouse/README.md b/mouse/README.md
new file mode 100644
index 0000000..ea98e2f
--- /dev/null
+++ b/mouse/README.md
@@ -0,0 +1,500 @@
+
+mouse
+=====
+
+Take full control of your mouse with this small Python library. Hook global events, register hotkeys, simulate mouse movement and clicks, and much more.
+
+_Huge thanks to [Kirill Pavlov](http://kirillpavlov.com/) for donating the package name. If you are looking for the Cheddargetter.com client implementation, [`pip install mouse==0.5.0`](https://pypi.python.org/pypi/mouse/0.5.0)._
+
+## Features
+
+- Global event hook on all mice devices (captures events regardless of focus).
+- **Listen** and **sends** mouse events.
+- Works with **Windows** and **Linux** (requires sudo).
+- **Pure Python**, no C modules to be compiled.
+- **Zero dependencies**. Trivial to install and deploy, just copy the files.
+- **Python 2 and 3**.
+- Includes **high level API** (e.g. [record](#mouse.record) and [play](#mouse.play).
+- Events automatically captured in separate thread, doesn't block main program.
+- Tested and documented.
+
+This program makes no attempt to hide itself, so don't use it for keyloggers.
+
+## Usage
+
+Install the [PyPI package](https://pypi.python.org/pypi/mouse/):
+
+ $ sudo pip install mouse
+
+or clone the repository (no installation required, source files are sufficient):
+
+ $ git clone https://github.com/boppreh/mouse
+
+Then check the [API docs](https://github.com/boppreh/mouse#api) to see what features are available.
+
+
+## Known limitations:
+
+- Events generated under Windows don't report device id (`event.device == None`). [#21](https://github.com/boppreh/keyboard/issues/21)
+- To avoid depending on X the Linux parts reads raw device files (`/dev/input/input*`) but this requries root.
+- Other applications, such as some games, may register hooks that swallow all key events. In this case `mouse` will be unable to report events.
+
+
+
+# API
+#### Table of Contents
+
+- [mouse.**ButtonEvent**](#mouse.ButtonEvent)
+- [mouse.**DOUBLE**](#mouse.DOUBLE)
+- [mouse.**DOWN**](#mouse.DOWN)
+- [mouse.**LEFT**](#mouse.LEFT)
+- [mouse.**MIDDLE**](#mouse.MIDDLE)
+- [mouse.**MoveEvent**](#mouse.MoveEvent)
+- [mouse.**RIGHT**](#mouse.RIGHT)
+- [mouse.**UP**](#mouse.UP)
+- [mouse.**WheelEvent**](#mouse.WheelEvent)
+- [mouse.**X**](#mouse.X)
+- [mouse.**X2**](#mouse.X2)
+- [mouse.**version**](#mouse.version)
+- [mouse.**is\_pressed**](#mouse.is_pressed)
+- [mouse.**press**](#mouse.press) *(aliases: `hold`)*
+- [mouse.**release**](#mouse.release)
+- [mouse.**click**](#mouse.click)
+- [mouse.**double\_click**](#mouse.double_click)
+- [mouse.**right\_click**](#mouse.right_click)
+- [mouse.**wheel**](#mouse.wheel)
+- [mouse.**move**](#mouse.move)
+- [mouse.**drag**](#mouse.drag)
+- [mouse.**on\_button**](#mouse.on_button)
+- [mouse.**on\_click**](#mouse.on_click)
+- [mouse.**on\_double\_click**](#mouse.on_double_click)
+- [mouse.**on\_right\_click**](#mouse.on_right_click)
+- [mouse.**on\_middle\_click**](#mouse.on_middle_click)
+- [mouse.**wait**](#mouse.wait)
+- [mouse.**get\_position**](#mouse.get_position)
+- [mouse.**hook**](#mouse.hook)
+- [mouse.**unhook**](#mouse.unhook)
+- [mouse.**unhook\_all**](#mouse.unhook_all)
+- [mouse.**record**](#mouse.record)
+- [mouse.**play**](#mouse.play) *(aliases: `replay`)*
+
+
+
+
+## class mouse.**ButtonEvent**
+
+ButtonEvent(event_type, button, time)
+
+
+
+
+### ButtonEvent.**button**
+
+Alias for field number 1
+
+
+
+
+### ButtonEvent.**count**(self, value, /)
+
+Return number of occurrences of value.
+
+
+
+
+### ButtonEvent.**event\_type**
+
+Alias for field number 0
+
+
+
+
+### ButtonEvent.**index**(self, value, start=0, stop=9223372036854775807, /)
+
+Return first index of value.
+
+Raises ValueError if the value is not present.
+
+
+
+
+### ButtonEvent.**time**
+
+Alias for field number 2
+
+
+
+
+
+
+## mouse.**DOUBLE**
+```py
+= 'double'
+```
+
+
+
+## mouse.**DOWN**
+```py
+= 'down'
+```
+
+
+
+## mouse.**LEFT**
+```py
+= 'left'
+```
+
+
+
+## mouse.**MIDDLE**
+```py
+= 'middle'
+```
+
+
+
+## class mouse.**MoveEvent**
+
+MoveEvent(x, y, time)
+
+
+
+
+### MoveEvent.**count**(self, value, /)
+
+Return number of occurrences of value.
+
+
+
+
+### MoveEvent.**index**(self, value, start=0, stop=9223372036854775807, /)
+
+Return first index of value.
+
+Raises ValueError if the value is not present.
+
+
+
+
+### MoveEvent.**time**
+
+Alias for field number 2
+
+
+
+
+### MoveEvent.**x**
+
+Alias for field number 0
+
+
+
+
+### MoveEvent.**y**
+
+Alias for field number 1
+
+
+
+
+
+
+## mouse.**RIGHT**
+```py
+= 'right'
+```
+
+
+
+## mouse.**UP**
+```py
+= 'up'
+```
+
+
+
+## class mouse.**WheelEvent**
+
+WheelEvent(delta, time)
+
+
+
+
+### WheelEvent.**count**(self, value, /)
+
+Return number of occurrences of value.
+
+
+
+
+### WheelEvent.**delta**
+
+Alias for field number 0
+
+
+
+
+### WheelEvent.**index**(self, value, start=0, stop=9223372036854775807, /)
+
+Return first index of value.
+
+Raises ValueError if the value is not present.
+
+
+
+
+### WheelEvent.**time**
+
+Alias for field number 1
+
+
+
+
+
+
+## mouse.**X**
+```py
+= 'x'
+```
+
+
+
+## mouse.**X2**
+```py
+= 'x2'
+```
+
+
+
+## mouse.**version**
+```py
+= '0.7.1'
+```
+
+
+
+## mouse.**is\_pressed**(button='left')
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L78)
+
+Returns True if the given button is currently pressed.
+
+
+
+
+## mouse.**press**(button='left')
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L83)
+
+Presses the given button (but doesn't release).
+
+
+
+
+## mouse.**release**(button='left')
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L87)
+
+Releases the given button.
+
+
+
+
+## mouse.**click**(button='left')
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L91)
+
+Sends a click with the given button.
+
+
+
+
+## mouse.**double\_click**(button='left')
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L96)
+
+Sends a double click with the given button.
+
+
+
+
+## mouse.**right\_click**()
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L101)
+
+Sends a right click with the given button.
+
+
+
+
+## mouse.**wheel**(delta=1)
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L105)
+
+Scrolls the wheel `delta` clicks. Sign indicates direction.
+
+
+
+
+## mouse.**move**(x, y, absolute=True, duration=0)
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L109)
+
+
+Moves the mouse. If `absolute`, to position (x, y), otherwise move relative
+to the current position. If `duration` is non-zero, animates the movement.
+
+
+
+
+
+## mouse.**drag**(start\_x, start\_y, end\_x, end\_y, absolute=True, duration=0)
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L143)
+
+
+Holds the left mouse button, moving from start to end position, then
+releases. `absolute` and `duration` are parameters regarding the mouse
+movement.
+
+
+
+
+
+## mouse.**on\_button**(callback, args=(), buttons=('left', 'middle', 'right', 'x', 'x2'), types=('up', 'down', 'double'))
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L156)
+
+Invokes `callback` with `args` when the specified event happens.
+
+
+
+
+## mouse.**on\_click**(callback, args=())
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L170)
+
+Invokes `callback` with `args` when the left button is clicked.
+
+
+
+
+## mouse.**on\_double\_click**(callback, args=())
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L174)
+
+
+Invokes `callback` with `args` when the left button is double clicked.
+
+
+
+
+
+## mouse.**on\_right\_click**(callback, args=())
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L180)
+
+Invokes `callback` with `args` when the right button is clicked.
+
+
+
+
+## mouse.**on\_middle\_click**(callback, args=())
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L184)
+
+Invokes `callback` with `args` when the middle button is clicked.
+
+
+
+
+## mouse.**wait**(button='left', target\_types=('up', 'down', 'double'))
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L188)
+
+
+Blocks program execution until the given button performs an event.
+
+
+
+
+
+## mouse.**get\_position**()
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L199)
+
+Returns the (x, y) mouse position.
+
+
+
+
+## mouse.**hook**(callback)
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L203)
+
+
+Installs a global listener on all available mouses, invoking `callback`
+each time it is moved, a key status changes or the wheel is spun. A mouse
+event is passed as argument, with type either `mouse.ButtonEvent`,
+`mouse.WheelEvent` or `mouse.MoveEvent`.
+
+Returns the given callback for easier development.
+
+
+
+
+
+## mouse.**unhook**(callback)
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L215)
+
+
+Removes a previously installed hook.
+
+
+
+
+
+## mouse.**unhook\_all**()
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L221)
+
+
+Removes all hooks registered by this application. Note this may include
+hooks installed by high level functions, such as [`record`](#mouse.record).
+
+
+
+
+
+## mouse.**record**(button='right', target\_types=('down',))
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L228)
+
+
+Records all mouse events until the user presses the given button.
+Then returns the list of events recorded. Pairs well with [`play(events)`](#mouse.play).
+
+Note: this is a blocking function.
+Note: for more details on the mouse hook and events see [`hook`](#mouse.hook).
+
+
+
+
+
+## mouse.**play**(events, speed\_factor=1.0, include\_clicks=True, include\_moves=True, include\_wheel=True)
+
+[\[source\]](https://github.com/boppreh/mouse/blob/master/mouse/__init__.py#L242)
+
+
+Plays a sequence of recorded events, maintaining the relative time
+intervals. If speed_factor is <= 0 then the actions are replayed as fast
+as the OS allows. Pairs well with [`record()`](#mouse.record).
+
+The parameters `include_*` define if events of that type should be inluded
+in the replay or ignored.
+
+
+
diff --git a/mouse/__init__.pyc b/mouse/__init__.pyc
deleted file mode 100644
index 0e8936f..0000000
Binary files a/mouse/__init__.pyc and /dev/null differ
diff --git a/mouse/__pycache__/__init__.cpython-38.pyc b/mouse/__pycache__/__init__.cpython-38.pyc
deleted file mode 100644
index 80e1dc4..0000000
Binary files a/mouse/__pycache__/__init__.cpython-38.pyc and /dev/null differ
diff --git a/mouse/__pycache__/_generic.cpython-38.pyc b/mouse/__pycache__/_generic.cpython-38.pyc
deleted file mode 100644
index f58ab70..0000000
Binary files a/mouse/__pycache__/_generic.cpython-38.pyc and /dev/null differ
diff --git a/mouse/__pycache__/_mouse_event.cpython-38.pyc b/mouse/__pycache__/_mouse_event.cpython-38.pyc
deleted file mode 100644
index 5839c75..0000000
Binary files a/mouse/__pycache__/_mouse_event.cpython-38.pyc and /dev/null differ
diff --git a/mouse/__pycache__/_nixcommon.cpython-38.pyc b/mouse/__pycache__/_nixcommon.cpython-38.pyc
deleted file mode 100644
index c614439..0000000
Binary files a/mouse/__pycache__/_nixcommon.cpython-38.pyc and /dev/null differ
diff --git a/mouse/__pycache__/_nixmouse.cpython-38.pyc b/mouse/__pycache__/_nixmouse.cpython-38.pyc
deleted file mode 100644
index 90d0e73..0000000
Binary files a/mouse/__pycache__/_nixmouse.cpython-38.pyc and /dev/null differ
diff --git a/mouse/_generic.pyc b/mouse/_generic.pyc
deleted file mode 100644
index f50aff6..0000000
Binary files a/mouse/_generic.pyc and /dev/null differ
diff --git a/mouse/_mouse_event.pyc b/mouse/_mouse_event.pyc
deleted file mode 100644
index 3c80f97..0000000
Binary files a/mouse/_mouse_event.pyc and /dev/null differ
diff --git a/mouse/_nixcommon.pyc b/mouse/_nixcommon.pyc
deleted file mode 100644
index 1112fea..0000000
Binary files a/mouse/_nixcommon.pyc and /dev/null differ
diff --git a/mouse/_nixmouse.pyc b/mouse/_nixmouse.pyc
deleted file mode 100644
index 13515f6..0000000
Binary files a/mouse/_nixmouse.pyc and /dev/null differ
diff --git a/mouse/make_release.py b/mouse/make_release.py
new file mode 100644
index 0000000..455fcb5
--- /dev/null
+++ b/mouse/make_release.py
@@ -0,0 +1,91 @@
+"""
+This little guy streamlines the release process of Python packages.
+
+By running `python3 make_release.py` it'll do the following tasks automatically:
+
+- Update README by calling `make_readme.sh` if this file exists.
+- Check PyPI RST long_description syntax.
+- Show the latest version from CHANGES.md and ask for a new version number.
+- Open vim to allow you to edit the list of changes for this new version, showing a list of commits since the last version.
+- Prepend your list of changes to CHANGES.md (and ask if you want to commit it now).
+- Add a git tag to the current commit.
+- Push tag to GitHub.
+- Publish a new release to GitHub, asking for the authentication token (optional).
+- Publish a new release on PyPI.
+
+Suggested way to organize your project for a smooth process:
+
+- Use Markdown everywhere.
+- Keep a description of your project in the package's docstring.
+- Generate your README from the package docstring plus API docs.
+- Convert your package docstring to RST in setup.py and use that as long_description.
+- Use raw semantic versioning for CHANGES.md and PyPI (e.g. 2.3.1), and prepend 'v' for git tags and releases (e.g. v2.3.1).
+
+"""
+import re
+import sys
+import os
+from subprocess import run, check_output
+import atexit
+import requests
+import mouse
+
+run(['make', 'clean', 'build'], check=True)
+
+assert re.fullmatch(r'\d+\.\d+\.\d+', mouse.version)
+last_version = check_output(['git', 'describe', '--abbrev=0'], universal_newlines=True).strip('v\n')
+assert mouse.version != last_version, 'Must update mouse.version first.'
+
+commits = check_output(['git', 'log', 'v{}..HEAD'.format(last_version), '--oneline'], universal_newlines=True)
+with open('message.txt', 'w') as message_file:
+ atexit.register(lambda: os.remove('message.txt'))
+
+ message_file.write('\n\n\n')
+ message_file.write('# Enter changes one per line like this:\n')
+ message_file.write('# - Added `foobar`.\n\n\n')
+ message_file.write('# As a reminder, here\'s the last commits since version {}:\n\n'.format(last_version))
+ for line in commits.strip().split('\n'):
+ message_file.write('# {}\n'.format(line))
+
+run(['vim', 'message.txt'])
+with open('message.txt') as message_file:
+ lines = [line for line in message_file.readlines() if not line.startswith('#')]
+message = ''.join(lines).strip()
+if not message:
+ print('Aborting release due to empty message.')
+ exit()
+with open('message.txt', 'w') as message_file:
+ message_file.write(message)
+
+with open('CHANGES.md') as changes_file:
+ old_changes = changes_file.read()
+with open('CHANGES.md', 'w') as changes_file:
+ changes_file.write('# {}\n\n{}\n\n\n{}'.format(mouse.version, message, old_changes))
+
+
+tag_name = 'v' + mouse.version
+if input('Commit README.md and CHANGES.md files? ').lower().startswith('y'):
+ run(['git', 'add', 'CHANGES.md', 'README.md'])
+ run(['git', 'commit', '-m', 'Update changes for {}'.format(tag_name)])
+ run(['git', 'push'])
+run(['git', 'tag', '-a', tag_name, '--file', 'message.txt'], check=True)
+run(['git', 'push', 'origin', tag_name], check=True)
+
+token = input('To make a release enter your GitHub repo authorization token: ').strip()
+if token:
+ git_remotes = check_output(['git', 'remote', '-v']).decode('utf-8')
+ repo_path = re.search(r'github.com[:/](.+?)(?:\.git)? \(push\)', git_remotes).group(1)
+ releases_url = 'https://api.github.com/repos/{}/releases'.format(repo_path)
+ print(releases_url)
+ release = {
+ "tag_name": tag_name,
+ "target_commitish": "master",
+ "name": tag_name,
+ "body": message,
+ "draft": False,
+ "prerelease": False,
+ }
+ response = requests.post(releases_url, json=release, headers={'Authorization': 'token ' + token})
+ print(response.status_code, response.text)
+
+run(['twine', 'upload', 'dist/*'], check=True, shell=True)
diff --git a/mouse/__init__.py b/mouse/mouse/__init__.py
similarity index 98%
rename from mouse/__init__.py
rename to mouse/mouse/__init__.py
index 71a9d14..3a21f46 100644
--- a/mouse/__init__.py
+++ b/mouse/mouse/__init__.py
@@ -166,10 +166,6 @@ def on_button(callback, args=(), buttons=(LEFT, MIDDLE, RIGHT, X, X2), types=(UP
callback(*args)
_listener.add_handler(handler)
return handler
-
-def on_pressed(callback, args=()):
- """ Invokes `callback` with `args` when the left button is pressed. """
- return on_button(callback, args, [LEFT], [DOWN])
def on_click(callback, args=()):
""" Invokes `callback` with `args` when the left button is clicked. """
diff --git a/mouse/__main__.py b/mouse/mouse/__main__.py
similarity index 100%
rename from mouse/__main__.py
rename to mouse/mouse/__main__.py
diff --git a/mouse/_generic.py b/mouse/mouse/_generic.py
similarity index 100%
rename from mouse/_generic.py
rename to mouse/mouse/_generic.py
diff --git a/mouse/_mouse_event.py b/mouse/mouse/_mouse_event.py
similarity index 100%
rename from mouse/_mouse_event.py
rename to mouse/mouse/_mouse_event.py
diff --git a/mouse/_mouse_tests.py b/mouse/mouse/_mouse_tests.py
similarity index 100%
rename from mouse/_mouse_tests.py
rename to mouse/mouse/_mouse_tests.py
diff --git a/mouse/_nixcommon.py b/mouse/mouse/_nixcommon.py
similarity index 96%
rename from mouse/_nixcommon.py
rename to mouse/mouse/_nixcommon.py
index a77de1d..d240f99 100644
--- a/mouse/_nixcommon.py
+++ b/mouse/mouse/_nixcommon.py
@@ -20,8 +20,6 @@ EV_REL = 0x02
EV_ABS = 0x03
EV_MSC = 0x04
-INVALID_ARGUMENT_ERRNO = 22
-
def make_uinput():
import fcntl, struct
@@ -31,12 +29,8 @@ def make_uinput():
fcntl.ioctl(uinput, UI_SET_EVBIT, EV_KEY)
UI_SET_KEYBIT = 0x40045565
- try:
- for i in range(0x300):
- fcntl.ioctl(uinput, UI_SET_KEYBIT, i)
- except OSError as e:
- if e.errno != INVALID_ARGUMENT_ERRNO:
- raise e
+ for i in range(256):
+ fcntl.ioctl(uinput, UI_SET_KEYBIT, i)
BUS_USB = 0x03
uinput_user_dev = "80sHHHHi64i64i64i64i"
diff --git a/mouse/_nixmouse.py b/mouse/mouse/_nixmouse.py
similarity index 100%
rename from mouse/_nixmouse.py
rename to mouse/mouse/_nixmouse.py
diff --git a/mouse/_winmouse.py b/mouse/mouse/_winmouse.py
similarity index 100%
rename from mouse/_winmouse.py
rename to mouse/mouse/_winmouse.py
diff --git a/mouse/setup.py b/mouse/setup.py
new file mode 100644
index 0000000..fdc1b9d
--- /dev/null
+++ b/mouse/setup.py
@@ -0,0 +1,38 @@
+"""
+Usage instructions:
+
+- If you are installing: `python setup.py install`
+- If you are developing: `python setup.py sdist --format=zip bdist_wheel --universal bdist_wininst && twine check dist/*`
+"""
+import mouse
+
+from setuptools import setup
+setup(
+ name='mouse',
+ version=mouse.version,
+ author='BoppreH',
+ author_email='boppreh@gmail.com',
+ packages=['mouse'],
+ package_data={'mouse': ['*.md']},
+ url='https://github.com/boppreh/mouse',
+ license='MIT',
+ description='Hook and simulate mouse events on Windows and Linux',
+ keywords = 'mouse hook simulate hotkey',
+
+ # Wheel creation breaks with Windows newlines.
+ # https://github.com/pypa/setuptools/issues/1126
+ long_description=mouse.__doc__.replace('\r\n', '\n'),
+ long_description_content_type='text/markdown',
+
+ install_requires=[], # OSX-specific dependency
+ classifiers=[
+ 'Development Status :: 4 - Beta',
+ 'License :: OSI Approved :: MIT License',
+ 'Operating System :: Microsoft :: Windows',
+ 'Operating System :: Unix',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 3',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ 'Topic :: Utilities',
+ ],
+)