-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: introduce `IdleManager` & `IdleNotifier` * refactor: encapsulate `event_queue` dispatching * refactor: rename `update_timeout` to `reset_timeout` * feat: enable idle and encapsulate some code * refactor: apply cargo clippy suggestions * refactor: parse `IdleThreshold` as human readable string; add idle notifier logs * chore(docs): document the `idle_threshold` property * refactor: change `idle_threshold` disable value to `"none"` --------- Co-authored-by: Pavel <work.belyavsky.p.a@gmail.com>
- Loading branch information
Showing
13 changed files
with
310 additions
and
42 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use wayland_client::EventQueue; | ||
|
||
pub trait Dispatcher { | ||
type State; | ||
|
||
fn get_event_queue_and_state( | ||
&mut self, | ||
) -> Option<(&mut EventQueue<Self::State>, &mut Self::State)>; | ||
|
||
fn dispatch(&mut self) -> anyhow::Result<bool> { | ||
let (event_queue, state) = match self.get_event_queue_and_state() { | ||
Some(queue) => queue, | ||
None => return Ok(false), | ||
}; | ||
|
||
let dispatched_count = event_queue.dispatch_pending(state)?; | ||
|
||
if dispatched_count > 0 { | ||
return Ok(true); | ||
} | ||
|
||
event_queue.flush()?; | ||
let Some(guard) = event_queue.prepare_read() else { | ||
return Ok(false); | ||
}; | ||
let Ok(count) = guard.read() else { | ||
return Ok(false); | ||
}; | ||
|
||
Ok(if count > 0 { | ||
event_queue.dispatch_pending(state)?; | ||
true | ||
} else { | ||
false | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use crate::{ | ||
dispatcher::Dispatcher, | ||
idle_notifier::{IdleNotifier, IdleState}, | ||
}; | ||
use config::Config; | ||
use log::debug; | ||
use wayland_client::{Connection, EventQueue}; | ||
|
||
pub struct IdleManager { | ||
pub event_queue: Option<EventQueue<IdleNotifier>>, | ||
pub idle_notifier: Option<IdleNotifier>, | ||
} | ||
|
||
impl Dispatcher for IdleManager { | ||
type State = IdleNotifier; | ||
|
||
fn get_event_queue_and_state( | ||
&mut self, | ||
) -> Option<(&mut EventQueue<Self::State>, &mut Self::State)> { | ||
Some((self.event_queue.as_mut()?, self.idle_notifier.as_mut()?)) | ||
} | ||
} | ||
|
||
impl IdleManager { | ||
pub(crate) fn init(config: &Config) -> anyhow::Result<Self> { | ||
let connection = Connection::connect_to_env()?; | ||
let event_queue = connection.new_event_queue(); | ||
let qhandle = event_queue.handle(); | ||
let display = connection.display(); | ||
|
||
display.get_registry(&qhandle, ()); | ||
|
||
let idle_notifier = IdleNotifier::init(config)?; | ||
|
||
let idle_manager = Self { | ||
event_queue: Some(event_queue), | ||
idle_notifier: Some(idle_notifier), | ||
}; | ||
debug!("Idle Manager: Initialized"); | ||
|
||
Ok(idle_manager) | ||
} | ||
|
||
pub(crate) fn get_idle_state(&self) -> Option<&IdleState> { | ||
self.idle_notifier | ||
.as_ref() | ||
.and_then(IdleNotifier::get_idle_state) | ||
} | ||
|
||
pub(crate) fn blocking_dispatch(&mut self) -> anyhow::Result<()> { | ||
if let Some(event_queue) = self.event_queue.as_mut() { | ||
event_queue.blocking_dispatch(self.idle_notifier.as_mut().unwrap())?; | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use config::Config; | ||
use log::debug; | ||
use wayland_client::{ | ||
delegate_noop, | ||
protocol::{ | ||
wl_registry, | ||
wl_seat::{self, WlSeat}, | ||
}, | ||
Dispatch, | ||
}; | ||
use wayland_protocols::ext::idle_notify::v1::client::{ | ||
ext_idle_notification_v1::{self, ExtIdleNotificationV1}, | ||
ext_idle_notifier_v1::ExtIdleNotifierV1, | ||
}; | ||
|
||
pub struct IdleNotifier { | ||
seat: Option<WlSeat>, | ||
threshold: u32, | ||
idle_state: Option<IdleState>, | ||
} | ||
|
||
pub enum IdleState { | ||
Idled, | ||
Resumed, | ||
} | ||
|
||
impl IdleNotifier { | ||
pub(crate) fn init(config: &Config) -> anyhow::Result<Self> { | ||
let threshold = config.general().idle_threshold.duration; | ||
let idle_notifier = Self { | ||
seat: None, | ||
idle_state: None, | ||
threshold, | ||
}; | ||
debug!("Idle Notifier: Initialized"); | ||
Ok(idle_notifier) | ||
} | ||
|
||
pub(crate) fn get_idle_state(&self) -> Option<&IdleState> { | ||
self.idle_state.as_ref() | ||
} | ||
} | ||
|
||
impl Dispatch<wl_registry::WlRegistry, ()> for IdleNotifier { | ||
fn event( | ||
state: &mut Self, | ||
registry: &wl_registry::WlRegistry, | ||
event: <wl_registry::WlRegistry as wayland_client::Proxy>::Event, | ||
_data: &(), | ||
_conn: &wayland_client::Connection, | ||
qhandle: &wayland_client::QueueHandle<Self>, | ||
) { | ||
if let wl_registry::Event::Global { | ||
name, | ||
interface, | ||
version, | ||
} = event | ||
{ | ||
match interface.as_ref() { | ||
"wl_seat" => { | ||
state.seat = | ||
Some(registry.bind::<wl_seat::WlSeat, _, _>(name, version, qhandle, ())); | ||
debug!("Idle Notifier: Bound the wl_seat"); | ||
} | ||
"ext_idle_notifier_v1" => { | ||
if state.threshold == 0 { | ||
return; | ||
} | ||
|
||
let idle_notifier = | ||
registry.bind::<ExtIdleNotifierV1, _, _>(name, version, qhandle, ()); | ||
debug!("Idle Notifier: Bound the ext_idle_notifier_v1"); | ||
|
||
if let Some(seat) = state.seat.as_ref() { | ||
idle_notifier.get_idle_notification(state.threshold, seat, qhandle, ()); | ||
} | ||
} | ||
_ => (), | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl Dispatch<ExtIdleNotificationV1, ()> for IdleNotifier { | ||
fn event( | ||
state: &mut Self, | ||
_idle_notification: &ext_idle_notification_v1::ExtIdleNotificationV1, | ||
event: <ext_idle_notification_v1::ExtIdleNotificationV1 as wayland_client::Proxy>::Event, | ||
_data: &(), | ||
_conn: &wayland_client::Connection, | ||
_qhandle: &wayland_client::QueueHandle<Self>, | ||
) { | ||
match event { | ||
ext_idle_notification_v1::Event::Idled => { | ||
state.idle_state = Some(IdleState::Idled); | ||
debug!("Idle Notifier: Idled"); | ||
} | ||
ext_idle_notification_v1::Event::Resumed => { | ||
state.idle_state = Some(IdleState::Resumed); | ||
debug!("Idle Notifier: Resumed"); | ||
} | ||
_ => (), | ||
} | ||
} | ||
} | ||
|
||
delegate_noop!(IdleNotifier: ignore WlSeat); | ||
delegate_noop!(IdleNotifier: ignore ExtIdleNotifierV1); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.