debug: Add dbus interface to control debug prints

This commit is contained in:
Dorota Czaplejewicz
2022-01-28 12:14:24 +00:00
parent 5a210712f6
commit bbceba7e9b
6 changed files with 123 additions and 9 deletions

View File

@ -1,6 +1,10 @@
# Dependencies which change based on build flags # Dependencies which change based on build flags
bitflags = "1.2.*" bitflags = "1.2.*"
clap = { version = "2.33.*", default-features = false } 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] [dependencies.cairo-rs]
version = "0.7.*" version = "0.7.*"

1
debian/control vendored
View File

@ -23,6 +23,7 @@ Build-Depends:
librust-serde-derive-1-dev (>= 1.0), librust-serde-derive-1-dev (>= 1.0),
librust-serde-yaml-0.8-dev (>= 0.8), librust-serde-yaml-0.8-dev (>= 0.8),
librust-xkbcommon-0.4+wayland-dev (>= 0.4), librust-xkbcommon-0.4+wayland-dev (>= 0.4),
librust-zbus-dev (>=1.0),
libwayland-dev (>= 1.16), libwayland-dev (>= 1.16),
lsb-release, lsb-release,
python3, python3,

71
src/debug.rs Normal file
View File

@ -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<dyn std::error::Error>> {
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,
}

View File

@ -13,6 +13,8 @@ extern crate gtk_sys;
extern crate maplit; extern crate maplit;
extern crate serde; extern crate serde;
extern crate xkbcommon; extern crate xkbcommon;
extern crate zbus;
extern crate zvariant;
#[cfg(test)] #[cfg(test)]
#[macro_use] #[macro_use]
@ -23,6 +25,7 @@ mod logging;
mod action; mod action;
mod animation; mod animation;
pub mod data; pub mod data;
mod debug;
mod drawing; mod drawing;
mod event_loop; mod event_loop;
pub mod float_ord; pub mod float_ord;

View File

@ -4,6 +4,7 @@
/*! Glue for the main loop. */ /*! Glue for the main loop. */
use crate::outputs::OutputId; use crate::outputs::OutputId;
use crate::debug;
use crate::state; use crate::state;
use glib::{Continue, MainContext, PRIORITY_DEFAULT, Receiver}; use glib::{Continue, MainContext, PRIORITY_DEFAULT, Receiver};
@ -94,6 +95,8 @@ mod c {
let now = Instant::now(); let now = Instant::now();
let state_manager = driver::Threaded::new(sender, state::Application::new(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 outputs = Outputs::new(state_manager.clone());
let mut wayland = Box::new(Wayland::new(outputs)); let mut wayland = Box::new(Wayland::new(outputs));
let wayland_raw = &mut *wayland as *mut _; let wayland_raw = &mut *wayland as *mut _;

View File

@ -6,6 +6,7 @@
* It's driven by the loop defined in the loop module. */ * It's driven by the loop defined in the loop module. */
use crate::animation; use crate::animation;
use crate::debug;
use crate::imservice::{ ContentHint, ContentPurpose }; use crate::imservice::{ ContentHint, ContentPurpose };
use crate::main::{ Commands, PanelCommand, PixelSize }; use crate::main::{ Commands, PanelCommand, PixelSize };
use crate::outputs; use crate::outputs;
@ -14,19 +15,20 @@ use std::cmp;
use std::collections::HashMap; use std::collections::HashMap;
use std::time::Instant; use std::time::Instant;
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
pub enum Presence { pub enum Presence {
Present, Present,
Missing, Missing,
} }
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct InputMethodDetails { pub struct InputMethodDetails {
pub hint: ContentHint, pub hint: ContentHint,
pub purpose: ContentPurpose, pub purpose: ContentPurpose,
} }
#[derive(Clone)] #[derive(Clone, Debug)]
pub enum InputMethod { pub enum InputMethod {
Active(InputMethodDetails), Active(InputMethodDetails),
InactiveSince(Instant), InactiveSince(Instant),
@ -34,12 +36,13 @@ pub enum InputMethod {
/// Incoming events. /// Incoming events.
/// This contains events that cause a change to the internal state. /// This contains events that cause a change to the internal state.
#[derive(Clone)] #[derive(Clone, Debug)]
pub enum Event { pub enum Event {
InputMethod(InputMethod), InputMethod(InputMethod),
Visibility(visibility::Event), Visibility(visibility::Event),
PhysicalKeyboard(Presence), PhysicalKeyboard(Presence),
Output(outputs::Event), Output(outputs::Event),
Debug(debug::Event),
/// Event triggered because a moment in time passed. /// Event triggered because a moment in time passed.
/// Use to animate state transitions. /// Use to animate state transitions.
/// The value is the ideal arrival time. /// The value is the ideal arrival time.
@ -59,7 +62,7 @@ impl From<outputs::Event> for Event {
} }
pub mod visibility { pub mod visibility {
#[derive(Clone)] #[derive(Clone, Debug)]
pub enum Event { pub enum Event {
/// User requested the panel to show /// User requested the panel to show
ForceVisible, ForceVisible,
@ -79,7 +82,7 @@ pub mod visibility {
} }
/// The outwardly visible state. /// The outwardly visible state.
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct Outcome { pub struct Outcome {
pub visibility: animation::Outcome, pub visibility: animation::Outcome,
pub im: InputMethod, pub im: InputMethod,
@ -137,11 +140,12 @@ impl Outcome {
/// All state changes return the next state and the optimal time for the next check. /// 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. /// This state tracker can be driven by any event loop.
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct Application { pub struct Application {
pub im: InputMethod, pub im: InputMethod,
pub visibility_override: visibility::State, pub visibility_override: visibility::State,
pub physical_keyboard: Presence, pub physical_keyboard: Presence,
pub debug_mode_enabled: bool,
/// The output on which the panel should appear. /// The output on which the panel should appear.
/// This is stored as part of the state /// This is stored as part of the state
/// because it's not clear how to derive the output from the rest 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), im: InputMethod::InactiveSince(now),
visibility_override: visibility::State::NotForced, visibility_override: visibility::State::NotForced,
physical_keyboard: Presence::Missing, physical_keyboard: Presence::Missing,
debug_mode_enabled: false,
preferred_output: None, preferred_output: None,
outputs: Default::default(), outputs: Default::default(),
} }
} }
pub fn apply_event(self, event: Event, _now: Instant) -> Self { pub fn apply_event(self, event: Event, now: Instant) -> Self {
match event { 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::TimeoutReached(_) => self,
Event::Visibility(visibility) => Self { Event::Visibility(visibility) => Self {
@ -235,7 +255,19 @@ impl Application {
..self ..self
}, },
} }
};
if state.debug_mode_enabled {
println!(
"State is now:
{:#?}
Outcome:
{:#?}",
state,
state.get_outcome(now),
);
} }
state
} }
fn get_preferred_height(output: &OutputState) -> Option<PixelSize> { fn get_preferred_height(output: &OutputState) -> Option<PixelSize> {