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