debug: Wire up egui-interface

This commit is contained in:
Victoria Brekenfeld 2022-01-11 17:22:23 +01:00
parent 57d94515d5
commit 928ce9c6f6
6 changed files with 328 additions and 50 deletions

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::state::Common;
use crate::{
input::{set_active_output, Devices},
state::{BackendData, State},
@ -15,7 +16,7 @@ use smithay::{
renderer::{gles2::Gles2Renderer, Bind, ImportDma, ImportEgl, Unbind},
x11::{Window, WindowBuilder, X11Backend, X11Event, X11Handle, X11Input, X11Surface},
},
desktop::{layer_map_for_output, Space},
desktop::layer_map_for_output,
reexports::{
calloop::{ping, EventLoop, LoopHandle},
gbm::Device as GbmDevice,
@ -33,7 +34,6 @@ use std::{
cell::RefCell,
rc::Rc,
sync::{Arc, Mutex},
time::Instant,
};
pub struct X11State {
@ -96,10 +96,10 @@ impl X11State {
.iter_mut()
.find(|s| s.output == output_ref)
{
if let Err(err) = surface.render_from_space(
if let Err(err) = surface.render_output(
&mut *x11_state.renderer.borrow_mut(),
state.common.spaces.active_space_mut(&output_ref),
&state.common.start_time,
&output_ref,
&mut state.common,
) {
slog_scope::error!("Error rendering: {}", err);
}
@ -130,12 +130,41 @@ pub struct Surface {
}
impl Surface {
pub fn render_from_space(
pub fn render_output(
&mut self,
renderer: &mut Gles2Renderer,
space: &mut Space,
start_time: &Instant,
output: &Output,
state: &mut Common,
) -> Result<()> {
#[allow(unused_mut)]
let mut custom_elements = Vec::new();
let space = state.spaces.active_space_mut(output);
#[cfg(feature = "debug")]
if state.egui.active {
let size = space.output_geometry(&self.output).unwrap();
let scale = space.output_scale(&self.output).unwrap();
let frame = state.egui.state.run(
|ctx| {
egui::SidePanel::left("my_left_panel").show(ctx, |ui| {
ui.label(format!(
"cosmic-comp version {}",
std::env!("CARGO_PKG_VERSION")
));
});
},
size,
size.to_f64().to_physical(scale).to_i32_round().size,
scale,
state.egui.alpha,
&state.start_time,
state.egui.modifiers.clone(),
);
custom_elements.push(
Box::new(frame) as smithay::desktop::space::DynamicRenderElements<Gles2Renderer>
);
}
let (buffer, age) = self
.surface
.buffer()
@ -148,11 +177,11 @@ impl Surface {
&self.output,
age as usize,
[0.153, 0.161, 0.165, 1.0],
&[],
&*custom_elements,
) {
Ok(Some(_)) => {
slog_scope::trace!("Finished rendering");
space.send_frames(false, start_time.elapsed().as_millis() as u32);
space.send_frames(false, state.start_time.elapsed().as_millis() as u32);
self.surface
.submit()
.with_context(|| "Failed to submit buffer for display")?;

View file

@ -2,14 +2,14 @@
use crate::state::State;
use smithay::{
backend::input::{Device, DeviceCapability, InputBackend, InputEvent},
backend::input::{Device, DeviceCapability, InputBackend, InputEvent, KeyState},
desktop::{layer_map_for_output, Space},
reexports::wayland_server::{protocol::wl_surface::WlSurface, Display},
utils::{Logical, Point},
wayland::{
data_device::set_data_device_focus,
output::Output,
seat::{CursorImageStatus, FilterResult, Keysym, Seat, XkbConfig},
seat::{keysyms, CursorImageStatus, FilterResult, KeysymHandle, Seat, XkbConfig},
shell::wlr_layer::Layer as WlrLayer,
SERIAL_COUNTER,
},
@ -17,9 +17,29 @@ use smithay::{
use std::{cell::RefCell, collections::HashMap};
pub struct ActiveOutput(pub RefCell<Output>);
pub struct SupressedKeys(RefCell<Vec<u32>>);
pub struct Devices(RefCell<HashMap<String, Vec<DeviceCapability>>>);
impl SupressedKeys {
fn new() -> SupressedKeys {
SupressedKeys(RefCell::new(Vec::new()))
}
fn add(&self, keysym: &KeysymHandle) {
self.0.borrow_mut().push(keysym.raw_code());
}
fn filter(&self, keysym: &KeysymHandle) -> bool {
let mut keys = self.0.borrow_mut();
if let Some(i) = keys.iter().position(|x| *x == keysym.raw_code()) {
keys.remove(i);
true
} else {
false
}
}
}
impl Devices {
fn new() -> Devices {
Devices(RefCell::new(HashMap::new()))
@ -61,8 +81,8 @@ pub fn add_seat(display: &mut Display, name: String) -> Seat {
let (seat, _) = Seat::new(display, name, None);
let userdata = seat.user_data();
userdata.insert_if_missing(|| Devices::new());
userdata.insert_if_missing(|| SupressedKeys::new());
userdata.insert_if_missing(|| RefCell::new(CursorImageStatus::Hidden));
userdata.insert_if_missing(|| Vec::<Keysym>::new());
seat
}
@ -137,6 +157,10 @@ impl State {
_ => {}
}
}
#[cfg(feature = "debug")]
{
self.common.egui.state.handle_device_added(&device);
}
}
InputEvent::DeviceRemoved { device } => {
for seat in &mut self.common.seats {
@ -157,6 +181,10 @@ impl State {
break;
}
}
#[cfg(feature = "debug")]
{
self.common.egui.state.handle_device_added(&device);
}
}
InputEvent::Keyboard { event, .. } => {
use smithay::backend::input::KeyboardKeyEvent;
@ -179,6 +207,37 @@ impl State {
time,
|modifiers, handle| {
// here we can handle global shortcuts and the like
if userdata.get::<SupressedKeys>().unwrap().filter(&handle) {
return FilterResult::Intercept(());
}
#[cfg(feature = "debug")]
{
self.common.egui.modifiers = modifiers.clone();
if self.common.seats.iter().position(|x| x == seat).unwrap()
== 0
&& modifiers.logo
&& handle.raw_syms().contains(&keysyms::KEY_Escape)
&& state == KeyState::Pressed
{
self.common.egui.active = !self.common.egui.active;
userdata.get::<SupressedKeys>().unwrap().add(&handle);
return FilterResult::Intercept(());
}
if self.common.seats.iter().position(|x| x == seat).unwrap()
== 0
&& self.common.egui.active
&& self.common.egui.state.wants_keyboard()
{
self.common.egui.state.handle_keyboard(
handle.raw_syms(),
state == KeyState::Pressed,
modifiers.clone(),
);
return FilterResult::Intercept(());
}
}
let _ = (modifiers, handle);
FilterResult::Forward
},
@ -233,6 +292,13 @@ impl State {
.unwrap()
.motion(position, under, serial, event.time());
#[cfg(feature = "debug")]
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0 {
self.common
.egui
.state
.handle_pointer_motion(position.to_i32_round());
}
break;
}
}
@ -256,6 +322,14 @@ impl State {
seat.get_pointer()
.unwrap()
.motion(position, under, serial, event.time());
#[cfg(feature = "debug")]
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0 {
self.common
.egui
.state
.handle_pointer_motion(position.to_i32_round());
}
break;
}
}
@ -271,6 +345,21 @@ impl State {
let userdata = seat.user_data();
let devices = userdata.get::<Devices>().unwrap();
if devices.has_device(&device) {
#[cfg(feature = "debug")]
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0
&& self.common.egui.active
&& self.common.egui.state.wants_pointer()
{
if let Some(button) = event.button() {
self.common.egui.state.handle_pointer_button(
button,
event.state() == ButtonState::Pressed,
self.common.egui.modifiers.clone(),
);
}
break;
}
let serial = SERIAL_COUNTER.next_serial();
let button = event.button_code();
let state = match event.state() {
@ -340,6 +429,24 @@ impl State {
let device = event.device();
for seat in self.common.seats.clone().iter() {
#[cfg(feature = "debug")]
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0
&& self.common.egui.active
&& self.common.egui.state.wants_pointer()
{
self.common.egui.state.handle_pointer_axis(
event
.amount_discrete(Axis::Horizontal)
.or_else(|| event.amount(Axis::Horizontal).map(|x| x * 3.0))
.unwrap_or(0.0),
event
.amount_discrete(Axis::Vertical)
.or_else(|| event.amount(Axis::Vertical).map(|x| x * 3.0))
.unwrap_or(0.0),
);
break;
}
let userdata = seat.user_data();
let devices = userdata.get::<Devices>().unwrap();
if devices.has_device(&device) {

View file

@ -67,7 +67,7 @@ fn init_logger() -> Result<slog_scope::GlobalLoggerGuard> {
slog_stdlog::init().unwrap();
slog_scope::info!("Version: {}", std::env!("CARGO_PKG_VERSION"));
if cfg!(debug_assertions) {
if cfg!(feature = "debug") {
slog_scope::debug!(
"Debug build ({})",
std::option_env!("GIT_HASH").unwrap_or("Unknown")

View file

@ -33,6 +33,17 @@ pub struct Common {
pub start_time: Instant,
pub should_stop: bool,
#[cfg(feature = "debug")]
pub egui: Egui,
}
#[cfg(feature = "debug")]
pub struct Egui {
pub state: smithay_egui::EguiState,
pub modifiers: smithay::wayland::seat::ModifiersState,
pub active: bool,
pub alpha: f32,
}
pub enum BackendData {
@ -78,6 +89,14 @@ impl State {
start_time: Instant::now(),
should_stop: false,
#[cfg(feature = "debug")]
egui: Egui {
state: smithay_egui::EguiState::new(),
modifiers: Default::default(),
active: false,
alpha: 1.0,
},
},
backend: BackendData::Unset,
}