mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-30 20:34:49 +01:00
Extract proto into crate, start impl'ing services
This commit is contained in:
parent
3d05338c82
commit
46ba7d9ad0
10 changed files with 328 additions and 77 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -1548,11 +1548,12 @@ name = "pinnacle"
|
|||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.4.1",
|
||||
"clap",
|
||||
"const_format",
|
||||
"image",
|
||||
"lazy_static",
|
||||
"nix 0.27.1",
|
||||
"pinnacle-api-defs",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"rmp",
|
||||
|
@ -1567,7 +1568,6 @@ dependencies = [
|
|||
"tokio-stream",
|
||||
"toml",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
"tonic-reflection",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
|
@ -1578,6 +1578,16 @@ dependencies = [
|
|||
"xkbcommon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pinnacle-api-defs"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"const_format",
|
||||
"prost",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.28"
|
||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -21,11 +21,6 @@ image = { version = "0.24", default-features = false, optional = true }
|
|||
serde = { version = "1.0", features = ["derive"] }
|
||||
rmp = { version = "0.8.12" }
|
||||
rmp-serde = { version = "1.1.2" }
|
||||
# calloop = { version = "0.12.2", features = ["executor", "futures-io"] }
|
||||
# futures-lite = { version = "2" }
|
||||
# async-process = { version = "2" }
|
||||
# async-channel = "2"
|
||||
# async-net = "2.0.0"
|
||||
x11rb = { version = "0.13", default-features = false, features = ["composite"], optional = true }
|
||||
shellexpand = "3.1.0"
|
||||
toml = "0.8"
|
||||
|
@ -42,10 +37,9 @@ tonic = "0.10.2"
|
|||
tonic-reflection = "0.10.2"
|
||||
tokio-stream = { version = "0.1.14", features = ["net"] }
|
||||
tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread", "process", "io-util"]}
|
||||
bitflags = "2.4.1"
|
||||
pinnacle-api-defs = { path = "./pinnacle-api-defs" }
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.10.2"
|
||||
const_format = "0.2.32"
|
||||
|
||||
[features]
|
||||
default = ["egl", "winit", "udev", "xwayland"]
|
||||
|
@ -66,3 +60,6 @@ udev = [
|
|||
]
|
||||
winit = ["smithay/backend_winit", "smithay/backend_drm"]
|
||||
xwayland = ["smithay/xwayland", "x11rb", "smithay/x11rb_event_source", "xcursor"]
|
||||
|
||||
[workspace]
|
||||
members = ["pinnacle-api-defs"]
|
||||
|
|
|
@ -9,7 +9,8 @@ enum Modifier {
|
|||
MODIFIER_UNSPECIFIED = 0;
|
||||
MODIFIER_SHIFT = 1;
|
||||
MODIFIER_CTRL = 2;
|
||||
MODIFIER_SUPER = 3;
|
||||
MODIFIER_ALT = 3;
|
||||
MODIFIER_SUPER = 4;
|
||||
}
|
||||
|
||||
message SetKeybindRequest {
|
||||
|
|
24
build.rs
24
build.rs
|
@ -1,32 +1,8 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use const_format::formatcp;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=api/lua");
|
||||
println!("cargo:rerun-if-changed=api/protocol");
|
||||
|
||||
std::process::Command::new("/bin/sh")
|
||||
.arg("install_libs.sh")
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
const VERSION: &str = "v0alpha1";
|
||||
const PROTOS: &[&str] = &[
|
||||
formatcp!("api/protocol/pinnacle/{VERSION}/pinnacle.proto"),
|
||||
formatcp!("api/protocol/pinnacle/input/{VERSION}/input.proto"),
|
||||
formatcp!("api/protocol/pinnacle/input/libinput/{VERSION}/libinput.proto"),
|
||||
formatcp!("api/protocol/pinnacle/output/{VERSION}/output.proto"),
|
||||
formatcp!("api/protocol/pinnacle/process/{VERSION}/process.proto"),
|
||||
formatcp!("api/protocol/pinnacle/tag/{VERSION}/tag.proto"),
|
||||
formatcp!("api/protocol/pinnacle/window/{VERSION}/window.proto"),
|
||||
formatcp!("api/protocol/pinnacle/window/rules/{VERSION}/rules.proto"),
|
||||
];
|
||||
|
||||
let descriptor_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("pinnacle.bin");
|
||||
|
||||
tonic_build::configure()
|
||||
.file_descriptor_set_path(descriptor_path)
|
||||
.compile(PROTOS, &["api/protocol"])
|
||||
.unwrap();
|
||||
}
|
||||
|
|
13
pinnacle-api-defs/Cargo.toml
Normal file
13
pinnacle-api-defs/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "pinnacle-api-defs"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
tonic = "0.10.2"
|
||||
prost = "0.12.3"
|
||||
# prost-types = "0.12.3"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.10.2"
|
||||
const_format = "0.2.32"
|
26
pinnacle-api-defs/build.rs
Normal file
26
pinnacle-api-defs/build.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use const_format::formatcp;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=api/protocol");
|
||||
|
||||
const VERSION: &str = "v0alpha1";
|
||||
const PROTOS: &[&str] = &[
|
||||
formatcp!("../api/protocol/pinnacle/{VERSION}/pinnacle.proto"),
|
||||
formatcp!("../api/protocol/pinnacle/input/{VERSION}/input.proto"),
|
||||
formatcp!("../api/protocol/pinnacle/input/libinput/{VERSION}/libinput.proto"),
|
||||
formatcp!("../api/protocol/pinnacle/output/{VERSION}/output.proto"),
|
||||
formatcp!("../api/protocol/pinnacle/process/{VERSION}/process.proto"),
|
||||
formatcp!("../api/protocol/pinnacle/tag/{VERSION}/tag.proto"),
|
||||
formatcp!("../api/protocol/pinnacle/window/{VERSION}/window.proto"),
|
||||
formatcp!("../api/protocol/pinnacle/window/rules/{VERSION}/rules.proto"),
|
||||
];
|
||||
|
||||
let descriptor_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("pinnacle.bin");
|
||||
|
||||
tonic_build::configure()
|
||||
.file_descriptor_set_path(descriptor_path)
|
||||
.compile(PROTOS, &["../api/protocol"])
|
||||
.unwrap();
|
||||
}
|
44
pinnacle-api-defs/src/lib.rs
Normal file
44
pinnacle-api-defs/src/lib.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
pub mod pinnacle {
|
||||
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.v0alpha1");
|
||||
}
|
||||
|
||||
pub mod input {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.input.v0alpha1");
|
||||
}
|
||||
|
||||
pub mod libinput {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.input.libinput.v0alpha1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod output {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.output.v0alpha1");
|
||||
}
|
||||
}
|
||||
|
||||
pub mod tag {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.tag.v0alpha1");
|
||||
}
|
||||
}
|
||||
|
||||
pub mod window {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.window.v0alpha1");
|
||||
}
|
||||
|
||||
pub mod rules {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.window.rules.v0alpha1");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const FILE_DESCRIPTOR_SET: &[u8] = tonic::include_file_descriptor_set!("pinnacle");
|
|
@ -1,44 +1,143 @@
|
|||
pub mod pinnacle {
|
||||
use std::{collections::HashSet, pin::Pin};
|
||||
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.v0alpha1");
|
||||
}
|
||||
use smithay::reexports::calloop;
|
||||
use tokio_stream::Stream;
|
||||
use tonic::{Response, Status};
|
||||
|
||||
pub mod input {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.input.v0alpha1");
|
||||
}
|
||||
use crate::{input::ModifierMask, state::State};
|
||||
|
||||
pub mod libinput {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.input.libinput.v0alpha1");
|
||||
}
|
||||
}
|
||||
}
|
||||
use self::pinnacle::{
|
||||
input::{
|
||||
libinput::v0alpha1::SetLibinputSettingRequest,
|
||||
v0alpha1::{
|
||||
SetKeybindRequest, SetKeybindResponse, SetMousebindRequest, SetMousebindResponse,
|
||||
SetXkbConfigRequest, SetXkbRepeatRequest,
|
||||
},
|
||||
},
|
||||
v0alpha1::QuitRequest,
|
||||
};
|
||||
|
||||
pub mod output {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.output.v0alpha1");
|
||||
}
|
||||
}
|
||||
pub use pinnacle_api_defs::pinnacle;
|
||||
pub use pinnacle_api_defs::FILE_DESCRIPTOR_SET;
|
||||
|
||||
pub mod tag {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.tag.v0alpha1");
|
||||
}
|
||||
}
|
||||
type ResponseStream<T> = Pin<Box<dyn Stream<Item = Result<T, Status>> + Send>>;
|
||||
pub type StateFnSender = calloop::channel::Sender<Box<dyn FnOnce(&mut State) + Send>>;
|
||||
|
||||
pub mod window {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.window.v0alpha1");
|
||||
}
|
||||
pub struct PinnacleService {
|
||||
pub sender: StateFnSender,
|
||||
}
|
||||
|
||||
pub mod rules {
|
||||
pub mod v0alpha1 {
|
||||
tonic::include_proto!("pinnacle.window.rules.v0alpha1");
|
||||
}
|
||||
}
|
||||
#[tonic::async_trait]
|
||||
impl pinnacle::v0alpha1::pinnacle_service_server::PinnacleService for PinnacleService {
|
||||
async fn quit(
|
||||
&self,
|
||||
_request: tonic::Request<QuitRequest>,
|
||||
) -> Result<tonic::Response<()>, tonic::Status> {
|
||||
tracing::trace!("PinnacleService.quit");
|
||||
let f = Box::new(|state: &mut State| {
|
||||
state.loop_signal.stop();
|
||||
});
|
||||
// Expect is ok here, if it panics then the state was dropped beforehand
|
||||
self.sender.send(f).expect("failed to send f");
|
||||
|
||||
Ok(tonic::Response::new(()))
|
||||
}
|
||||
}
|
||||
|
||||
pub const FILE_DESCRIPTOR_SET: &[u8] = tonic::include_file_descriptor_set!("pinnacle");
|
||||
pub struct InputService {
|
||||
pub sender: StateFnSender,
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl pinnacle::input::v0alpha1::input_service_server::InputService for InputService {
|
||||
type SetKeybindStream = ResponseStream<SetKeybindResponse>;
|
||||
type SetMousebindStream = ResponseStream<SetMousebindResponse>;
|
||||
|
||||
async fn set_keybind(
|
||||
&self,
|
||||
request: tonic::Request<SetKeybindRequest>,
|
||||
) -> Result<Response<Self::SetKeybindStream>, Status> {
|
||||
let request = request.into_inner();
|
||||
|
||||
tracing::debug!(request = ?request);
|
||||
|
||||
let modifiers = request
|
||||
.modifiers()
|
||||
.fold(ModifierMask::empty(), |acc, modifier| match modifier {
|
||||
pinnacle::input::v0alpha1::Modifier::Unspecified => acc,
|
||||
pinnacle::input::v0alpha1::Modifier::Shift => acc | ModifierMask::SHIFT,
|
||||
pinnacle::input::v0alpha1::Modifier::Ctrl => acc | ModifierMask::CTRL,
|
||||
pinnacle::input::v0alpha1::Modifier::Alt => acc | ModifierMask::ALT,
|
||||
pinnacle::input::v0alpha1::Modifier::Super => acc | ModifierMask::SUPER,
|
||||
});
|
||||
let key = request
|
||||
.key
|
||||
.ok_or_else(|| Status::invalid_argument("no key specified"))?;
|
||||
|
||||
use pinnacle::input::v0alpha1::set_keybind_request::Key;
|
||||
let keysym = match key {
|
||||
Key::RawCode(num) => {
|
||||
tracing::info!("set keybind: {:?}, raw {}", modifiers, num);
|
||||
xkbcommon::xkb::Keysym::new(num)
|
||||
}
|
||||
Key::XkbName(s) => {
|
||||
if s.chars().count() == 1 {
|
||||
let Some(ch) = s.chars().next() else { unreachable!() };
|
||||
let keysym = xkbcommon::xkb::Keysym::from_char(ch);
|
||||
tracing::info!("set keybind: {:?}, {:?}", modifiers, keysym);
|
||||
keysym
|
||||
} else {
|
||||
let keysym =
|
||||
xkbcommon::xkb::keysym_from_name(&s, xkbcommon::xkb::KEYSYM_NO_FLAGS);
|
||||
tracing::info!("set keybind: {:?}, {:?}", modifiers, keysym);
|
||||
keysym
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let (sender, receiver) = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
self.sender
|
||||
.send(Box::new(move |state| {
|
||||
state
|
||||
.input_state
|
||||
.grpc_keybinds
|
||||
.insert((modifiers, keysym), sender);
|
||||
}))
|
||||
.map_err(|_| Status::internal("internal state was not running"))?;
|
||||
|
||||
let receiver_stream = tokio_stream::wrappers::UnboundedReceiverStream::new(receiver);
|
||||
|
||||
Ok(Response::new(
|
||||
Box::pin(receiver_stream) as Self::SetKeybindStream
|
||||
))
|
||||
}
|
||||
|
||||
async fn set_mousebind(
|
||||
&self,
|
||||
request: tonic::Request<SetMousebindRequest>,
|
||||
) -> Result<Response<Self::SetMousebindStream>, Status> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_xkb_config(
|
||||
&self,
|
||||
request: tonic::Request<SetXkbConfigRequest>,
|
||||
) -> Result<Response<()>, Status> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_xkb_repeat(
|
||||
&self,
|
||||
request: tonic::Request<SetXkbRepeatRequest>,
|
||||
) -> Result<Response<()>, Status> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn set_libinput_setting(
|
||||
&self,
|
||||
request: tonic::Request<SetLibinputSettingRequest>,
|
||||
) -> Result<Response<()>, Status> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
55
src/input.rs
55
src/input.rs
|
@ -5,11 +5,12 @@ pub mod libinput;
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::{
|
||||
api::msg::{CallbackId, Modifier, ModifierMask, MouseEdge, OutgoingMsg},
|
||||
api::msg::{CallbackId, Modifier, MouseEdge, OutgoingMsg},
|
||||
focus::FocusTarget,
|
||||
state::WithState,
|
||||
window::WindowElement,
|
||||
};
|
||||
use pinnacle_api_defs::pinnacle::input::v0alpha1::SetKeybindResponse;
|
||||
use smithay::{
|
||||
backend::input::{
|
||||
AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent,
|
||||
|
@ -24,24 +25,38 @@ use smithay::{
|
|||
utils::{Logical, Point, SERIAL_COUNTER},
|
||||
wayland::{seat::WaylandFocus, shell::wlr_layer},
|
||||
};
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
use xkbcommon::xkb::Keysym;
|
||||
|
||||
use crate::state::State;
|
||||
|
||||
use self::libinput::LibinputSetting;
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Debug, Hash, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct ModifierMask: u8 {
|
||||
const SHIFT = 1;
|
||||
const CTRL = 1 << 1;
|
||||
const ALT = 1 << 2;
|
||||
const SUPER = 1 << 3;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct InputState {
|
||||
/// A hashmap of modifier keys and keycodes to callback IDs
|
||||
pub keybinds: HashMap<(ModifierMask, Keysym), CallbackId>,
|
||||
pub keybinds: HashMap<(crate::api::msg::ModifierMask, Keysym), CallbackId>,
|
||||
/// A hashmap of modifier keys and mouse button codes to callback IDs
|
||||
pub mousebinds: HashMap<(ModifierMask, u32, MouseEdge), CallbackId>,
|
||||
pub reload_keybind: Option<(ModifierMask, Keysym)>,
|
||||
pub kill_keybind: Option<(ModifierMask, Keysym)>,
|
||||
pub mousebinds: HashMap<(crate::api::msg::ModifierMask, u32, MouseEdge), CallbackId>,
|
||||
pub reload_keybind: Option<(crate::api::msg::ModifierMask, Keysym)>,
|
||||
pub kill_keybind: Option<(crate::api::msg::ModifierMask, Keysym)>,
|
||||
/// User defined libinput settings that will be applied
|
||||
pub libinput_settings: Vec<LibinputSetting>,
|
||||
/// All libinput devices that have been connected
|
||||
pub libinput_devices: Vec<input::Device>,
|
||||
|
||||
pub grpc_keybinds:
|
||||
HashMap<(ModifierMask, Keysym), UnboundedSender<Result<SetKeybindResponse, tonic::Status>>>,
|
||||
}
|
||||
|
||||
impl InputState {
|
||||
|
@ -54,6 +69,7 @@ impl InputState {
|
|||
enum KeyAction {
|
||||
/// Call a callback from a config process
|
||||
CallCallback(CallbackId),
|
||||
CallGrpcCallback(ModifierMask, Keysym),
|
||||
Quit,
|
||||
SwitchVt(i32),
|
||||
ReloadConfig,
|
||||
|
@ -176,6 +192,7 @@ impl State {
|
|||
serial,
|
||||
time,
|
||||
|state, modifiers, keysym| {
|
||||
tracing::debug!(keysym = ?keysym, raw_keysyms = ?keysym.raw_syms(), modified_syms = ?keysym.modified_syms());
|
||||
if press_state == KeyState::Pressed {
|
||||
let mut modifier_mask = Vec::<Modifier>::new();
|
||||
if modifiers.alt {
|
||||
|
@ -190,11 +207,30 @@ impl State {
|
|||
if modifiers.logo {
|
||||
modifier_mask.push(Modifier::Super);
|
||||
}
|
||||
let modifier_mask = ModifierMask::from(modifier_mask);
|
||||
let modifier_mask = crate::api::msg::ModifierMask::from(modifier_mask);
|
||||
|
||||
let mut grpc_modifiers = ModifierMask::empty();
|
||||
if modifiers.alt {
|
||||
grpc_modifiers |= ModifierMask::ALT;
|
||||
}
|
||||
if modifiers.shift {
|
||||
grpc_modifiers |= ModifierMask::SHIFT;
|
||||
}
|
||||
if modifiers.ctrl {
|
||||
grpc_modifiers |= ModifierMask::CTRL;
|
||||
}
|
||||
if modifiers.logo {
|
||||
grpc_modifiers |= ModifierMask::SUPER;
|
||||
}
|
||||
|
||||
|
||||
let raw_sym = keysym.raw_syms().iter().next();
|
||||
let mod_sym = keysym.modified_sym();
|
||||
|
||||
if state.input_state.grpc_keybinds.get(&(grpc_modifiers, keysym.modified_sym())).is_some() {
|
||||
return FilterResult::Intercept(KeyAction::CallGrpcCallback(grpc_modifiers, keysym.modified_sym()));
|
||||
}
|
||||
|
||||
let cb_id_mod = state.input_state.keybinds.get(&(modifier_mask, mod_sym));
|
||||
|
||||
let cb_id_raw = raw_sym.and_then(|raw_sym| {
|
||||
|
@ -239,6 +275,11 @@ impl State {
|
|||
}
|
||||
}
|
||||
}
|
||||
Some(KeyAction::CallGrpcCallback(mods, keysym)) => {
|
||||
if let Some(sender) = self.input_state.grpc_keybinds.get(&(mods, keysym)) {
|
||||
let _ = sender.send(Ok(SetKeybindResponse {}));
|
||||
}
|
||||
}
|
||||
Some(KeyAction::SwitchVt(vt)) => {
|
||||
self.switch_vt(vt);
|
||||
}
|
||||
|
@ -270,7 +311,7 @@ impl State {
|
|||
ButtonState::Released => MouseEdge::Release,
|
||||
ButtonState::Pressed => MouseEdge::Press,
|
||||
};
|
||||
let modifier_mask = ModifierMask::from(keyboard.modifier_state());
|
||||
let modifier_mask = crate::api::msg::ModifierMask::from(keyboard.modifier_state());
|
||||
|
||||
// If any mousebinds are detected, call the config's callback and return.
|
||||
if let Some(&callback_id) =
|
||||
|
|
46
src/state.rs
46
src/state.rs
|
@ -3,7 +3,14 @@
|
|||
use std::{cell::RefCell, sync::Arc, time::Duration};
|
||||
|
||||
use crate::{
|
||||
api::{msg::Msg, ApiState},
|
||||
api::{
|
||||
msg::Msg,
|
||||
protocol::{
|
||||
pinnacle::v0alpha1::pinnacle_service_server::PinnacleServiceServer, InputService,
|
||||
PinnacleService,
|
||||
},
|
||||
ApiState,
|
||||
},
|
||||
backend::Backend,
|
||||
config::Config,
|
||||
cursor::Cursor,
|
||||
|
@ -11,6 +18,7 @@ use crate::{
|
|||
grab::resize_grab::ResizeSurfaceState,
|
||||
window::WindowElement,
|
||||
};
|
||||
use pinnacle_api_defs::pinnacle::input::v0alpha1::input_service_server::InputServiceServer;
|
||||
use smithay::{
|
||||
desktop::{PopupManager, Space},
|
||||
input::{keyboard::XkbConfig, pointer::CursorImageStatus, Seat, SeatState},
|
||||
|
@ -227,6 +235,42 @@ impl State {
|
|||
};
|
||||
tracing::debug!("xwayland set up");
|
||||
|
||||
let (grpc_sender, grpc_receiver) =
|
||||
calloop::channel::channel::<Box<dyn FnOnce(&mut Self) + Send>>();
|
||||
|
||||
loop_handle.insert_idle(|data| {
|
||||
data.state
|
||||
.loop_handle
|
||||
.insert_source(grpc_receiver, |msg, _, data| match msg {
|
||||
Event::Msg(f) => f(&mut data.state),
|
||||
Event::Closed => panic!("grpc receiver was closed"),
|
||||
})
|
||||
.expect("failed to insert grpc_receiver into loop");
|
||||
});
|
||||
|
||||
let pinnacle_service = PinnacleService {
|
||||
sender: grpc_sender.clone(),
|
||||
};
|
||||
let input_service = InputService {
|
||||
sender: grpc_sender.clone(),
|
||||
};
|
||||
|
||||
let refl_service = tonic_reflection::server::Builder::configure()
|
||||
.register_encoded_file_descriptor_set(crate::api::protocol::FILE_DESCRIPTOR_SET)
|
||||
.build()?;
|
||||
|
||||
let addr = "127.0.0.1:8080".parse()?;
|
||||
|
||||
tokio::spawn(async move {
|
||||
tonic::transport::Server::builder()
|
||||
.add_service(refl_service)
|
||||
.add_service(PinnacleServiceServer::new(pinnacle_service))
|
||||
.add_service(InputServiceServer::new(input_service))
|
||||
.serve(addr)
|
||||
.await
|
||||
.expect("failed to serve grpc");
|
||||
});
|
||||
|
||||
Ok(Self {
|
||||
backend,
|
||||
loop_signal,
|
||||
|
|
Loading…
Add table
Reference in a new issue