From bbceba7e9b21c4ff9ac6c23265f65f082481fd3a Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Fri, 28 Jan 2022 12:14:24 +0000 Subject: [PATCH] debug: Add dbus interface to control debug prints --- Cargo.deps | 4 +++ debian/control | 1 + src/debug.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 +++ src/main.rs | 3 +++ src/state.rs | 50 ++++++++++++++++++++++++++++------- 6 files changed, 123 insertions(+), 9 deletions(-) create mode 100644 src/debug.rs diff --git a/Cargo.deps b/Cargo.deps index 31bc0dc1..e7c5e06f 100644 --- a/Cargo.deps +++ b/Cargo.deps @@ -1,6 +1,10 @@ # Dependencies which change based on build flags bitflags = "1.2.*" clap = { version = "2.33.*", default-features = false } +zbus = "1.0.*" +zvariant = "2.0.*" +# Newer versions seem to confuse the version of Cargo on Debian Bullseye +zvariant_derive = "2.0.*" [dependencies.cairo-rs] version = "0.7.*" diff --git a/debian/control b/debian/control index 03db5ffd..e000afb6 100644 --- a/debian/control +++ b/debian/control @@ -23,6 +23,7 @@ Build-Depends: librust-serde-derive-1-dev (>= 1.0), librust-serde-yaml-0.8-dev (>= 0.8), librust-xkbcommon-0.4+wayland-dev (>= 0.4), + librust-zbus-dev (>=1.0), libwayland-dev (>= 1.16), lsb-release, python3, diff --git a/src/debug.rs b/src/debug.rs new file mode 100644 index 00000000..b6cc50ed --- /dev/null +++ b/src/debug.rs @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2022 Purism SPC + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +use std::thread; +use zbus::{Connection, ObjectServer, dbus_interface, fdo}; + +use crate::event_loop; +use crate::state; + + +use std::convert::TryInto; + + +/// Accepts commands controlling the debug mode +struct Manager { + sender: event_loop::driver::Threaded, + enabled: bool, +} + +#[dbus_interface(name = "sm.puri.SqueekDebug")] +impl Manager { + #[dbus_interface(property, name = "Enabled")] + fn get_enabled(&self) -> bool { + self.enabled + } + #[dbus_interface(property, name = "Enabled")] + fn set_enabled(&mut self, enabled: bool) { + self.enabled = enabled; + self.sender + .send(state::Event::Debug( + if enabled { Event::Enable } + else { Event::Disable } + )) + .unwrap(); + } +} + +fn start(mgr: Manager) -> Result<(), Box> { + let connection = Connection::new_session()?; + fdo::DBusProxy::new(&connection)?.request_name( + "sm.puri.SqueekDebug", + fdo::RequestNameFlags::ReplaceExisting.into(), + )?; + + let mut object_server = ObjectServer::new(&connection); + object_server.at(&"/sm/puri/SqueekDebug".try_into()?, mgr)?; + + loop { + if let Err(err) = object_server.try_handle_next() { + eprintln!("{}", err); + } + } +} + +pub fn init(sender: event_loop::driver::Threaded) { + let mgr = Manager { + sender, + enabled: false, + }; + thread::spawn(move || { + start(mgr).unwrap(); + }); +} + +#[derive(Debug, Clone, Copy)] +pub enum Event { + Enable, + Disable, +} diff --git a/src/lib.rs b/src/lib.rs index 9fe36843..618f5a06 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,8 @@ extern crate gtk_sys; extern crate maplit; extern crate serde; extern crate xkbcommon; +extern crate zbus; +extern crate zvariant; #[cfg(test)] #[macro_use] @@ -23,6 +25,7 @@ mod logging; mod action; mod animation; pub mod data; +mod debug; mod drawing; mod event_loop; pub mod float_ord; diff --git a/src/main.rs b/src/main.rs index c32cf660..d78ff767 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ /*! Glue for the main loop. */ use crate::outputs::OutputId; +use crate::debug; use crate::state; use glib::{Continue, MainContext, PRIORITY_DEFAULT, Receiver}; @@ -94,6 +95,8 @@ mod c { let now = Instant::now(); let state_manager = driver::Threaded::new(sender, state::Application::new(now)); + debug::init(state_manager.clone()); + let outputs = Outputs::new(state_manager.clone()); let mut wayland = Box::new(Wayland::new(outputs)); let wayland_raw = &mut *wayland as *mut _; diff --git a/src/state.rs b/src/state.rs index 5254a940..5c9b7245 100644 --- a/src/state.rs +++ b/src/state.rs @@ -6,6 +6,7 @@ * It's driven by the loop defined in the loop module. */ use crate::animation; +use crate::debug; use crate::imservice::{ ContentHint, ContentPurpose }; use crate::main::{ Commands, PanelCommand, PixelSize }; use crate::outputs; @@ -14,19 +15,20 @@ use std::cmp; use std::collections::HashMap; use std::time::Instant; -#[derive(Clone, Copy)] + +#[derive(Clone, Copy, Debug)] pub enum Presence { Present, Missing, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct InputMethodDetails { pub hint: ContentHint, pub purpose: ContentPurpose, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum InputMethod { Active(InputMethodDetails), InactiveSince(Instant), @@ -34,12 +36,13 @@ pub enum InputMethod { /// Incoming events. /// This contains events that cause a change to the internal state. -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Event { InputMethod(InputMethod), Visibility(visibility::Event), PhysicalKeyboard(Presence), Output(outputs::Event), + Debug(debug::Event), /// Event triggered because a moment in time passed. /// Use to animate state transitions. /// The value is the ideal arrival time. @@ -59,7 +62,7 @@ impl From for Event { } pub mod visibility { - #[derive(Clone)] + #[derive(Clone, Debug)] pub enum Event { /// User requested the panel to show ForceVisible, @@ -79,7 +82,7 @@ pub mod visibility { } /// The outwardly visible state. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Outcome { pub visibility: animation::Outcome, pub im: InputMethod, @@ -137,11 +140,12 @@ impl Outcome { /// All state changes return the next state and the optimal time for the next check. /// /// This state tracker can be driven by any event loop. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Application { pub im: InputMethod, pub visibility_override: visibility::State, pub physical_keyboard: Presence, + pub debug_mode_enabled: bool, /// The output on which the panel should appear. /// This is stored as part of the state /// because it's not clear how to derive the output from the rest of the state. @@ -163,13 +167,29 @@ impl Application { im: InputMethod::InactiveSince(now), visibility_override: visibility::State::NotForced, physical_keyboard: Presence::Missing, + debug_mode_enabled: false, preferred_output: None, outputs: Default::default(), } } - pub fn apply_event(self, event: Event, _now: Instant) -> Self { - match event { + pub fn apply_event(self, event: Event, now: Instant) -> Self { + if self.debug_mode_enabled { + println!( + "Received event: +{:#?}", + event, + ); + } + let state = match event { + Event::Debug(dbg) => Self { + debug_mode_enabled: match dbg { + debug::Event::Enable => true, + debug::Event::Disable => false, + }, + ..self + }, + Event::TimeoutReached(_) => self, Event::Visibility(visibility) => Self { @@ -235,7 +255,19 @@ impl Application { ..self }, } + }; + + if state.debug_mode_enabled { + println!( + "State is now: +{:#?} +Outcome: +{:#?}", + state, + state.get_outcome(now), + ); } + state } fn get_preferred_height(output: &OutputState) -> Option {