From 8657bc249ceb00a3b919fadf4c5c6d23335cf95a Mon Sep 17 00:00:00 2001 From: "Brian J. Tarricone" Date: Fri, 27 May 2022 18:28:01 -0700 Subject: [PATCH] Stop threading the xcb connection everywhere Easier to just store a reference to it in the structs. --- locker/src/main.rs | 42 +++++++------- locker/src/monitor.rs | 98 +++++++++++++++++--------------- locker/src/screensaver.rs | 116 +++++++++++++++++++------------------- 3 files changed, 131 insertions(+), 125 deletions(-) diff --git a/locker/src/main.rs b/locker/src/main.rs index 9117d73..d50130c 100644 --- a/locker/src/main.rs +++ b/locker/src/main.rs @@ -81,23 +81,23 @@ fn main() -> anyhow::Result<()> { let subservices1 = Rc::clone(&subservices); let subservices2 = Rc::clone(&subservices); CommandHandlers { - restart_handler: &move |screensaver, conn, trigger| { - restart_daemon(screensaver, &mut subservices1.lock().unwrap(), trigger.map(|t| (conn, t))) + restart_handler: &move |screensaver, trigger| { + restart_daemon(screensaver, &mut subservices1.lock().unwrap(), trigger) }, - exit_handler: &move |screensaver, conn, trigger| { - exit_daemon(screensaver, &mut subservices2.lock().unwrap(), trigger.map(|t| (conn, t))) + exit_handler: &move |screensaver, trigger| { + exit_daemon(screensaver, &mut subservices2.lock().unwrap(), trigger) }, } }; let mut screensaver = Screensaver::new(&config, &helper_dir, &command_handlers, &conn, screen)?; 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), Ok(_) => debug!("Got --{} arg; screen locked on startup", LOCKED_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), Ok(_) => debug!("Got --{} arg; screen locked on startup", BLANKED_ARG), } @@ -112,10 +112,10 @@ fn main() -> anyhow::Result<()> { loop { - if let Err(err) = screensaver.handle_xcb_events(&conn) { + if let Err(err) = screensaver.handle_xcb_events() { if conn.has_error().is_err() { 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); } @@ -149,17 +149,17 @@ fn main() -> anyhow::Result<()> { if pfd.revents().filter(|pf| pf.contains(PollFlags::POLLIN)).is_some() { 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 == 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(&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(()), }; if let Err(err) = result { if conn.has_error().is_err() { 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); } @@ -170,13 +170,13 @@ fn main() -> anyhow::Result<()> { 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 let Err(err) = screensaver.blank_screen(&conn) { + if let Err(err) = screensaver.blank_screen() { error!("POSSIBLY FAILED TO BLANK SCREEN: {}", err); } } 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); } } @@ -280,7 +280,7 @@ fn handle_signals(screensaver: &mut Screensaver, subservices: &mut Subservices, 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"); let exe = read_link("/proc/self/exe")?; @@ -297,14 +297,14 @@ fn restart_daemon(screensaver: &mut Screensaver, subservices: &mut Subservices, match unsafe { fork() } { Err(err) => { error!("Failed to fork: {}", err); - if let Some((conn, ev)) = trigger { - bscreensaver::send_command_reply(conn, ev, false); + if let Some(ev) = trigger { + bscreensaver::send_command_reply(screensaver.xcb_connection(), ev, false); } Err(err)?; }, Ok(ForkResult::Parent { .. }) => { - if let Some((conn, ev)) = trigger { - bscreensaver::send_command_reply(conn, ev, true); + if let Some(ev) = trigger { + bscreensaver::send_command_reply(screensaver.xcb_connection(), ev, true); } exit(0); }, @@ -319,11 +319,11 @@ fn restart_daemon(screensaver: &mut Screensaver, subservices: &mut Subservices, 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"); kill_child_processes(screensaver, subservices); - if let Some((conn, ev)) = trigger { - bscreensaver::send_command_reply(conn, ev, true); + if let Some(ev) = trigger { + bscreensaver::send_command_reply(screensaver.xcb_connection(), ev, true); } exit(0); } diff --git a/locker/src/monitor.rs b/locker/src/monitor.rs index b1c1524..3550a96 100644 --- a/locker/src/monitor.rs +++ b/locker/src/monitor.rs @@ -14,7 +14,8 @@ struct BacklightControl { step: u32, } -pub struct Monitor { +pub struct Monitor<'a> { + pub conn: &'a xcb::Connection, pub root: x::Window, pub black_gc: x::Gcontext, pub output: randr::Output, @@ -28,7 +29,7 @@ pub struct Monitor { backlight_control: Option, } -impl Monitor { +impl<'a> Monitor<'a> { pub fn set_up_all(conn: &xcb::Connection) -> xcb::Result> { let mut monitors = Vec::new(); for screen in conn.get_setup().roots() { @@ -57,7 +58,7 @@ impl Monitor { Ok(monitors) } - pub fn new(conn: &xcb::Connection, screen: &x::Screen, output: randr::Output, crtc_info: &randr::GetCrtcInfoReply) -> xcb::Result { + pub fn new(conn: &'a xcb::Connection, screen: &x::Screen, output: randr::Output, crtc_info: &randr::GetCrtcInfoReply) -> xcb::Result> { let (blanker_window, unlock_window) = create_windows(conn, &screen, &crtc_info)?; let blank_cursor = create_blank_cursor(conn, &screen)?; @@ -77,6 +78,7 @@ impl Monitor { } Ok(Monitor { + conn, root: screen.root(), black_gc, 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 { x::Rectangle { 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(); - cookies.push(conn.send_request_checked(&x::ConfigureWindow { + cookies.push(self.conn.send_request_checked(&x::ConfigureWindow { window: self.blanker_window, value_list: &[ 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, })); for cookie in cookies { - conn.check_request(cookie)?; + self.conn.check_request(cookie)?; } - self.hide_cursor(conn); + self.hide_cursor(); Ok(()) } - pub fn unblank(&self, conn: &xcb::Connection) -> anyhow::Result<()> { - self.show_cursor(conn); + pub fn unblank(&self) -> anyhow::Result<()> { + self.show_cursor(); - conn.send_and_check_request(&x::UnmapWindow { + self.conn.send_and_check_request(&x::UnmapWindow { window: self.blanker_window, })?; Ok(()) } - pub fn lock(&self, conn: &xcb::Connection) -> anyhow::Result<()> { + pub fn lock(&self) -> anyhow::Result<()> { 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, value_list: &[ 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, })); 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, grab_window: self.unlock_window, time: x::CURRENT_TIME, pointer_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 { // FIXME: try to grab later? 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, grab_window: self.unlock_window, 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, 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 { // FIXME: try to grab later? warn!("Failed to grab pointer on window {:?}: {:?}", self.blanker_window, reply.status()); @@ -186,27 +181,27 @@ impl Monitor { Ok(()) } - pub fn unlock(&self, conn: &xcb::Connection) -> anyhow::Result<()> { + pub fn unlock(&self) -> anyhow::Result<()> { 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, })); - cookies.push(conn.send_request_checked(&x::UngrabPointer { + cookies.push(self.conn.send_request_checked(&x::UngrabPointer { 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, })); for cookie in cookies { - conn.check_request(cookie)?; + self.conn.check_request(cookie)?; } Ok(()) } - pub fn show_cursor(&self, conn: &xcb::Connection) { - if let Err(err) = conn.send_and_check_request(&x::ChangeWindowAttributes { + pub fn show_cursor(&self) { + if let Err(err) = self.conn.send_and_check_request(&x::ChangeWindowAttributes { window: self.blanker_window, value_list: &[ x::Cw::Cursor(x::CURSOR_NONE), @@ -216,8 +211,8 @@ impl Monitor { } } - pub fn hide_cursor(&self, conn: &xcb::Connection) { - if let Err(err) = conn.send_and_check_request(&x::ChangeWindowAttributes { + pub fn hide_cursor(&self) { + if let Err(err) = self.conn.send_and_check_request(&x::ChangeWindowAttributes { window: self.blanker_window, value_list: &[ x::Cw::Cursor(self.blank_cursor), @@ -227,30 +222,30 @@ impl Monitor { } } - pub fn brightness_up(&self, conn: &xcb::Connection) -> anyhow::Result<()> { - self.brightness_change(conn, |backlight_control, cur_brightness| cur_brightness as i32 + backlight_control.step as i32) + pub fn brightness_up(&self) -> anyhow::Result<()> { + 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<()> { - self.brightness_change(conn, |backlight_control, cur_brightness| cur_brightness as i32 - backlight_control.step as i32) + pub fn brightness_down(&self) -> anyhow::Result<()> { + self.brightness_change(|backlight_control, cur_brightness| cur_brightness as i32 - backlight_control.step as i32) } - fn brightness_change i32>(&self, conn: &xcb::Connection, updater: F) -> anyhow::Result<()> { + fn brightness_change i32>(&self, updater: F) -> anyhow::Result<()> { 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 = cmp::min(backlight_control.max_level, new_level); let new_level = cmp::max(backlight_control.min_level, new_level); if new_level != cur_brightness as i32 { - self.set_brightness(conn, &backlight_control, new_level)?; + self.set_brightness(&backlight_control, new_level)?; } } } Ok(()) } - fn get_current_brightness(&self, conn: &xcb::Connection, backlight_control: &BacklightControl) -> anyhow::Result> { - let cookie = conn.send_request(&randr::GetOutputProperty { + fn get_current_brightness(&self, backlight_control: &BacklightControl) -> anyhow::Result> { + let cookie = self.conn.send_request(&randr::GetOutputProperty { output: self.output, property: backlight_control.property, r#type: x::ATOM_INTEGER, @@ -259,7 +254,7 @@ impl Monitor { delete: false, pending: false, }); - let reply = conn.wait_for_reply(cookie)?; + let reply = self.conn.wait_for_reply(cookie)?; let data = reply.data::(); if data.len() == 1 { Ok(Some(data[0])) @@ -268,8 +263,8 @@ impl Monitor { } } - fn set_brightness(&self, conn: &xcb::Connection, backlight_control: &BacklightControl, level: i32) -> anyhow::Result<()> { - conn.send_and_check_request(&randr::ChangeOutputProperty { + fn set_brightness(&self, backlight_control: &BacklightControl, level: i32) -> anyhow::Result<()> { + self.conn.send_and_check_request(&randr::ChangeOutputProperty { output: self.output, property: backlight_control.property, 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)> { let blanker_window: x::Window = conn.generate_id(); let unlock_window: x::Window = conn.generate_id(); diff --git a/locker/src/screensaver.rs b/locker/src/screensaver.rs index 7e18a3b..9b7138f 100644 --- a/locker/src/screensaver.rs +++ b/locker/src/screensaver.rs @@ -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 restart_handler: &'a CommandHandler, @@ -57,16 +57,17 @@ struct CommandAtoms { pub struct Screensaver<'a> { config: &'a Configuration, helper_dir: PathBuf, + conn: &'a xcb::Connection, command_atoms: CommandAtoms, command_handlers: &'a CommandHandlers<'a>, blanker_state: BlankerState, - monitors: Vec, + monitors: Vec>, last_user_activity: Instant, unlock_dialog: Option>, } impl<'a> Screensaver<'a> { - pub fn new>(config: &'a Configuration, helper_dir: P, command_handlers: &'a CommandHandlers<'a>, conn: &xcb::Connection, screen: &x::Screen) -> anyhow::Result { + pub fn new>(config: &'a Configuration, helper_dir: P, command_handlers: &'a CommandHandlers<'a>, conn: &'a xcb::Connection, screen: &x::Screen) -> anyhow::Result { let _ = create_command_window(conn, screen)?; let command_atoms = CommandAtoms { blank: create_atom(&conn, BCommand::Blank.atom_name())?, @@ -79,10 +80,11 @@ impl<'a> Screensaver<'a> { Ok(Self { config, helper_dir: helper_dir.as_ref().to_path_buf(), + conn, command_atoms, command_handlers, blanker_state: BlankerState::Idle, - monitors: Monitor::set_up_all(&conn)?, + monitors: Monitor::set_up_all(conn)?, last_user_activity: Instant::now(), unlock_dialog: None, }) @@ -96,13 +98,17 @@ impl<'a> Screensaver<'a> { self.last_user_activity } + pub fn xcb_connection(&self) -> &xcb::Connection { + self.conn + } + pub fn unlock_dialog_pidfd(&self) -> Option<&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 { - 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() { match unlock_dialog.embedder.event(&event) { Err(err) => { @@ -130,20 +136,16 @@ impl<'a> Screensaver<'a> { match event { xcb::Event::RandR(randr::Event::Notify(ev)) => { debug!("Got xrandr notify event: {:#?}", ev); - let old_monitors = std::mem::replace(&mut self.monitors, Vec::new()); - for monitor in old_monitors { - monitor.release(conn); - } - self.monitors = Monitor::set_up_all(conn)?; + self.monitors = Monitor::set_up_all(self.conn)?; match self.blanker_state { BlankerState::Idle => (), BlankerState::Blanked => { self.blanker_state = BlankerState::Idle; - self.blank_screen(conn)?; + self.blank_screen()?; }, BlankerState::Locked => { 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)) => { let res = match ev.r#type() { - b if b == self.command_atoms.blank => Some(self.blank_screen(conn)), - l if l == self.command_atoms.lock => Some(self.lock_screen(conn)), + b if b == self.command_atoms.blank => Some(self.blank_screen()), + l if l == self.command_atoms.lock => Some(self.lock_screen()), d if d == self.command_atoms.deactivate => { self.last_user_activity = Instant::now(); match self.blanker_state { BlankerState::Idle => Some(Ok(())), - BlankerState::Blanked => Some(self.unblank_screen(conn)), + BlankerState::Blanked => Some(self.unblank_screen()), BlankerState::Locked => { if self.unlock_dialog.is_none() { - match self.start_unlock_dialog(conn, None) { + match self.start_unlock_dialog(None) { Ok(unlock_dialog) => { self.unlock_dialog = Some(unlock_dialog); 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))), - e if e == self.command_atoms.exit => Some((self.command_handlers.exit_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, Some(&ev))), _ => None, }; @@ -187,7 +189,7 @@ impl<'a> Screensaver<'a> { } else { 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() => { @@ -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 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 { - conn.send_and_check_request(&x::ConfigureWindow { + self.conn.send_and_check_request(&x::ConfigureWindow { window: unlock_dialog.embedder.embedder_window(), value_list: &[ x::ConfigWindow::X(x), @@ -221,7 +223,7 @@ impl<'a> Screensaver<'a> { 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) { 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()), gc: monitor.black_gc, 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)) => { - if let Err(err) = keysym_for_keypress(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::XF86MonBrightnessDown && self.config.handle_brightness_keys => self.monitors.iter().map(|monitor| monitor.brightness_down(conn)).collect(), + 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()).collect(), + Some(keysym) if keysym == xkb::key::XF86MonBrightnessDown && self.config.handle_brightness_keys => self.monitors.iter().map(|monitor| monitor.brightness_down()).collect(), _ => Ok(()), }) { 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), } @@ -257,13 +259,13 @@ impl<'a> Screensaver<'a> { 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 { BlankerState::Idle => Ok(()), - BlankerState::Blanked => self.unblank_screen(conn), + BlankerState::Blanked => self.unblank_screen(), BlankerState::Locked => match &self.unlock_dialog { None => { - self.unlock_dialog = match self.start_unlock_dialog(&conn, Some(ev)) { + self.unlock_dialog = match self.start_unlock_dialog(Some(ev)) { Err(err) => { error!("Unable to start unlock dialog: {}", err); None @@ -275,7 +277,7 @@ impl<'a> Screensaver<'a> { Some(unlock_dialog) => { let mut cookies = Vec::new(); 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, value_list: &[ x::ConfigWindow::StackMode(x::StackMode::Above), @@ -283,7 +285,7 @@ impl<'a> Screensaver<'a> { })); } for cookie in cookies { - conn.check_request(cookie)?; + self.conn.check_request(cookie)?; } 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) } - 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() { match unlock_dialog.child.try_wait() { Err(err) => { @@ -308,28 +310,28 @@ impl<'a> Screensaver<'a> { }, Ok(Some(status)) if status.success() => { info!("Authentication succeeded"); - self.unlock_screen(conn)?; + self.unlock_screen()?; } Ok(Some(status)) if status.signal().is_some() => { if let Some(signum) = status.signal() { 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(()) } - fn start_unlock_dialog(&self, conn: &'a xcb::Connection, trigger_event: Option) -> anyhow::Result> { + fn start_unlock_dialog(&self, trigger_event: Option) -> anyhow::Result> { let mut monitor_data = None; for monitor in &self.monitors { - let cookie = conn.send_request(&x::QueryPointer { + let cookie = self.conn.send_request(&x::QueryPointer { 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 py = reply.root_y() as i32; if reply.same_screen() @@ -347,11 +349,11 @@ impl<'a> Screensaver<'a> { }); for monitor in &self.monitors { - monitor.show_cursor(conn); + monitor.show_cursor(); } 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) => { warn!("Failed to get keysym for key press event: {}", err); 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()); - let cookie = conn.send_request(&x::GetWindowAttributes { + let cookie = self.conn.send_request(&x::GetWindowAttributes { 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) { - conn.send_and_check_request(&x::ChangeWindowAttributes { + self.conn.send_and_check_request(&x::ChangeWindowAttributes { window: client_window, value_list: &[ 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 { monitor_geom, @@ -408,7 +410,7 @@ impl<'a> Screensaver<'a> { 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 { return Ok(()) } @@ -416,7 +418,7 @@ impl<'a> Screensaver<'a> { info!("Blanking"); for monitor in &self.monitors { - monitor.blank(conn)?; + monitor.blank()?; } self.blanker_state = BlankerState::Blanked; @@ -424,7 +426,7 @@ impl<'a> Screensaver<'a> { Ok(()) } - fn unblank_screen(&mut self, conn: &xcb::Connection) -> anyhow::Result<()> { + fn unblank_screen(&mut self) -> anyhow::Result<()> { if self.blanker_state != BlankerState::Blanked { return Ok(()); } @@ -432,7 +434,7 @@ impl<'a> Screensaver<'a> { info!("Unblanking"); for monitor in &self.monitors { - monitor.unblank(conn)?; + monitor.unblank()?; } self.blanker_state = BlankerState::Idle; @@ -440,8 +442,8 @@ impl<'a> Screensaver<'a> { Ok(()) } - pub fn lock_screen(&mut self, conn: &xcb::Connection) -> anyhow::Result<()> { - self.blank_screen(conn)?; + pub fn lock_screen(&mut self) -> anyhow::Result<()> { + self.blank_screen()?; if self.blanker_state >= BlankerState::Locked { return Ok(()); } @@ -449,7 +451,7 @@ impl<'a> Screensaver<'a> { info!("Locking"); for monitor in &self.monitors { - monitor.lock(conn)?; + monitor.lock()?; } self.blanker_state = BlankerState::Locked; @@ -457,7 +459,7 @@ impl<'a> Screensaver<'a> { Ok(()) } - fn unlock_screen(&mut self, conn: &xcb::Connection) -> anyhow::Result<()> { + fn unlock_screen(&mut self) -> anyhow::Result<()> { if self.blanker_state != BlankerState::Locked { return Ok(()); } @@ -465,18 +467,18 @@ impl<'a> Screensaver<'a> { info!("Unlocking"); for monitor in &self.monitors { - monitor.unlock(conn)?; + monitor.unlock()?; } self.blanker_state = BlankerState::Blanked; - self.unblank_screen(conn)?; + self.unblank_screen()?; Ok(()) } - fn hide_cursor(&self, conn: &xcb::Connection) { + fn hide_cursor(&self) { for monitor in &self.monitors { - monitor.hide_cursor(conn); + monitor.hide_cursor(); } } }