mathcraft-window-tools 0.1.0__tar.gz

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.
@@ -0,0 +1,5 @@
1
+ include demo.py
2
+ include test_mathematics.py
3
+ include test_input.py
4
+ include test_desktop_cursor.py
5
+ include test_math_entry.py
@@ -0,0 +1,359 @@
1
+ Metadata-Version: 2.4
2
+ Name: mathcraft-window-tools
3
+ Version: 0.1.0
4
+ Summary: Math helpers and an experimental Windows terminal with input interception and cursor overlays
5
+ Keywords: math,mathematics,vectors,numerical-methods,powershell
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+
11
+ # mathcraft-window-tools
12
+
13
+ Имя пакета на PyPI: `mathcraft-window-tools`; имя импорта: `mathcraft`.
14
+
15
+ Пакет содержит математический API и экспериментальный Windows-терминал.
16
+ **`mathcraft.math()` не является вычислением:** он открывает окно PowerShell и по
17
+ умолчанию включает перехват ввода внутри терминала, виртуальную мышь и временную
18
+ замену стандартных системных курсоров на прозрачные. Над терминалом, PyCharm и
19
+ VS Code отображается отдельный указатель. `Ctrl+Alt+F12` отключает эти режимы.
20
+ Импорт пакета и вызовы `mathcraft.mathematics` сами по себе ничего из этого не запускают.
21
+
22
+
23
+ Математические функции, статистика, векторы, матрицы и численные методы на Python 3.8+.
24
+ Математический API не требует Tkinter. Дополнительно пакет содержит описанное ниже
25
+ окно PowerShell для Windows; оно запускается только явным вызовом `math()`.
26
+
27
+ Установка из локальной папки проекта:
28
+
29
+ ```powershell
30
+ python -m pip install .
31
+ ```
32
+
33
+ Небольшая импортируемая библиотека Python для Windows 10 (сборка 19041+) и Windows 11.
34
+ Создаёт **собственное окно Python/Tkinter**, включает для него `WDA_EXCLUDEFROMCAPTURE`,
35
+ а команды исполняет в отдельном, **постоянном процессе PowerShell 5.1** через stdin/stdout.
36
+
37
+ ## Использование
38
+
39
+ 1. Положите папку `mathcraft` рядом со своим `.py`-файлом.
40
+ 2. Выполните:
41
+
42
+ ```python
43
+ import mathcraft
44
+ mathcraft.math()
45
+ ```
46
+
47
+ Или запустите файл `demo.py`:
48
+
49
+ ```powershell
50
+ python demo.py
51
+ ```
52
+
53
+ Нужен только обычный Python 3 с Tkinter. Дополнительные `pip install` не требуются.
54
+ `math()` запускает цикл графического интерфейса в основном потоке и возвращается после закрытия окна.
55
+
56
+ ## Как это работает
57
+
58
+ - `ctypes` получает настоящий top-level HWND окна Tk через `GetAncestor(..., GA_ROOT)`.
59
+ - `SetWindowDisplayAffinity(hwnd, 0x11)` применяется к собственному окну Python.
60
+ - `GetWindowDisplayAffinity` дополнительно проверяет установленный флаг.
61
+ - Обычное окно `powershell.exe` не показывается. PowerShell получает команды через stdin,
62
+ а его вывод отображается внутри защищённого окна Python.
63
+ - Текущие переменные и рабочий каталог сохраняются между командами благодаря постоянной сессии.
64
+
65
+ ## Ограничения
66
+
67
+ - Это **не штатное консольное окно Windows PowerShell** и не полноценный ConPTY-терминал.
68
+ - Команды, которым нужен интерактивный диалог/TTY (`Read-Host`, консольные редакторы), не поддерживаются.
69
+ - Остановка долго выполняющейся команды через интерфейс не реализована, закройте окно для завершения процесса.
70
+ - Нельзя снаружи Python назначить WDA чужому окну `powershell.exe`.
71
+ - Это не абсолютная защита от всех методов захвата, и для неё требуется работающий DWM.
72
+ - Выполнены автоматические и нативные проверки в Windows; совместимость с конкретными программами записи отдельно не проверена.
73
+
74
+ Документация Microsoft: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowdisplayaffinity
75
+
76
+ ## Математика (Python API)
77
+
78
+ Модуль `mathcraft.mathematics` работает без дополнительных зависимостей.
79
+ Функции `math` (например, `sqrt`, `sin`, `cos`, `log`, `factorial`, `comb`,
80
+ `gcd`, константы `pi`, `e`) доступны под исходными именами установленного Python.
81
+ Из `statistics` доступны `mean`, `fmean`, `median`, `mode`, `multimode`,
82
+ `variance`, `pvariance`, `stdev`, `pstdev`, `geometric_mean`, `harmonic_mean`.
83
+ Это импорты стандартной библиотеки, а не скопированные исходники сторонних пакетов.
84
+
85
+ ```python
86
+ from mathcraft import mathematics as m
87
+
88
+ print(m.sqrt(81)) # 9.0
89
+ print(m.mean([2, 4, 6])) # 4
90
+ print(m.dot([1, 2], [3, 4])) # 11.0
91
+ print(m.norm([3, 4])) # 5.0
92
+ print(m.cross([1, 0, 0], [0, 1, 0])) # [0, 0, 1]
93
+ print(m.transpose([[1, 2], [3, 4]])) # [[1, 3], [2, 4]]
94
+ print(m.matmul([[1, 2]], [[3], [4]])) # [[11.0]]
95
+ print(m.derivative(lambda x: x*x, 3)) # примерно 6
96
+ print(m.integrate(lambda x: x*x, 0, 1)) # примерно 1/3
97
+ print(m.bisect(lambda x: x*x-2, 0, 2)) # примерно sqrt(2)
98
+ ```
99
+
100
+ Дополнительные методы рассчитаны на вещественные числа. `dot` требует одинаковой
101
+ длины векторов, `cross` — длины 3. Матрицы должны быть непустыми и прямоугольными;
102
+ для умножения число столбцов первой равно числу строк второй.
103
+
104
+ `derivative(function, x, h=1e-5)` использует центральную разность.
105
+ `integrate(function, a, b, steps=1000)` использует метод трапеций;
106
+ обратные пределы меняют знак результата. Это приближённые вычисления.
107
+ `bisect(function, a, b, tolerance=1e-10, max_iterations=1000)` требует непрерывной
108
+ функции и интервала со сменой знака (либо нуля на границе). `tolerance` ограничивает
109
+ половину ширины интервала, а не значение функции. Исчерпание итераций или точности
110
+ float приводит к `RuntimeError`. Неверные размеры, нечисловые параметры с
111
+ неподходящими типами и неограниченные значения дают `ValueError`/`TypeError`.
112
+ Математические вызовы из этого примера выполняются в Python, не в строке `PS>`.
113
+
114
+ Проверка математического API:
115
+
116
+ ```powershell
117
+ python -m unittest -v test_mathematics
118
+ ```
119
+
120
+
121
+ ## Сборка и публикация на PyPI
122
+
123
+ Из корня проекта:
124
+
125
+ ```powershell
126
+ python -m pip install --upgrade build twine
127
+ python -m build
128
+ python -m twine check dist/*
129
+ python -m twine upload dist/*
130
+ ```
131
+
132
+ Загрузка требует учётной записи PyPI и API-токена. Токен вводится средствами
133
+ Twine, а не сохраняется в исходниках. Пакет ещё не опубликован; после публикации
134
+ установка будет выполняться командой `python -m pip install mathcraft-window-tools`.
135
+ Доступность имени окончательно определяется PyPI при первой публикации.
136
+ Автор и лицензия в метаданных пока не указаны: добавьте свои реальные данные
137
+ и выбранный текст лицензии перед публичным выпуском.
138
+
139
+
140
+ ## Автоматическое копирование
141
+
142
+ Выделенный мышью или клавиатурой текст в выводе терминала и строке ввода
143
+ автоматически копируется в системный буфер обмена после отпускания кнопки мыши
144
+ или клавиши. Нажимать Ctrl+C не требуется. Пустое выделение не очищает буфер.
145
+ Копируется ровно выделенный текст, включая приглашение `PS>`, если оно выделено.
146
+
147
+
148
+ ## Экспериментальный перехват ввода (Windows, явное включение)
149
+
150
+ ```python
151
+ import mathcraft
152
+
153
+ mathcraft.math(experimental_input=True)
154
+ ```
155
+
156
+ Обычный `mathcraft.math()` включает все три режима: `experimental_input=True`,
157
+ `virtual_mouse=True`, `desktop_cursor=True`. Отключение глобальной замены курсоров
158
+ выполняется параметром `desktop_cursor=False`; остальные переключатели независимы.
159
+ Режим использует `WH_KEYBOARD_LL` и `WH_MOUSE_LL` на отдельном потоке.
160
+ Поддерживаемые клавиши обрабатываются в Tkinter; клики левой, средней и правой
161
+ кнопок и вертикальное колесо передаются собственным виджетам. Исходные события
162
+ подавляются для последующих низкоуровневых хуков. Перехват работает только при
163
+ активном окне терминала; клики перехватываются только в его клиентской области.
164
+ Заголовок окна и другие приложения сохраняют обычную обработку.
165
+
166
+ **Отключение:** `Ctrl+Alt+F12` или кнопка `Disable input interception`.
167
+ Повторное включение требует перезапуска с явным параметром. Статус показан в окне.
168
+ При закрытии окна, выходе из mainloop, завершении PowerShell и ошибке запуска
169
+ хуки снимаются. Если GUI не обновлялся 0,5 секунды, новые события пропускаются;
170
+ при переполнении очереди и ошибках режим отключается. Завершения уже перехваченных
171
+ клавиш/кнопок могут поглощаться для согласования пар press/release.
172
+
173
+ ### Точные границы эксперимента
174
+
175
+ - Без `virtual_mouse=True` движение и координаты системного курсора остаются
176
+ обычными. Виртуальный режим описан ниже.
177
+ - Модификаторы, сочетания с Alt/Win, функциональные клавиши, дополнительные кнопки
178
+ мыши, горизонтальное колесо и программно внедрённые события проходят обычно.
179
+ - Поддерживаются обычный текст, основные клавиши редактирования/навигации,
180
+ Ctrl+A/C/V/X/Z/Y. IME, AltGr, составные символы, системные переключения раскладки
181
+ и двойные клики не имеют гарантии совместимости. Dead key отключает режим.
182
+ - Raw Input, драйверы, хуки перед нашим хуком и средства чтения содержимого
183
+ приложения/буфера обмена не блокируются. Автокопирование выделения сохраняется.
184
+ - Windows может незаметно снять медленный низкоуровневый хук. Индикатор отображает
185
+ запрошенный режим, а не подтверждённую изоляцию ввода. Это не антикейлоггер
186
+ и не гарантия невидимости для программ записи.
187
+
188
+ Документация: [keyboard hook](https://learn.microsoft.com/en-us/windows/win32/winmsg/lowlevelkeyboardproc),
189
+ [mouse hook](https://learn.microsoft.com/en-us/windows/win32/winmsg/lowlevelmouseproc),
190
+ [Raw Input](https://learn.microsoft.com/en-us/windows/win32/inputdev/about-raw-input).
191
+
192
+ Проверки на Windows:
193
+
194
+ ```powershell
195
+ python -m unittest -v test_input test_mathematics
196
+ ```
197
+
198
+ Проверены маршрутизация синтетических структур событий, работа с Unicode в Entry,
199
+ аварийное отключение и установка/снятие настоящих хуков с невидимым тестовым окном.
200
+ Физический ввод в активном терминале, разные раскладки, перетаскивание и совместимость
201
+ с программами записи требуют отдельной ручной проверки; тесты не доказывают
202
+ сокрытие событий от стороннего наблюдателя.
203
+
204
+
205
+ ## Виртуальный курсор внутри терминала
206
+
207
+ ```python
208
+ import mathcraft
209
+
210
+ mathcraft.math(experimental_input=True, virtual_mouse=True)
211
+ ```
212
+
213
+ `virtual_mouse=True` также включает экспериментальный перехват клавиатуры.
214
+ Когда системная мышь находится внутри клиентской области активного терминала,
215
+ следующее поддерживаемое движение начинает виртуальную сессию. Обычный указатель
216
+ остаётся в точке начала сессии; отдельные координаты накапливаются внутри библиотеки.
217
+ Клики, выделение, наведение и вертикальная прокрутка направляются собственным
218
+ виджетам по виртуальным координатам. Вместо системной стрелки отображается
219
+ собственный указатель в неактивируемом окне с `WDA_EXCLUDEFROMCAPTURE`.
220
+ Это окно не забирает фокус и не участвует в обработке кликов.
221
+
222
+ При выходе виртуального указателя за границы клиентской области обычная мышь
223
+ возвращается в текущую виртуальную точку. Так можно перейти в другие приложения
224
+ и пользоваться заголовком окна. Потеря фокуса, `Ctrl+Alt+F12`, кнопка отключения,
225
+ закрытие окна и остановка GUI-обработки более чем на 0,5 секунды также возвращают
226
+ штатную обработку. Если другое приложение само переместило системный курсор,
227
+ библиотека не перезаписывает его новую позицию. Вне терминала перехват не применяется.
228
+
229
+ Координаты GUI и хуков согласованы через временный DPI-контекст потока;
230
+ глобальные настройки DPI процесса и системная схема курсоров не меняются.
231
+
232
+ Режим не блокирует Raw Input, драйверные наблюдатели, программный ввод и хуки,
233
+ установленные перед нашим. Модификаторы и системные комбинации по-прежнему проходят
234
+ обычно; не реализованные в собственном обработчике Ctrl-комбинации передаются Tk.
235
+ Буфер обмена, включая ранее добавленное автоматическое копирование, не изолирован.
236
+ Исключение окна указателя из захвата зависит от способа записи, как и исключение
237
+ самого терминала. Проверка флага WinAPI не доказывает совместимость со всеми
238
+ программами записи.
239
+
240
+ Проверки включают синтетические события, снятие нативных хуков, восстановление
241
+ курсоров виджетов и проверку affinity окна указателя. Дополнительно выполнен
242
+ нативный интеграционный тест с помеченными искусственными движениями/кликами:
243
+ тестовый подкласс обрабатывал только их как физические события. Проверены
244
+ неподвижность системного курсора, движение виртуального, маршрутизация кликов
245
+ в Entry и восстановление/снятие хуков после отключения. Физические устройства,
246
+ разные DPI нескольких мониторов и программы записи отдельно не проверены.
247
+
248
+
249
+ ## Прозрачные системные курсоры и указатель поверх редакторов
250
+
251
+ Теперь обычный запуск включает этот режим:
252
+
253
+ ```python
254
+ import mathcraft
255
+
256
+ mathcraft.math()
257
+ ```
258
+
259
+ При запуске 13 стандартных ролей системного курсора временно заменяются
260
+ полностью прозрачными изображениями. Это не буквальный размер 0×0: используются
261
+ валидные размеры курсора и прозрачные маски. Изменения применяются в памяти;
262
+ регистрация новой схемы в реестре и установка драйверов не выполняются.
263
+
264
+ Окно виртуального указателя следует за обычной системной позицией мыши и
265
+ отображается над нашим терминалом, PyCharm (`pycharm.exe`, `pycharm64.exe`),
266
+ VS Code (`Code.exe`; также распознаётся `code-insiders.exe`). Выбор определяется именем исполняемого файла окна под
267
+ указателем, а не его заголовком. Переименованные сборки и другие редакторы
268
+ не включены. В остальных приложениях виртуальная стрелка не рисуется,
269
+ хотя стандартные системные курсоры остаются прозрачными до отключения режима.
270
+
271
+ Обычные клики, наведение, ввод текста, меню и перетаскивание продолжают обрабатываться
272
+ Windows и редакторами. Никакое внедрение в PyCharm/VS Code не выполняется.
273
+ Клавиатурные input-хуки сами по себе этим режимом не включаются.
274
+ Для сочетания с ранее добавленным режимом внутри терминала:
275
+
276
+ ```python
277
+ mathcraft.math(experimental_input=True, virtual_mouse=True)
278
+ ```
279
+
280
+ Внутри терминала при активной виртуальной сессии используется его прежний
281
+ виртуальный указатель; поверх редакторов — обычная позиция системной мыши.
282
+
283
+ `Ctrl+Alt+F12` действует также вне окна терминала и восстанавливает курсоры.
284
+ Кнопка `Restore cursor / disable input` и закрытие окна выполняют ту же очистку.
285
+ Отдельный процесс хранит копии исходных курсоров и возвращает их при завершении
286
+ родительского Python-процесса либо отсутствии GUI-heartbeat более трёх секунд.
287
+ При отказе точного восстановления используется загрузка выбранной системной схемы.
288
+ Одновременно допускается одна глобальная сессия замены курсоров.
289
+
290
+ Запуск без глобальной замены:
291
+
292
+ ```python
293
+ mathcraft.math(desktop_cursor=False)
294
+ ```
295
+
296
+ Ручная загрузка выбранной в Windows схемы курсоров, если требуется восстановление:
297
+
298
+ ```powershell
299
+ python -m mathcraft._cursor_guard --restore
300
+ ```
301
+
302
+ ### Что проверено и что не гарантируется
303
+
304
+ - Проверены прозрачные AND/XOR-маски всех 13 системных ролей, восстановление их
305
+ bitmap-данных и hotspots после потери heartbeat, штатное закрытие watchdog
306
+ и его завершение после аварийного выхода родительского процесса.
307
+ - Проверен обычный `math()`: появление overlay в собственном окне, отключение
308
+ режима, восстановление курсоров Tk-виджетов. Сопоставление имён редакторов
309
+ покрыто тестами; работа в живых PyCharm и VS Code отдельно не проверена.
310
+ - Окно overlay имеет `WDA_EXCLUDEFROMCAPTURE`. Совместимость с конкретными
311
+ программами записи требует отдельного теста. Рекордер может кэшировать прежнее
312
+ изображение курсора или рисовать собственную стрелку.
313
+ - Режим заменяет стандартные системные роли, но не все частные курсоры приложений,
314
+ включая некоторые формы курсора редакторов или курсор, рисуемый внутри кадра.
315
+ Такой частный курсор может остаться видимым и попасть в запись.
316
+ - Координаты мыши, клики, Raw Input и драйверные наблюдатели не скрываются этим
317
+ режимом. При одновременном уничтожении Python и его watchdog независимое
318
+ автоматическое восстановление не гарантируется.
319
+
320
+
321
+ ## Новая точка входа `math()`
322
+
323
+ ```python
324
+ import mathcraft
325
+
326
+ mathcraft.math(2 + 2, 'ignored', anything=123)
327
+ ```
328
+
329
+ Этот вызов открывает терминал и включает режимы курсора/перехвата. Он не выполняет
330
+ математическое вычисление и не возвращает результат выражения. Позиционные
331
+ аргументы и неизвестные именованные аргументы не используются. Сам Python
332
+ вычисляет выражения до вызова функции: например, `mathcraft.math(1 / 0)` всё равно
333
+ выдаст `ZeroDivisionError` до входа в функцию.
334
+
335
+ Сигнатура:
336
+
337
+ ```python
338
+ math(*args, title="Window Manager", experimental_input=True,
339
+ virtual_mouse=True, desktop_cursor=True, **kwargs)
340
+ ```
341
+
342
+ `title` и три переключателя — распознаваемые настройки; их значения применяются.
343
+ Другие именованные аргументы игнорируются. Например, запуск без трёх режимов:
344
+
345
+ ```python
346
+ mathcraft.math(123, title="My Window", experimental_input=False,
347
+ virtual_mouse=False, desktop_cursor=False)
348
+ ```
349
+
350
+ `mathcraft.launch()` сохранён для совместимости. У него первый позиционный
351
+ аргумент по-прежнему является заголовком окна; у `mathcraft.math()` все
352
+ позиционные аргументы игнорируются. Реальные математические функции остаются
353
+ в `mathcraft.mathematics`.
354
+
355
+ Проверка API без открытия терминала и изменения системных курсоров:
356
+
357
+ ```powershell
358
+ python -m unittest -v test_math_entry
359
+ ```