Stop threading the xcb connection everywhere
Easier to just store a reference to it in the structs.
This commit is contained in:
parent
761b906fb7
commit
8657bc249c
@ -81,23 +81,23 @@ fn main() -> anyhow::Result<()> {
|
|||||||
let subservices1 = Rc::clone(&subservices);
|
let subservices1 = Rc::clone(&subservices);
|
||||||
let subservices2 = Rc::clone(&subservices);
|
let subservices2 = Rc::clone(&subservices);
|
||||||
CommandHandlers {
|
CommandHandlers {
|
||||||
restart_handler: &move |screensaver, conn, trigger| {
|
restart_handler: &move |screensaver, trigger| {
|
||||||
restart_daemon(screensaver, &mut subservices1.lock().unwrap(), trigger.map(|t| (conn, t)))
|
restart_daemon(screensaver, &mut subservices1.lock().unwrap(), trigger)
|
||||||
},
|
},
|
||||||
exit_handler: &move |screensaver, conn, trigger| {
|
exit_handler: &move |screensaver, trigger| {
|
||||||
exit_daemon(screensaver, &mut subservices2.lock().unwrap(), trigger.map(|t| (conn, t)))
|
exit_daemon(screensaver, &mut subservices2.lock().unwrap(), trigger)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut screensaver = Screensaver::new(&config, &helper_dir, &command_handlers, &conn, screen)?;
|
let mut screensaver = Screensaver::new(&config, &helper_dir, &command_handlers, &conn, screen)?;
|
||||||
|
|
||||||
if args.is_present(LOCKED_ARG) {
|
if args.is_present(LOCKED_ARG) {
|
||||||
match screensaver.lock_screen(&conn) {
|
match screensaver.lock_screen() {
|
||||||
Err(err) => error!("POSSIBLY FAILED TO LOCK SCREEN ON STARTUP: {}", err),
|
Err(err) => error!("POSSIBLY FAILED TO LOCK SCREEN ON STARTUP: {}", err),
|
||||||
Ok(_) => debug!("Got --{} arg; screen locked on startup", LOCKED_ARG),
|
Ok(_) => debug!("Got --{} arg; screen locked on startup", LOCKED_ARG),
|
||||||
}
|
}
|
||||||
} else if args.is_present(BLANKED_ARG) {
|
} else if args.is_present(BLANKED_ARG) {
|
||||||
match screensaver.blank_screen(&conn) {
|
match screensaver.blank_screen() {
|
||||||
Err(err) => warn!("Possibly failed to blank screen on startup: {}", err),
|
Err(err) => warn!("Possibly failed to blank screen on startup: {}", err),
|
||||||
Ok(_) => debug!("Got --{} arg; screen locked on startup", BLANKED_ARG),
|
Ok(_) => debug!("Got --{} arg; screen locked on startup", BLANKED_ARG),
|
||||||
}
|
}
|
||||||
@ -112,10 +112,10 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Err(err) = screensaver.handle_xcb_events(&conn) {
|
if let Err(err) = screensaver.handle_xcb_events() {
|
||||||
if conn.has_error().is_err() {
|
if conn.has_error().is_err() {
|
||||||
error!("Lost connection to X server; attempting to restart");
|
error!("Lost connection to X server; attempting to restart");
|
||||||
(command_handlers.restart_handler)(&mut screensaver, &conn, None)?;
|
(command_handlers.restart_handler)(&mut screensaver, None)?;
|
||||||
}
|
}
|
||||||
warn!("Error handling event: {}", err);
|
warn!("Error handling event: {}", err);
|
||||||
}
|
}
|
||||||
@ -149,17 +149,17 @@ fn main() -> anyhow::Result<()> {
|
|||||||
if pfd.revents().filter(|pf| pf.contains(PollFlags::POLLIN)).is_some() {
|
if pfd.revents().filter(|pf| pf.contains(PollFlags::POLLIN)).is_some() {
|
||||||
let result = match pfd.as_raw_fd() {
|
let result = match pfd.as_raw_fd() {
|
||||||
fd if fd == signal_fd.as_raw_fd() => handle_signals(&mut screensaver, &mut subservices.lock().unwrap(), &mut signal_fd),
|
fd if fd == signal_fd.as_raw_fd() => handle_signals(&mut screensaver, &mut subservices.lock().unwrap(), &mut signal_fd),
|
||||||
fd if fd == conn.as_raw_fd() => screensaver.handle_xcb_events(&conn),
|
fd if fd == conn.as_raw_fd() => screensaver.handle_xcb_events(),
|
||||||
fd if opt_contains(&dbus_service_fd, &fd) => subservices.lock().unwrap().handle_quit(),
|
fd if opt_contains(&dbus_service_fd, &fd) => subservices.lock().unwrap().handle_quit(),
|
||||||
fd if opt_contains(&systemd_service_fd, &fd) => subservices.lock().unwrap().handle_quit(),
|
fd if opt_contains(&systemd_service_fd, &fd) => subservices.lock().unwrap().handle_quit(),
|
||||||
fd if opt_contains(&dialog_fd, &fd) => screensaver.handle_unlock_dialog_quit(&conn),
|
fd if opt_contains(&dialog_fd, &fd) => screensaver.handle_unlock_dialog_quit(),
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
if conn.has_error().is_err() {
|
if conn.has_error().is_err() {
|
||||||
error!("Lost connection to X server; atempting to restart");
|
error!("Lost connection to X server; atempting to restart");
|
||||||
(command_handlers.restart_handler)(&mut screensaver, &conn, None)?;
|
(command_handlers.restart_handler)(&mut screensaver, None)?;
|
||||||
}
|
}
|
||||||
warn!("Error handling event: {}", err);
|
warn!("Error handling event: {}", err);
|
||||||
}
|
}
|
||||||
@ -170,13 +170,13 @@ fn main() -> anyhow::Result<()> {
|
|||||||
let since_last_activity = Instant::now().duration_since(screensaver.last_user_activity());
|
let since_last_activity = Instant::now().duration_since(screensaver.last_user_activity());
|
||||||
|
|
||||||
if screensaver.blanker_state() < BlankerState::Blanked && since_last_activity > config.lock_timeout - config.blank_before_locking {
|
if screensaver.blanker_state() < BlankerState::Blanked && since_last_activity > config.lock_timeout - config.blank_before_locking {
|
||||||
if let Err(err) = screensaver.blank_screen(&conn) {
|
if let Err(err) = screensaver.blank_screen() {
|
||||||
error!("POSSIBLY FAILED TO BLANK SCREEN: {}", err);
|
error!("POSSIBLY FAILED TO BLANK SCREEN: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if screensaver.blanker_state() < BlankerState::Locked && since_last_activity > config.lock_timeout {
|
if screensaver.blanker_state() < BlankerState::Locked && since_last_activity > config.lock_timeout {
|
||||||
if let Err(err) = screensaver.lock_screen(&conn) {
|
if let Err(err) = screensaver.lock_screen() {
|
||||||
error!("POSSIBLY FAILED TO LOCK SCREEN: {}", err);
|
error!("POSSIBLY FAILED TO LOCK SCREEN: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ fn handle_signals(screensaver: &mut Screensaver, subservices: &mut Subservices,
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restart_daemon(screensaver: &mut Screensaver, subservices: &mut Subservices, trigger: Option<(&xcb::Connection, &x::ClientMessageEvent)>) -> anyhow::Result<()> {
|
fn restart_daemon(screensaver: &mut Screensaver, subservices: &mut Subservices, trigger: Option<&x::ClientMessageEvent>) -> anyhow::Result<()> {
|
||||||
info!("Restarting");
|
info!("Restarting");
|
||||||
|
|
||||||
let exe = read_link("/proc/self/exe")?;
|
let exe = read_link("/proc/self/exe")?;
|
||||||
@ -297,14 +297,14 @@ fn restart_daemon(screensaver: &mut Screensaver, subservices: &mut Subservices,
|
|||||||
match unsafe { fork() } {
|
match unsafe { fork() } {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to fork: {}", err);
|
error!("Failed to fork: {}", err);
|
||||||
if let Some((conn, ev)) = trigger {
|
if let Some(ev) = trigger {
|
||||||
bscreensaver::send_command_reply(conn, ev, false);
|
bscreensaver::send_command_reply(screensaver.xcb_connection(), ev, false);
|
||||||
}
|
}
|
||||||
Err(err)?;
|
Err(err)?;
|
||||||
},
|
},
|
||||||
Ok(ForkResult::Parent { .. }) => {
|
Ok(ForkResult::Parent { .. }) => {
|
||||||
if let Some((conn, ev)) = trigger {
|
if let Some(ev) = trigger {
|
||||||
bscreensaver::send_command_reply(conn, ev, true);
|
bscreensaver::send_command_reply(screensaver.xcb_connection(), ev, true);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
},
|
},
|
||||||
@ -319,11 +319,11 @@ fn restart_daemon(screensaver: &mut Screensaver, subservices: &mut Subservices,
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit_daemon(screensaver: &mut Screensaver, subservices: &mut Subservices, trigger: Option<(&xcb::Connection, &x::ClientMessageEvent)>) -> anyhow::Result<()> {
|
fn exit_daemon(screensaver: &mut Screensaver, subservices: &mut Subservices, trigger: Option<&x::ClientMessageEvent>) -> anyhow::Result<()> {
|
||||||
info!("Quitting");
|
info!("Quitting");
|
||||||
kill_child_processes(screensaver, subservices);
|
kill_child_processes(screensaver, subservices);
|
||||||
if let Some((conn, ev)) = trigger {
|
if let Some(ev) = trigger {
|
||||||
bscreensaver::send_command_reply(conn, ev, true);
|
bscreensaver::send_command_reply(screensaver.xcb_connection(), ev, true);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@ struct BacklightControl {
|
|||||||
step: u32,
|
step: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Monitor {
|
pub struct Monitor<'a> {
|
||||||
|
pub conn: &'a xcb::Connection,
|
||||||
pub root: x::Window,
|
pub root: x::Window,
|
||||||
pub black_gc: x::Gcontext,
|
pub black_gc: x::Gcontext,
|
||||||
pub output: randr::Output,
|
pub output: randr::Output,
|
||||||
@ -28,7 +29,7 @@ pub struct Monitor {
|
|||||||
backlight_control: Option<BacklightControl>,
|
backlight_control: Option<BacklightControl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Monitor {
|
impl<'a> Monitor<'a> {
|
||||||
pub fn set_up_all(conn: &xcb::Connection) -> xcb::Result<Vec<Monitor>> {
|
pub fn set_up_all(conn: &xcb::Connection) -> xcb::Result<Vec<Monitor>> {
|
||||||
let mut monitors = Vec::new();
|
let mut monitors = Vec::new();
|
||||||
for screen in conn.get_setup().roots() {
|
for screen in conn.get_setup().roots() {
|
||||||
@ -57,7 +58,7 @@ impl Monitor {
|
|||||||
Ok(monitors)
|
Ok(monitors)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(conn: &xcb::Connection, screen: &x::Screen, output: randr::Output, crtc_info: &randr::GetCrtcInfoReply) -> xcb::Result<Monitor> {
|
pub fn new(conn: &'a xcb::Connection, screen: &x::Screen, output: randr::Output, crtc_info: &randr::GetCrtcInfoReply) -> xcb::Result<Monitor<'a>> {
|
||||||
let (blanker_window, unlock_window) = create_windows(conn, &screen, &crtc_info)?;
|
let (blanker_window, unlock_window) = create_windows(conn, &screen, &crtc_info)?;
|
||||||
let blank_cursor = create_blank_cursor(conn, &screen)?;
|
let blank_cursor = create_blank_cursor(conn, &screen)?;
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(Monitor {
|
Ok(Monitor {
|
||||||
|
conn,
|
||||||
root: screen.root(),
|
root: screen.root(),
|
||||||
black_gc,
|
black_gc,
|
||||||
output,
|
output,
|
||||||
@ -91,13 +93,6 @@ impl Monitor {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn release(self, conn: &xcb::Connection) {
|
|
||||||
let _ = destroy_cursor(conn, self.blank_cursor);
|
|
||||||
let _ = destroy_window(&conn, self.unlock_window);
|
|
||||||
let _ = destroy_window(&conn, self.blanker_window);
|
|
||||||
let _ = destroy_gc(&conn, self.black_gc);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn geometry(&self) -> x::Rectangle {
|
pub fn geometry(&self) -> x::Rectangle {
|
||||||
x::Rectangle {
|
x::Rectangle {
|
||||||
x: self.x,
|
x: self.x,
|
||||||
@ -107,67 +102,67 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blank(&self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn blank(&self) -> anyhow::Result<()> {
|
||||||
let mut cookies = Vec::new();
|
let mut cookies = Vec::new();
|
||||||
cookies.push(conn.send_request_checked(&x::ConfigureWindow {
|
cookies.push(self.conn.send_request_checked(&x::ConfigureWindow {
|
||||||
window: self.blanker_window,
|
window: self.blanker_window,
|
||||||
value_list: &[
|
value_list: &[
|
||||||
x::ConfigWindow::StackMode(x::StackMode::Above),
|
x::ConfigWindow::StackMode(x::StackMode::Above),
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
cookies.push(conn.send_request_checked(&x::MapWindow {
|
cookies.push(self.conn.send_request_checked(&x::MapWindow {
|
||||||
window: self.blanker_window,
|
window: self.blanker_window,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for cookie in cookies {
|
for cookie in cookies {
|
||||||
conn.check_request(cookie)?;
|
self.conn.check_request(cookie)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.hide_cursor(conn);
|
self.hide_cursor();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unblank(&self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn unblank(&self) -> anyhow::Result<()> {
|
||||||
self.show_cursor(conn);
|
self.show_cursor();
|
||||||
|
|
||||||
conn.send_and_check_request(&x::UnmapWindow {
|
self.conn.send_and_check_request(&x::UnmapWindow {
|
||||||
window: self.blanker_window,
|
window: self.blanker_window,
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lock(&self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn lock(&self) -> anyhow::Result<()> {
|
||||||
let mut cookies = Vec::new();
|
let mut cookies = Vec::new();
|
||||||
|
|
||||||
cookies.push(conn.send_request_checked(&x::ConfigureWindow {
|
cookies.push(self.conn.send_request_checked(&x::ConfigureWindow {
|
||||||
window: self.unlock_window,
|
window: self.unlock_window,
|
||||||
value_list: &[
|
value_list: &[
|
||||||
x::ConfigWindow::StackMode(x::StackMode::Above),
|
x::ConfigWindow::StackMode(x::StackMode::Above),
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
cookies.push(conn.send_request_checked(&x::MapWindow {
|
cookies.push(self.conn.send_request_checked(&x::MapWindow {
|
||||||
window: self.unlock_window,
|
window: self.unlock_window,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for cookie in cookies {
|
for cookie in cookies {
|
||||||
conn.check_request(cookie)?;
|
self.conn.check_request(cookie)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cookie = conn.send_request(&x::GrabKeyboard {
|
let cookie = self.conn.send_request(&x::GrabKeyboard {
|
||||||
owner_events: true,
|
owner_events: true,
|
||||||
grab_window: self.unlock_window,
|
grab_window: self.unlock_window,
|
||||||
time: x::CURRENT_TIME,
|
time: x::CURRENT_TIME,
|
||||||
pointer_mode: x::GrabMode::Async,
|
pointer_mode: x::GrabMode::Async,
|
||||||
keyboard_mode: x::GrabMode::Async,
|
keyboard_mode: x::GrabMode::Async,
|
||||||
});
|
});
|
||||||
let reply = conn.wait_for_reply(cookie)?;
|
let reply = self.conn.wait_for_reply(cookie)?;
|
||||||
if reply.status() != x::GrabStatus::Success {
|
if reply.status() != x::GrabStatus::Success {
|
||||||
// FIXME: try to grab later?
|
// FIXME: try to grab later?
|
||||||
warn!("Failed to grab keyboard on window {:?}: {:?}", self.blanker_window, reply.status());
|
warn!("Failed to grab keyboard on window {:?}: {:?}", self.blanker_window, reply.status());
|
||||||
}
|
}
|
||||||
|
|
||||||
let cookie = conn.send_request(&x::GrabPointer {
|
let cookie = self.conn.send_request(&x::GrabPointer {
|
||||||
owner_events: true,
|
owner_events: true,
|
||||||
grab_window: self.unlock_window,
|
grab_window: self.unlock_window,
|
||||||
event_mask: x::EventMask::BUTTON_PRESS | x::EventMask::BUTTON_RELEASE | x::EventMask::POINTER_MOTION | x::EventMask::POINTER_MOTION_HINT,
|
event_mask: x::EventMask::BUTTON_PRESS | x::EventMask::BUTTON_RELEASE | x::EventMask::POINTER_MOTION | x::EventMask::POINTER_MOTION_HINT,
|
||||||
@ -177,7 +172,7 @@ impl Monitor {
|
|||||||
cursor: x::CURSOR_NONE,
|
cursor: x::CURSOR_NONE,
|
||||||
time: x::CURRENT_TIME,
|
time: x::CURRENT_TIME,
|
||||||
});
|
});
|
||||||
let reply = conn.wait_for_reply(cookie)?;
|
let reply = self.conn.wait_for_reply(cookie)?;
|
||||||
if reply.status() != x::GrabStatus::Success {
|
if reply.status() != x::GrabStatus::Success {
|
||||||
// FIXME: try to grab later?
|
// FIXME: try to grab later?
|
||||||
warn!("Failed to grab pointer on window {:?}: {:?}", self.blanker_window, reply.status());
|
warn!("Failed to grab pointer on window {:?}: {:?}", self.blanker_window, reply.status());
|
||||||
@ -186,27 +181,27 @@ impl Monitor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unlock(&self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn unlock(&self) -> anyhow::Result<()> {
|
||||||
let mut cookies = Vec::new();
|
let mut cookies = Vec::new();
|
||||||
|
|
||||||
cookies.push(conn.send_request_checked(&x::UngrabKeyboard {
|
cookies.push(self.conn.send_request_checked(&x::UngrabKeyboard {
|
||||||
time: x::CURRENT_TIME,
|
time: x::CURRENT_TIME,
|
||||||
}));
|
}));
|
||||||
cookies.push(conn.send_request_checked(&x::UngrabPointer {
|
cookies.push(self.conn.send_request_checked(&x::UngrabPointer {
|
||||||
time: x::CURRENT_TIME,
|
time: x::CURRENT_TIME,
|
||||||
}));
|
}));
|
||||||
cookies.push(conn.send_request_checked(&x::UnmapWindow {
|
cookies.push(self.conn.send_request_checked(&x::UnmapWindow {
|
||||||
window: self.unlock_window,
|
window: self.unlock_window,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
for cookie in cookies {
|
for cookie in cookies {
|
||||||
conn.check_request(cookie)?;
|
self.conn.check_request(cookie)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_cursor(&self, conn: &xcb::Connection) {
|
pub fn show_cursor(&self) {
|
||||||
if let Err(err) = conn.send_and_check_request(&x::ChangeWindowAttributes {
|
if let Err(err) = self.conn.send_and_check_request(&x::ChangeWindowAttributes {
|
||||||
window: self.blanker_window,
|
window: self.blanker_window,
|
||||||
value_list: &[
|
value_list: &[
|
||||||
x::Cw::Cursor(x::CURSOR_NONE),
|
x::Cw::Cursor(x::CURSOR_NONE),
|
||||||
@ -216,8 +211,8 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hide_cursor(&self, conn: &xcb::Connection) {
|
pub fn hide_cursor(&self) {
|
||||||
if let Err(err) = conn.send_and_check_request(&x::ChangeWindowAttributes {
|
if let Err(err) = self.conn.send_and_check_request(&x::ChangeWindowAttributes {
|
||||||
window: self.blanker_window,
|
window: self.blanker_window,
|
||||||
value_list: &[
|
value_list: &[
|
||||||
x::Cw::Cursor(self.blank_cursor),
|
x::Cw::Cursor(self.blank_cursor),
|
||||||
@ -227,30 +222,30 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn brightness_up(&self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn brightness_up(&self) -> anyhow::Result<()> {
|
||||||
self.brightness_change(conn, |backlight_control, cur_brightness| cur_brightness as i32 + backlight_control.step as i32)
|
self.brightness_change(|backlight_control, cur_brightness| cur_brightness as i32 + backlight_control.step as i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn brightness_down(&self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn brightness_down(&self) -> anyhow::Result<()> {
|
||||||
self.brightness_change(conn, |backlight_control, cur_brightness| cur_brightness as i32 - backlight_control.step as i32)
|
self.brightness_change(|backlight_control, cur_brightness| cur_brightness as i32 - backlight_control.step as i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn brightness_change<F: FnOnce(&BacklightControl, u32) -> i32>(&self, conn: &xcb::Connection, updater: F) -> anyhow::Result<()> {
|
fn brightness_change<F: FnOnce(&BacklightControl, u32) -> i32>(&self, updater: F) -> anyhow::Result<()> {
|
||||||
if let Some(backlight_control) = &self.backlight_control {
|
if let Some(backlight_control) = &self.backlight_control {
|
||||||
if let Ok(Some(cur_brightness)) = self.get_current_brightness(conn, &backlight_control) {
|
if let Ok(Some(cur_brightness)) = self.get_current_brightness(&backlight_control) {
|
||||||
let new_level = updater(&backlight_control, cur_brightness);
|
let new_level = updater(&backlight_control, cur_brightness);
|
||||||
let new_level = cmp::min(backlight_control.max_level, new_level);
|
let new_level = cmp::min(backlight_control.max_level, new_level);
|
||||||
let new_level = cmp::max(backlight_control.min_level, new_level);
|
let new_level = cmp::max(backlight_control.min_level, new_level);
|
||||||
if new_level != cur_brightness as i32 {
|
if new_level != cur_brightness as i32 {
|
||||||
self.set_brightness(conn, &backlight_control, new_level)?;
|
self.set_brightness(&backlight_control, new_level)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_current_brightness(&self, conn: &xcb::Connection, backlight_control: &BacklightControl) -> anyhow::Result<Option<u32>> {
|
fn get_current_brightness(&self, backlight_control: &BacklightControl) -> anyhow::Result<Option<u32>> {
|
||||||
let cookie = conn.send_request(&randr::GetOutputProperty {
|
let cookie = self.conn.send_request(&randr::GetOutputProperty {
|
||||||
output: self.output,
|
output: self.output,
|
||||||
property: backlight_control.property,
|
property: backlight_control.property,
|
||||||
r#type: x::ATOM_INTEGER,
|
r#type: x::ATOM_INTEGER,
|
||||||
@ -259,7 +254,7 @@ impl Monitor {
|
|||||||
delete: false,
|
delete: false,
|
||||||
pending: false,
|
pending: false,
|
||||||
});
|
});
|
||||||
let reply = conn.wait_for_reply(cookie)?;
|
let reply = self.conn.wait_for_reply(cookie)?;
|
||||||
let data = reply.data::<u32>();
|
let data = reply.data::<u32>();
|
||||||
if data.len() == 1 {
|
if data.len() == 1 {
|
||||||
Ok(Some(data[0]))
|
Ok(Some(data[0]))
|
||||||
@ -268,8 +263,8 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_brightness(&self, conn: &xcb::Connection, backlight_control: &BacklightControl, level: i32) -> anyhow::Result<()> {
|
fn set_brightness(&self, backlight_control: &BacklightControl, level: i32) -> anyhow::Result<()> {
|
||||||
conn.send_and_check_request(&randr::ChangeOutputProperty {
|
self.conn.send_and_check_request(&randr::ChangeOutputProperty {
|
||||||
output: self.output,
|
output: self.output,
|
||||||
property: backlight_control.property,
|
property: backlight_control.property,
|
||||||
r#type: x::ATOM_INTEGER,
|
r#type: x::ATOM_INTEGER,
|
||||||
@ -280,6 +275,15 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for Monitor<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = destroy_cursor(self.conn, self.blank_cursor);
|
||||||
|
let _ = destroy_window(self.conn, self.unlock_window);
|
||||||
|
let _ = destroy_window(self.conn, self.blanker_window);
|
||||||
|
let _ = destroy_gc(self.conn, self.black_gc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn create_windows(conn: &xcb::Connection, screen: &x::Screen, crtc_info: &randr::GetCrtcInfoReply) -> xcb::Result<(x::Window, x::Window)> {
|
fn create_windows(conn: &xcb::Connection, screen: &x::Screen, crtc_info: &randr::GetCrtcInfoReply) -> xcb::Result<(x::Window, x::Window)> {
|
||||||
let blanker_window: x::Window = conn.generate_id();
|
let blanker_window: x::Window = conn.generate_id();
|
||||||
let unlock_window: x::Window = conn.generate_id();
|
let unlock_window: x::Window = conn.generate_id();
|
||||||
|
@ -39,7 +39,7 @@ impl<'a> Drop for UnlockDialog<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommandHandler = dyn Fn(&mut Screensaver, &xcb::Connection, Option<&x::ClientMessageEvent>) -> anyhow::Result<()>;
|
type CommandHandler = dyn Fn(&mut Screensaver, Option<&x::ClientMessageEvent>) -> anyhow::Result<()>;
|
||||||
|
|
||||||
pub struct CommandHandlers<'a> {
|
pub struct CommandHandlers<'a> {
|
||||||
pub restart_handler: &'a CommandHandler,
|
pub restart_handler: &'a CommandHandler,
|
||||||
@ -57,16 +57,17 @@ struct CommandAtoms {
|
|||||||
pub struct Screensaver<'a> {
|
pub struct Screensaver<'a> {
|
||||||
config: &'a Configuration,
|
config: &'a Configuration,
|
||||||
helper_dir: PathBuf,
|
helper_dir: PathBuf,
|
||||||
|
conn: &'a xcb::Connection,
|
||||||
command_atoms: CommandAtoms,
|
command_atoms: CommandAtoms,
|
||||||
command_handlers: &'a CommandHandlers<'a>,
|
command_handlers: &'a CommandHandlers<'a>,
|
||||||
blanker_state: BlankerState,
|
blanker_state: BlankerState,
|
||||||
monitors: Vec<Monitor>,
|
monitors: Vec<Monitor<'a>>,
|
||||||
last_user_activity: Instant,
|
last_user_activity: Instant,
|
||||||
unlock_dialog: Option<UnlockDialog<'a>>,
|
unlock_dialog: Option<UnlockDialog<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Screensaver<'a> {
|
impl<'a> Screensaver<'a> {
|
||||||
pub fn new<P: AsRef<Path>>(config: &'a Configuration, helper_dir: P, command_handlers: &'a CommandHandlers<'a>, conn: &xcb::Connection, screen: &x::Screen) -> anyhow::Result<Self> {
|
pub fn new<P: AsRef<Path>>(config: &'a Configuration, helper_dir: P, command_handlers: &'a CommandHandlers<'a>, conn: &'a xcb::Connection, screen: &x::Screen) -> anyhow::Result<Self> {
|
||||||
let _ = create_command_window(conn, screen)?;
|
let _ = create_command_window(conn, screen)?;
|
||||||
let command_atoms = CommandAtoms {
|
let command_atoms = CommandAtoms {
|
||||||
blank: create_atom(&conn, BCommand::Blank.atom_name())?,
|
blank: create_atom(&conn, BCommand::Blank.atom_name())?,
|
||||||
@ -79,10 +80,11 @@ impl<'a> Screensaver<'a> {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
config,
|
config,
|
||||||
helper_dir: helper_dir.as_ref().to_path_buf(),
|
helper_dir: helper_dir.as_ref().to_path_buf(),
|
||||||
|
conn,
|
||||||
command_atoms,
|
command_atoms,
|
||||||
command_handlers,
|
command_handlers,
|
||||||
blanker_state: BlankerState::Idle,
|
blanker_state: BlankerState::Idle,
|
||||||
monitors: Monitor::set_up_all(&conn)?,
|
monitors: Monitor::set_up_all(conn)?,
|
||||||
last_user_activity: Instant::now(),
|
last_user_activity: Instant::now(),
|
||||||
unlock_dialog: None,
|
unlock_dialog: None,
|
||||||
})
|
})
|
||||||
@ -96,13 +98,17 @@ impl<'a> Screensaver<'a> {
|
|||||||
self.last_user_activity
|
self.last_user_activity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn xcb_connection(&self) -> &xcb::Connection {
|
||||||
|
self.conn
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unlock_dialog_pidfd(&self) -> Option<&PidFd> {
|
pub fn unlock_dialog_pidfd(&self) -> Option<&PidFd> {
|
||||||
self.unlock_dialog.as_ref().map(|ud| &ud.child_pidfd)
|
self.unlock_dialog.as_ref().map(|ud| &ud.child_pidfd)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_xcb_events(&mut self, conn: &'a xcb::Connection) -> anyhow::Result<()> {
|
pub fn handle_xcb_events(&mut self) -> anyhow::Result<()> {
|
||||||
loop {
|
loop {
|
||||||
if let Some(event) = conn.poll_for_event()? {
|
if let Some(event) = self.conn.poll_for_event()? {
|
||||||
let embedder_handled = if let Some(mut unlock_dialog) = self.unlock_dialog.take() {
|
let embedder_handled = if let Some(mut unlock_dialog) = self.unlock_dialog.take() {
|
||||||
match unlock_dialog.embedder.event(&event) {
|
match unlock_dialog.embedder.event(&event) {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -130,20 +136,16 @@ impl<'a> Screensaver<'a> {
|
|||||||
match event {
|
match event {
|
||||||
xcb::Event::RandR(randr::Event::Notify(ev)) => {
|
xcb::Event::RandR(randr::Event::Notify(ev)) => {
|
||||||
debug!("Got xrandr notify event: {:#?}", ev);
|
debug!("Got xrandr notify event: {:#?}", ev);
|
||||||
let old_monitors = std::mem::replace(&mut self.monitors, Vec::new());
|
self.monitors = Monitor::set_up_all(self.conn)?;
|
||||||
for monitor in old_monitors {
|
|
||||||
monitor.release(conn);
|
|
||||||
}
|
|
||||||
self.monitors = Monitor::set_up_all(conn)?;
|
|
||||||
match self.blanker_state {
|
match self.blanker_state {
|
||||||
BlankerState::Idle => (),
|
BlankerState::Idle => (),
|
||||||
BlankerState::Blanked => {
|
BlankerState::Blanked => {
|
||||||
self.blanker_state = BlankerState::Idle;
|
self.blanker_state = BlankerState::Idle;
|
||||||
self.blank_screen(conn)?;
|
self.blank_screen()?;
|
||||||
},
|
},
|
||||||
BlankerState::Locked => {
|
BlankerState::Locked => {
|
||||||
self.blanker_state = BlankerState::Idle;
|
self.blanker_state = BlankerState::Idle;
|
||||||
self.lock_screen(conn)?;
|
self.lock_screen()?;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -153,16 +155,16 @@ impl<'a> Screensaver<'a> {
|
|||||||
},
|
},
|
||||||
xcb::Event::X(x::Event::ClientMessage(ev)) => {
|
xcb::Event::X(x::Event::ClientMessage(ev)) => {
|
||||||
let res = match ev.r#type() {
|
let res = match ev.r#type() {
|
||||||
b if b == self.command_atoms.blank => Some(self.blank_screen(conn)),
|
b if b == self.command_atoms.blank => Some(self.blank_screen()),
|
||||||
l if l == self.command_atoms.lock => Some(self.lock_screen(conn)),
|
l if l == self.command_atoms.lock => Some(self.lock_screen()),
|
||||||
d if d == self.command_atoms.deactivate => {
|
d if d == self.command_atoms.deactivate => {
|
||||||
self.last_user_activity = Instant::now();
|
self.last_user_activity = Instant::now();
|
||||||
match self.blanker_state {
|
match self.blanker_state {
|
||||||
BlankerState::Idle => Some(Ok(())),
|
BlankerState::Idle => Some(Ok(())),
|
||||||
BlankerState::Blanked => Some(self.unblank_screen(conn)),
|
BlankerState::Blanked => Some(self.unblank_screen()),
|
||||||
BlankerState::Locked => {
|
BlankerState::Locked => {
|
||||||
if self.unlock_dialog.is_none() {
|
if self.unlock_dialog.is_none() {
|
||||||
match self.start_unlock_dialog(conn, None) {
|
match self.start_unlock_dialog(None) {
|
||||||
Ok(unlock_dialog) => {
|
Ok(unlock_dialog) => {
|
||||||
self.unlock_dialog = Some(unlock_dialog);
|
self.unlock_dialog = Some(unlock_dialog);
|
||||||
Some(Ok(()))
|
Some(Ok(()))
|
||||||
@ -175,8 +177,8 @@ impl<'a> Screensaver<'a> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
r if r == self.command_atoms.restart => Some((self.command_handlers.restart_handler)(self, conn, Some(&ev))),
|
r if r == self.command_atoms.restart => Some((self.command_handlers.restart_handler)(self, Some(&ev))),
|
||||||
e if e == self.command_atoms.exit => Some((self.command_handlers.exit_handler)(self, conn, Some(&ev))),
|
e if e == self.command_atoms.exit => Some((self.command_handlers.exit_handler)(self, Some(&ev))),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,7 +189,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
crate::send_command_reply(conn, &ev, is_success);
|
crate::send_command_reply(self.conn, &ev, is_success);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
xcb::Event::X(x::Event::MapNotify(ev)) if ev.window() == self.unlock_dialog_window() => {
|
xcb::Event::X(x::Event::MapNotify(ev)) if ev.window() == self.unlock_dialog_window() => {
|
||||||
@ -208,7 +210,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
let x = std::cmp::max(0, monitor_geom.x as i32 + monitor_geom.width as i32 / 2 - ev.width() as i32 / 2);
|
let x = std::cmp::max(0, monitor_geom.x as i32 + monitor_geom.width as i32 / 2 - ev.width() as i32 / 2);
|
||||||
let y = std::cmp::max(0, monitor_geom.y as i32 + monitor_geom.height as i32 / 2 - ev.height() as i32 / 2);
|
let y = std::cmp::max(0, monitor_geom.y as i32 + monitor_geom.height as i32 / 2 - ev.height() as i32 / 2);
|
||||||
if x != ev.x() as i32 || y != ev.y() as i32 {
|
if x != ev.x() as i32 || y != ev.y() as i32 {
|
||||||
conn.send_and_check_request(&x::ConfigureWindow {
|
self.conn.send_and_check_request(&x::ConfigureWindow {
|
||||||
window: unlock_dialog.embedder.embedder_window(),
|
window: unlock_dialog.embedder.embedder_window(),
|
||||||
value_list: &[
|
value_list: &[
|
||||||
x::ConfigWindow::X(x),
|
x::ConfigWindow::X(x),
|
||||||
@ -221,7 +223,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
xcb::Event::X(x::Event::Expose(ev)) => {
|
xcb::Event::X(x::Event::Expose(ev)) => {
|
||||||
if let Some(monitor) = self.monitors.iter().find(|m| ev.window() == m.blanker_window || ev.window() == m.unlock_window) {
|
if let Some(monitor) = self.monitors.iter().find(|m| ev.window() == m.blanker_window || ev.window() == m.unlock_window) {
|
||||||
debug!("got expose for {} at {}x{}+{}+{}", ev.window().resource_id(), ev.width(), ev.height(), ev.x(), ev.y());
|
debug!("got expose for {} at {}x{}+{}+{}", ev.window().resource_id(), ev.width(), ev.height(), ev.x(), ev.y());
|
||||||
conn.send_and_check_request(&x::PolyFillRectangle {
|
self.conn.send_and_check_request(&x::PolyFillRectangle {
|
||||||
drawable: x::Drawable::Window(ev.window()),
|
drawable: x::Drawable::Window(ev.window()),
|
||||||
gc: monitor.black_gc,
|
gc: monitor.black_gc,
|
||||||
rectangles: &[
|
rectangles: &[
|
||||||
@ -235,16 +237,16 @@ impl<'a> Screensaver<'a> {
|
|||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ev @ xcb::Event::X(x::Event::MotionNotify(_)) => self.handle_user_activity(conn, ev)?,
|
ev @ xcb::Event::X(x::Event::MotionNotify(_)) => self.handle_user_activity(ev)?,
|
||||||
xcb::Event::X(x::Event::KeyPress(ev)) => {
|
xcb::Event::X(x::Event::KeyPress(ev)) => {
|
||||||
if let Err(err) = keysym_for_keypress(conn, &ev).and_then(|keysym| match keysym {
|
if let Err(err) = keysym_for_keypress(self.conn, &ev).and_then(|keysym| match keysym {
|
||||||
Some(keysym) if keysym == xkb::key::XF86MonBrightnessUp && self.config.handle_brightness_keys => self.monitors.iter().map(|monitor| monitor.brightness_up(conn)).collect(),
|
Some(keysym) if keysym == xkb::key::XF86MonBrightnessUp && self.config.handle_brightness_keys => self.monitors.iter().map(|monitor| monitor.brightness_up()).collect(),
|
||||||
Some(keysym) if keysym == xkb::key::XF86MonBrightnessDown && self.config.handle_brightness_keys => self.monitors.iter().map(|monitor| monitor.brightness_down(conn)).collect(),
|
Some(keysym) if keysym == xkb::key::XF86MonBrightnessDown && self.config.handle_brightness_keys => self.monitors.iter().map(|monitor| monitor.brightness_down()).collect(),
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
}) {
|
}) {
|
||||||
warn!("Failed to handle key press {}: {}", ev.detail(), err);
|
warn!("Failed to handle key press {}: {}", ev.detail(), err);
|
||||||
}
|
}
|
||||||
self.handle_user_activity(conn, xcb::Event::X(x::Event::KeyPress(ev)))?;
|
self.handle_user_activity(xcb::Event::X(x::Event::KeyPress(ev)))?;
|
||||||
},
|
},
|
||||||
ev => trace!("Got other event: {:#?}", ev),
|
ev => trace!("Got other event: {:#?}", ev),
|
||||||
}
|
}
|
||||||
@ -257,13 +259,13 @@ impl<'a> Screensaver<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_user_activity(&mut self, conn: &'a xcb::Connection, ev: xcb::Event) -> anyhow::Result<()> {
|
fn handle_user_activity(&mut self, ev: xcb::Event) -> anyhow::Result<()> {
|
||||||
match self.blanker_state {
|
match self.blanker_state {
|
||||||
BlankerState::Idle => Ok(()),
|
BlankerState::Idle => Ok(()),
|
||||||
BlankerState::Blanked => self.unblank_screen(conn),
|
BlankerState::Blanked => self.unblank_screen(),
|
||||||
BlankerState::Locked => match &self.unlock_dialog {
|
BlankerState::Locked => match &self.unlock_dialog {
|
||||||
None => {
|
None => {
|
||||||
self.unlock_dialog = match self.start_unlock_dialog(&conn, Some(ev)) {
|
self.unlock_dialog = match self.start_unlock_dialog(Some(ev)) {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Unable to start unlock dialog: {}", err);
|
error!("Unable to start unlock dialog: {}", err);
|
||||||
None
|
None
|
||||||
@ -275,7 +277,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
Some(unlock_dialog) => {
|
Some(unlock_dialog) => {
|
||||||
let mut cookies = Vec::new();
|
let mut cookies = Vec::new();
|
||||||
for win in [unlock_dialog.blanker_window, unlock_dialog.embedder.embedder_window(), unlock_dialog.embedder.client_window()] {
|
for win in [unlock_dialog.blanker_window, unlock_dialog.embedder.embedder_window(), unlock_dialog.embedder.client_window()] {
|
||||||
cookies.push(conn.send_request_checked(&x::ConfigureWindow {
|
cookies.push(self.conn.send_request_checked(&x::ConfigureWindow {
|
||||||
window: win,
|
window: win,
|
||||||
value_list: &[
|
value_list: &[
|
||||||
x::ConfigWindow::StackMode(x::StackMode::Above),
|
x::ConfigWindow::StackMode(x::StackMode::Above),
|
||||||
@ -283,7 +285,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
for cookie in cookies {
|
for cookie in cookies {
|
||||||
conn.check_request(cookie)?;
|
self.conn.check_request(cookie)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
@ -299,7 +301,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
self.unlock_dialog.as_ref().map(|ud| ud.embedder.client_window()).unwrap_or(x::WINDOW_NONE)
|
self.unlock_dialog.as_ref().map(|ud| ud.embedder.client_window()).unwrap_or(x::WINDOW_NONE)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_unlock_dialog_quit(&mut self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn handle_unlock_dialog_quit(&mut self) -> anyhow::Result<()> {
|
||||||
if let Some(mut unlock_dialog) = self.unlock_dialog.take() {
|
if let Some(mut unlock_dialog) = self.unlock_dialog.take() {
|
||||||
match unlock_dialog.child.try_wait() {
|
match unlock_dialog.child.try_wait() {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -308,28 +310,28 @@ impl<'a> Screensaver<'a> {
|
|||||||
},
|
},
|
||||||
Ok(Some(status)) if status.success() => {
|
Ok(Some(status)) if status.success() => {
|
||||||
info!("Authentication succeeded");
|
info!("Authentication succeeded");
|
||||||
self.unlock_screen(conn)?;
|
self.unlock_screen()?;
|
||||||
}
|
}
|
||||||
Ok(Some(status)) if status.signal().is_some() => {
|
Ok(Some(status)) if status.signal().is_some() => {
|
||||||
if let Some(signum) = status.signal() {
|
if let Some(signum) = status.signal() {
|
||||||
warn!("Unlock dialog crashed with signal {}", signum);
|
warn!("Unlock dialog crashed with signal {}", signum);
|
||||||
}
|
}
|
||||||
self.hide_cursor(conn);
|
self.hide_cursor();
|
||||||
},
|
},
|
||||||
Ok(Some(_)) => self.hide_cursor(conn), // auth failed, dialog has quit, do nothing
|
Ok(Some(_)) => self.hide_cursor(), // auth failed, dialog has quit, do nothing
|
||||||
Ok(None) => self.unlock_dialog = Some(unlock_dialog), // dialog still running
|
Ok(None) => self.unlock_dialog = Some(unlock_dialog), // dialog still running
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_unlock_dialog(&self, conn: &'a xcb::Connection, trigger_event: Option<xcb::Event>) -> anyhow::Result<UnlockDialog<'a>> {
|
fn start_unlock_dialog(&self, trigger_event: Option<xcb::Event>) -> anyhow::Result<UnlockDialog<'a>> {
|
||||||
let mut monitor_data = None;
|
let mut monitor_data = None;
|
||||||
for monitor in &self.monitors {
|
for monitor in &self.monitors {
|
||||||
let cookie = conn.send_request(&x::QueryPointer {
|
let cookie = self.conn.send_request(&x::QueryPointer {
|
||||||
window: monitor.root,
|
window: monitor.root,
|
||||||
});
|
});
|
||||||
let reply = conn.wait_for_reply(cookie)?;
|
let reply = self.conn.wait_for_reply(cookie)?;
|
||||||
let px = reply.root_x() as i32;
|
let px = reply.root_x() as i32;
|
||||||
let py = reply.root_y() as i32;
|
let py = reply.root_y() as i32;
|
||||||
if reply.same_screen()
|
if reply.same_screen()
|
||||||
@ -347,11 +349,11 @@ impl<'a> Screensaver<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for monitor in &self.monitors {
|
for monitor in &self.monitors {
|
||||||
monitor.show_cursor(conn);
|
monitor.show_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
let trigger_event = match trigger_event {
|
let trigger_event = match trigger_event {
|
||||||
Some(xcb::Event::X(x::Event::KeyPress(ev))) => match keysym_for_keypress(conn, &ev) {
|
Some(xcb::Event::X(x::Event::KeyPress(ev))) => match keysym_for_keypress(self.conn, &ev) {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("Failed to get keysym for key press event: {}", err);
|
warn!("Failed to get keysym for key press event: {}", err);
|
||||||
Some(xcb::Event::X(x::Event::KeyPress(ev)))
|
Some(xcb::Event::X(x::Event::KeyPress(ev)))
|
||||||
@ -379,12 +381,12 @@ impl<'a> Screensaver<'a> {
|
|||||||
};
|
};
|
||||||
debug!("Dialog process created plug window 0x{:x}", client_window.resource_id());
|
debug!("Dialog process created plug window 0x{:x}", client_window.resource_id());
|
||||||
|
|
||||||
let cookie = conn.send_request(&x::GetWindowAttributes {
|
let cookie = self.conn.send_request(&x::GetWindowAttributes {
|
||||||
window: client_window,
|
window: client_window,
|
||||||
});
|
});
|
||||||
let reply = conn.wait_for_reply(cookie)?;
|
let reply = self.conn.wait_for_reply(cookie)?;
|
||||||
if !reply.your_event_mask().contains(x::EventMask::STRUCTURE_NOTIFY) {
|
if !reply.your_event_mask().contains(x::EventMask::STRUCTURE_NOTIFY) {
|
||||||
conn.send_and_check_request(&x::ChangeWindowAttributes {
|
self.conn.send_and_check_request(&x::ChangeWindowAttributes {
|
||||||
window: client_window,
|
window: client_window,
|
||||||
value_list: &[
|
value_list: &[
|
||||||
x::Cw::EventMask(reply.your_event_mask() | x::EventMask::STRUCTURE_NOTIFY),
|
x::Cw::EventMask(reply.your_event_mask() | x::EventMask::STRUCTURE_NOTIFY),
|
||||||
@ -392,7 +394,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let embedder = Embedder::start(conn, unlock_window, client_window)?;
|
let embedder = Embedder::start(self.conn, unlock_window, client_window)?;
|
||||||
|
|
||||||
Ok(UnlockDialog {
|
Ok(UnlockDialog {
|
||||||
monitor_geom,
|
monitor_geom,
|
||||||
@ -408,7 +410,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
let _ = self.unlock_dialog.take();
|
let _ = self.unlock_dialog.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blank_screen(&mut self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn blank_screen(&mut self) -> anyhow::Result<()> {
|
||||||
if self.blanker_state >= BlankerState::Blanked {
|
if self.blanker_state >= BlankerState::Blanked {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
@ -416,7 +418,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
info!("Blanking");
|
info!("Blanking");
|
||||||
|
|
||||||
for monitor in &self.monitors {
|
for monitor in &self.monitors {
|
||||||
monitor.blank(conn)?;
|
monitor.blank()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.blanker_state = BlankerState::Blanked;
|
self.blanker_state = BlankerState::Blanked;
|
||||||
@ -424,7 +426,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unblank_screen(&mut self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
fn unblank_screen(&mut self) -> anyhow::Result<()> {
|
||||||
if self.blanker_state != BlankerState::Blanked {
|
if self.blanker_state != BlankerState::Blanked {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -432,7 +434,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
info!("Unblanking");
|
info!("Unblanking");
|
||||||
|
|
||||||
for monitor in &self.monitors {
|
for monitor in &self.monitors {
|
||||||
monitor.unblank(conn)?;
|
monitor.unblank()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.blanker_state = BlankerState::Idle;
|
self.blanker_state = BlankerState::Idle;
|
||||||
@ -440,8 +442,8 @@ impl<'a> Screensaver<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lock_screen(&mut self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
pub fn lock_screen(&mut self) -> anyhow::Result<()> {
|
||||||
self.blank_screen(conn)?;
|
self.blank_screen()?;
|
||||||
if self.blanker_state >= BlankerState::Locked {
|
if self.blanker_state >= BlankerState::Locked {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -449,7 +451,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
info!("Locking");
|
info!("Locking");
|
||||||
|
|
||||||
for monitor in &self.monitors {
|
for monitor in &self.monitors {
|
||||||
monitor.lock(conn)?;
|
monitor.lock()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.blanker_state = BlankerState::Locked;
|
self.blanker_state = BlankerState::Locked;
|
||||||
@ -457,7 +459,7 @@ impl<'a> Screensaver<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock_screen(&mut self, conn: &xcb::Connection) -> anyhow::Result<()> {
|
fn unlock_screen(&mut self) -> anyhow::Result<()> {
|
||||||
if self.blanker_state != BlankerState::Locked {
|
if self.blanker_state != BlankerState::Locked {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -465,18 +467,18 @@ impl<'a> Screensaver<'a> {
|
|||||||
info!("Unlocking");
|
info!("Unlocking");
|
||||||
|
|
||||||
for monitor in &self.monitors {
|
for monitor in &self.monitors {
|
||||||
monitor.unlock(conn)?;
|
monitor.unlock()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.blanker_state = BlankerState::Blanked;
|
self.blanker_state = BlankerState::Blanked;
|
||||||
self.unblank_screen(conn)?;
|
self.unblank_screen()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hide_cursor(&self, conn: &xcb::Connection) {
|
fn hide_cursor(&self) {
|
||||||
for monitor in &self.monitors {
|
for monitor in &self.monitors {
|
||||||
monitor.hide_cursor(conn);
|
monitor.hide_cursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user