M1 Input: факты о smithay 0.7 / winit 0.30 (verified)
M1 Input: факты о smithay 0.7 / winit 0.30 (verified)
Section titled “M1 Input: факты о smithay 0.7 / winit 0.30 (verified)”Исследование для ввода M1 (look-mode, WASD, клик-фокус). Все пути проверены по исходникам smithay 0.7.0 (/tmp/smithay07) и winit 0.30.13.
InputEvent::PointerMotionAbsolute— единственный мышиный источник winit-бэкенда. Абсолютные координаты окна; относительного события нет (PointerMotionEvent = UnusedEvent), winit получает relative-motion но smithay его дропает (device_eventне имплементирован).- На краях окна события просто прекращаются — дельта насыщается нулём (rubber-band). При sens 0.003 rad/px и окне 1280px: ~±110° от центра. Это ограничение M1; M2-фикс — патч smithay на пересылку
DeviceEvent::MouseMotion+set_cursor_grab(Locked). - Скрытие курсора:
Window::set_cursor_visible(false)— НЕ останавливает события. Вызывать из Redraw-arm (там естьbackend.window()), только при смене флага. set_cursor_positionна Wayland требуетCursorGrabMode::Locked→ убивает поток событий. Не использовать.CursorEntered/CursorLeftsmithay дропает — первый ивент после возврата может дать спайк дельты; сбрасыватьlastпри |delta| > пол-окна.
Keyboard
Section titled “Keyboard”- Сканкоды (evdev): W=17, A=30, S=31, D=32, F=33, Space=57, CtrlL=29, ShiftL=42, ShiftR=54.
key_code() = scancode + 8(xkb). Физическая раскладка = ZQSD работает как WASD (игровая конвенция). - Повторы клавиш не приходят: smithay фильтрует
event.repeatиis_synthetic. - Focus loss не синтезирует release на Wayland: при alt-tab зажатая W остаётся «нажатой». Обязательно чистить свой pressed-set на
WinitEvent::Focus(false)(сейчас игнорируется). - Перехват WASD от клиента:
FilterResult::Intercept(())+ помнить перехваченные для перехвата release (паттерн anvilsuppressed_keys).
Клик-фокус (raycast)
Section titled “Клик-фокус (raycast)”HoverState { hit: Option<Hit> }уже обновляется каждый Update (nihil_core::raycast::update_hitsиз центрального луча камеры).Hit { entity, dist, local, px }.- Маппинг:
Hit.entity → WindowEntity(id) → Nihil.window_entities[&id] → raise + keyboard.set_focus. В look-mode ЛКМ кликает по прицелу; в pointer-mode — фолбэк на 2Delement_under.
Look-mode протокол
Section titled “Look-mode протокол”- Вход: удержание ПКМ (button_code 0x111; самосбрасывающийся). Выход: release ПКМ,
Focus(false), Escape. - В look-mode НЕ слать
pointer.motion/frame— фокус заморожен (клиент видит стационарный курсор). - Чувствительность:
2.5 / window_height_pxrad/px (инвариант к DPI/resize). dy — инвертировать (экран y вниз, pitch вверх). - Накопление дельт между Redraw (несколько событий на кадр), запись в
MoverInputпередapp.update(), обнуление после.
Известные ограничения M1
Section titled “Известные ограничения M1”- Поворот насыщается у краёв окна (~±110°) — absolute-only на Wayland-хосте. M2: патч smithay (DeviceEvent::MouseMotion → InputEvent::PointerMotion) + cursor grab.
- Повторы клавиш у клиентов не работают в nested-режиме (smithay limitation, не наш баг).