mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
More work on fullscreen
This commit is contained in:
parent
a2887567a3
commit
7a8fc983a9
2 changed files with 148 additions and 21 deletions
|
@ -8,7 +8,7 @@ use smithay::{
|
|||
egl::EGLDevice,
|
||||
renderer::{
|
||||
damage::{self, OutputDamageTracker},
|
||||
element::{surface::WaylandSurfaceRenderElement, AsRenderElements},
|
||||
element::{self, surface::WaylandSurfaceRenderElement, AsRenderElements},
|
||||
gles::{GlesRenderer, GlesTexture},
|
||||
ImportDma, ImportEgl, ImportMemWl,
|
||||
},
|
||||
|
@ -38,7 +38,7 @@ use smithay::{
|
|||
|
||||
use crate::{
|
||||
render::{pointer::PointerElement, CustomRenderElements, OutputRenderElements},
|
||||
state::{take_presentation_feedback, CalloopData, State},
|
||||
state::{take_presentation_feedback, CalloopData, State, WithState},
|
||||
};
|
||||
|
||||
use super::Backend;
|
||||
|
@ -294,6 +294,70 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
|
|||
));
|
||||
}
|
||||
|
||||
let active_tag_with_fullscreen = {
|
||||
output.with_state(|state| {
|
||||
state
|
||||
.tags
|
||||
.iter()
|
||||
.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 mut output_render_elements = Vec::<
|
||||
OutputRenderElements<
|
||||
GlesRenderer,
|
||||
WaylandSurfaceRenderElement<GlesRenderer>,
|
||||
>,
|
||||
>::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);
|
||||
|
||||
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 {
|
||||
let space_render_elements =
|
||||
space::space_render_elements(renderer, [&state.space], &output, 1.0)
|
||||
.expect("Failed to get render elements");
|
||||
|
||||
let mut output_render_elements = Vec::<
|
||||
OutputRenderElements<
|
||||
GlesRenderer,
|
||||
WaylandSurfaceRenderElement<GlesRenderer>,
|
||||
>,
|
||||
>::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 render_res = state.backend_data.backend.bind().and_then(|_| {
|
||||
let age = if *full_redraw > 0 {
|
||||
0
|
||||
|
@ -304,24 +368,6 @@ pub fn run_winit() -> Result<(), Box<dyn Error>> {
|
|||
let renderer = state.backend_data.backend.renderer();
|
||||
|
||||
// render_output()
|
||||
let space_render_elements =
|
||||
space::space_render_elements(renderer, [&state.space], &output, 1.0)
|
||||
.expect("Failed to get render elements");
|
||||
|
||||
let mut output_render_elements = Vec::<
|
||||
OutputRenderElements<GlesRenderer, WaylandSurfaceRenderElement<GlesRenderer>>,
|
||||
>::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),
|
||||
);
|
||||
|
||||
state
|
||||
.backend_data
|
||||
|
|
|
@ -8,10 +8,11 @@ use smithay::{
|
|||
WindowSurfaceType,
|
||||
},
|
||||
input::{pointer::Focus, Seat},
|
||||
output::Output,
|
||||
reexports::{
|
||||
wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge},
|
||||
wayland_server::{
|
||||
protocol::{wl_seat::WlSeat, wl_surface::WlSurface},
|
||||
protocol::{wl_output::WlOutput, wl_seat::WlSeat, wl_surface::WlSurface},
|
||||
Resource,
|
||||
},
|
||||
},
|
||||
|
@ -301,6 +302,86 @@ impl<B: Backend> XdgShellHandler for State<B> {
|
|||
}
|
||||
}
|
||||
|
||||
fn fullscreen_request(&mut self, surface: ToplevelSurface, mut wl_output: Option<WlOutput>) {
|
||||
if !surface
|
||||
.current_state()
|
||||
.capabilities
|
||||
.contains(xdg_toplevel::WmCapabilities::Fullscreen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let wl_surface = surface.wl_surface();
|
||||
let output = wl_output
|
||||
.as_ref()
|
||||
.and_then(Output::from_resource)
|
||||
.or_else(|| {
|
||||
self.window_for_surface(wl_surface)
|
||||
.and_then(|window| self.space.outputs_for_element(&window).get(0).cloned())
|
||||
});
|
||||
|
||||
if let Some(output) = output {
|
||||
let Some(geometry) = self.space.output_geometry(&output) else {
|
||||
surface.send_configure();
|
||||
return;
|
||||
};
|
||||
|
||||
let client = self
|
||||
.display_handle
|
||||
.get_client(wl_surface.id())
|
||||
.expect("wl_surface had no client");
|
||||
for output in output.client_outputs(&client) {
|
||||
wl_output = Some(output);
|
||||
}
|
||||
|
||||
surface.with_pending_state(|state| {
|
||||
state.states.set(xdg_toplevel::State::Fullscreen);
|
||||
state.size = Some(geometry.size);
|
||||
state.fullscreen_output = wl_output;
|
||||
});
|
||||
|
||||
let Some(window) = self.window_for_surface(wl_surface) else {
|
||||
tracing::error!("wl_surface had no window");
|
||||
return;
|
||||
};
|
||||
|
||||
window.with_state(|state| {
|
||||
let tags = state.tags.iter();
|
||||
for tag in tags {
|
||||
tag.set_fullscreen_window(window.clone());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
surface.send_configure();
|
||||
}
|
||||
|
||||
fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
|
||||
if !surface
|
||||
.current_state()
|
||||
.states
|
||||
.contains(xdg_toplevel::State::Fullscreen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
surface.with_pending_state(|state| {
|
||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||
state.size = None;
|
||||
state.fullscreen_output.take();
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
surface.send_pending_configure();
|
||||
}
|
||||
|
||||
// fn minimize_request(&mut self, surface: ToplevelSurface) {
|
||||
// if let Some(window) = self.window_for_surface(surface.wl_surface()) {
|
||||
// self.space.unmap_elem(&window);
|
||||
|
|
Loading…
Reference in a new issue