Initial import. Most things seem working.
This includes an abortive attempt to do a gtk4 dialog (which I don't think is possible, as gtk4 doesn't allow embedding toplevels anymore), and an iced dialog, which I just never started writing.
This commit is contained in:
13
async-xcb/Cargo.toml
Normal file
13
async-xcb/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "async-xcb"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
async-io = "1.6"
|
||||
async-std = { version = "1.11", features = ["attributes"] }
|
||||
futures = "0.3"
|
||||
futures-lite = "1.12"
|
||||
nix = "0.23"
|
||||
# git source needed until extension event error resolution fix is released
|
||||
xcb = { git = "https://github.com/rust-x-bindings/rust-xcb", rev = "d09b5f91bc07d56673f1bc0d6c7ecd72b5ff7b3e" }
|
49
async-xcb/src/lib.rs
Normal file
49
async-xcb/src/lib.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use async_io::{Async, ReadableOwned};
|
||||
use futures::prelude::*;
|
||||
use futures_lite::ready;
|
||||
use nix::{fcntl::{fcntl, F_GETFL, F_SETFL, OFlag}, unistd::read};
|
||||
use std::{io, os::unix::io::AsRawFd, pin::Pin, sync::Arc, task::{Context, Poll}};
|
||||
|
||||
pub struct AsyncConnection {
|
||||
conn: Arc<Async<xcb::Connection>>,
|
||||
readable: Option<ReadableOwned<xcb::Connection>>,
|
||||
}
|
||||
|
||||
impl AsyncConnection {
|
||||
pub fn new(conn: xcb::Connection) -> io::Result<Self> {
|
||||
let flags = fcntl(conn.as_raw_fd(), F_GETFL)?;
|
||||
fcntl(conn.as_raw_fd(), F_SETFL(OFlag::from_bits_truncate(flags) | OFlag::O_NONBLOCK))?;
|
||||
Ok(Self {
|
||||
conn: Arc::new(Async::new(conn)?),
|
||||
readable: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncRead for AsyncConnection {
|
||||
fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<std::io::Result<usize>> {
|
||||
loop {
|
||||
match read(self.conn.as_raw_fd(), buf) {
|
||||
Err(nix::Error::EAGAIN) => (),
|
||||
Err(err) => {
|
||||
self.readable = None;
|
||||
return Poll::Ready(Err(err.into()));
|
||||
},
|
||||
Ok(count) => {
|
||||
self.readable = None;
|
||||
return Poll::Ready(Ok(count));
|
||||
}
|
||||
}
|
||||
|
||||
if self.readable.is_none() {
|
||||
self.readable = Some(Arc::clone(&self.conn).readable_owned());
|
||||
}
|
||||
|
||||
if let Some(f) = &mut self.readable {
|
||||
let res = ready!(Pin::new(f).poll(cx));
|
||||
self.readable = None;
|
||||
res?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user