mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
commit
34d643aae6
3 changed files with 123 additions and 102 deletions
|
@ -59,14 +59,14 @@ So, this is my attempt at making an Awesome-esque Wayland compositor.
|
|||
|
||||
## Dependencies
|
||||
You'll need the following packages, as specified by [Smithay](https://github.com/Smithay/smithay):
|
||||
`libwayland libxkbcommon libudev libinput libgdm libseat`
|
||||
`libwayland libxkbcommon libudev libinput libgdm libseat`, as well as `xwayland`.
|
||||
- Arch:
|
||||
```
|
||||
sudo pacman -S wayland wayland-protocols libxkbcommon systemd-libs libinput mesa seatd
|
||||
sudo pacman -S wayland wayland-protocols libxkbcommon systemd-libs libinput mesa seatda xwayland
|
||||
```
|
||||
- Debian:
|
||||
```
|
||||
sudo apt install libwayland-dev libxkbcommon-dev libudev-dev libinput-dev libgdm-dev libseat-dev
|
||||
sudo apt install libwayland-dev libxkbcommon-dev libudev-dev libinput-dev libgdm-dev libseat-dev xwayland
|
||||
```
|
||||
- NixOS: Use the provided [`shell.nix`](shell.nix).
|
||||
- TODO: other distros.
|
||||
|
|
|
@ -122,7 +122,7 @@ struct UdevOutputId {
|
|||
}
|
||||
|
||||
pub struct UdevData {
|
||||
session: LibSeatSession,
|
||||
pub session: LibSeatSession,
|
||||
display_handle: DisplayHandle,
|
||||
dmabuf_state: Option<(DmabufState, DmabufGlobal)>,
|
||||
primary_gpu: DrmNode,
|
||||
|
@ -303,7 +303,7 @@ pub fn run_udev() -> Result<(), Box<dyn Error>> {
|
|||
libinput_context.suspend();
|
||||
tracing::info!("pausing session");
|
||||
|
||||
for backend in data.state.backend_data.backends.values() {
|
||||
for backend in data.state.backend_data.backends.values_mut() {
|
||||
backend.drm.pause();
|
||||
}
|
||||
}
|
||||
|
@ -1076,9 +1076,7 @@ impl State<UdevData> {
|
|||
}
|
||||
|
||||
fn device_removed(&mut self, node: DrmNode) {
|
||||
let device = if let Some(device) = self.backend_data.backends.get_mut(&node) {
|
||||
device
|
||||
} else {
|
||||
let Some(device) = self.backend_data.backends.get_mut(&node) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -1291,15 +1289,11 @@ impl State<UdevData> {
|
|||
}
|
||||
|
||||
fn render_surface(&mut self, node: DrmNode, crtc: crtc::Handle) {
|
||||
let device = if let Some(device) = self.backend_data.backends.get_mut(&node) {
|
||||
device
|
||||
} else {
|
||||
let Some(device) = self.backend_data.backends.get_mut(&node) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let surface = if let Some(surface) = device.surfaces.get_mut(&crtc) {
|
||||
surface
|
||||
} else {
|
||||
let Some(surface) = device.surfaces.get_mut(&crtc) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -1584,7 +1578,7 @@ fn render_surface<'a>(
|
|||
let time = clock.now();
|
||||
|
||||
// We need to send frames to the cursor surface so that xwayland windows will properly
|
||||
// update on motion.
|
||||
// update the cursor on motion.
|
||||
if let CursorImageStatus::Surface(surf) = cursor_status {
|
||||
send_frames_surface_tree(surf, output, time, Some(Duration::ZERO), |_, _| None);
|
||||
}
|
||||
|
|
197
src/input.rs
197
src/input.rs
|
@ -8,10 +8,13 @@ use crate::{
|
|||
window::WindowElement,
|
||||
};
|
||||
use smithay::{
|
||||
backend::input::{
|
||||
backend::{
|
||||
input::{
|
||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent,
|
||||
KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent,
|
||||
},
|
||||
session::Session,
|
||||
},
|
||||
desktop::{layer_map_for_output, space::SpaceElement},
|
||||
input::{
|
||||
keyboard::{keysyms, FilterResult},
|
||||
|
@ -41,6 +44,13 @@ impl InputState {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum KeyAction {
|
||||
CallCallback(CallbackId),
|
||||
Quit,
|
||||
SwitchVt(i32),
|
||||
}
|
||||
|
||||
impl<B: Backend> State<B> {
|
||||
pub fn surface_under<P>(&self, point: P) -> Option<(FocusTarget, Point<i32, Logical>)>
|
||||
where
|
||||
|
@ -87,6 +97,107 @@ impl<B: Backend> State<B> {
|
|||
})
|
||||
}
|
||||
|
||||
fn keyboard<I: InputBackend>(&mut self, event: I::KeyboardKeyEvent) {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let time = event.time_msec();
|
||||
let press_state = event.state();
|
||||
let mut move_mode = false;
|
||||
let action = self
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat has no keyboard") // FIXME: handle err
|
||||
.input(
|
||||
self,
|
||||
event.key_code(),
|
||||
press_state,
|
||||
serial,
|
||||
time,
|
||||
|state, modifiers, keysym| {
|
||||
if press_state == KeyState::Pressed {
|
||||
let mut modifier_mask = Vec::<Modifier>::new();
|
||||
if modifiers.alt {
|
||||
modifier_mask.push(Modifier::Alt);
|
||||
}
|
||||
if modifiers.shift {
|
||||
modifier_mask.push(Modifier::Shift);
|
||||
}
|
||||
if modifiers.ctrl {
|
||||
modifier_mask.push(Modifier::Ctrl);
|
||||
}
|
||||
if modifiers.logo {
|
||||
modifier_mask.push(Modifier::Super);
|
||||
}
|
||||
let raw_sym = if keysym.raw_syms().len() == 1 {
|
||||
keysym.raw_syms()[0]
|
||||
} else {
|
||||
keysyms::KEY_NoSymbol
|
||||
};
|
||||
if let Some(callback_id) = state
|
||||
.input_state
|
||||
.keybinds
|
||||
.get(&(modifier_mask.into(), raw_sym))
|
||||
{
|
||||
return FilterResult::Intercept(KeyAction::CallCallback(*callback_id));
|
||||
} else if modifiers.ctrl
|
||||
&& modifiers.shift
|
||||
&& modifiers.alt
|
||||
&& keysym.modified_sym() == keysyms::KEY_Escape
|
||||
{
|
||||
return FilterResult::Intercept(KeyAction::Quit);
|
||||
} else if let mut vt @ keysyms::KEY_XF86Switch_VT_1..=keysyms::KEY_XF86Switch_VT_12 =
|
||||
keysym.modified_sym() {
|
||||
vt = vt - keysyms::KEY_XF86Switch_VT_1 + 1;
|
||||
tracing::info!("Switching to vt {vt}");
|
||||
return FilterResult::Intercept(KeyAction::SwitchVt(vt as i32));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if keysym.modified_sym() == keysyms::KEY_Control_L {
|
||||
match press_state {
|
||||
KeyState::Pressed => {
|
||||
move_mode = true;
|
||||
}
|
||||
KeyState::Released => {
|
||||
move_mode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
FilterResult::Forward
|
||||
},
|
||||
);
|
||||
|
||||
self.move_mode = move_mode;
|
||||
|
||||
match action {
|
||||
Some(KeyAction::CallCallback(callback_id)) => {
|
||||
if let Some(stream) = self.api_state.stream.as_ref() {
|
||||
if let Err(err) = crate::api::send_to_client(
|
||||
&mut stream.lock().expect("Could not lock stream mutex"),
|
||||
&OutgoingMsg::CallCallback {
|
||||
callback_id,
|
||||
args: None,
|
||||
},
|
||||
) {
|
||||
tracing::error!("error sending msg to client: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(KeyAction::SwitchVt(vt)) => {
|
||||
if let Some(st) = (self as &mut dyn std::any::Any).downcast_mut::<State<UdevData>>()
|
||||
{
|
||||
if let Err(err) = st.backend_data.session.change_vt(vt) {
|
||||
tracing::error!("Failed to switch to vt {vt}: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(KeyAction::Quit) => {
|
||||
self.loop_signal.stop();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn pointer_button<I: InputBackend>(&mut self, event: I::PointerButtonEvent) {
|
||||
let pointer = self.seat.get_pointer().expect("Seat has no pointer"); // FIXME: handle err
|
||||
let keyboard = self.seat.get_keyboard().expect("Seat has no keyboard"); // FIXME: handle err
|
||||
|
@ -303,90 +414,6 @@ impl<B: Backend> State<B> {
|
|||
.expect("Seat has no pointer")
|
||||
.axis(self, frame);
|
||||
}
|
||||
|
||||
fn keyboard<I: InputBackend>(&mut self, event: I::KeyboardKeyEvent) {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let time = event.time_msec();
|
||||
let press_state = event.state();
|
||||
let mut move_mode = false;
|
||||
let action = self
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat has no keyboard") // FIXME: handle err
|
||||
.input(
|
||||
self,
|
||||
event.key_code(),
|
||||
press_state,
|
||||
serial,
|
||||
time,
|
||||
|state, modifiers, keysym| {
|
||||
if press_state == KeyState::Pressed {
|
||||
let mut modifier_mask = Vec::<Modifier>::new();
|
||||
if modifiers.alt {
|
||||
modifier_mask.push(Modifier::Alt);
|
||||
}
|
||||
if modifiers.shift {
|
||||
modifier_mask.push(Modifier::Shift);
|
||||
}
|
||||
if modifiers.ctrl {
|
||||
modifier_mask.push(Modifier::Ctrl);
|
||||
}
|
||||
if modifiers.logo {
|
||||
modifier_mask.push(Modifier::Super);
|
||||
}
|
||||
let raw_sym = if keysym.raw_syms().len() == 1 {
|
||||
keysym.raw_syms()[0]
|
||||
} else {
|
||||
keysyms::KEY_NoSymbol
|
||||
};
|
||||
if let Some(callback_id) = state
|
||||
.input_state
|
||||
.keybinds
|
||||
.get(&(modifier_mask.into(), raw_sym))
|
||||
{
|
||||
return FilterResult::Intercept(*callback_id);
|
||||
} else if modifiers.ctrl
|
||||
&& modifiers.shift
|
||||
&& modifiers.alt
|
||||
&& keysym.modified_sym() == keysyms::KEY_Escape
|
||||
{
|
||||
return FilterResult::Intercept(CallbackId(999999));
|
||||
}
|
||||
}
|
||||
|
||||
if keysym.modified_sym() == keysyms::KEY_Control_L {
|
||||
match press_state {
|
||||
KeyState::Pressed => {
|
||||
move_mode = true;
|
||||
}
|
||||
KeyState::Released => {
|
||||
move_mode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
FilterResult::Forward
|
||||
},
|
||||
);
|
||||
|
||||
self.move_mode = move_mode;
|
||||
|
||||
if let Some(callback_id) = action {
|
||||
if callback_id.0 == 999999 {
|
||||
self.loop_signal.stop();
|
||||
}
|
||||
if let Some(stream) = self.api_state.stream.as_ref() {
|
||||
if let Err(err) = crate::api::send_to_client(
|
||||
&mut stream.lock().expect("Could not lock stream mutex"),
|
||||
&OutgoingMsg::CallCallback {
|
||||
callback_id,
|
||||
args: None,
|
||||
},
|
||||
) {
|
||||
tracing::warn!("error sending msg to client: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl State<WinitData> {
|
||||
|
|
Loading…
Reference in a new issue