From 9933d64ed238f14504ab69c4962ceb5934529c56 Mon Sep 17 00:00:00 2001 From: Ottatop Date: Wed, 10 Apr 2024 07:13:16 -0500 Subject: [PATCH] Fix hang when layer shell nested popup appears And also some minor changes, also there is a possibility that switching back to the tty Pinnacle is in will lead to a black screen, really need to find a way to reproduce --- src/backend/udev.rs | 92 +++++++++++++++++++-------------------- src/handlers/xdg_shell.rs | 23 ++++++++++ src/render.rs | 25 +++++------ 3 files changed, 79 insertions(+), 61 deletions(-) diff --git a/src/backend/udev.rs b/src/backend/udev.rs index a31ea64..9243757 100644 --- a/src/backend/udev.rs +++ b/src/backend/udev.rs @@ -90,7 +90,7 @@ use crate::{ output::OutputName, render::{ pointer::PointerElement, pointer_render_elements, take_presentation_feedback, - OutputRenderElements, + OutputRenderElement, }, state::{State, SurfaceDmabufFeedback, WithState}, }; @@ -119,7 +119,7 @@ type UdevRenderFrameResult<'a> = RenderFrameResult< 'a, BufferObject<()>, GbmFramebuffer, - OutputRenderElements, WaylandSurfaceRenderElement>>, + OutputRenderElement, WaylandSurfaceRenderElement>>, >; /// Udev state attached to each [`Output`]. @@ -513,53 +513,51 @@ pub fn setup_udev( state.device_changed(node); - { - // Apply pending gammas - // - // Also welcome to some really doodoo code + // Apply pending gammas + // + // Also welcome to some really doodoo code - let udev = state.backend.udev_mut(); - let Some(backend) = udev.backends.get_mut(&node) else { - unreachable!(); - }; - for (crtc, surface) in backend.surfaces.iter_mut() { - match std::mem::take(&mut surface.pending_gamma_change) { - PendingGammaChange::Idle => { - debug!("Restoring from previous gamma"); - if let Err(err) = Udev::set_gamma_internal( - &backend.drm, - crtc, - surface.previous_gamma.clone(), - ) { - warn!("Failed to reset gamma: {err}"); - surface.previous_gamma = None; - } - } - PendingGammaChange::Restore => { - debug!("Restoring to original gamma"); - if let Err(err) = Udev::set_gamma_internal( - &backend.drm, - crtc, - None::<[&[u16]; 3]>, - ) { - warn!("Failed to reset gamma: {err}"); - } + let udev = state.backend.udev_mut(); + let Some(backend) = udev.backends.get_mut(&node) else { + unreachable!(); + }; + for (crtc, surface) in backend.surfaces.iter_mut() { + match std::mem::take(&mut surface.pending_gamma_change) { + PendingGammaChange::Idle => { + debug!("Restoring from previous gamma"); + if let Err(err) = Udev::set_gamma_internal( + &backend.drm, + crtc, + surface.previous_gamma.clone(), + ) { + warn!("Failed to reset gamma: {err}"); surface.previous_gamma = None; } - PendingGammaChange::Change(gamma) => { - debug!("Changing to pending gamma"); - match Udev::set_gamma_internal( - &backend.drm, - crtc, - Some([&gamma[0], &gamma[1], &gamma[2]]), - ) { - Ok(()) => { - surface.previous_gamma = Some(gamma); - } - Err(err) => { - warn!("Failed to set pending gamma: {err}"); - surface.previous_gamma = None; - } + } + PendingGammaChange::Restore => { + debug!("Restoring to original gamma"); + if let Err(err) = Udev::set_gamma_internal( + &backend.drm, + crtc, + None::<[&[u16]; 3]>, + ) { + warn!("Failed to reset gamma: {err}"); + } + surface.previous_gamma = None; + } + PendingGammaChange::Change(gamma) => { + debug!("Changing to pending gamma"); + match Udev::set_gamma_internal( + &backend.drm, + crtc, + Some([&gamma[0], &gamma[1], &gamma[2]]), + ) { + Ok(()) => { + surface.previous_gamma = Some(gamma); + } + Err(err) => { + warn!("Failed to set pending gamma: {err}"); + surface.previous_gamma = None; } } } @@ -863,7 +861,7 @@ type GbmDrmCompositor = DrmCompositor< fn render_frame<'a>( compositor: &mut GbmDrmCompositor, renderer: &mut UdevRenderer<'a>, - elements: &'a [OutputRenderElements< + elements: &'a [OutputRenderElement< UdevRenderer<'a>, WaylandSurfaceRenderElement>, >], diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index beb8c83..01ccff9 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -154,6 +154,29 @@ impl XdgShellHandler for State { .unwrap_or_else(|| (0, 0).into()); tracing::debug!(?loc); break; + } else { + let layer_and_op = self.space.outputs().find_map(|op| { + let layer_map = layer_map_for_output(op); + + let ret = layer_map + .layers() + .find(|l| l.wl_surface() == s) + .cloned() + .map(|layer| { + ( + layer_map.layer_geometry(&layer).unwrap_or_default(), + op.clone(), + ) + }); + + ret + }); + + if let Some((layer_geo, op)) = layer_and_op { + let op_loc = self.space.output_geometry(&op).unwrap_or_default().loc; + loc += layer_geo.loc + op_loc; + break; + } } } diff --git a/src/render.rs b/src/render.rs index c6182fe..4c1cd4f 100644 --- a/src/render.rs +++ b/src/render.rs @@ -46,7 +46,7 @@ render_elements! { } render_elements! { - pub OutputRenderElements where R: ImportAll + ImportMem; + pub OutputRenderElement where R: ImportAll + ImportMem; Custom = Wrap, Surface = WaylandSurfaceRenderElement, Pointer = PointerRenderElement, @@ -137,16 +137,13 @@ fn window_render_elements( renderer: &mut R, scale: Scale, ) -> ( - Vec>>, - Vec>>, + Vec>>, + Vec>>, ) where R: Renderer + ImportAll + ImportMem, ::TextureId: 'static, { - // bot wwwwwFFww top - // rev wwFFwwwww - let mut last_fullscreen_split_at = 0; let mut elements = windows @@ -180,9 +177,9 @@ where Some(rect) => { elems.into_iter().filter_map(|elem| { CropRenderElement::from_element(elem, scale, rect.to_physical_precise_round(scale)) - }).map(TransformRenderElement::from).map(OutputRenderElements::from).collect::>() + }).map(TransformRenderElement::from).map(OutputRenderElement::from).collect::>() }, - None => elems.into_iter().map(OutputRenderElements::from).collect(), + None => elems.into_iter().map(OutputRenderElement::from).collect(), } }).collect::>(); @@ -203,7 +200,7 @@ pub fn pointer_render_elements( cursor_status: &mut CursorImageStatus, dnd_icon: Option<&WlSurface>, pointer_element: &PointerElement<::TextureId>, -) -> Vec>> +) -> Vec>> where R: Renderer + ImportAll, ::TextureId: Clone + 'static, @@ -264,7 +261,7 @@ pub fn generate_render_elements( renderer: &mut R, space: &Space, windows: &[WindowElement], -) -> Vec>> +) -> Vec>> where R: Renderer + ImportAll + ImportMem, ::TextureId: 'static, @@ -272,7 +269,7 @@ where { let scale = Scale::from(output.current_scale().fractional_scale()); - let mut output_render_elements: Vec> = Vec::new(); + let mut output_render_elements: Vec> = Vec::new(); let (windows, override_redirect_windows) = windows .iter() @@ -309,7 +306,7 @@ where // TODO: don't unconditionally render OR windows above fullscreen ones, // | base it on if it's a descendant or not - output_render_elements.extend(o_r_elements.map(OutputRenderElements::from)); + output_render_elements.extend(o_r_elements.map(OutputRenderElement::from)); let LayerRenderElements { background, @@ -329,7 +326,7 @@ where overlay .into_iter() .chain(top) - .map(OutputRenderElements::from), + .map(OutputRenderElement::from), ); output_render_elements.extend(rest_of_window_elements); @@ -338,7 +335,7 @@ where bottom .into_iter() .chain(background) - .map(OutputRenderElements::from), + .map(OutputRenderElement::from), ); output_render_elements