fullscreen: Use CosmicWindow for decorations

This commit is contained in:
Victoria Brekenfeld 2023-09-18 18:29:13 +02:00
parent 098dd1e37d
commit 4e1c16c384
8 changed files with 188 additions and 86 deletions

View file

@ -972,7 +972,7 @@ fn render_node_for_output(
let workspace = shell.active_space(output); let workspace = shell.active_space(output);
let nodes = workspace let nodes = workspace
.get_fullscreen(output) .get_fullscreen(output)
.map(|w| vec![w.clone()]) .map(|w| vec![w.surface()])
.unwrap_or_else(|| workspace.windows().collect::<Vec<_>>()) .unwrap_or_else(|| workspace.windows().collect::<Vec<_>>())
.into_iter() .into_iter()
.flat_map(|w| w.wl_surface().and_then(|s| source_node_for_surface(&s, dh))) .flat_map(|w| w.wl_surface().and_then(|s| source_node_for_surface(&s, dh)))

View file

@ -1460,7 +1460,11 @@ impl State {
let focus_stack = workspace.focus_stack.get(seat); let focus_stack = workspace.focus_stack.get(seat);
let focused_window = focus_stack.last(); let focused_window = focus_stack.last();
if let Some(window) = focused_window.map(|f| f.active_window()) { if let Some(window) = focused_window.map(|f| f.active_window()) {
workspace.maximize_toggle(&window, &current_output); workspace.maximize_toggle(
&window,
&current_output,
self.common.event_loop_handle.clone(),
);
} }
} }
Action::Resizing(direction) => self.common.shell.set_resize_mode( Action::Resizing(direction) => self.common.shell.set_resize_mode(
@ -1624,14 +1628,20 @@ fn sessions_for_output(state: &Common, output: &Output) -> impl Iterator<Item =
.map(|s| (&**s).clone()) .map(|s| (&**s).clone())
.chain( .chain(
maybe_fullscreen maybe_fullscreen
.and_then(|w| w.user_data().get::<ScreencopySessions>()) .as_ref()
.map(|sessions| { .and_then(|w| {
sessions if let Some(sessions) = w.surface().user_data().get::<ScreencopySessions>() {
.0 Some(
.borrow() sessions
.iter() .0
.map(|s| (&**s).clone()) .borrow()
.collect::<Vec<_>>() .iter()
.map(|s| (&**s).clone())
.collect::<Vec<_>>(),
)
} else {
None
}
}) })
.into_iter() .into_iter()
.flatten(), .flatten(),

View file

@ -33,6 +33,7 @@ use smithay::{
Seat, Seat,
}, },
output::Output, output::Output,
reexports::wayland_server::protocol::wl_surface::WlSurface,
render_elements, render_elements,
utils::{Buffer as BufferCoords, IsAlive, Logical, Point, Rectangle, Serial, Size}, utils::{Buffer as BufferCoords, IsAlive, Logical, Point, Rectangle, Serial, Size},
wayland::seat::WaylandFocus, wayland::seat::WaylandFocus,
@ -45,6 +46,7 @@ use std::{
Arc, Mutex, Arc, Mutex,
}, },
}; };
use wayland_backend::server::ObjectId;
use super::{surface::SSD_HEIGHT, CosmicSurface}; use super::{surface::SSD_HEIGHT, CosmicSurface};
@ -257,7 +259,11 @@ impl Program for CosmicWindowInternal {
.windows() .windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(&surface)) .find(|(w, _)| w.wl_surface().as_ref() == Some(&surface))
.unwrap(); .unwrap();
workspace.maximize_request(&window, &output) workspace.maximize_toggle(
&window,
&output,
data.state.common.event_loop_handle.clone(),
)
} }
} }
}); });
@ -698,6 +704,16 @@ impl PointerTarget<State> for CosmicWindow {
} }
} }
impl WaylandFocus for CosmicWindow {
fn wl_surface(&self) -> Option<WlSurface> {
self.0.with_program(|p| p.window.wl_surface())
}
fn same_client_as(&self, object_id: &ObjectId) -> bool {
self.0.with_program(|p| p.window.same_client_as(object_id))
}
}
render_elements! { render_elements! {
pub CosmicWindowRenderElement<R> where R: ImportAll + ImportMem; pub CosmicWindowRenderElement<R> where R: ImportAll + ImportMem;
Header = MemoryRenderBufferRenderElement<R>, Header = MemoryRenderBufferRenderElement<R>,

View file

@ -224,13 +224,13 @@ impl Common {
continue; // Focus is valid, continue; // Focus is valid,
} }
} }
KeyboardFocusTarget::Fullscreen(surface) => { KeyboardFocusTarget::Fullscreen(window) => {
let workspace = state.common.shell.active_space(&output); let workspace = state.common.shell.active_space(&output);
let focus_stack = workspace.focus_stack.get(&seat); let focus_stack = workspace.focus_stack.get(&seat);
if focus_stack if focus_stack
.last() .last()
.map(|m| m.has_active_window(&surface)) .map(|m| m.has_active_window(&window.surface()))
.unwrap_or(false) .unwrap_or(false)
&& workspace.get_fullscreen(&output).is_some() && workspace.get_fullscreen(&output).is_some()
{ {

View file

@ -1,7 +1,10 @@
use std::sync::Weak; use std::sync::Weak;
use crate::{ use crate::{
shell::{element::CosmicMapped, layout::tiling::ResizeForkTarget, CosmicSurface}, shell::{
element::{CosmicMapped, CosmicWindow},
layout::tiling::ResizeForkTarget,
},
utils::prelude::*, utils::prelude::*,
wayland::handlers::xdg_shell::popup::get_popup_toplevel, wayland::handlers::xdg_shell::popup::get_popup_toplevel,
}; };
@ -29,7 +32,7 @@ use smithay::{
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum PointerFocusTarget { pub enum PointerFocusTarget {
Element(CosmicMapped), Element(CosmicMapped),
Fullscreen(CosmicSurface), Fullscreen(CosmicWindow),
LayerSurface(LayerSurface), LayerSurface(LayerSurface),
Popup(PopupKind), Popup(PopupKind),
OverrideRedirect(X11Surface), OverrideRedirect(X11Surface),
@ -39,7 +42,7 @@ pub enum PointerFocusTarget {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum KeyboardFocusTarget { pub enum KeyboardFocusTarget {
Element(CosmicMapped), Element(CosmicMapped),
Fullscreen(CosmicSurface), Fullscreen(CosmicWindow),
Group(WindowGroup), Group(WindowGroup),
LayerSurface(LayerSurface), LayerSurface(LayerSurface),
Popup(PopupKind), Popup(PopupKind),
@ -551,8 +554,8 @@ impl From<CosmicMapped> for PointerFocusTarget {
} }
} }
impl From<CosmicSurface> for PointerFocusTarget { impl From<CosmicWindow> for PointerFocusTarget {
fn from(s: CosmicSurface) -> Self { fn from(s: CosmicWindow) -> Self {
PointerFocusTarget::Fullscreen(s) PointerFocusTarget::Fullscreen(s)
} }
} }
@ -587,8 +590,8 @@ impl From<CosmicMapped> for KeyboardFocusTarget {
} }
} }
impl From<CosmicSurface> for KeyboardFocusTarget { impl From<CosmicWindow> for KeyboardFocusTarget {
fn from(s: CosmicSurface) -> Self { fn from(s: CosmicWindow) -> Self {
KeyboardFocusTarget::Fullscreen(s) KeyboardFocusTarget::Fullscreen(s)
} }
} }

View file

@ -21,6 +21,7 @@ use crate::{
xwayland::XWaylandState, xwayland::XWaylandState,
}; };
use calloop::LoopHandle;
use id_tree::Tree; use id_tree::Tree;
use indexmap::IndexSet; use indexmap::IndexSet;
use keyframe::{ease, functions::EaseInOutCubic}; use keyframe::{ease, functions::EaseInOutCubic};
@ -60,6 +61,7 @@ use super::{
element::{ element::{
resize_indicator::ResizeIndicator, stack::CosmicStackRenderElement, resize_indicator::ResizeIndicator, stack::CosmicStackRenderElement,
swap_indicator::SwapIndicator, window::CosmicWindowRenderElement, CosmicMapped, swap_indicator::SwapIndicator, window::CosmicWindowRenderElement, CosmicMapped,
CosmicWindow,
}, },
focus::{ focus::{
target::{KeyboardFocusTarget, PointerFocusTarget, WindowGroup}, target::{KeyboardFocusTarget, PointerFocusTarget, WindowGroup},
@ -87,7 +89,7 @@ pub struct Workspace {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FullscreenSurface { pub struct FullscreenSurface {
pub surface: CosmicSurface, pub window: CosmicWindow,
pub exclusive: bool, pub exclusive: bool,
original_size: Size<i32, Logical>, original_size: Size<i32, Logical>,
start_at: Option<Instant>, start_at: Option<Instant>,
@ -117,7 +119,7 @@ impl FullscreenSurface {
impl IsAlive for FullscreenSurface { impl IsAlive for FullscreenSurface {
fn alive(&self) -> bool { fn alive(&self) -> bool {
self.surface.alive() self.window.alive()
} }
} }
@ -182,7 +184,7 @@ impl Workspace {
if let Some(signal) = f.animation_signal.take() { if let Some(signal) = f.animation_signal.take() {
signal.store(true, Ordering::SeqCst); signal.store(true, Ordering::SeqCst);
if let Some(client) = if let Some(client) =
f.surface.wl_surface().as_ref().and_then(Resource::client) f.window.wl_surface().as_ref().and_then(Resource::client)
{ {
clients.push((client.id(), client)); clients.push((client.id(), client));
} }
@ -198,7 +200,7 @@ impl Workspace {
if let Some(signal) = f.animation_signal.take() { if let Some(signal) = f.animation_signal.take() {
signal.store(true, Ordering::SeqCst); signal.store(true, Ordering::SeqCst);
if let Some(client) = if let Some(client) =
f.surface.wl_surface().as_ref().and_then(Resource::client) f.window.wl_surface().as_ref().and_then(Resource::client)
{ {
clients.push((client.id(), client)); clients.push((client.id(), client));
} }
@ -235,8 +237,8 @@ impl Workspace {
output: &Output, output: &Output,
toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>, toplevel_info: &mut ToplevelInfoState<State, CosmicSurface>,
) { ) {
if let Some(dead_output_window) = self.fullscreen.remove(output) { if let Some(dead_output_fullscreen) = self.fullscreen.remove(output) {
self.unfullscreen_request(&dead_output_window.surface); self.unfullscreen_request(&dead_output_fullscreen.window.surface());
} }
self.tiling_layer.unmap_output(output, toplevel_info); self.tiling_layer.unmap_output(output, toplevel_info);
self.floating_layer.unmap_output(output, toplevel_info); self.floating_layer.unmap_output(output, toplevel_info);
@ -337,14 +339,19 @@ impl Workspace {
pub fn recalculate(&mut self, output: &Output) { pub fn recalculate(&mut self, output: &Output) {
if let Some(f) = self.fullscreen.get(output) { if let Some(f) = self.fullscreen.get(output) {
if !f.exclusive { if !f.exclusive {
f.surface f.window
.set_geometry(layer_map_for_output(output).non_exclusive_zone()); .set_geometry(layer_map_for_output(output).non_exclusive_zone());
} }
} }
self.tiling_layer.recalculate(output); self.tiling_layer.recalculate(output);
} }
pub fn maximize_request(&mut self, window: &CosmicSurface, output: &Output) { pub fn maximize_request(
&mut self,
window: &CosmicSurface,
output: &Output,
evlh: LoopHandle<'static, crate::state::Data>,
) {
if self.fullscreen.contains_key(output) { if self.fullscreen.contains_key(output) {
return; return;
} }
@ -353,10 +360,14 @@ impl Workspace {
window.set_fullscreen(false); window.set_fullscreen(false);
window.set_maximized(true); window.set_maximized(true);
self.set_fullscreen(window, output, false) self.set_fullscreen(window, output, false, evlh)
} }
pub fn unmaximize_request(&mut self, window: &CosmicSurface) -> Option<Size<i32, Logical>> { pub fn unmaximize_request(&mut self, window: &CosmicSurface) -> Option<Size<i32, Logical>> {
if self.fullscreen.values().any(|w| &w.surface == window) { if self
.fullscreen
.values()
.any(|f| &f.window.surface() == window)
{
self.unfullscreen_request(window); self.unfullscreen_request(window);
self.floating_layer.unmaximize_request(window) self.floating_layer.unmaximize_request(window)
} else { } else {
@ -364,11 +375,16 @@ impl Workspace {
} }
} }
pub fn fullscreen_request(&mut self, window: &CosmicSurface, output: &Output) { pub fn fullscreen_request(
&mut self,
window: &CosmicSurface,
output: &Output,
evlh: LoopHandle<'static, crate::state::Data>,
) {
if self if self
.fullscreen .fullscreen
.get(output) .get(output)
.map(|w| &w.surface != window) .map(|f| &f.window.surface() != window)
.unwrap_or(false) .unwrap_or(false)
{ {
return; return;
@ -380,10 +396,16 @@ impl Workspace {
window.set_maximized(false); window.set_maximized(false);
window.set_fullscreen(true); window.set_fullscreen(true);
self.set_fullscreen(window, output, true) self.set_fullscreen(window, output, true, evlh)
} }
fn set_fullscreen<'a>(&mut self, window: &'a CosmicSurface, output: &Output, exclusive: bool) { fn set_fullscreen<'a>(
&mut self,
window: &'a CosmicSurface,
output: &Output,
exclusive: bool,
evlh: LoopHandle<'static, crate::state::Data>,
) {
if let Some(mapped) = self if let Some(mapped) = self
.mapped() .mapped()
.find(|m| m.windows().any(|(w, _)| &w == window)) .find(|m| m.windows().any(|(w, _)| &w == window))
@ -391,11 +413,12 @@ impl Workspace {
mapped.set_active(window); mapped.set_active(window);
} }
window.set_geometry(if exclusive { let window = CosmicWindow::new(window.clone(), evlh);
let geo = if exclusive {
output.geometry() output.geometry()
} else { } else {
layer_map_for_output(output).non_exclusive_zone() layer_map_for_output(output).non_exclusive_zone()
}); };
let original_size = window.geometry().size; let original_size = window.geometry().size;
let signal = if let Some(surface) = window.wl_surface() { let signal = if let Some(surface) = window.wl_surface() {
let signal = Arc::new(AtomicBool::new(false)); let signal = Arc::new(AtomicBool::new(false));
@ -409,12 +432,14 @@ impl Workspace {
} else { } else {
None None
}; };
window.send_configure(); window.set_geometry(geo);
window.output_enter(output, Rectangle::from_loc_and_size((0, 0), geo.size));
window.surface().send_configure();
self.fullscreen.insert( self.fullscreen.insert(
output.clone(), output.clone(),
FullscreenSurface { FullscreenSurface {
surface: window.clone(), window: window.clone(),
exclusive, exclusive,
original_size, original_size,
start_at: Some(Instant::now()), start_at: Some(Instant::now()),
@ -428,8 +453,9 @@ impl Workspace {
if let Some((output, f)) = self if let Some((output, f)) = self
.fullscreen .fullscreen
.iter_mut() .iter_mut()
.find(|(_, w)| &w.surface == window) .find(|(_, f)| &f.window.surface() == window)
{ {
f.window.output_leave(output);
window.set_maximized(false); window.set_maximized(false);
window.set_fullscreen(false); window.set_fullscreen(false);
self.floating_layer.unmaximize_request(window); self.floating_layer.unmaximize_request(window);
@ -472,13 +498,15 @@ impl Workspace {
pub fn remove_fullscreen(&mut self, output: &Output) { pub fn remove_fullscreen(&mut self, output: &Output) {
if let Some(FullscreenSurface { if let Some(FullscreenSurface {
surface, window,
ended_at, ended_at,
start_at, start_at,
animation_signal, animation_signal,
.. ..
}) = self.fullscreen.get_mut(output) }) = self.fullscreen.get_mut(output)
{ {
window.output_leave(output);
let surface = window.surface();
surface.set_maximized(false); surface.set_maximized(false);
surface.set_fullscreen(false); surface.set_fullscreen(false);
self.floating_layer.unmaximize_request(&surface); self.floating_layer.unmaximize_request(&surface);
@ -519,28 +547,33 @@ impl Workspace {
} }
} }
pub fn maximize_toggle(&mut self, window: &CosmicSurface, output: &Output) { pub fn maximize_toggle(
&mut self,
window: &CosmicSurface,
output: &Output,
evlh: LoopHandle<'static, crate::state::Data>,
) {
if self.fullscreen.contains_key(output) { if self.fullscreen.contains_key(output) {
self.unmaximize_request(window); self.unmaximize_request(window);
} else { } else {
self.maximize_request(window, output); self.maximize_request(window, output, evlh);
} }
} }
pub fn get_fullscreen(&self, output: &Output) -> Option<&CosmicSurface> { pub fn get_fullscreen(&self, output: &Output) -> Option<&CosmicWindow> {
self.fullscreen self.fullscreen
.get(output) .get(output)
.filter(|w| w.alive() && w.exclusive) .filter(|f| f.alive() && f.exclusive)
.filter(|w| w.ended_at.is_none() && w.start_at.is_none()) .filter(|f| f.ended_at.is_none() && f.start_at.is_none())
.map(|w| &w.surface) .map(|f| &f.window)
} }
pub fn get_maximized(&self, output: &Output) -> Option<&CosmicSurface> { pub fn get_maximized(&self, output: &Output) -> Option<&CosmicWindow> {
self.fullscreen self.fullscreen
.get(output) .get(output)
.filter(|w| w.alive() && !w.exclusive) .filter(|f| f.alive() && !f.exclusive)
.filter(|w| w.ended_at.is_none() && w.start_at.is_none()) .filter(|f| f.ended_at.is_none() && f.start_at.is_none())
.map(|w| &w.surface) .map(|f| &f.window)
} }
pub fn resize_request( pub fn resize_request(
@ -574,7 +607,7 @@ impl Workspace {
if self if self
.fullscreen .fullscreen
.values() .values()
.any(|f| f.surface.wl_surface().as_ref() == Some(&toplevel)) .any(|f| f.window.surface().wl_surface().as_ref() == Some(&toplevel))
{ {
return false; return false;
} }
@ -692,20 +725,20 @@ impl Workspace {
pub fn is_fullscreen(&self, mapped: &CosmicMapped) -> bool { pub fn is_fullscreen(&self, mapped: &CosmicMapped) -> bool {
self.fullscreen self.fullscreen
.values() .values()
.any(|f| f.exclusive && f.surface == mapped.active_window()) .any(|f| f.exclusive && f.window.surface() == mapped.active_window())
} }
pub fn is_maximized(&self, mapped: &CosmicMapped) -> bool { pub fn is_maximized(&self, mapped: &CosmicMapped) -> bool {
self.fullscreen self.fullscreen
.values() .values()
.any(|f| !f.exclusive && f.surface == mapped.active_window()) .any(|f| !f.exclusive && f.window.surface() == mapped.active_window())
} }
pub fn is_floating(&self, mapped: &CosmicMapped) -> bool { pub fn is_floating(&self, mapped: &CosmicMapped) -> bool {
!self !self
.fullscreen .fullscreen
.values() .values()
.any(|f| f.surface == mapped.active_window()) .any(|f| f.window.surface() == mapped.active_window())
&& self.floating_layer.mapped().any(|m| m == mapped) && self.floating_layer.mapped().any(|m| m == mapped)
} }
@ -713,7 +746,7 @@ impl Workspace {
!self !self
.fullscreen .fullscreen
.values() .values()
.any(|f| f.surface == mapped.active_window()) .any(|f| f.window.surface() == mapped.active_window())
&& self.tiling_layer.mapped().any(|(_, m, _)| m == mapped) && self.tiling_layer.mapped().any(|(_, m, _)| m == mapped)
} }
@ -808,9 +841,9 @@ impl Workspace {
if let Some(fullscreen) = self.fullscreen.get(output) { if let Some(fullscreen) = self.fullscreen.get(output) {
// fullscreen window // fullscreen window
let bbox = fullscreen.surface.bbox(); let bbox = fullscreen.window.bbox();
let element_geo = Rectangle::from_loc_and_size( let element_geo = Rectangle::from_loc_and_size(
self.element_for_surface(&fullscreen.surface) self.element_for_surface(&fullscreen.window.surface())
.and_then(|elem| { .and_then(|elem| {
self.floating_layer self.floating_layer
.space .space
@ -883,18 +916,21 @@ impl Workspace {
y: target_geo.size.h as f64 / bbox.size.h as f64, y: target_geo.size.h as f64 / bbox.size.h as f64,
}; };
window_elements.extend( let (w_elements, p_elements) = fullscreen
AsRenderElements::<R>::render_elements::<WaylandSurfaceRenderElement<R>>( .window
&fullscreen.surface, .split_render_elements::<R, CosmicWindowRenderElement<R>>(
renderer, renderer,
render_loc, render_loc,
output_scale.into(), output_scale.into(),
alpha, alpha,
) );
.into_iter() window_elements.extend(
.map(|elem| RescaleRenderElement::from_element(elem, render_loc, scale)) w_elements
.map(Into::into), .into_iter()
.map(|elem| RescaleRenderElement::from_element(elem, render_loc, scale))
.map(Into::into),
); );
popup_elements.extend(p_elements.into_iter().map(Into::into));
} }
if self if self
@ -1008,8 +1044,9 @@ where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
{ {
Fullscreen(RescaleRenderElement<WaylandSurfaceRenderElement<R>>), OverrideRedirect(WaylandSurfaceRenderElement<R>),
Wayland(WaylandSurfaceRenderElement<R>), Fullscreen(RescaleRenderElement<CosmicWindowRenderElement<R>>),
FullscreenPopup(CosmicWindowRenderElement<R>),
Window(CosmicMappedRenderElement<R>), Window(CosmicMappedRenderElement<R>),
Backdrop(TextureRenderElement<GlesTexture>), Backdrop(TextureRenderElement<GlesTexture>),
} }
@ -1021,8 +1058,9 @@ where
{ {
fn id(&self) -> &smithay::backend::renderer::element::Id { fn id(&self) -> &smithay::backend::renderer::element::Id {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.id(),
WorkspaceRenderElement::Fullscreen(elem) => elem.id(), WorkspaceRenderElement::Fullscreen(elem) => elem.id(),
WorkspaceRenderElement::Wayland(elem) => elem.id(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.id(),
WorkspaceRenderElement::Window(elem) => elem.id(), WorkspaceRenderElement::Window(elem) => elem.id(),
WorkspaceRenderElement::Backdrop(elem) => elem.id(), WorkspaceRenderElement::Backdrop(elem) => elem.id(),
} }
@ -1030,8 +1068,9 @@ where
fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter { fn current_commit(&self) -> smithay::backend::renderer::utils::CommitCounter {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.current_commit(),
WorkspaceRenderElement::Fullscreen(elem) => elem.current_commit(), WorkspaceRenderElement::Fullscreen(elem) => elem.current_commit(),
WorkspaceRenderElement::Wayland(elem) => elem.current_commit(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.current_commit(),
WorkspaceRenderElement::Window(elem) => elem.current_commit(), WorkspaceRenderElement::Window(elem) => elem.current_commit(),
WorkspaceRenderElement::Backdrop(elem) => elem.current_commit(), WorkspaceRenderElement::Backdrop(elem) => elem.current_commit(),
} }
@ -1039,8 +1078,9 @@ where
fn src(&self) -> Rectangle<f64, smithay::utils::Buffer> { fn src(&self) -> Rectangle<f64, smithay::utils::Buffer> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.src(),
WorkspaceRenderElement::Fullscreen(elem) => elem.src(), WorkspaceRenderElement::Fullscreen(elem) => elem.src(),
WorkspaceRenderElement::Wayland(elem) => elem.src(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.src(),
WorkspaceRenderElement::Window(elem) => elem.src(), WorkspaceRenderElement::Window(elem) => elem.src(),
WorkspaceRenderElement::Backdrop(elem) => elem.src(), WorkspaceRenderElement::Backdrop(elem) => elem.src(),
} }
@ -1048,8 +1088,9 @@ where
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, smithay::utils::Physical> { fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, smithay::utils::Physical> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.geometry(scale),
WorkspaceRenderElement::Fullscreen(elem) => elem.geometry(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.geometry(scale),
WorkspaceRenderElement::Wayland(elem) => elem.geometry(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.geometry(scale),
WorkspaceRenderElement::Window(elem) => elem.geometry(scale), WorkspaceRenderElement::Window(elem) => elem.geometry(scale),
WorkspaceRenderElement::Backdrop(elem) => elem.geometry(scale), WorkspaceRenderElement::Backdrop(elem) => elem.geometry(scale),
} }
@ -1057,8 +1098,9 @@ where
fn location(&self, scale: Scale<f64>) -> Point<i32, smithay::utils::Physical> { fn location(&self, scale: Scale<f64>) -> Point<i32, smithay::utils::Physical> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.location(scale),
WorkspaceRenderElement::Fullscreen(elem) => elem.location(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.location(scale),
WorkspaceRenderElement::Wayland(elem) => elem.location(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.location(scale),
WorkspaceRenderElement::Window(elem) => elem.location(scale), WorkspaceRenderElement::Window(elem) => elem.location(scale),
WorkspaceRenderElement::Backdrop(elem) => elem.location(scale), WorkspaceRenderElement::Backdrop(elem) => elem.location(scale),
} }
@ -1066,8 +1108,9 @@ where
fn transform(&self) -> smithay::utils::Transform { fn transform(&self) -> smithay::utils::Transform {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.transform(),
WorkspaceRenderElement::Fullscreen(elem) => elem.transform(), WorkspaceRenderElement::Fullscreen(elem) => elem.transform(),
WorkspaceRenderElement::Wayland(elem) => elem.transform(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.transform(),
WorkspaceRenderElement::Window(elem) => elem.transform(), WorkspaceRenderElement::Window(elem) => elem.transform(),
WorkspaceRenderElement::Backdrop(elem) => elem.transform(), WorkspaceRenderElement::Backdrop(elem) => elem.transform(),
} }
@ -1079,8 +1122,9 @@ where
commit: Option<smithay::backend::renderer::utils::CommitCounter>, commit: Option<smithay::backend::renderer::utils::CommitCounter>,
) -> Vec<Rectangle<i32, smithay::utils::Physical>> { ) -> Vec<Rectangle<i32, smithay::utils::Physical>> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::Fullscreen(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::Fullscreen(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::Wayland(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::FullscreenPopup(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::Window(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::Window(elem) => elem.damage_since(scale, commit),
WorkspaceRenderElement::Backdrop(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::Backdrop(elem) => elem.damage_since(scale, commit),
} }
@ -1088,8 +1132,9 @@ where
fn opaque_regions(&self, scale: Scale<f64>) -> Vec<Rectangle<i32, smithay::utils::Physical>> { fn opaque_regions(&self, scale: Scale<f64>) -> Vec<Rectangle<i32, smithay::utils::Physical>> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::Fullscreen(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Fullscreen(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::Wayland(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::FullscreenPopup(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale),
WorkspaceRenderElement::Backdrop(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Backdrop(elem) => elem.opaque_regions(scale),
} }
@ -1097,8 +1142,9 @@ where
fn alpha(&self) -> f32 { fn alpha(&self) -> f32 {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.alpha(),
WorkspaceRenderElement::Fullscreen(elem) => elem.alpha(), WorkspaceRenderElement::Fullscreen(elem) => elem.alpha(),
WorkspaceRenderElement::Wayland(elem) => elem.alpha(), WorkspaceRenderElement::FullscreenPopup(elem) => elem.alpha(),
WorkspaceRenderElement::Window(elem) => elem.alpha(), WorkspaceRenderElement::Window(elem) => elem.alpha(),
WorkspaceRenderElement::Backdrop(elem) => elem.alpha(), WorkspaceRenderElement::Backdrop(elem) => elem.alpha(),
} }
@ -1114,8 +1160,9 @@ impl RenderElement<GlowRenderer> for WorkspaceRenderElement<GlowRenderer> {
damage: &[Rectangle<i32, smithay::utils::Physical>], damage: &[Rectangle<i32, smithay::utils::Physical>],
) -> Result<(), GlesError> { ) -> Result<(), GlesError> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Fullscreen(elem) => elem.draw(frame, src, dst, damage), WorkspaceRenderElement::Fullscreen(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Wayland(elem) => elem.draw(frame, src, dst, damage), WorkspaceRenderElement::FullscreenPopup(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), WorkspaceRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Backdrop(elem) => { WorkspaceRenderElement::Backdrop(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage) RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
@ -1128,8 +1175,9 @@ impl RenderElement<GlowRenderer> for WorkspaceRenderElement<GlowRenderer> {
renderer: &mut GlowRenderer, renderer: &mut GlowRenderer,
) -> Option<smithay::backend::renderer::element::UnderlyingStorage> { ) -> Option<smithay::backend::renderer::element::UnderlyingStorage> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Fullscreen(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Fullscreen(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Wayland(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::FullscreenPopup(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Backdrop(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Backdrop(elem) => elem.underlying_storage(renderer),
} }
@ -1147,8 +1195,9 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
damage: &[Rectangle<i32, smithay::utils::Physical>], damage: &[Rectangle<i32, smithay::utils::Physical>],
) -> Result<(), GlMultiError> { ) -> Result<(), GlMultiError> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Fullscreen(elem) => elem.draw(frame, src, dst, damage), WorkspaceRenderElement::Fullscreen(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Wayland(elem) => elem.draw(frame, src, dst, damage), WorkspaceRenderElement::FullscreenPopup(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), WorkspaceRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
WorkspaceRenderElement::Backdrop(elem) => { WorkspaceRenderElement::Backdrop(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame.glow_frame_mut(), src, dst, damage) RenderElement::<GlowRenderer>::draw(elem, frame.glow_frame_mut(), src, dst, damage)
@ -1162,8 +1211,9 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
renderer: &mut GlMultiRenderer<'a, 'b>, renderer: &mut GlMultiRenderer<'a, 'b>,
) -> Option<smithay::backend::renderer::element::UnderlyingStorage> { ) -> Option<smithay::backend::renderer::element::UnderlyingStorage> {
match self { match self {
WorkspaceRenderElement::OverrideRedirect(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Fullscreen(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Fullscreen(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Wayland(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::FullscreenPopup(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer),
WorkspaceRenderElement::Backdrop(elem) => { WorkspaceRenderElement::Backdrop(elem) => {
elem.underlying_storage(renderer.glow_renderer_mut()) elem.underlying_storage(renderer.glow_renderer_mut())
@ -1172,17 +1222,28 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
} }
} }
impl<R> From<RescaleRenderElement<WaylandSurfaceRenderElement<R>>> for WorkspaceRenderElement<R> impl<R> From<RescaleRenderElement<CosmicWindowRenderElement<R>>> for WorkspaceRenderElement<R>
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static, <R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>, CosmicMappedRenderElement<R>: RenderElement<R>,
{ {
fn from(elem: RescaleRenderElement<WaylandSurfaceRenderElement<R>>) -> Self { fn from(elem: RescaleRenderElement<CosmicWindowRenderElement<R>>) -> Self {
WorkspaceRenderElement::Fullscreen(elem) WorkspaceRenderElement::Fullscreen(elem)
} }
} }
impl<R> From<CosmicWindowRenderElement<R>> for WorkspaceRenderElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
fn from(elem: CosmicWindowRenderElement<R>) -> Self {
WorkspaceRenderElement::FullscreenPopup(elem)
}
}
impl<R> From<WaylandSurfaceRenderElement<R>> for WorkspaceRenderElement<R> impl<R> From<WaylandSurfaceRenderElement<R>> for WorkspaceRenderElement<R>
where where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer, R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
@ -1190,7 +1251,7 @@ where
CosmicMappedRenderElement<R>: RenderElement<R>, CosmicMappedRenderElement<R>: RenderElement<R>,
{ {
fn from(elem: WaylandSurfaceRenderElement<R>) -> Self { fn from(elem: WaylandSurfaceRenderElement<R>) -> Self {
WorkspaceRenderElement::Wayland(elem) WorkspaceRenderElement::OverrideRedirect(elem)
} }
} }

View file

@ -164,7 +164,7 @@ impl XdgShellHandler for State {
.windows() .windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface())) .find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
.unwrap(); .unwrap();
workspace.maximize_request(&window, &output) workspace.maximize_request(&window, &output, self.common.event_loop_handle.clone())
} }
} }
} }
@ -206,7 +206,11 @@ impl XdgShellHandler for State {
.windows() .windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface())) .find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
.unwrap(); .unwrap();
workspace.fullscreen_request(&window, &output) workspace.fullscreen_request(
&window,
&output,
self.common.event_loop_handle.clone(),
)
} }
} }
} }

View file

@ -401,7 +401,11 @@ impl XwmHandler for Data {
{ {
if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) { if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap(); let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
workspace.maximize_request(&window, &output) workspace.maximize_request(
&window,
&output,
self.state.common.event_loop_handle.clone(),
)
} }
} }
} }
@ -436,7 +440,11 @@ impl XwmHandler for Data {
{ {
if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) { if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap(); let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
workspace.fullscreen_request(&window, &output) workspace.fullscreen_request(
&window,
&output,
self.state.common.event_loop_handle.clone(),
)
} }
} }
} }