debug: Add dbus interface to control debug prints
This commit is contained in:
@ -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
1
debian/control
vendored
@ -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
71
src/debug.rs
Normal 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,
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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 _;
|
||||||
|
|||||||
50
src/state.rs
50
src/state.rs
@ -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> {
|
||||||
|
|||||||
Reference in New Issue
Block a user