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