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
This commit is contained in:
Ottatop 2024-04-10 07:13:16 -05:00
parent 589b0b135f
commit 9933d64ed2
3 changed files with 79 additions and 61 deletions

View file

@ -90,7 +90,7 @@ use crate::{
output::OutputName, output::OutputName,
render::{ render::{
pointer::PointerElement, pointer_render_elements, take_presentation_feedback, pointer::PointerElement, pointer_render_elements, take_presentation_feedback,
OutputRenderElements, OutputRenderElement,
}, },
state::{State, SurfaceDmabufFeedback, WithState}, state::{State, SurfaceDmabufFeedback, WithState},
}; };
@ -119,7 +119,7 @@ type UdevRenderFrameResult<'a> = RenderFrameResult<
'a, 'a,
BufferObject<()>, BufferObject<()>,
GbmFramebuffer, GbmFramebuffer,
OutputRenderElements<UdevRenderer<'a>, WaylandSurfaceRenderElement<UdevRenderer<'a>>>, OutputRenderElement<UdevRenderer<'a>, WaylandSurfaceRenderElement<UdevRenderer<'a>>>,
>; >;
/// Udev state attached to each [`Output`]. /// Udev state attached to each [`Output`].
@ -513,53 +513,51 @@ pub fn setup_udev(
state.device_changed(node); state.device_changed(node);
{ // Apply pending gammas
// Apply pending gammas //
// // Also welcome to some really doodoo code
// Also welcome to some really doodoo code
let udev = state.backend.udev_mut(); let udev = state.backend.udev_mut();
let Some(backend) = udev.backends.get_mut(&node) else { let Some(backend) = udev.backends.get_mut(&node) else {
unreachable!(); unreachable!();
}; };
for (crtc, surface) in backend.surfaces.iter_mut() { for (crtc, surface) in backend.surfaces.iter_mut() {
match std::mem::take(&mut surface.pending_gamma_change) { match std::mem::take(&mut surface.pending_gamma_change) {
PendingGammaChange::Idle => { PendingGammaChange::Idle => {
debug!("Restoring from previous gamma"); debug!("Restoring from previous gamma");
if let Err(err) = Udev::set_gamma_internal( if let Err(err) = Udev::set_gamma_internal(
&backend.drm, &backend.drm,
crtc, crtc,
surface.previous_gamma.clone(), surface.previous_gamma.clone(),
) { ) {
warn!("Failed to reset gamma: {err}"); 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}");
}
surface.previous_gamma = None; surface.previous_gamma = None;
} }
PendingGammaChange::Change(gamma) => { }
debug!("Changing to pending gamma"); PendingGammaChange::Restore => {
match Udev::set_gamma_internal( debug!("Restoring to original gamma");
&backend.drm, if let Err(err) = Udev::set_gamma_internal(
crtc, &backend.drm,
Some([&gamma[0], &gamma[1], &gamma[2]]), crtc,
) { None::<[&[u16]; 3]>,
Ok(()) => { ) {
surface.previous_gamma = Some(gamma); warn!("Failed to reset gamma: {err}");
} }
Err(err) => { surface.previous_gamma = None;
warn!("Failed to set pending 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>( fn render_frame<'a>(
compositor: &mut GbmDrmCompositor, compositor: &mut GbmDrmCompositor,
renderer: &mut UdevRenderer<'a>, renderer: &mut UdevRenderer<'a>,
elements: &'a [OutputRenderElements< elements: &'a [OutputRenderElement<
UdevRenderer<'a>, UdevRenderer<'a>,
WaylandSurfaceRenderElement<UdevRenderer<'a>>, WaylandSurfaceRenderElement<UdevRenderer<'a>>,
>], >],

View file

@ -154,6 +154,29 @@ impl XdgShellHandler for State {
.unwrap_or_else(|| (0, 0).into()); .unwrap_or_else(|| (0, 0).into());
tracing::debug!(?loc); tracing::debug!(?loc);
break; 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;
}
} }
} }

View file

@ -46,7 +46,7 @@ render_elements! {
} }
render_elements! { render_elements! {
pub OutputRenderElements<R, E> where R: ImportAll + ImportMem; pub OutputRenderElement<R, E> where R: ImportAll + ImportMem;
Custom = Wrap<E>, Custom = Wrap<E>,
Surface = WaylandSurfaceRenderElement<R>, Surface = WaylandSurfaceRenderElement<R>,
Pointer = PointerRenderElement<R>, Pointer = PointerRenderElement<R>,
@ -137,16 +137,13 @@ fn window_render_elements<R>(
renderer: &mut R, renderer: &mut R,
scale: Scale<f64>, scale: Scale<f64>,
) -> ( ) -> (
Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>>, Vec<OutputRenderElement<R, WaylandSurfaceRenderElement<R>>>,
Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>>, Vec<OutputRenderElement<R, WaylandSurfaceRenderElement<R>>>,
) )
where where
R: Renderer + ImportAll + ImportMem, R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
{ {
// bot wwwwwFFww top
// rev wwFFwwwww
let mut last_fullscreen_split_at = 0; let mut last_fullscreen_split_at = 0;
let mut elements = windows let mut elements = windows
@ -180,9 +177,9 @@ where
Some(rect) => { Some(rect) => {
elems.into_iter().filter_map(|elem| { elems.into_iter().filter_map(|elem| {
CropRenderElement::from_element(elem, scale, rect.to_physical_precise_round(scale)) CropRenderElement::from_element(elem, scale, rect.to_physical_precise_round(scale))
}).map(TransformRenderElement::from).map(OutputRenderElements::from).collect::<Vec<_>>() }).map(TransformRenderElement::from).map(OutputRenderElement::from).collect::<Vec<_>>()
}, },
None => elems.into_iter().map(OutputRenderElements::from).collect(), None => elems.into_iter().map(OutputRenderElement::from).collect(),
} }
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
@ -203,7 +200,7 @@ pub fn pointer_render_elements<R>(
cursor_status: &mut CursorImageStatus, cursor_status: &mut CursorImageStatus,
dnd_icon: Option<&WlSurface>, dnd_icon: Option<&WlSurface>,
pointer_element: &PointerElement<<R as Renderer>::TextureId>, pointer_element: &PointerElement<<R as Renderer>::TextureId>,
) -> Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>> ) -> Vec<OutputRenderElement<R, WaylandSurfaceRenderElement<R>>>
where where
R: Renderer + ImportAll, R: Renderer + ImportAll,
<R as Renderer>::TextureId: Clone + 'static, <R as Renderer>::TextureId: Clone + 'static,
@ -264,7 +261,7 @@ pub fn generate_render_elements<R, T>(
renderer: &mut R, renderer: &mut R,
space: &Space<WindowElement>, space: &Space<WindowElement>,
windows: &[WindowElement], windows: &[WindowElement],
) -> Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>> ) -> Vec<OutputRenderElement<R, WaylandSurfaceRenderElement<R>>>
where where
R: Renderer<TextureId = T> + ImportAll + ImportMem, R: Renderer<TextureId = T> + ImportAll + ImportMem,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
@ -272,7 +269,7 @@ where
{ {
let scale = Scale::from(output.current_scale().fractional_scale()); let scale = Scale::from(output.current_scale().fractional_scale());
let mut output_render_elements: Vec<OutputRenderElements<_, _>> = Vec::new(); let mut output_render_elements: Vec<OutputRenderElement<_, _>> = Vec::new();
let (windows, override_redirect_windows) = windows let (windows, override_redirect_windows) = windows
.iter() .iter()
@ -309,7 +306,7 @@ where
// TODO: don't unconditionally render OR windows above fullscreen ones, // TODO: don't unconditionally render OR windows above fullscreen ones,
// | base it on if it's a descendant or not // | 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 { let LayerRenderElements {
background, background,
@ -329,7 +326,7 @@ where
overlay overlay
.into_iter() .into_iter()
.chain(top) .chain(top)
.map(OutputRenderElements::from), .map(OutputRenderElement::from),
); );
output_render_elements.extend(rest_of_window_elements); output_render_elements.extend(rest_of_window_elements);
@ -338,7 +335,7 @@ where
bottom bottom
.into_iter() .into_iter()
.chain(background) .chain(background)
.map(OutputRenderElements::from), .map(OutputRenderElement::from),
); );
output_render_elements output_render_elements