feat: add nested Phase 0 compositor
This commit is contained in:
1 parent
aab447ef25
commit
475d433ec4
8 files changed
+2710
-2
No files matched your search
@@ -0,0 +1,125 @@
|
||||
use smithay::{
|
||||
backend::input::{
|
||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent,
|
||||
KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent,
|
||||
},
|
||||
input::{
|
||||
keyboard::FilterResult,
|
||||
pointer::{AxisFrame, ButtonEvent, MotionEvent},
|
||||
},
|
||||
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||
utils::{SERIAL_COUNTER, Serial},
|
||||
};
|
||||
|
||||
use crate::Ferese;
|
||||
|
||||
impl Ferese {
|
||||
pub fn process_input_event<I: InputBackend>(&mut self, event: InputEvent<I>) {
|
||||
match event {
|
||||
InputEvent::Keyboard { event, .. } => {
|
||||
let keyboard = self.seat.get_keyboard().expect("seat has a keyboard");
|
||||
keyboard.input::<(), _>(
|
||||
self,
|
||||
event.key_code(),
|
||||
event.state(),
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
Event::time(&event) as u32,
|
||||
|_, _, _| FilterResult::Forward,
|
||||
);
|
||||
}
|
||||
InputEvent::PointerMotionAbsolute { event, .. } => {
|
||||
let Some(output) = self.space.outputs().next() else {
|
||||
return;
|
||||
};
|
||||
let Some(geometry) = self.space.output_geometry(output) else {
|
||||
return;
|
||||
};
|
||||
let position = event.position_transformed(geometry.size) + geometry.loc.to_f64();
|
||||
let pointer = self.seat.get_pointer().expect("seat has a pointer");
|
||||
pointer.motion(
|
||||
self,
|
||||
self.surface_under(position),
|
||||
&MotionEvent {
|
||||
location: position,
|
||||
serial: SERIAL_COUNTER.next_serial(),
|
||||
time: event.time() as u32,
|
||||
},
|
||||
);
|
||||
pointer.frame(self);
|
||||
}
|
||||
InputEvent::PointerButton { event, .. } => {
|
||||
let pointer = self.seat.get_pointer().expect("seat has a pointer");
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
if event.state() == ButtonState::Pressed && !pointer.is_grabbed() {
|
||||
self.focus_window_under_pointer(serial);
|
||||
}
|
||||
pointer.button(
|
||||
self,
|
||||
&ButtonEvent {
|
||||
button: event.button_code(),
|
||||
state: event.state(),
|
||||
serial,
|
||||
time: event.time() as u32,
|
||||
},
|
||||
);
|
||||
pointer.frame(self);
|
||||
}
|
||||
InputEvent::PointerAxis { event, .. } => {
|
||||
let source = event.source();
|
||||
let horizontal = event.amount(Axis::Horizontal).unwrap_or_else(|| {
|
||||
event.amount_v120(Axis::Horizontal).unwrap_or(0.0) * 15.0 / 120.0
|
||||
});
|
||||
let vertical = event.amount(Axis::Vertical).unwrap_or_else(|| {
|
||||
event.amount_v120(Axis::Vertical).unwrap_or(0.0) * 15.0 / 120.0
|
||||
});
|
||||
let mut frame = AxisFrame::new(event.time() as u32).source(source);
|
||||
if horizontal != 0.0 {
|
||||
frame = frame.value(Axis::Horizontal, horizontal);
|
||||
if let Some(value) = event.amount_v120(Axis::Horizontal) {
|
||||
frame = frame.v120(Axis::Horizontal, value as i32);
|
||||
}
|
||||
}
|
||||
if vertical != 0.0 {
|
||||
frame = frame.value(Axis::Vertical, vertical);
|
||||
if let Some(value) = event.amount_v120(Axis::Vertical) {
|
||||
frame = frame.v120(Axis::Vertical, value as i32);
|
||||
}
|
||||
}
|
||||
if source == AxisSource::Finger {
|
||||
if event.amount(Axis::Horizontal) == Some(0.0) {
|
||||
frame = frame.stop(Axis::Horizontal);
|
||||
}
|
||||
if event.amount(Axis::Vertical) == Some(0.0) {
|
||||
frame = frame.stop(Axis::Vertical);
|
||||
}
|
||||
}
|
||||
let pointer = self.seat.get_pointer().expect("seat has a pointer");
|
||||
pointer.axis(self, frame);
|
||||
pointer.frame(self);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn focus_window_under_pointer(&mut self, serial: Serial) {
|
||||
let pointer = self.seat.get_pointer().expect("seat has a pointer");
|
||||
let keyboard = self.seat.get_keyboard().expect("seat has a keyboard");
|
||||
if let Some((window, _)) = self.space.element_under(pointer.current_location()) {
|
||||
let window = window.clone();
|
||||
self.space.raise_element(&window, true);
|
||||
let surface = window
|
||||
.toplevel()
|
||||
.expect("mapped window has a toplevel")
|
||||
.wl_surface()
|
||||
.clone();
|
||||
keyboard.set_focus(self, Some(surface), serial);
|
||||
} else {
|
||||
keyboard.set_focus(self, Option::<WlSurface>::None, serial);
|
||||
}
|
||||
self.space.elements().for_each(|window| {
|
||||
if let Some(toplevel) = window.toplevel() {
|
||||
toplevel.send_pending_configure();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user