mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
Rework fullscreen tracking, fix fullscreen on udev
This commit is contained in:
parent
0ead02921f
commit
d75e0dad22
6 changed files with 93 additions and 53 deletions
|
@ -32,7 +32,8 @@ use smithay::{
|
|||
renderer::{
|
||||
damage::{self, OutputDamageTracker},
|
||||
element::{
|
||||
texture::TextureBuffer, AsRenderElements, RenderElement, RenderElementStates,
|
||||
self, surface::WaylandSurfaceRenderElement, texture::TextureBuffer,
|
||||
AsRenderElements, RenderElement, RenderElementStates,
|
||||
},
|
||||
gles::{GlesRenderer, GlesTexture},
|
||||
multigpu::{gbm::GbmGlesBackend, GpuManager, MultiRenderer, MultiTexture},
|
||||
|
@ -98,7 +99,7 @@ use smithay_drm_extras::{
|
|||
use crate::{
|
||||
api::msg::{Args, OutgoingMsg},
|
||||
render::{pointer::PointerElement, CustomRenderElements, OutputRenderElements},
|
||||
state::{take_presentation_feedback, CalloopData, State, SurfaceDmabufFeedback},
|
||||
state::{take_presentation_feedback, CalloopData, State, SurfaceDmabufFeedback, WithState},
|
||||
window::WindowElement,
|
||||
};
|
||||
|
||||
|
@ -1377,6 +1378,7 @@ impl State<UdevData> {
|
|||
&mut self.cursor_status,
|
||||
self.dnd_icon.as_ref(),
|
||||
&self.clock,
|
||||
&self.focus_state.focus_stack,
|
||||
);
|
||||
let reschedule = match &result {
|
||||
Ok(has_rendered) => !has_rendered,
|
||||
|
@ -1482,11 +1484,12 @@ fn render_surface<'a>(
|
|||
cursor_status: &mut CursorImageStatus,
|
||||
dnd_icon: Option<&WlSurface>,
|
||||
clock: &Clock<Monotonic>,
|
||||
focus_stack: &[WindowElement],
|
||||
) -> Result<bool, SwapBuffersError> {
|
||||
let output_geometry = space.output_geometry(output).unwrap();
|
||||
let scale = Scale::from(output.current_scale().fractional_scale());
|
||||
|
||||
let mut custom_elements: Vec<CustomRenderElements<_>> = Vec::new();
|
||||
let mut custom_render_elements: Vec<CustomRenderElements<_>> = Vec::new();
|
||||
// draw input method surface if any
|
||||
let rectangle = input_method.coordinates();
|
||||
let position = Point::from((
|
||||
|
@ -1494,7 +1497,7 @@ fn render_surface<'a>(
|
|||
rectangle.loc.y + rectangle.size.h,
|
||||
));
|
||||
input_method.with_surface(|surface| {
|
||||
custom_elements.extend(AsRenderElements::<UdevRenderer<'a, '_>>::render_elements(
|
||||
custom_render_elements.extend(AsRenderElements::<UdevRenderer<'a, '_>>::render_elements(
|
||||
&SurfaceTree::from_surface(surface),
|
||||
renderer,
|
||||
position.to_physical_precise_round(scale),
|
||||
|
@ -1537,7 +1540,7 @@ fn render_surface<'a>(
|
|||
pointer_element.set_status(cursor_status.clone());
|
||||
}
|
||||
|
||||
custom_elements.extend(pointer_element.render_elements(
|
||||
custom_render_elements.extend(pointer_element.render_elements(
|
||||
renderer,
|
||||
cursor_pos_scaled,
|
||||
scale,
|
||||
|
@ -1545,7 +1548,7 @@ fn render_surface<'a>(
|
|||
));
|
||||
|
||||
if let Some(dnd_icon) = dnd_icon {
|
||||
custom_elements.extend(AsRenderElements::render_elements(
|
||||
custom_render_elements.extend(AsRenderElements::render_elements(
|
||||
&smithay::desktop::space::SurfaceTree::from_surface(dnd_icon),
|
||||
renderer,
|
||||
cursor_pos_scaled,
|
||||
|
@ -1555,19 +1558,57 @@ fn render_surface<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
let mut output_render_elements = custom_elements
|
||||
.into_iter()
|
||||
.map(OutputRenderElements::from)
|
||||
.collect::<Vec<_>>();
|
||||
let output_render_elements = {
|
||||
let top_fullscreen_window = focus_stack.iter().rev().find(|win| {
|
||||
win.with_state(|state| {
|
||||
state.status.is_fullscreen() && state.tags.iter().any(|tag| tag.active())
|
||||
})
|
||||
});
|
||||
|
||||
let space_render_elements =
|
||||
space::space_render_elements(renderer, [space], output, 1.0).unwrap();
|
||||
// If fullscreen windows exist, render only the topmost one
|
||||
// TODO: wait until the fullscreen window has committed, this will stop flickering
|
||||
if let Some(window) = top_fullscreen_window {
|
||||
let mut output_render_elements =
|
||||
Vec::<OutputRenderElements<_, WaylandSurfaceRenderElement<_>>>::new();
|
||||
|
||||
output_render_elements.extend(
|
||||
space_render_elements
|
||||
.into_iter()
|
||||
.map(OutputRenderElements::Space),
|
||||
);
|
||||
let window_render_elements: Vec<WaylandSurfaceRenderElement<_>> =
|
||||
window.render_elements(renderer, (0, 0).into(), scale, 1.0);
|
||||
|
||||
output_render_elements.extend(
|
||||
custom_render_elements
|
||||
.into_iter()
|
||||
.map(OutputRenderElements::from),
|
||||
);
|
||||
|
||||
output_render_elements.extend(
|
||||
window_render_elements
|
||||
.into_iter()
|
||||
.map(|elem| OutputRenderElements::Window(element::Wrap::from(elem))),
|
||||
);
|
||||
|
||||
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 mut output_render_elements =
|
||||
Vec::<OutputRenderElements<_, WaylandSurfaceRenderElement<_>>>::new();
|
||||
|
||||
output_render_elements.extend(
|
||||
custom_render_elements
|
||||
.into_iter()
|
||||
.map(OutputRenderElements::from),
|
||||
);
|
||||
output_render_elements.extend(
|
||||
space_render_elements
|
||||
.into_iter()
|
||||
.map(OutputRenderElements::from),
|
||||
);
|
||||
output_render_elements
|
||||
}
|
||||
};
|
||||
|
||||
let res = surface.compositor.render_frame::<_, _, GlesTexture>(
|
||||
renderer,
|
||||
|
|
|
@ -295,21 +295,20 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
|
|||
));
|
||||
}
|
||||
|
||||
let active_tag_with_fullscreen = {
|
||||
output.with_state(|state| {
|
||||
state
|
||||
.tags
|
||||
.iter()
|
||||
.filter(|tag| tag.active())
|
||||
.find(|tag| tag.fullscreen_window().is_some())
|
||||
.cloned()
|
||||
})
|
||||
};
|
||||
|
||||
let output_render_elements = {
|
||||
let renderer = state.backend_data.backend.renderer();
|
||||
|
||||
if let Some(tag) = active_tag_with_fullscreen {
|
||||
let top_fullscreen_window =
|
||||
state.focus_state.focus_stack.iter().rev().find(|win| {
|
||||
win.with_state(|state| {
|
||||
state.status.is_fullscreen()
|
||||
&& state.tags.iter().any(|tag| tag.active())
|
||||
})
|
||||
});
|
||||
|
||||
// If fullscreen windows exist, render only the topmost one
|
||||
// TODO: wait until the fullscreen window has committed, this will stop flickering
|
||||
if let Some(window) = top_fullscreen_window {
|
||||
let mut output_render_elements = Vec::<
|
||||
OutputRenderElements<
|
||||
GlesRenderer,
|
||||
|
@ -317,7 +316,6 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
|
|||
>,
|
||||
>::new();
|
||||
|
||||
let Some(window) = tag.fullscreen_window() else { unreachable!() };
|
||||
let window_render_elements: Vec<WaylandSurfaceRenderElement<_>> =
|
||||
window.render_elements(renderer, (0, 0).into(), scale, 1.0);
|
||||
|
||||
|
@ -335,6 +333,7 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
output_render_elements
|
||||
} else {
|
||||
// render everything
|
||||
let space_render_elements =
|
||||
space::space_render_elements(renderer, [&state.space], &output, 1.0)
|
||||
.expect("Failed to get render elements");
|
||||
|
|
|
@ -326,7 +326,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
|
|||
window.with_state(|state| {
|
||||
let tags = state.tags.iter();
|
||||
for tag in tags {
|
||||
tag.set_fullscreen_window(window.clone());
|
||||
// tag.set_fullscreen_window(window.clone());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ impl<B: Backend> XdgShellHandler for State<B> {
|
|||
if let Some(window) = self.window_for_surface(surface.wl_surface()) {
|
||||
window.with_state(|state| {
|
||||
for tag in state.tags.iter() {
|
||||
tag.set_fullscreen_window(None);
|
||||
// tag.set_fullscreen_window(None);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
16
src/input.rs
16
src/input.rs
|
@ -57,7 +57,6 @@ impl<B: Backend> State<B> {
|
|||
where
|
||||
P: Into<Point<f64, Logical>>,
|
||||
{
|
||||
// TODO: fullscreen
|
||||
let point: Point<f64, Logical> = point.into();
|
||||
|
||||
let output = self.space.outputs().find(|op| {
|
||||
|
@ -74,14 +73,15 @@ impl<B: Backend> State<B> {
|
|||
|
||||
let layers = layer_map_for_output(output);
|
||||
|
||||
let top_fullscreen_window = self.focus_state.focus_stack.iter().rev().find(|win| {
|
||||
win.with_state(|state| {
|
||||
state.status.is_fullscreen() && state.tags.iter().any(|tag| tag.active())
|
||||
})
|
||||
});
|
||||
|
||||
// I think I'm going a bit too far with the functional stuff
|
||||
[output]
|
||||
.into_iter()
|
||||
.flat_map(|op| op.with_state(|state| state.tags.clone()))
|
||||
.filter(|tag| tag.active())
|
||||
.find(|tag| tag.fullscreen_window().is_some())
|
||||
.and_then(|tag| tag.fullscreen_window())
|
||||
.map(|window| (FocusTarget::from(window), output_geo.loc))
|
||||
top_fullscreen_window
|
||||
.map(|window| (FocusTarget::from(window.clone()), output_geo.loc))
|
||||
.or_else(|| {
|
||||
layers
|
||||
.layer_under(wlr_layer::Layer::Overlay, point)
|
||||
|
|
|
@ -12,7 +12,7 @@ use smithay::{
|
|||
|
||||
use crate::window::WindowElement;
|
||||
|
||||
use self::pointer::PointerRenderElement;
|
||||
use self::pointer::{PointerElement, PointerRenderElement};
|
||||
|
||||
pub mod pointer;
|
||||
|
||||
|
@ -60,3 +60,15 @@ where
|
|||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_elements<R, T>(
|
||||
renderer: &mut R,
|
||||
pointer_element: &mut PointerElement<T>,
|
||||
) -> Vec<OutputRenderElements<R, WaylandSurfaceRenderElement<R>>>
|
||||
where
|
||||
R: Renderer + ImportAll,
|
||||
<R as Renderer>::TextureId: 'static,
|
||||
T: Texture,
|
||||
{
|
||||
vec![]
|
||||
}
|
||||
|
|
12
src/tag.rs
12
src/tag.rs
|
@ -13,7 +13,6 @@ use crate::{
|
|||
backend::Backend,
|
||||
layout::Layout,
|
||||
state::{State, WithState},
|
||||
window::WindowElement,
|
||||
};
|
||||
|
||||
static TAG_ID_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
|
@ -45,8 +44,6 @@ struct TagInner {
|
|||
active: bool,
|
||||
/// What layout this tag has.
|
||||
layout: Layout,
|
||||
/// The fullscreen window, if any.
|
||||
fullscreen_window: Option<WindowElement>,
|
||||
}
|
||||
|
||||
impl PartialEq for TagInner {
|
||||
|
@ -84,14 +81,6 @@ impl Tag {
|
|||
pub fn set_layout(&self, layout: Layout) {
|
||||
self.0.borrow_mut().layout = layout;
|
||||
}
|
||||
|
||||
pub fn fullscreen_window(&self) -> Option<WindowElement> {
|
||||
self.0.borrow().fullscreen_window.clone()
|
||||
}
|
||||
|
||||
pub fn set_fullscreen_window(&self, window: impl Into<Option<WindowElement>>) {
|
||||
self.0.borrow_mut().fullscreen_window = window.into();
|
||||
}
|
||||
}
|
||||
|
||||
impl Tag {
|
||||
|
@ -101,7 +90,6 @@ impl Tag {
|
|||
name,
|
||||
active: false,
|
||||
layout: Layout::MasterStack, // TODO: get from config
|
||||
fullscreen_window: None,
|
||||
})))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue