From 5d173a46a65dbfacc9fc211f53e6166fe3801435 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 7 Mar 2023 22:20:44 +0100 Subject: [PATCH] shell: Fix missing titlebars --- src/backend/kms/mod.rs | 29 ++-- src/backend/render/mod.rs | 17 ++- src/shell/element/mod.rs | 2 + src/shell/element/window.rs | 178 ++++++++++++++++++++-- src/shell/layout/floating/grabs/moving.rs | 3 +- src/shell/layout/floating/mod.rs | 3 +- src/shell/layout/tiling/mod.rs | 3 +- src/shell/mod.rs | 2 +- src/shell/workspace.rs | 3 +- src/utils/iced.rs | 2 +- src/wayland/handlers/screencopy.rs | 4 +- 11 files changed, 208 insertions(+), 38 deletions(-) diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index 912f75a8..433ec1c2 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -1,7 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only +#[cfg(feature = "debug")] +use crate::backend::render::element::AsGlowRenderer; use crate::{ - backend::render::{element::CosmicElement, workspace_elements, CLEAR_COLOR}, + backend::render::{workspace_elements, CLEAR_COLOR}, config::OutputConfig, shell::Shell, state::{BackendData, ClientState, Common, Data, Fps}, @@ -944,15 +946,6 @@ impl Surface { return Ok(()); } - self.fps.start(); - #[cfg(feature = "debug")] - if let Some(rd) = self.fps.rd.as_mut() { - rd.start_frame_capture( - renderer.glow_renderer().egl_context().get_context_handle(), - std::ptr::null(), - ); - } - let compositor = self.surface.as_mut().unwrap(); let (render_node, mut renderer) = match render_node { Some((render_node, allocator)) => ( @@ -963,8 +956,17 @@ impl Surface { None => (target_node, api.single_renderer(&target_node).unwrap()), }; + self.fps.start(); + #[cfg(feature = "debug")] + if let Some(rd) = self.fps.rd.as_mut() { + rd.start_frame_capture( + renderer.glow_renderer().egl_context().get_context_handle(), + std::ptr::null(), + ); + } + let handle = state.shell.workspaces.active(&self.output).handle; - let elements: Vec>> = workspace_elements( + let elements = workspace_elements( Some(&render_node), &mut renderer, state, @@ -973,7 +975,10 @@ impl Surface { CursorMode::All, &mut Some(&mut self.fps), false, - )?; + ) + .map_err(|err| { + anyhow::format_err!("Failed to accumulate elements for rendering: {:?}", err) + })?; self.fps.elements(); let res = compositor.render_frame::<_, _, Gles2Renderbuffer>( diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 8f3e5336..76f853e1 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -12,7 +12,8 @@ use crate::{ }; use crate::{ shell::{ - layout::floating::SeatMoveGrabState, CosmicMappedRenderElement, WorkspaceRenderElement, + element::window::CosmicWindowRenderElement, layout::floating::SeatMoveGrabState, + CosmicMappedRenderElement, }, state::{Common, Fps}, utils::prelude::SeatExt, @@ -169,6 +170,7 @@ where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: Clone + 'static, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, E: From> + From>, { #[cfg(feature = "debug")] @@ -222,7 +224,7 @@ where elements } -pub fn workspace_elements( +pub fn workspace_elements( _gpu: Option<&DrmNode>, renderer: &mut R, state: &mut Common, @@ -231,19 +233,18 @@ pub fn workspace_elements( cursor_mode: CursorMode, _fps: &mut Option<&mut Fps>, exclude_workspace_overview: bool, -) -> Result, OutputNoMode> +) -> Result>, RenderError> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: Clone + 'static, + ::Error: From, CosmicMappedRenderElement: RenderElement, - E: From> - + From> - + From>, + CosmicWindowRenderElement: RenderElement, { #[cfg(feature = "debug")] puffin::profile_function!(); - let mut elements: Vec = cursor_elements(renderer, state, output, cursor_mode); + let mut elements = cursor_elements(renderer, state, output, cursor_mode); #[cfg(feature = "debug")] { @@ -336,6 +337,7 @@ where ::Error: From, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, Source: Clone, { let handle = state.shell.workspaces.active(output).handle; @@ -385,6 +387,7 @@ where ::Error: From, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, Source: Clone, { #[cfg(feature = "debug")] diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 9d28f9d9..702281d3 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -50,6 +50,7 @@ pub mod stack; pub use self::stack::CosmicStack; pub mod window; pub use self::window::CosmicWindow; +use self::window::CosmicWindowRenderElement; #[cfg(feature = "debug")] use egui::plot::{Corner, Legend, Plot, PlotPoints, Polygon}; @@ -886,6 +887,7 @@ where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, { type RenderElement = CosmicMappedRenderElement; fn render_elements>( diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 1627fbbb..06ff52d5 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -1,4 +1,8 @@ use crate::{ + backend::render::{ + element::{AsGlowFrame, AsGlowRenderer}, + GlMultiFrame, GlMultiRenderer, + }, shell::Shell, state::State, utils::{ @@ -8,7 +12,7 @@ use crate::{ wayland::handlers::screencopy::ScreencopySessions, }; use calloop::LoopHandle; -use cosmic::{iced_native::Command, Element}; +use cosmic::iced_native::Command; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; use iced_softbuffer::native::raqote::{DrawOptions, DrawTarget, PathBuilder, SolidSource, Source}; use smithay::{ @@ -17,8 +21,11 @@ use smithay::{ renderer::{ element::{ memory::MemoryRenderBufferRenderElement, surface::WaylandSurfaceRenderElement, - AsRenderElements, + AsRenderElements, Element, Id, RenderElement, }, + glow::GlowRenderer, + multigpu::Error as MultiError, + utils::CommitCounter, ImportAll, ImportMem, Renderer, }, }, @@ -29,8 +36,7 @@ use smithay::{ Seat, }, output::Output, - render_elements, - utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size}, + utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform}, wayland::seat::WaylandFocus, }; use std::{ @@ -240,7 +246,7 @@ impl Program for CosmicWindowInternal { target.pop_clip(); } - fn view(&self) -> Element<'_, Self::Message> { + fn view(&self) -> cosmic::Element<'_, Self::Message> { cosmic::widget::header_bar() .title(self.last_title.lock().unwrap().clone()) .on_drag(Message::DragStart) @@ -536,16 +542,162 @@ impl PointerTarget for CosmicWindow { } } -render_elements! { - pub CosmicWindowRenderElement where R: ImportAll + ImportMem; - Header=MemoryRenderBufferRenderElement, - Window=WaylandSurfaceRenderElement, +pub enum CosmicWindowRenderElement +where + R: ImportAll + ImportMem + AsGlowRenderer + Renderer, + ::TextureId: 'static, +{ + Header(MemoryRenderBufferRenderElement), + Window(WaylandSurfaceRenderElement), +} + +impl From> for CosmicWindowRenderElement +where + R: ImportAll + ImportMem + AsGlowRenderer + Renderer, + ::TextureId: 'static, +{ + fn from(elem: WaylandSurfaceRenderElement) -> Self { + CosmicWindowRenderElement::Window(elem) + } +} + +impl From> for CosmicWindowRenderElement +where + R: ImportAll + ImportMem + AsGlowRenderer + Renderer, + ::TextureId: 'static, +{ + fn from(elem: MemoryRenderBufferRenderElement) -> Self { + CosmicWindowRenderElement::Header(elem) + } +} + +impl Element for CosmicWindowRenderElement +where + R: AsGlowRenderer + Renderer + ImportAll + ImportMem, + ::TextureId: 'static, +{ + fn id(&self) -> &Id { + match self { + CosmicWindowRenderElement::Header(h) => h.id(), + CosmicWindowRenderElement::Window(w) => w.id(), + } + } + + fn current_commit(&self) -> CommitCounter { + match self { + CosmicWindowRenderElement::Header(h) => h.current_commit(), + CosmicWindowRenderElement::Window(w) => w.current_commit(), + } + } + + fn src(&self) -> Rectangle { + match self { + CosmicWindowRenderElement::Header(h) => h.src(), + CosmicWindowRenderElement::Window(w) => w.src(), + } + } + + fn geometry(&self, scale: Scale) -> Rectangle { + match self { + CosmicWindowRenderElement::Header(h) => h.geometry(scale), + CosmicWindowRenderElement::Window(w) => w.geometry(scale), + } + } + + fn location(&self, scale: Scale) -> Point { + match self { + CosmicWindowRenderElement::Header(h) => h.location(scale), + CosmicWindowRenderElement::Window(w) => w.location(scale), + } + } + + fn transform(&self) -> Transform { + match self { + CosmicWindowRenderElement::Header(h) => h.transform(), + CosmicWindowRenderElement::Window(w) => w.transform(), + } + } + + fn damage_since( + &self, + scale: Scale, + commit: Option, + ) -> Vec> { + match self { + CosmicWindowRenderElement::Header(h) => h.damage_since(scale, commit), + CosmicWindowRenderElement::Window(w) => w.damage_since(scale, commit), + } + } + + fn opaque_regions(&self, scale: Scale) -> Vec> { + match self { + CosmicWindowRenderElement::Header(h) => h.opaque_regions(scale), + CosmicWindowRenderElement::Window(w) => w.opaque_regions(scale), + } + } +} + +impl RenderElement for CosmicWindowRenderElement { + fn draw<'a>( + &self, + frame: &mut ::Frame<'a>, + src: Rectangle, + dst: Rectangle, + damage: &[Rectangle], + ) -> Result<(), ::Error> { + match self { + CosmicWindowRenderElement::Header(h) => h.draw(frame, src, dst, damage), + CosmicWindowRenderElement::Window(w) => w.draw(frame, src, dst, damage), + } + } + + fn underlying_storage( + &self, + renderer: &mut GlowRenderer, + ) -> Option { + match self { + CosmicWindowRenderElement::Header(h) => h.underlying_storage(renderer), + CosmicWindowRenderElement::Window(w) => w.underlying_storage(renderer), + } + } +} + +impl<'a, 'b> RenderElement> + for CosmicWindowRenderElement> +{ + fn draw<'c>( + &self, + frame: &mut GlMultiFrame<'a, 'b, 'c>, + src: Rectangle, + dst: Rectangle, + damage: &[Rectangle], + ) -> Result<(), as Renderer>::Error> { + match self { + CosmicWindowRenderElement::Header(h) => h + .draw(frame.glow_frame_mut(), src, dst, damage) + .map_err(|err| MultiError::Render(err)), + CosmicWindowRenderElement::Window(w) => w.draw(frame, src, dst, damage), + } + } + + fn underlying_storage( + &self, + renderer: &mut GlMultiRenderer<'a, 'b>, + ) -> Option { + match self { + CosmicWindowRenderElement::Header(h) => { + h.underlying_storage(renderer.glow_renderer_mut()) + } + CosmicWindowRenderElement::Window(w) => w.underlying_storage(renderer), + } + } } impl AsRenderElements for CosmicWindow where - R: Renderer + ImportAll + ImportMem, + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, + CosmicWindowRenderElement: RenderElement, { type RenderElement = CosmicWindowRenderElement; fn render_elements>( @@ -568,9 +720,11 @@ where ) }); if has_ssd { - elements.extend(AsRenderElements::::render_elements::< + elements.extend(AsRenderElements::::render_elements::< CosmicWindowRenderElement, - >(&self.0, renderer, location, scale)) + >( + &self.0, renderer.glow_renderer_mut(), location, scale + )) } elements.into_iter().map(C::from).collect() diff --git a/src/shell/layout/floating/grabs/moving.rs b/src/shell/layout/floating/grabs/moving.rs index 9ef4ace6..5e2f2cd1 100644 --- a/src/shell/layout/floating/grabs/moving.rs +++ b/src/shell/layout/floating/grabs/moving.rs @@ -3,7 +3,7 @@ use crate::{ backend::render::{element::AsGlowRenderer, IndicatorShader}, shell::{ - element::{CosmicMapped, CosmicMappedRenderElement}, + element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, focus::target::{KeyboardFocusTarget, PointerFocusTarget}, }, utils::prelude::*, @@ -42,6 +42,7 @@ impl MoveGrabState { R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, I: From>, { #[cfg(feature = "debug")] diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index ddcb5f59..3b380ec2 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -15,7 +15,7 @@ use std::collections::HashMap; use crate::{ backend::render::{element::AsGlowRenderer, IndicatorShader}, shell::{ - element::{CosmicMapped, CosmicMappedRenderElement}, + element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, grabs::ResizeEdge, CosmicSurface, }, @@ -354,6 +354,7 @@ impl FloatingLayout { R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, { #[cfg(feature = "debug")] puffin::profile_function!(); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index e2b97cda..9223b656 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -3,7 +3,7 @@ use crate::{ backend::render::{element::AsGlowRenderer, IndicatorShader}, shell::{ - element::{CosmicMapped, CosmicMappedRenderElement}, + element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, focus::{ target::{KeyboardFocusTarget, WindowGroup}, FocusDirection, @@ -1311,6 +1311,7 @@ impl TilingLayout { R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, { #[cfg(feature = "debug")] puffin::profile_function!(); diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 44321fa7..6668cfe3 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -40,7 +40,7 @@ use crate::{ }, }; -mod element; +pub mod element; pub mod focus; pub mod grabs; pub mod layout; diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index e49c5883..ac512887 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -35,7 +35,7 @@ use std::collections::HashMap; use tracing::warn; use super::{ - element::CosmicMapped, + element::{window::CosmicWindowRenderElement, CosmicMapped}, focus::{FocusStack, FocusStackMut}, grabs::{ResizeEdge, ResizeGrab}, CosmicMappedRenderElement, CosmicSurface, @@ -445,6 +445,7 @@ impl Workspace { R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, { #[cfg(feature = "debug")] puffin::profile_function!(); diff --git a/src/utils/iced.rs b/src/utils/iced.rs index 9d833adb..f7ede6c8 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -230,10 +230,10 @@ impl IcedElement

{ pub fn force_update(&self) { let mut internal = self.0.lock().unwrap(); - internal.update(true); for (_buffer, ref mut needs_redraw) in internal.buffers.values_mut() { *needs_redraw = true; } + internal.update(true); } } diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index ba0cebea..033b18b8 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -47,7 +47,7 @@ use crate::{ element::{AsGlowRenderer, CosmicElement}, render_output, render_workspace, CursorMode, CLEAR_COLOR, }, - shell::{CosmicMappedRenderElement, CosmicSurface}, + shell::{element::window::CosmicWindowRenderElement, CosmicMappedRenderElement, CosmicSurface}, state::{BackendData, ClientState, Common, Data, State}, utils::prelude::OutputExt, wayland::protocols::{ @@ -627,6 +627,7 @@ pub fn render_output_to_buffer( ::Error: From, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, { let cursor_mode = match session.cursor_mode() { ScreencopyCursorMode::Embedded => CursorMode::All, @@ -756,6 +757,7 @@ pub fn render_workspace_to_buffer( ::Error: From, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, { let cursor_mode = match session.cursor_mode() { ScreencopyCursorMode::Embedded => CursorMode::All,