diff --git a/README.md b/README.md index affc4fb..65b1466 100644 --- a/README.md +++ b/README.md @@ -25,3 +25,13 @@ automatically loads `$XDG_CONFIG_HOME/catacomb/post_start.sh` (or `~/.config/catacomb/post_start.sh` if `XDG_CONFIG_HOME` is not defined). You can find an example configuration [here](./post_start.sh). + +## Controls + +| Open application overview | Minimize everything | Close applications | +| ------------------------------------------- | -------------------------------- | -------------------------- | +| ![open overview](./docs/enter_overview.mp4) | ![minimize](./docs/minimize.mp4) | ![close](./docs/close.mp4) | + +| Double-tap to cycle | Tiling | +| -------------------------- | ---------------------------- | +| ![cycle](./docs/cycle.mp4) | ![tiling](./docs/tiling.mp4) | diff --git a/docs/close.mp4 b/docs/close.mp4 new file mode 100644 index 0000000..36eb819 Binary files /dev/null and b/docs/close.mp4 differ diff --git a/docs/cycle.mp4 b/docs/cycle.mp4 new file mode 100644 index 0000000..1a4da95 Binary files /dev/null and b/docs/cycle.mp4 differ diff --git a/docs/enter_overview.mp4 b/docs/enter_overview.mp4 new file mode 100644 index 0000000..9365ea6 Binary files /dev/null and b/docs/enter_overview.mp4 differ diff --git a/docs/minimize.mp4 b/docs/minimize.mp4 new file mode 100644 index 0000000..1183457 Binary files /dev/null and b/docs/minimize.mp4 differ diff --git a/docs/tiling.mp4 b/docs/tiling.mp4 new file mode 100644 index 0000000..afd9b1e Binary files /dev/null and b/docs/tiling.mp4 differ diff --git a/src/catacomb.rs b/src/catacomb.rs index 4150169..dd01a15 100644 --- a/src/catacomb.rs +++ b/src/catacomb.rs @@ -370,14 +370,14 @@ impl Catacomb { self.idle_notifier_state.set_is_inhibited(inhibited); // Redraw only when there is damage present. - if self.windows.damaged() { + if true || self.windows.damaged() { // Apply pending client updates. if let Some(renderer) = self.backend.renderer() { self.windows.import_buffers(renderer); } // Draw all visible clients. - let rendered = self.backend.render(&mut self.windows); + let rendered = self.backend.render(&mut self.windows, &self.touch_state); // Update render time prediction. let frame_interval = self.output().frame_interval(); diff --git a/src/drawing.rs b/src/drawing.rs index b03540a..fb19a3b 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -323,6 +323,7 @@ pub struct Graphics { pub active_drop_target: RenderTexture, pub urgency_icon: RenderTexture, pub drop_target: RenderTexture, + pub touch: RenderTexture, gesture_handle_default: Option, gesture_handle_blocked: Option, @@ -337,10 +338,13 @@ impl Graphics { let urgency_icon = Texture::from_buffer(renderer, 1., &URGENCY_ICON_RGBA, 1, 1, true); + let touch = Texture::from_buffer(renderer, 1., &[150, 150, 150, 255], 1, 1, true); + Self { active_drop_target: RenderTexture::new(active_drop_target), urgency_icon: RenderTexture::new(urgency_icon), drop_target: RenderTexture::new(drop_target), + touch: RenderTexture::new(touch), gesture_handle_default: None, gesture_handle_blocked: None, gesture_handle_locked: None, diff --git a/src/input.rs b/src/input.rs index 77daa7c..c267ce7 100644 --- a/src/input.rs +++ b/src/input.rs @@ -57,7 +57,7 @@ pub struct TouchState { active_app_id: Option, velocity: Point, events: Vec, - slot: Option, + pub slot: Option, start: TouchStart, last_tap: Instant, is_drag: bool, diff --git a/src/udev.rs b/src/udev.rs index 2874746..0a8b940 100644 --- a/src/udev.rs +++ b/src/udev.rs @@ -53,6 +53,7 @@ use tracing::{debug, error}; use crate::catacomb::Catacomb; use crate::drawing::{CatacombElement, Graphics}; +use crate::input::TouchState; use crate::output::Output; use crate::protocols::screencopy::frame::Screencopy; use crate::trace_error; @@ -245,13 +246,13 @@ impl Udev { /// Render a frame. /// /// Will return `true` if something was rendered. - pub fn render(&mut self, windows: &mut Windows) -> bool { + pub fn render(&mut self, windows: &mut Windows, touch: &TouchState) -> bool { let output_device = match &mut self.output_device { Some(output_device) => output_device, None => return false, }; - match output_device.render(&self.event_loop, windows) { + match output_device.render(&self.event_loop, windows, touch) { Ok(rendered) => rendered, Err(err) => { error!("{err}"); @@ -619,13 +620,14 @@ impl OutputDevice { &mut self, event_loop: &LoopHandle<'static, Catacomb>, windows: &mut Windows, + touch: &TouchState, ) -> Result> { let scale = windows.output().scale(); // Update output mode since we're using static for transforms. self.drm_compositor.set_output_mode_source(windows.canvas().into()); - let textures = windows.textures(&mut self.gles, &mut self.graphics); + let textures = windows.textures(&mut self.gles, &mut self.graphics, touch); let mut frame_result = self.drm_compositor.render_frame(&mut self.gles, textures, CLEAR_COLOR)?; let rendered = !frame_result.is_empty; @@ -650,7 +652,7 @@ impl OutputDevice { return Err(format!("unsupported buffer format: {buffer_type:?}").into()); } - self.copy_framebuffer_shm(windows, region, buffer)? + self.copy_framebuffer_shm(windows, region, buffer, touch)? }; // Wait for OpenGL sync to submit screencopy, frame. @@ -709,6 +711,7 @@ impl OutputDevice { windows: &mut Windows, region: Rectangle, buffer: &WlBuffer, + touch: &TouchState, ) -> Result> { // Create and bind an offscreen render buffer. let buffer_dimensions = renderer::buffer_dimensions(buffer).unwrap(); @@ -725,7 +728,7 @@ impl OutputDevice { let damage = transform.transform_rect_in(region, &output_size); // Collect textures for rendering. - let textures = windows.textures(&mut self.gles, &mut self.graphics); + let textures = windows.textures(&mut self.gles, &mut self.graphics, touch); // Initialize the buffer to our clear color. let mut frame = self.gles.render(output_size, transform)?; diff --git a/src/windows/mod.rs b/src/windows/mod.rs index dcdba3d..ba1ef7a 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -368,6 +368,7 @@ impl Windows { &mut self, renderer: &mut GlesRenderer, graphics: &mut Graphics, + touch: &TouchState, ) -> &[CatacombElement] { // Clear global damage. self.dirty = false; @@ -375,6 +376,20 @@ impl Windows { let scale = self.output.scale(); self.textures.clear(); + if touch.slot.is_some() { + let mut touch_location = touch.position.to_physical(scale).to_i32_round(); + touch_location.y -= 15; + let touch_bounds = Rectangle::from_loc_and_size(touch_location, (20, 20)); + CatacombElement::add_element( + &mut self.textures, + graphics.touch.clone(), + touch_location, + touch_bounds, + 10., + scale, + ); + } + // Draw gesture handle when not in fullscreen/lock view. if !matches!(self.view, View::Fullscreen(_) | View::Lock(_)) { // Get texture for gesture handle.