mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-26 21:58:10 +01:00
Working MVP for setting keybinds through the api
This commit is contained in:
parent
2b40019045
commit
da783fcf7f
7 changed files with 236 additions and 9 deletions
|
@ -9,7 +9,7 @@ edition = "2021"
|
|||
pinnacle_api = { path = "../pinnacle_api" }
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||
smithay = { git = "https://github.com/Smithay/smithay" }
|
||||
smithay = { git = "https://github.com/Smithay/smithay", rev = "9b3d173" }
|
||||
smithay-drm-extras = { git = "https://github.com/Smithay/smithay", optional = true }
|
||||
thiserror = "1.0.40"
|
||||
xcursor = {version = "0.3.4", optional = true }
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use pinnacle_api::message::{ModifierMask, Modifiers};
|
||||
use smithay::{
|
||||
backend::input::{
|
||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent,
|
||||
|
@ -18,6 +21,10 @@ use crate::{
|
|||
state::State,
|
||||
};
|
||||
|
||||
pub struct InputState {
|
||||
pub keybinds: HashMap<(ModifierMask, u32), u32>,
|
||||
}
|
||||
|
||||
impl<B: Backend> State<B> {
|
||||
pub fn surface_under<P>(&self, point: P) -> Option<(Window, Point<i32, Logical>)>
|
||||
where
|
||||
|
@ -189,8 +196,28 @@ impl<B: Backend> State<B> {
|
|||
press_state,
|
||||
serial,
|
||||
time,
|
||||
|state, _modifiers, keysym| {
|
||||
|state, modifiers, keysym| {
|
||||
if press_state == KeyState::Pressed {
|
||||
let mut modifier_mask = Vec::<Modifiers>::new();
|
||||
if modifiers.alt {
|
||||
modifier_mask.push(Modifiers::Alt);
|
||||
}
|
||||
if modifiers.shift {
|
||||
modifier_mask.push(Modifiers::Shift);
|
||||
}
|
||||
if modifiers.ctrl {
|
||||
modifier_mask.push(Modifiers::Ctrl);
|
||||
}
|
||||
if modifiers.logo {
|
||||
modifier_mask.push(Modifiers::Super);
|
||||
}
|
||||
if let Some(callback_id) = state
|
||||
.input_state
|
||||
.keybinds
|
||||
.get(&(modifier_mask.into(), keysym.modified_sym()))
|
||||
{
|
||||
return FilterResult::Intercept(1);
|
||||
}
|
||||
match keysym.modified_sym() {
|
||||
keysyms::KEY_L => return FilterResult::Intercept(1),
|
||||
keysyms::KEY_K => return FilterResult::Intercept(2),
|
||||
|
|
|
@ -13,7 +13,7 @@ mod xdg;
|
|||
use std::error::Error;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
pinnacle_api::run()?;
|
||||
// pinnacle_api::run()?;
|
||||
|
||||
match tracing_subscriber::EnvFilter::try_from_default_env() {
|
||||
Ok(env_filter) => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::{error::Error, os::fd::AsRawFd, sync::Arc};
|
||||
use std::{collections::HashMap, error::Error, os::fd::AsRawFd, sync::Arc};
|
||||
|
||||
use pinnacle_api::{message::Msg, PinnacleSocketSource, PinnacleStreamSource};
|
||||
use smithay::{
|
||||
backend::renderer::element::RenderElementStates,
|
||||
desktop::{
|
||||
|
@ -34,7 +35,7 @@ use smithay::{
|
|||
},
|
||||
};
|
||||
|
||||
use crate::backend::Backend;
|
||||
use crate::{backend::Backend, input::InputState};
|
||||
|
||||
pub struct State<B: Backend> {
|
||||
pub backend_data: B,
|
||||
|
@ -57,6 +58,7 @@ pub struct State<B: Backend> {
|
|||
pub xdg_shell_state: XdgShellState,
|
||||
pub viewporter_state: ViewporterState,
|
||||
pub fractional_scale_manager_state: FractionalScaleManagerState,
|
||||
pub input_state: InputState,
|
||||
|
||||
pub popup_manager: PopupManager,
|
||||
|
||||
|
@ -95,6 +97,29 @@ impl<B: Backend> State<B> {
|
|||
},
|
||||
)?;
|
||||
|
||||
loop_handle.insert_source(PinnacleSocketSource::new()?, |stream, _, data| {
|
||||
data.state
|
||||
.loop_handle
|
||||
.insert_source(PinnacleStreamSource::new(stream), |msg, _, data| {
|
||||
// TODO: do stuff with msg
|
||||
match msg {
|
||||
Msg::SetKeybind {
|
||||
key,
|
||||
modifiers,
|
||||
callback_id,
|
||||
} => {
|
||||
tracing::info!("set keybind: {:?}, {}", modifiers, key);
|
||||
data.state
|
||||
.input_state
|
||||
.keybinds
|
||||
.insert((modifiers.into(), key), callback_id);
|
||||
}
|
||||
Msg::SetMousebind { button } => todo!(),
|
||||
};
|
||||
})
|
||||
.unwrap();
|
||||
})?;
|
||||
|
||||
let display_handle = display.handle();
|
||||
let mut seat_state = SeatState::new();
|
||||
let mut seat = seat_state.new_wl_seat(&display_handle, backend_data.seat_name());
|
||||
|
@ -119,6 +144,9 @@ impl<B: Backend> State<B> {
|
|||
fractional_scale_manager_state: FractionalScaleManagerState::new::<Self>(
|
||||
&display_handle,
|
||||
),
|
||||
input_state: InputState {
|
||||
keybinds: HashMap::new(),
|
||||
},
|
||||
|
||||
seat,
|
||||
|
||||
|
@ -136,6 +164,17 @@ impl<B: Backend> State<B> {
|
|||
.find(|window| window.wl_surface().map(|s| s == *surface).unwrap_or(false))
|
||||
.cloned()
|
||||
}
|
||||
|
||||
pub fn handle_msg(msg: Msg) {
|
||||
match msg {
|
||||
Msg::SetKeybind {
|
||||
key,
|
||||
modifiers,
|
||||
callback_id,
|
||||
} => todo!(),
|
||||
Msg::SetMousebind { button } => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CalloopData<B: Backend> {
|
||||
|
|
|
@ -12,3 +12,4 @@ serde = { version = "1.0.164", features = ["derive"] }
|
|||
serde_json = { version = "1.0.96" }
|
||||
rmp-serde = { version = "1.1.1" }
|
||||
xkbcommon = { version = "0.5.0" }
|
||||
smithay = { git = "https://github.com/Smithay/smithay", rev = "9b3d173" }
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
use std::{
|
||||
error::Error,
|
||||
io,
|
||||
os::unix::net::{UnixListener, UnixStream},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use smithay::reexports::calloop::{
|
||||
self, generic::Generic, EventSource, Interest, Mode, PostAction,
|
||||
};
|
||||
|
||||
use crate::message::Msg;
|
||||
|
||||
pub mod message;
|
||||
|
@ -42,3 +47,143 @@ fn handle_client(stream: UnixStream) {
|
|||
println!("{:?}", msg);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PinnacleSocketSource {
|
||||
socket: Generic<UnixListener>,
|
||||
}
|
||||
|
||||
impl PinnacleSocketSource {
|
||||
pub fn new() -> Result<Self, io::Error> {
|
||||
let socket_path = Path::new(SOCKET_PATH);
|
||||
|
||||
if socket_path.exists() {
|
||||
std::fs::remove_file(socket_path)?;
|
||||
}
|
||||
|
||||
let listener = UnixListener::bind(SOCKET_PATH)?;
|
||||
|
||||
let socket = Generic::new(listener, Interest::READ, Mode::Level);
|
||||
|
||||
Ok(Self { socket })
|
||||
}
|
||||
}
|
||||
|
||||
impl EventSource for PinnacleSocketSource {
|
||||
type Event = UnixStream;
|
||||
|
||||
type Metadata = ();
|
||||
|
||||
type Ret = ();
|
||||
|
||||
type Error = io::Error;
|
||||
|
||||
fn process_events<F>(
|
||||
&mut self,
|
||||
readiness: calloop::Readiness,
|
||||
token: calloop::Token,
|
||||
mut callback: F,
|
||||
) -> Result<calloop::PostAction, Self::Error>
|
||||
where
|
||||
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
|
||||
{
|
||||
self.socket
|
||||
.process_events(readiness, token, |_readiness, listener| {
|
||||
listener.set_nonblocking(true)?;
|
||||
while let Ok((stream, _sock_addr)) = listener.accept() {
|
||||
stream.set_nonblocking(true)?;
|
||||
callback(stream, &mut ());
|
||||
}
|
||||
|
||||
Ok(PostAction::Continue)
|
||||
})
|
||||
}
|
||||
|
||||
fn register(
|
||||
&mut self,
|
||||
poll: &mut calloop::Poll,
|
||||
token_factory: &mut calloop::TokenFactory,
|
||||
) -> calloop::Result<()> {
|
||||
self.socket.register(poll, token_factory)
|
||||
}
|
||||
|
||||
fn reregister(
|
||||
&mut self,
|
||||
poll: &mut calloop::Poll,
|
||||
token_factory: &mut calloop::TokenFactory,
|
||||
) -> calloop::Result<()> {
|
||||
self.socket.reregister(poll, token_factory)
|
||||
}
|
||||
|
||||
fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> {
|
||||
self.socket.unregister(poll)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PinnacleStreamSource {
|
||||
stream: Generic<UnixStream>,
|
||||
}
|
||||
|
||||
impl PinnacleStreamSource {
|
||||
pub fn new(stream: UnixStream) -> Self {
|
||||
Self {
|
||||
stream: Generic::new(stream, Interest::READ, Mode::Level),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EventSource for PinnacleStreamSource {
|
||||
type Event = Msg;
|
||||
|
||||
type Metadata = ();
|
||||
|
||||
type Ret = ();
|
||||
|
||||
type Error = io::Error;
|
||||
|
||||
fn process_events<F>(
|
||||
&mut self,
|
||||
readiness: calloop::Readiness,
|
||||
token: calloop::Token,
|
||||
mut callback: F,
|
||||
) -> Result<PostAction, Self::Error>
|
||||
where
|
||||
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
|
||||
{
|
||||
self.stream
|
||||
.process_events(readiness, token, |_readiness, stream| {
|
||||
match rmp_serde::from_read(stream as &UnixStream) {
|
||||
Ok(msg) => callback(msg, &mut ()),
|
||||
Err(rmp_serde::decode::Error::InvalidMarkerRead(err))
|
||||
if err.kind() == io::ErrorKind::UnexpectedEof =>
|
||||
{
|
||||
stream.shutdown(std::net::Shutdown::Both)?;
|
||||
println!("Stream closed: {:?}", err);
|
||||
return Ok(PostAction::Remove);
|
||||
}
|
||||
Err(err) => println!("{:?}", err),
|
||||
}
|
||||
|
||||
Ok(PostAction::Continue)
|
||||
})
|
||||
}
|
||||
|
||||
fn register(
|
||||
&mut self,
|
||||
poll: &mut calloop::Poll,
|
||||
token_factory: &mut calloop::TokenFactory,
|
||||
) -> calloop::Result<()> {
|
||||
self.stream.register(poll, token_factory)
|
||||
}
|
||||
|
||||
fn reregister(
|
||||
&mut self,
|
||||
poll: &mut calloop::Poll,
|
||||
token_factory: &mut calloop::TokenFactory,
|
||||
) -> calloop::Result<()> {
|
||||
self.stream.reregister(poll, token_factory)
|
||||
}
|
||||
|
||||
fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> {
|
||||
self.stream.unregister(poll)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,23 @@ pub enum Action {
|
|||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum Modifiers {
|
||||
Shift,
|
||||
Ctrl,
|
||||
Alt,
|
||||
Super,
|
||||
Shift = 0b0000_0001,
|
||||
Ctrl = 0b0000_0010,
|
||||
Alt = 0b0000_0100,
|
||||
Super = 0b0000_1000,
|
||||
}
|
||||
|
||||
/// A bitmask of [Modifiers] for the purpose of hashing.
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
pub struct ModifierMask(u8);
|
||||
|
||||
impl<T: IntoIterator<Item = Modifiers>> From<T> for ModifierMask {
|
||||
fn from(value: T) -> Self {
|
||||
let value = value.into_iter();
|
||||
let mut mask: u8 = 0b0000_0000;
|
||||
for modifier in value {
|
||||
mask |= modifier as u8;
|
||||
}
|
||||
Self(mask)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue