mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
Stop rendering instead of unmapping windows (regression)
Layer shell surfaces currently don't render anymore. I may need to manually render them instead of getting them through Space::space_render_elements.
This commit is contained in:
parent
5744654cb1
commit
15e03b6c17
9 changed files with 141 additions and 46 deletions
|
@ -1344,18 +1344,19 @@ impl State {
|
|||
};
|
||||
|
||||
let result = render_surface(
|
||||
&mut self.cursor_status,
|
||||
&self.space,
|
||||
&self.windows,
|
||||
self.dnd_icon.as_ref(),
|
||||
&self.focus_state.focus_stack,
|
||||
surface,
|
||||
&mut renderer,
|
||||
&self.space,
|
||||
&output,
|
||||
self.seat.input_method(),
|
||||
self.pointer_location,
|
||||
&pointer_image,
|
||||
&mut backend.pointer_element,
|
||||
&mut self.cursor_status,
|
||||
self.dnd_icon.as_ref(),
|
||||
self.pointer_location,
|
||||
&self.clock,
|
||||
&self.focus_state.focus_stack,
|
||||
);
|
||||
let reschedule = match &result {
|
||||
Ok(has_rendered) => !has_rendered,
|
||||
|
@ -1448,30 +1449,32 @@ impl State {
|
|||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn render_surface<'a>(
|
||||
cursor_status: &mut CursorImageStatus,
|
||||
space: &Space<WindowElement>,
|
||||
windows: &[WindowElement],
|
||||
dnd_icon: Option<&WlSurface>,
|
||||
focus_stack: &[WindowElement],
|
||||
surface: &'a mut SurfaceData,
|
||||
renderer: &mut UdevRenderer<'a, '_>,
|
||||
space: &Space<WindowElement>,
|
||||
output: &Output,
|
||||
input_method: &InputMethodHandle,
|
||||
pointer_location: Point<f64, Logical>,
|
||||
pointer_image: &TextureBuffer<MultiTexture>,
|
||||
pointer_element: &mut PointerElement<MultiTexture>,
|
||||
cursor_status: &mut CursorImageStatus,
|
||||
dnd_icon: Option<&WlSurface>,
|
||||
pointer_location: Point<f64, Logical>,
|
||||
clock: &Clock<Monotonic>,
|
||||
focus_stack: &[WindowElement],
|
||||
) -> Result<bool, SwapBuffersError> {
|
||||
let output_render_elements = crate::render::generate_render_elements(
|
||||
renderer,
|
||||
space,
|
||||
output,
|
||||
input_method,
|
||||
windows,
|
||||
pointer_location,
|
||||
pointer_element,
|
||||
Some(pointer_image),
|
||||
cursor_status,
|
||||
dnd_icon,
|
||||
focus_stack,
|
||||
renderer,
|
||||
output,
|
||||
input_method,
|
||||
pointer_element,
|
||||
Some(pointer_image),
|
||||
);
|
||||
|
||||
let res = surface.compositor.render_frame::<_, _, GlesTexture>(
|
||||
|
|
|
@ -237,16 +237,17 @@ pub fn run_winit() -> anyhow::Result<()> {
|
|||
*full_redraw = full_redraw.saturating_sub(1);
|
||||
|
||||
let output_render_elements = crate::render::generate_render_elements(
|
||||
backend.backend.renderer(),
|
||||
&state.space,
|
||||
&output,
|
||||
state.seat.input_method(),
|
||||
&state.windows,
|
||||
state.pointer_location,
|
||||
&mut pointer_element,
|
||||
None,
|
||||
&mut state.cursor_status,
|
||||
state.dnd_icon.as_ref(),
|
||||
&state.focus_state.focus_stack,
|
||||
backend.backend.renderer(),
|
||||
&output,
|
||||
state.seat.input_method(),
|
||||
&mut pointer_element,
|
||||
None,
|
||||
);
|
||||
|
||||
let render_res = backend.backend.bind().and_then(|_| {
|
||||
|
@ -271,6 +272,7 @@ pub fn run_winit() -> anyhow::Result<()> {
|
|||
Ok(render_output_result) => {
|
||||
let has_rendered = render_output_result.damage.is_some();
|
||||
if let Some(damage) = render_output_result.damage {
|
||||
// tracing::debug!("damage rects are {damage:?}");
|
||||
if let Err(err) = backend.backend.submit(Some(&damage)) {
|
||||
tracing::warn!("{}", err);
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ impl CompositorHandler for State {
|
|||
if let Some(window) = self.window_for_surface(surface) {
|
||||
window.with_state(|state| {
|
||||
if let LocationRequestState::Acknowledged(new_pos) = state.loc_request_state {
|
||||
tracing::debug!("Mapping Acknowledged window");
|
||||
state.loc_request_state = LocationRequestState::Idle;
|
||||
self.space.map_element(window.clone(), new_pos, false);
|
||||
}
|
||||
|
@ -128,6 +129,7 @@ impl CompositorHandler for State {
|
|||
}
|
||||
|
||||
// correct focus layering
|
||||
// TODO: maybe do this at the end of every event loop cycle instead?
|
||||
self.focus_state.fix_up_focus(&mut self.space);
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,8 @@ impl XdgShellHandler for State {
|
|||
self.windows.push(window.clone());
|
||||
|
||||
let win_clone = window.clone();
|
||||
|
||||
// Let the initial configure happen before updating the windows
|
||||
self.schedule(
|
||||
move |_data| {
|
||||
if let WindowElement::Wayland(window) = &win_clone {
|
||||
|
@ -170,10 +172,8 @@ impl XdgShellHandler for State {
|
|||
self.update_windows(&focused_output);
|
||||
}
|
||||
|
||||
// let mut windows: Vec<Window> = self.space.elements().cloned().collect();
|
||||
// windows.retain(|window| window.toplevel() != &surface);
|
||||
// Layouts::master_stack(self, windows, crate::layout::Direction::Left);
|
||||
let focus = self.focus_state.current_focus().map(FocusTarget::Window);
|
||||
|
||||
self.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard")
|
||||
|
@ -192,7 +192,7 @@ impl XdgShellHandler for State {
|
|||
crate::grab::move_grab::move_request_client(
|
||||
self,
|
||||
surface.wl_surface(),
|
||||
&Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat"),
|
||||
&Seat::from_resource(&seat).expect("couldn't get seat from WlSeat"),
|
||||
serial,
|
||||
BUTTON_LEFT,
|
||||
);
|
||||
|
@ -209,7 +209,7 @@ impl XdgShellHandler for State {
|
|||
crate::grab::resize_grab::resize_request_client(
|
||||
self,
|
||||
surface.wl_surface(),
|
||||
&Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat"),
|
||||
&Seat::from_resource(&seat).expect("couldn't get seat from WlSeat"),
|
||||
serial,
|
||||
edges.into(),
|
||||
BUTTON_LEFT,
|
||||
|
@ -230,7 +230,7 @@ impl XdgShellHandler for State {
|
|||
}
|
||||
|
||||
fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) {
|
||||
let seat: Seat<Self> = Seat::from_resource(&seat).expect("Couldn't get seat from WlSeat");
|
||||
let seat: Seat<Self> = Seat::from_resource(&seat).expect("couldn't get seat from WlSeat");
|
||||
let popup_kind = PopupKind::Xdg(surface);
|
||||
if let Some(root) = find_popup_root_surface(&popup_kind).ok().and_then(|root| {
|
||||
self.window_for_surface(&root)
|
||||
|
@ -282,18 +282,43 @@ impl XdgShellHandler for State {
|
|||
match &configure {
|
||||
Configure::Toplevel(configure) => {
|
||||
if configure.serial >= serial {
|
||||
// tracing::debug!("acked configure, new loc is {:?}", new_loc);
|
||||
tracing::debug!("acked configure, new loc is {:?}", new_loc);
|
||||
state.loc_request_state =
|
||||
LocationRequestState::Acknowledged(new_loc);
|
||||
|
||||
// Send a frame here because it causes (most) unmapped windows to
|
||||
// commit. I haven't done enough doc diving to know if there's a
|
||||
// better way.
|
||||
|
||||
if let Some(focused_output) =
|
||||
self.focus_state.focused_output.clone()
|
||||
{
|
||||
tracing::debug!("Sending ack frame to window");
|
||||
window.send_frame(
|
||||
&focused_output,
|
||||
self.clock.now(),
|
||||
Some(Duration::ZERO),
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
// Forcibly map the window after 16ms if it hasn't committed
|
||||
let current_time = self.clock.now();
|
||||
let win_clone = window.clone();
|
||||
self.schedule(
|
||||
move |data| {
|
||||
smithay::utils::Time::elapsed(
|
||||
¤t_time,
|
||||
data.state.clock.now(),
|
||||
) > Duration::from_millis(100)
|
||||
},
|
||||
move |data| {
|
||||
win_clone.send_frame(
|
||||
&focused_output,
|
||||
data.state.clock.now(),
|
||||
Some(Duration::ZERO),
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
/// Compute tiled window locations and sizes, size maximized and fullscreen windows correctly,
|
||||
/// and send configures and that cool stuff.
|
||||
pub fn update_windows(&mut self, output: &Output) {
|
||||
let Some(layout) = output.with_state(|state| {
|
||||
state.focused_tags().next().cloned().map(|tag| tag.layout())
|
||||
|
@ -66,6 +68,9 @@ impl State {
|
|||
})
|
||||
});
|
||||
|
||||
tracing::debug!("{} on", windows_on_foc_tags.len());
|
||||
|
||||
// Don't unmap windows that aren't on `output` (that would clear all other monitors)
|
||||
windows_not_on_foc_tags.retain(|win| win.output(self) == Some(output.clone()));
|
||||
|
||||
let tiled_windows = windows_on_foc_tags
|
||||
|
@ -132,13 +137,14 @@ impl State {
|
|||
});
|
||||
}
|
||||
|
||||
self.loop_handle.insert_idle(|data| {
|
||||
crate::state::schedule_on_commit(data, windows_on_foc_tags, |dt| {
|
||||
for win in windows_not_on_foc_tags {
|
||||
dt.state.space.unmap_elem(&win);
|
||||
}
|
||||
})
|
||||
});
|
||||
// self.loop_handle.insert_idle(|data| {
|
||||
// crate::state::schedule_on_commit(data, windows_on_foc_tags, |dt| {
|
||||
// for win in windows_not_on_foc_tags {
|
||||
// // dt.state.space.map_element(win, (500, 0), false);
|
||||
// dt.state.space.unmap_elem(&win);
|
||||
// }
|
||||
// })
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
//! While Pinnacle is not a library, this documentation serves to guide those who want to
|
||||
//! contribute or learn how building something like this works.
|
||||
|
||||
#![deny(unused_imports)] // gonna force myself to keep stuff clean
|
||||
#![warn(clippy::unwrap_used)]
|
||||
|
||||
mod api;
|
||||
|
|
|
@ -11,7 +11,7 @@ use smithay::{
|
|||
ImportAll, ImportMem, Renderer, Texture,
|
||||
},
|
||||
desktop::{
|
||||
space::{self, SpaceRenderElements, SurfaceTree},
|
||||
space::{SpaceRenderElements, SurfaceTree},
|
||||
Space,
|
||||
},
|
||||
input::pointer::{CursorImageAttributes, CursorImageStatus},
|
||||
|
@ -25,7 +25,7 @@ use smithay::{
|
|||
wayland::{compositor, input_method::InputMethodHandle},
|
||||
};
|
||||
|
||||
use crate::{state::WithState, window::WindowElement};
|
||||
use crate::{state::WithState, tag::Tag, window::WindowElement};
|
||||
|
||||
use self::pointer::{PointerElement, PointerRenderElement};
|
||||
|
||||
|
@ -78,16 +78,17 @@ where
|
|||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn generate_render_elements<R, T>(
|
||||
renderer: &mut R,
|
||||
space: &Space<WindowElement>,
|
||||
output: &Output,
|
||||
input_method: &InputMethodHandle,
|
||||
windows: &[WindowElement],
|
||||
pointer_location: Point<f64, Logical>,
|
||||
pointer_element: &mut PointerElement<T>,
|
||||
pointer_image: Option<&TextureBuffer<T>>,
|
||||
cursor_status: &mut CursorImageStatus,
|
||||
dnd_icon: Option<&WlSurface>,
|
||||
focus_stack: &[WindowElement],
|
||||
renderer: &mut R,
|
||||
output: &Output,
|
||||
input_method: &InputMethodHandle,
|
||||
pointer_element: &mut PointerElement<T>,
|
||||
pointer_image: Option<&TextureBuffer<T>>,
|
||||
) -> Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>>
|
||||
where
|
||||
R: Renderer<TextureId = T> + ImportAll + ImportMem,
|
||||
|
@ -211,9 +212,18 @@ where
|
|||
output_render_elements
|
||||
} else {
|
||||
// render everything
|
||||
let space_render_elements =
|
||||
space::space_render_elements(renderer, [space], output, 1.0)
|
||||
.expect("Failed to get render elements");
|
||||
// let space_render_elements =
|
||||
// space::space_render_elements(renderer, [space], output, 1.0)
|
||||
// .expect("Failed to get render elements");
|
||||
|
||||
let tags = space
|
||||
.outputs()
|
||||
.flat_map(|op| {
|
||||
op.with_state(|state| state.focused_tags().cloned().collect::<Vec<_>>())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let space_render_elements: Vec<WaylandSurfaceRenderElement<R>> =
|
||||
Tag::tag_render_elements(&tags, windows, space, renderer);
|
||||
|
||||
let mut output_render_elements =
|
||||
Vec::<OutputRenderElements<_, WaylandSurfaceRenderElement<_>>>::new();
|
||||
|
@ -226,6 +236,7 @@ where
|
|||
output_render_elements.extend(
|
||||
space_render_elements
|
||||
.into_iter()
|
||||
.map(CustomRenderElements::from)
|
||||
.map(OutputRenderElements::from),
|
||||
);
|
||||
output_render_elements
|
||||
|
|
|
@ -589,6 +589,10 @@ impl ApiState {
|
|||
|
||||
pub trait WithState {
|
||||
type State: Default;
|
||||
|
||||
/// Access data map state.
|
||||
///
|
||||
/// RefCell Safety: This function will panic if called within itself.
|
||||
fn with_state<F, T>(&self, func: F) -> T
|
||||
where
|
||||
F: FnMut(&mut Self::State) -> T;
|
||||
|
|
45
src/tag.rs
45
src/tag.rs
|
@ -7,11 +7,20 @@ use std::{
|
|||
sync::atomic::{AtomicU32, Ordering},
|
||||
};
|
||||
|
||||
use smithay::output::Output;
|
||||
use smithay::{
|
||||
backend::renderer::{
|
||||
element::{surface::WaylandSurfaceRenderElement, AsRenderElements},
|
||||
ImportAll, ImportMem, Renderer,
|
||||
},
|
||||
desktop::{space::SpaceElement, Space},
|
||||
output::Output,
|
||||
utils::Scale,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
layout::Layout,
|
||||
state::{State, WithState},
|
||||
window::WindowElement,
|
||||
};
|
||||
|
||||
static TAG_ID_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
|
@ -64,6 +73,7 @@ impl Eq for TagInner {}
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Tag(Rc<RefCell<TagInner>>);
|
||||
|
||||
// RefCell Safety: These methods should never panic because they are all self-contained or Copy.
|
||||
impl Tag {
|
||||
pub fn id(&self) -> TagId {
|
||||
self.0.borrow().id
|
||||
|
@ -107,4 +117,37 @@ impl Tag {
|
|||
.find(|output| output.with_state(|state| state.tags.iter().any(|tg| tg == self)))
|
||||
.cloned()
|
||||
}
|
||||
|
||||
/// Get the render_elements for the provided tags.
|
||||
pub fn tag_render_elements<R, C>(
|
||||
tags: &[Tag],
|
||||
windows: &[WindowElement],
|
||||
space: &Space<WindowElement>,
|
||||
renderer: &mut R,
|
||||
) -> Vec<C>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
<R as Renderer>::TextureId: 'static,
|
||||
C: From<WaylandSurfaceRenderElement<R>>,
|
||||
{
|
||||
let elements = windows
|
||||
.iter()
|
||||
.filter(|win| {
|
||||
win.with_state(|state| {
|
||||
state
|
||||
.tags
|
||||
.iter()
|
||||
.any(|tag| tags.iter().any(|tag2| tag == tag2))
|
||||
})
|
||||
})
|
||||
.flat_map(|win| {
|
||||
let loc = (space.element_location(win).unwrap_or((0, 0).into())
|
||||
- win.geometry().loc)
|
||||
.to_physical(1);
|
||||
win.render_elements::<C>(renderer, loc, Scale::from(1.0), 1.0)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
elements
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue