lark/tests/smoke.rs
Niko Marmeladkov 41fa466410 Первая версия Lark DE
Композитор Wayland на smithay: сессия, xdg-shell, ввод, рендеринг через
OpenGL ES с отслеживанием повреждений. Протоколы xdg-decoration,
viewporter и presentation-time.

Окна в стиле Windows 11: заголовок с названием и кнопками, перетаскивание,
изменение размера за края и углы, сворачивание и разворачивание.

Панель задач с подписями окон, часами и переключателем рабочих областей.
Меню «Пуск» со списком приложений и поиском в текущей раскладке.
Переключение окон по Alt+Tab с подтверждением при отпускании Alt.

Собственный растровщик текста на fontdb + fontdue с гамма-коррекцией
покрытия: без хинтинга штрихи на мелком кегле выходят рваными.

Приложения запускаются в отдельной сессии D-Bus, иначе однопользовательские
программы находят уже запущенный экземпляр во внешней сессии и открывают
окно не в Lark.

127 тестов, clippy без замечаний.
2026-10-18 09:18:57 +03:00

102 lines
4.7 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! Тесты обработки ввода на бэкенде winit.
//!
//! Изначально композитор не собирался с ошибкой
//! `no method named key_code found for struct WinitKeyboardInputEvent`:
//! трейт `KeyboardKeyEvent` не был импортирован. Такие ошибки дешевле ловить
//! тестом, чем запуском композитора, поэтому здесь проверяется, что трейты
//! событий ввода smithay доступны и что их методы вызываются корректно.
use smithay::backend::input::{
AbsolutePositionEvent, Axis, Event, InputBackend, InputEvent, Keycode, KeyboardKeyEvent,
KeyState, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
};
use smithay::backend::winit::{self, WinitInput};
/// Проверяет, что трейты событий ввода реализованы для типов бэкенда winit.
///
/// Ошибка `no method named key_code` возникает именно тогда, когда трейт не
/// импортирован, поэтому проверка идёт через обобщённые сигнатуры.
#[test]
fn input_event_traits_are_available() {
fn assert_keyboard<E: KeyboardKeyEvent<WinitInput>>() {}
fn assert_button<E: PointerButtonEvent<WinitInput>>() {}
fn assert_axis<E: PointerAxisEvent<WinitInput>>() {}
fn assert_motion<E: PointerMotionAbsoluteEvent<WinitInput>>() {}
assert_keyboard::<winit::WinitKeyboardInputEvent>();
assert_button::<winit::WinitMouseInputEvent>();
assert_axis::<winit::WinitMouseWheelEvent>();
assert_motion::<winit::WinitMouseMovedEvent>();
}
/// Проверяет, что из события клавиатуры извлекаются код, состояние и время.
///
/// Именно эти три значения композитор передаёт в `KeyboardHandle::input`.
#[test]
fn keyboard_event_exposes_code_state_and_time() {
fn read<E: KeyboardKeyEvent<WinitInput>>(event: &E) -> (Keycode, KeyState) {
(event.key_code(), event.state())
}
// Вызов компилируется, только если все методы трейта доступны.
let _ = read::<winit::WinitKeyboardInputEvent>;
}
/// Проверяет, что события указателя дают доступ к координатам, кнопкам и
/// осям прокрутки.
#[test]
fn pointer_events_expose_expected_fields() {
fn read_motion<E: PointerMotionAbsoluteEvent<WinitInput>>(event: &E) -> (f64, f64) {
(event.x(), event.y())
}
fn read_button<E: PointerButtonEvent<WinitInput>>(
event: &E,
) -> (u32, smithay::backend::input::ButtonState) {
(event.button_code(), event.state())
}
fn read_axis<E: PointerAxisEvent<WinitInput>>(event: &E) {
let _ = event.source();
let _ = event.relative_direction(Axis::Vertical);
let _ = event.amount_v120(Axis::Horizontal);
}
let _ = read_motion::<winit::WinitMouseMovedEvent>;
let _ = read_button::<winit::WinitMouseInputEvent>;
let _ = read_axis::<winit::WinitMouseWheelEvent>;
}
/// Проверяет разбор всех событий ввода, которые обрабатывает композитор.
///
/// Это защищает от ситуации, когда в `match` добавлена ветка для события,
/// доступ к полям которого требует неимпортированного трейта.
#[test]
fn compositor_handles_all_input_variants() {
fn route<B: InputBackend>(event: InputEvent<B>) {
match event {
InputEvent::Keyboard { event } => {
let code: Keycode = event.key_code();
let state: KeyState = event.state();
let _ = (code, state, event.time());
}
InputEvent::PointerMotionAbsolute { event } => {
let _ = (event.x(), event.y());
let _ = event.position_transformed((100, 100).into());
}
InputEvent::PointerButton { event } => {
let _ = (event.button_code(), event.state());
}
InputEvent::PointerAxis { event } => {
let _ = event.source();
let _ = event.amount(Axis::Vertical);
let _ = event.amount_v120(Axis::Vertical);
let _ = event.relative_direction(Axis::Vertical);
}
_ => {}
}
}
// Проверка на этапе компиляции для бэкенда winit.
let _ = route::<WinitInput>;
}