unfettered-keyboard/src/ufkbd_gnome.rs
Richard Acayan b378240a38 wayland: ignore errors when reading socket
On Phosh, the EWOULDBLOCK error may be emitted when reading from the
Wayland socket, which is not fatal. Ignore errors encountered while
reading, as fatal errors would be emitted by other operations in the
main loop.
2024-07-30 17:27:44 -04:00

100 lines
2.7 KiB
Rust

// SPDX-License-Identifier: GPL-3.0-only
/*
* Copyright (c) 2024, Richard Acayan. All rights reserved.
*/
mod core;
mod dbus;
mod wayland;
use crate::core::Layout;
use crate::dbus::session;
use crate::dbus::osk::OSK0;
use crate::wayland::Dispatcher;
use polling::Event;
use polling::Events;
use polling::Poller;
use std::future::pending;
use std::path::Path;
use std::sync::Arc;
use std::time::Instant;
use tokio::task;
use wayland_client::globals;
use zbus::InterfaceRef;
pub struct VisibilityManager(InterfaceRef<OSK0<Dispatcher>>);
impl VisibilityManager {
pub fn set_visible(&self, visible: bool)
{
let osk = self.0.clone();
task::spawn(async move {
let osk = osk.get().await;
osk.set_visible(visible).await;
});
}
}
#[tokio::main(flavor = "current_thread")]
async fn main()
{
let conn_wl = wayland_client::Connection::connect_to_env().unwrap();
let (globals, mut queue) = globals::registry_queue_init::<Dispatcher>(&conn_wl)
.expect("Registry required");
let layouts = Path::new("/usr/share/unfettered-keyboard/layouts");
let layout = Layout::load(layouts, "latn_qwerty_us.xml")
.expect("Layout should be loadable");
let mut dispatcher = Dispatcher::new(layout, queue.handle(), &globals).unwrap();
let wl_evt = Event::readable(0);
let conn_zbus = zbus::Connection::session().await.unwrap();
let res = session::register(&conn_zbus).await;
if let Err(e) = res {
eprintln!("warn: GNOME session registration failed: {}", e);
}
let conn_wl = Arc::new(conn_wl);
let gfx = dispatcher.graphics();
let osk = OSK0::start(&conn_zbus, gfx, conn_wl.clone()).await;
match osk {
Ok(k) => dispatcher.set_osk(VisibilityManager(k)),
Err(e) => eprintln!("warn: bind to sm.puri.OSK0 failed: {}", e),
}
let mut events = Events::new();
let poller = Poller::new().unwrap();
task::spawn_blocking(move || {
loop {
conn_wl.flush().unwrap();
let guard = queue.prepare_read().unwrap();
let fd = guard.connection_fd();
let timer = dispatcher.button().next_time().map(|t| t - Instant::now());
unsafe {
poller.add(&fd, wl_evt).unwrap();
}
events.clear();
poller.wait(&mut events, timer).unwrap();
poller.delete(fd).unwrap();
if !events.is_empty() {
// This may still emit EWOULDBLOCK errors.
let _ = guard.read();
queue.dispatch_pending(&mut dispatcher).unwrap();
}
dispatcher.dispatch_timers();
}
});
pending::<()>().await;
}