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,
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<UdevRenderer<'a>, WaylandSurfaceRenderElement<UdevRenderer<'a>>>,
OutputRenderElement<UdevRenderer<'a>, WaylandSurfaceRenderElement<UdevRenderer<'a>>>,
>;
/// 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<UdevRenderer<'a>>,
>],

View file

@ -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;
}
}
}

View file

@ -46,7 +46,7 @@ render_elements! {
}
render_elements! {
pub OutputRenderElements<R, E> where R: ImportAll + ImportMem;
pub OutputRenderElement<R, E> where R: ImportAll + ImportMem;
Custom = Wrap<E>,
Surface = WaylandSurfaceRenderElement<R>,
Pointer = PointerRenderElement<R>,
@ -137,16 +137,13 @@ fn window_render_elements<R>(
renderer: &mut R,
scale: Scale<f64>,
) -> (
Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>>,
Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>>,
Vec<OutputRenderElement<R, WaylandSurfaceRenderElement<R>>>,
Vec<OutputRenderElement<R, WaylandSurfaceRenderElement<R>>>,
)
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::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::<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<_>>();
@ -203,7 +200,7 @@ pub fn pointer_render_elements<R>(
cursor_status: &mut CursorImageStatus,
dnd_icon: Option<&WlSurface>,
pointer_element: &PointerElement<<R as Renderer>::TextureId>,
) -> Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>>
) -> Vec<OutputRenderElement<R, WaylandSurfaceRenderElement<R>>>
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: Clone + 'static,
@ -264,7 +261,7 @@ pub fn generate_render_elements<R, T>(
renderer: &mut R,
space: &Space<WindowElement>,
windows: &[WindowElement],
) -> Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>>
) -> Vec<OutputRenderElement<R, WaylandSurfaceRenderElement<R>>>
where
R: Renderer<TextureId = T> + ImportAll + ImportMem,
<R as Renderer>::TextureId: 'static,
@ -272,7 +269,7 @@ where
{
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
.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