makcu 2.1.2__py3-none-any.whl → 2.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- makcu/README.md +405 -0
- makcu/__init__.py +22 -60
- makcu/__main__.py +388 -387
- makcu/conftest.py +33 -33
- makcu/connection.py +553 -459
- makcu/controller.py +410 -376
- makcu/enums.py +7 -7
- makcu/errors.py +13 -13
- makcu/makcu.pyi +10 -10
- makcu/mouse.py +249 -249
- makcu/test_suite.py +141 -144
- {makcu-2.1.2.dist-info → makcu-2.2.0.dist-info}/METADATA +3 -29
- makcu-2.2.0.dist-info/RECORD +17 -0
- makcu-2.1.2.dist-info/RECORD +0 -16
- {makcu-2.1.2.dist-info → makcu-2.2.0.dist-info}/WHEEL +0 -0
- {makcu-2.1.2.dist-info → makcu-2.2.0.dist-info}/licenses/LICENSE +0 -0
- {makcu-2.1.2.dist-info → makcu-2.2.0.dist-info}/top_level.txt +0 -0
makcu/test_suite.py
CHANGED
@@ -1,145 +1,142 @@
|
|
1
|
-
import pytest
|
2
|
-
import time
|
3
|
-
from makcu import MouseButton
|
4
|
-
|
5
|
-
|
6
|
-
TEST_BUTTONS = (MouseButton.LEFT, MouseButton.RIGHT, MouseButton.MIDDLE)
|
7
|
-
BUTTON_STATE_KEYS = ('left', 'right', 'middle', 'mouse4', 'mouse5')
|
8
|
-
MOVE_COORDS = ((10, 0), (0, 10), (-10, 0), (0, -10))
|
9
|
-
|
10
|
-
def test_connect_to_port(makcu):
|
11
|
-
print("Connecting to port...")
|
12
|
-
makcu.connect()
|
13
|
-
assert makcu.is_connected(), "Failed to connect to the makcu"
|
14
|
-
|
15
|
-
def test_press_and_release(makcu):
|
16
|
-
makcu.press(MouseButton.LEFT)
|
17
|
-
makcu.release(MouseButton.LEFT)
|
18
|
-
|
19
|
-
def test_firmware_version(makcu):
|
20
|
-
version = makcu.
|
21
|
-
assert version and len(version.strip()) > 0
|
22
|
-
|
23
|
-
def test_middle_click(makcu):
|
24
|
-
makcu.press(MouseButton.MIDDLE)
|
25
|
-
makcu.release(MouseButton.MIDDLE)
|
26
|
-
|
27
|
-
def test_device_info(makcu):
|
28
|
-
print("Fetching device info...")
|
29
|
-
info = makcu.mouse.get_device_info()
|
30
|
-
print(f"Device Info: {info}")
|
31
|
-
assert info.get("port")
|
32
|
-
assert info.get("isConnected") is True
|
33
|
-
|
34
|
-
def test_port_connection(makcu):
|
35
|
-
assert makcu.is_connected()
|
36
|
-
|
37
|
-
def test_button_mask(makcu):
|
38
|
-
print("Getting button mask...")
|
39
|
-
mask = makcu.get_button_mask()
|
40
|
-
print(f"Mask value: {mask}")
|
41
|
-
assert isinstance(mask, int)
|
42
|
-
|
43
|
-
def test_get_button_states(makcu):
|
44
|
-
states = makcu.get_button_states()
|
45
|
-
assert isinstance(states, dict)
|
46
|
-
for key in BUTTON_STATE_KEYS:
|
47
|
-
assert key in states
|
48
|
-
|
49
|
-
def test_lock_state(makcu):
|
50
|
-
print("Locking LEFT button...")
|
51
|
-
makcu.lock_left(True)
|
52
|
-
print("Querying lock state while LEFT is locked...")
|
53
|
-
state = makcu.is_locked(MouseButton.LEFT)
|
54
|
-
print(state)
|
55
|
-
assert state
|
56
|
-
|
57
|
-
def test_makcu_behavior(makcu):
|
58
|
-
makcu.move(25, 25)
|
59
|
-
makcu.click(MouseButton.LEFT)
|
60
|
-
makcu.scroll(-2)
|
61
|
-
|
62
|
-
def test_batch_commands(makcu):
|
63
|
-
print("Testing batch command execution (10 commands)...")
|
64
|
-
|
65
|
-
start_time = time.perf_counter()
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
makcu.move(5, 5)
|
102
|
-
makcu.move(5, 5)
|
103
|
-
makcu.move(5, 5)
|
104
|
-
makcu.move(5, 5)
|
105
|
-
makcu.move(5, 5)
|
106
|
-
makcu.move(5, 5)
|
107
|
-
makcu.move(5, 5)
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
makcu.
|
133
|
-
makcu.
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
@pytest.mark.skip(reason="Capture test disabled until firmware supports tracking clicks from software input")
|
144
|
-
def test_capture_right_clicks(makcu):
|
1
|
+
import pytest
|
2
|
+
import time
|
3
|
+
from makcu import MouseButton
|
4
|
+
|
5
|
+
|
6
|
+
TEST_BUTTONS = (MouseButton.LEFT, MouseButton.RIGHT, MouseButton.MIDDLE)
|
7
|
+
BUTTON_STATE_KEYS = ('left', 'right', 'middle', 'mouse4', 'mouse5')
|
8
|
+
MOVE_COORDS = ((10, 0), (0, 10), (-10, 0), (0, -10))
|
9
|
+
|
10
|
+
def test_connect_to_port(makcu):
|
11
|
+
print("Connecting to port...")
|
12
|
+
makcu.connect()
|
13
|
+
assert makcu.is_connected(), "Failed to connect to the makcu"
|
14
|
+
|
15
|
+
def test_press_and_release(makcu):
|
16
|
+
makcu.press(MouseButton.LEFT)
|
17
|
+
makcu.release(MouseButton.LEFT)
|
18
|
+
|
19
|
+
def test_firmware_version(makcu):
|
20
|
+
version = makcu.get_firmware_version()
|
21
|
+
assert version and len(version.strip()) > 0
|
22
|
+
|
23
|
+
def test_middle_click(makcu):
|
24
|
+
makcu.press(MouseButton.MIDDLE)
|
25
|
+
makcu.release(MouseButton.MIDDLE)
|
26
|
+
|
27
|
+
def test_device_info(makcu):
|
28
|
+
print("Fetching device info...")
|
29
|
+
info = makcu.mouse.get_device_info()
|
30
|
+
print(f"Device Info: {info}")
|
31
|
+
assert info.get("port")
|
32
|
+
assert info.get("isConnected") is True
|
33
|
+
|
34
|
+
def test_port_connection(makcu):
|
35
|
+
assert makcu.is_connected()
|
36
|
+
|
37
|
+
def test_button_mask(makcu):
|
38
|
+
print("Getting button mask...")
|
39
|
+
mask = makcu.get_button_mask()
|
40
|
+
print(f"Mask value: {mask}")
|
41
|
+
assert isinstance(mask, int)
|
42
|
+
|
43
|
+
def test_get_button_states(makcu):
|
44
|
+
states = makcu.get_button_states()
|
45
|
+
assert isinstance(states, dict)
|
46
|
+
for key in BUTTON_STATE_KEYS:
|
47
|
+
assert key in states
|
48
|
+
|
49
|
+
def test_lock_state(makcu):
|
50
|
+
print("Locking LEFT button...")
|
51
|
+
makcu.lock_left(True)
|
52
|
+
print("Querying lock state while LEFT is locked...")
|
53
|
+
state = makcu.is_locked(MouseButton.LEFT)
|
54
|
+
print(state)
|
55
|
+
assert state
|
56
|
+
|
57
|
+
def test_makcu_behavior(makcu):
|
58
|
+
makcu.move(25, 25)
|
59
|
+
makcu.click(MouseButton.LEFT)
|
60
|
+
makcu.scroll(-2)
|
61
|
+
|
62
|
+
def test_batch_commands(makcu):
|
63
|
+
print("Testing batch command execution (10 commands)...")
|
64
|
+
|
65
|
+
start_time = time.perf_counter()
|
66
|
+
|
67
|
+
async def combo_actions():
|
68
|
+
await makcu.batch_execute([
|
69
|
+
lambda: makcu.move(5, 5),
|
70
|
+
lambda: makcu.click(MouseButton.LEFT),
|
71
|
+
lambda: makcu.scroll(-1)
|
72
|
+
])
|
73
|
+
|
74
|
+
combo_actions()
|
75
|
+
|
76
|
+
end_time = time.perf_counter()
|
77
|
+
elapsed_ms = (end_time - start_time) * 1000
|
78
|
+
|
79
|
+
print(f"Batch execution time: {elapsed_ms:.2f}ms")
|
80
|
+
print(f"Average per command: {elapsed_ms/10:.2f}ms")
|
81
|
+
|
82
|
+
|
83
|
+
assert elapsed_ms < 50, f"Batch commands took {elapsed_ms:.2f}ms, expected < 50ms"
|
84
|
+
|
85
|
+
|
86
|
+
start_time = time.perf_counter()
|
87
|
+
for _ in range(10):
|
88
|
+
makcu.move(5, 5)
|
89
|
+
end_time = time.perf_counter()
|
90
|
+
|
91
|
+
move_only_ms = (end_time - start_time) * 1000
|
92
|
+
print(f"10 move commands: {move_only_ms:.2f}ms ({move_only_ms/10:.2f}ms per move)")
|
93
|
+
|
94
|
+
def test_rapid_moves(makcu):
|
95
|
+
start = time.perf_counter_ns()
|
96
|
+
|
97
|
+
|
98
|
+
makcu.move(5, 5)
|
99
|
+
makcu.move(5, 5)
|
100
|
+
makcu.move(5, 5)
|
101
|
+
makcu.move(5, 5)
|
102
|
+
makcu.move(5, 5)
|
103
|
+
makcu.move(5, 5)
|
104
|
+
makcu.move(5, 5)
|
105
|
+
makcu.move(5, 5)
|
106
|
+
makcu.move(5, 5)
|
107
|
+
makcu.move(5, 5)
|
108
|
+
|
109
|
+
elapsed_ms = (time.perf_counter_ns() - start) / 1_000_000
|
110
|
+
print(f"10 rapid moves: {elapsed_ms:.2f}ms")
|
111
|
+
assert elapsed_ms < 30
|
112
|
+
|
113
|
+
def test_button_performance(makcu):
|
114
|
+
start = time.perf_counter_ns()
|
115
|
+
|
116
|
+
|
117
|
+
for button in TEST_BUTTONS:
|
118
|
+
makcu.press(button)
|
119
|
+
makcu.release(button)
|
120
|
+
|
121
|
+
elapsed_ms = (time.perf_counter_ns() - start) / 1_000_000
|
122
|
+
print(f"Button operations: {elapsed_ms:.2f}ms")
|
123
|
+
assert elapsed_ms < 20
|
124
|
+
|
125
|
+
def test_mixed_operations(makcu):
|
126
|
+
start = time.perf_counter_ns()
|
127
|
+
|
128
|
+
|
129
|
+
makcu.move(20, 20)
|
130
|
+
makcu.press(MouseButton.LEFT)
|
131
|
+
makcu.move(-20, -20)
|
132
|
+
makcu.release(MouseButton.LEFT)
|
133
|
+
makcu.scroll(1)
|
134
|
+
|
135
|
+
elapsed_ms = (time.perf_counter_ns() - start) / 1_000_000
|
136
|
+
print(f"Mixed operations: {elapsed_ms:.2f}ms")
|
137
|
+
assert elapsed_ms < 15
|
138
|
+
|
139
|
+
|
140
|
+
@pytest.mark.skip(reason="Capture test disabled until firmware supports tracking clicks from software input")
|
141
|
+
def test_capture_right_clicks(makcu):
|
145
142
|
pass
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: makcu
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.2.0
|
4
4
|
Summary: Python library for Makcu hardware device control
|
5
5
|
Author: SleepyTotem
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -708,7 +708,7 @@ Requires-Dist: twine>=4.0
|
|
708
708
|
Requires-Dist: rich>=14.0
|
709
709
|
Dynamic: license-file
|
710
710
|
|
711
|
-
# 🖱️ Makcu Python Library v2.
|
711
|
+
# 🖱️ Makcu Python Library v2.2.0
|
712
712
|
|
713
713
|
[](https://pypi.org/project/makcu/)
|
714
714
|
[](https://pypi.org/project/makcu/)
|
@@ -716,16 +716,6 @@ Dynamic: license-file
|
|
716
716
|
|
717
717
|
Makcu Py Lib is a high-performance Python library for controlling Makcu devices — now with **async/await support**, **zero-delay command execution**, and **automatic reconnection**!
|
718
718
|
|
719
|
-
## What's New in v2.0
|
720
|
-
|
721
|
-
- **Async/Await Support**: Full async API for modern Python applications
|
722
|
-
- **Zero-Delay Commands**: Removed all `sleep()` calls with proper command tracking
|
723
|
-
- **Auto-Reconnection**: Automatic device reconnection on disconnect
|
724
|
-
- **Parallel Operations**: Execute multiple commands simultaneously
|
725
|
-
- **Enhanced Debugging**: Better logging and error tracking
|
726
|
-
- **Gaming-Optimized**: Sub-3ms command execution for 240Hz+ gaming
|
727
|
-
- **Ultra-Fast Performance**: 10-50x faster than >=v1.4
|
728
|
-
|
729
719
|
---
|
730
720
|
|
731
721
|
## 📦 Installation
|
@@ -950,17 +940,6 @@ python -m makcu --runtest
|
|
950
940
|
|
951
941
|
---
|
952
942
|
|
953
|
-
## ⚠️ Sync vs Async Limitations
|
954
|
-
|
955
|
-
Some methods such as `lock()`, `unlock()`, and `click_human_like()` are currently only implemented in synchronous form. To use them in async workflows, run via thread executor:
|
956
|
-
|
957
|
-
```python
|
958
|
-
loop = asyncio.get_running_loop()
|
959
|
-
await loop.run_in_executor(None, makcu.lock, MouseButton.LEFT)
|
960
|
-
```
|
961
|
-
|
962
|
-
> Note: `drag` and `get_all_lock_states` are supported only in the synchronous interface as of v2.0.
|
963
|
-
|
964
943
|
### Test Suite
|
965
944
|
|
966
945
|
- File: `test_suite.py`
|
@@ -1027,9 +1006,6 @@ Based on the measured test suite, v2.0 is on average **~17× faster** than v1.3
|
|
1027
1006
|
### Tips for Maximum Performance
|
1028
1007
|
|
1029
1008
|
```python
|
1030
|
-
# Use gaming profile for fastest clicks
|
1031
|
-
makcu.click_human_like(MouseButton.LEFT, profile="gaming")
|
1032
|
-
|
1033
1009
|
# Disable debug mode in production
|
1034
1010
|
makcu = create_controller(debug=False)
|
1035
1011
|
|
@@ -1126,11 +1102,9 @@ GPL License © SleepyTotem
|
|
1126
1102
|
|
1127
1103
|
---
|
1128
1104
|
|
1129
|
-
## 🙋 Support
|
1105
|
+
## 🙋 Support
|
1130
1106
|
|
1131
1107
|
- **Issues**: [GitHub Issues](https://github.com/SleepyTotem/makcu-py-lib/issues)
|
1132
|
-
- **Discussions**: [GitHub Discussions](https://github.com/SleepyTotem/makcu-py-lib/discussions)
|
1133
|
-
- **Pull Requests**: Welcome! Please read CONTRIBUTING.md
|
1134
1108
|
|
1135
1109
|
---
|
1136
1110
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
makcu/README.md,sha256=FrZkK3T6m42s1D61WN8f7rVMWMbr9nPwMgQaXcYWKzQ,11125
|
2
|
+
makcu/__init__.py,sha256=rfBNEd2V5vwfX4dHQzEowF3z0T6CoObYSsKculIgCnI,427
|
3
|
+
makcu/__main__.py,sha256=WYf8QKcgMNHh0GP7szXZdnoeExT55Aokkflj-u1IaJc,14030
|
4
|
+
makcu/conftest.py,sha256=BqPx6ywYONYGyKH11Bam9aV5zSGXR6odE5Z8hGFrn4U,863
|
5
|
+
makcu/connection.py,sha256=LkvzPwT1Er9JblGR8pZRMLTTCBBd6a1F62X_FkLaXEg,20179
|
6
|
+
makcu/controller.py,sha256=EBtiScaOU0CV7NmwVdR3CwFpbT5RymdrNveRKo5ehFU,13242
|
7
|
+
makcu/enums.py,sha256=1SvIv5IoMIfXyoMAq8I5r_aKMVKjYR-L_hXkFLJ_5mw,119
|
8
|
+
makcu/errors.py,sha256=hXdeUCHvbzfqWX3uotG12Xv8EPwWs-5aHQ12xpgwx3Y,229
|
9
|
+
makcu/makcu.pyi,sha256=UfbX7774u_a9oyIa1rweWqIRoQxVAjhhHUuukDp3jiA,237
|
10
|
+
makcu/mouse.py,sha256=YZQDA5OGQlCxCDu3Huzwp5bjH__9yb867iLSVTYOKP4,8157
|
11
|
+
makcu/py.typed,sha256=lI_IPBO6A6a5eY5kRQDNsdSydUb3sFWtcC_ML8FNftU,111
|
12
|
+
makcu/test_suite.py,sha256=VkEsloTX8ozprwDhWVJ5GFS5qeIxJxXz47xCcZKNIVY,3889
|
13
|
+
makcu-2.2.0.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
14
|
+
makcu-2.2.0.dist-info/METADATA,sha256=_6_IPbDGcLgm5Xb0ES6dB2dpMDb_t99Ju7WvXqidYk0,53836
|
15
|
+
makcu-2.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
16
|
+
makcu-2.2.0.dist-info/top_level.txt,sha256=IRO1UVb5LK_ovjau0g4oObyXQqy00tVEE-yF5lPgw1w,6
|
17
|
+
makcu-2.2.0.dist-info/RECORD,,
|
makcu-2.1.2.dist-info/RECORD
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
makcu/__init__.py,sha256=HyjxvhE5feNyh4ZMY5U0U_X-7BzltSh_gOsX_o5mSLA,1745
|
2
|
-
makcu/__main__.py,sha256=9zqNog6Ugh1QjsZUOh7ZDTa1KwiOxLfDoOiBw2neiCo,14385
|
3
|
-
makcu/conftest.py,sha256=9BAV65DARtS4rELiMI5Gb6I-shxdnzCBA4g1lOYjG5s,896
|
4
|
-
makcu/connection.py,sha256=OT3cB7T8eJT4boCqajdPQtlTEMy-W9n9dqIIIVbL3Xc,15135
|
5
|
-
makcu/controller.py,sha256=csQMJ97zSv-i6sI8EHkqosFByS859B-hg2unvjHPKcA,13059
|
6
|
-
makcu/enums.py,sha256=VmvCLmpghVHuTAkvCGMfA14MgWTtFVMfsGQQNnJ58Ts,126
|
7
|
-
makcu/errors.py,sha256=X_eWPKkVgcyryT6-_7jjVkcHKtrAZAsarbfMRpIcz58,242
|
8
|
-
makcu/makcu.pyi,sha256=tSmJ3zs6zFClZll5DcWd17ZQr9nvDDJqhKXDR1hr7dk,247
|
9
|
-
makcu/mouse.py,sha256=CzUI3vr_IrvYuEfGzDWgtm6wSUl9kYimvmHaR2azuL0,8406
|
10
|
-
makcu/py.typed,sha256=lI_IPBO6A6a5eY5kRQDNsdSydUb3sFWtcC_ML8FNftU,111
|
11
|
-
makcu/test_suite.py,sha256=7Rsq5sKeR4zvCMTNZDv6TCYMKs7B3EVTuwyIDgHfdk8,4092
|
12
|
-
makcu-2.1.2.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
13
|
-
makcu-2.1.2.dist-info/METADATA,sha256=B_TaI8tz6CQi6ERMvtIbGxfokjjZY-Z5-hrJDCO8jps,55063
|
14
|
-
makcu-2.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
-
makcu-2.1.2.dist-info/top_level.txt,sha256=IRO1UVb5LK_ovjau0g4oObyXQqy00tVEE-yF5lPgw1w,6
|
16
|
-
makcu-2.1.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|