shell: Support maximize and fullscreen requests
This commit is contained in:
parent
f59bb8a06e
commit
bb07ab4155
5 changed files with 166 additions and 103 deletions
|
|
@ -107,6 +107,12 @@ impl CosmicMapped {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_active(&self, window: &Window) {
|
||||||
|
if let CosmicMappedInternal::Stack(stack) = &self.element {
|
||||||
|
stack.set_active(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn focus_window(&self, window: &Window) {
|
pub fn focus_window(&self, window: &Window) {
|
||||||
match &self.element {
|
match &self.element {
|
||||||
CosmicMappedInternal::Stack(stack) => stack.set_active(window),
|
CosmicMappedInternal::Stack(stack) => stack.set_active(window),
|
||||||
|
|
|
||||||
|
|
@ -155,30 +155,34 @@ impl FloatingLayout {
|
||||||
self.space.element_geometry(elem)
|
self.space.element_geometry(elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maximize_request(&mut self, window: &CosmicMapped, output: &Output) {
|
pub fn maximize_request(&mut self, window: &Window) {
|
||||||
let layers = layer_map_for_output(&output);
|
if let Some(mapped) = self
|
||||||
let geometry = layers.non_exclusive_zone();
|
.space
|
||||||
|
.elements()
|
||||||
if let Some(location) = self.space.element_location(window) {
|
.find(|m| m.windows().any(|(w, _)| &w == window))
|
||||||
*window.last_geometry.lock().unwrap() = Some(Rectangle::from_loc_and_size(
|
{
|
||||||
location,
|
if let Some(location) = self.space.element_location(mapped) {
|
||||||
window.geometry().size,
|
*mapped.last_geometry.lock().unwrap() = Some(Rectangle::from_loc_and_size(
|
||||||
));
|
location,
|
||||||
|
mapped.geometry().size,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.space.map_element(window.clone(), geometry.loc, true);
|
|
||||||
window.set_maximized(true);
|
|
||||||
window.set_size(geometry.size);
|
|
||||||
window.configure();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unmaximize_request(&mut self, window: &CosmicMapped) {
|
pub fn unmaximize_request(&mut self, window: &Window) {
|
||||||
let last_geometry = window.last_geometry.lock().unwrap().clone();
|
let maybe_mapped = self
|
||||||
window.set_maximized(false);
|
.space
|
||||||
window.set_size(last_geometry.map(|g| g.size).expect("No previous size?"));
|
.elements()
|
||||||
window.configure();
|
.find(|m| m.windows().any(|(w, _)| &w == window))
|
||||||
let last_location = last_geometry.map(|g| g.loc).expect("No previous location?");
|
.cloned();
|
||||||
self.space.map_element(window.clone(), last_location, true);
|
|
||||||
|
if let Some(mapped) = maybe_mapped {
|
||||||
|
let last_geometry = mapped.last_geometry.lock().unwrap().clone();
|
||||||
|
mapped.set_size(last_geometry.map(|g| g.size).expect("No previous size?"));
|
||||||
|
let last_location = last_geometry.map(|g| g.loc).expect("No previous location?");
|
||||||
|
self.space.map_element(mapped, last_location, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -795,7 +795,7 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Data::Mapped { mapped, .. } => {
|
Data::Mapped { mapped, .. } => {
|
||||||
if !mapped.is_fullscreen() {
|
if !(mapped.is_fullscreen() || mapped.is_maximized()) {
|
||||||
mapped.set_tiled(true);
|
mapped.set_tiled(true);
|
||||||
mapped.set_size(
|
mapped.set_size(
|
||||||
(geo.size.w - inner * 2, geo.size.h - inner * 2).into(),
|
(geo.size.w - inner * 2, geo.size.h - inner * 2).into(),
|
||||||
|
|
|
||||||
|
|
@ -157,26 +157,103 @@ impl Workspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
pub fn maximize_request(&mut self, window: &Window, output: &Output) {
|
||||||
pub fn maximize_request(&mut self, window: &CosmicWindow, output: &Output) {
|
if self.fullscreen.contains_key(output) {
|
||||||
if self.fullscreen.values().any(|w| w == window) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if self.floating_layer.windows.contains(window) {
|
|
||||||
self.floating_layer
|
self.floating_layer.maximize_request(window);
|
||||||
.maximize_request(, window, output);
|
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||||
|
xdg.with_pending_state(|state| {
|
||||||
|
state.states.set(xdg_toplevel::State::Maximized);
|
||||||
|
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.set_fullscreen(window, output)
|
||||||
}
|
}
|
||||||
pub fn unmaximize_request(&mut self, window: &CosmicMapped) {
|
pub fn unmaximize_request(&mut self, window: &Window) {
|
||||||
if self.fullscreen.values().any(|w| w == window) {
|
if self.fullscreen.values().any(|w| w == window) {
|
||||||
|
self.floating_layer.unmaximize_request(window);
|
||||||
return self.unfullscreen_request(window);
|
return self.unfullscreen_request(window);
|
||||||
}
|
}
|
||||||
if self.floating_layer.windows.contains(window) {
|
|
||||||
self.floating_layer
|
|
||||||
.unmaximize_request(window);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fullscreen_request(&mut self, window: &Window, output: &Output) {
|
||||||
|
if self.fullscreen.contains_key(output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||||
|
xdg.with_pending_state(|state| {
|
||||||
|
state.states.set(xdg_toplevel::State::Fullscreen);
|
||||||
|
state.states.unset(xdg_toplevel::State::Maximized);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.set_fullscreen(window, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_fullscreen(&mut self, window: &Window, output: &Output) {
|
||||||
|
if let Some(mapped) = self
|
||||||
|
.mapped()
|
||||||
|
.find(|m| m.windows().any(|(w, _)| &w == window))
|
||||||
|
{
|
||||||
|
mapped.set_active(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||||
|
xdg.with_pending_state(|state| {
|
||||||
|
state.size = Some(
|
||||||
|
output
|
||||||
|
.current_mode()
|
||||||
|
.map(|m| m.size)
|
||||||
|
.unwrap_or((0, 0).into())
|
||||||
|
.to_f64()
|
||||||
|
.to_logical(output.current_scale().fractional_scale())
|
||||||
|
.to_i32_round(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
xdg.send_configure();
|
||||||
|
}
|
||||||
|
self.fullscreen.insert(output.clone(), window.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unfullscreen_request(&mut self, window: &Window) {
|
||||||
|
if self.fullscreen.values().any(|w| w == window) {
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||||
|
xdg.with_pending_state(|state| {
|
||||||
|
state.states.unset(xdg_toplevel::State::Fullscreen);
|
||||||
|
state.states.unset(xdg_toplevel::State::Maximized);
|
||||||
|
state.size = None;
|
||||||
|
});
|
||||||
|
self.floating_layer.refresh();
|
||||||
|
self.tiling_layer.refresh();
|
||||||
|
xdg.send_configure();
|
||||||
|
}
|
||||||
|
self.fullscreen.retain(|_, w| w != window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fullscreen_toggle(&mut self, window: &Window, output: &Output) {
|
||||||
|
if self.fullscreen.contains_key(output) {
|
||||||
|
self.unfullscreen_request(window)
|
||||||
|
} else {
|
||||||
|
self.fullscreen_request(window, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_fullscreen(&self, output: &Output) -> Option<&Window> {
|
||||||
|
self.fullscreen.get(output).filter(|w| w.alive())
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn resize_request(
|
pub fn resize_request(
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
surface: &WlSurface,
|
surface: &WlSurface,
|
||||||
|
|
@ -203,59 +280,6 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub fn fullscreen_request(&mut self, window: &Window, output: &Output) {
|
|
||||||
if self.fullscreen.contains_key(output) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
if let Kind::Xdg(xdg) = &window.toplevel() {
|
|
||||||
xdg.with_pending_state(|state| {
|
|
||||||
state.states.set(xdg_toplevel::State::Fullscreen);
|
|
||||||
state.size = Some(
|
|
||||||
output
|
|
||||||
.current_mode()
|
|
||||||
.map(|m| m.size)
|
|
||||||
.unwrap_or((0, 0).into())
|
|
||||||
.to_f64()
|
|
||||||
.to_logical(output.current_scale().fractional_scale())
|
|
||||||
.to_i32_round(),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
xdg.send_configure();
|
|
||||||
self.fullscreen.insert(output.clone(), window.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unfullscreen_request(&mut self, window: &Window) {
|
|
||||||
if self.fullscreen.values().any(|w| w == window) {
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
if let Kind::Xdg(xdg) = &window.toplevel() {
|
|
||||||
xdg.with_pending_state(|state| {
|
|
||||||
state.states.unset(xdg_toplevel::State::Fullscreen);
|
|
||||||
state.size = None;
|
|
||||||
});
|
|
||||||
self.floating_layer.refresh();
|
|
||||||
self.tiling_layer.refresh();
|
|
||||||
xdg.send_configure();
|
|
||||||
}
|
|
||||||
self.fullscreen.retain(|_, w| w != window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fullscreen_toggle(&mut self, window: &Window, output: &Output) {
|
|
||||||
if self.fullscreen.contains_key(output) {
|
|
||||||
self.unfullscreen_request(window)
|
|
||||||
} else {
|
|
||||||
self.fullscreen_request(window, output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_fullscreen(&self, output: &Output) -> Option<&Window> {
|
|
||||||
self.fullscreen.get(output).filter(|w| w.alive())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn toggle_tiling(&mut self, seat: &Seat<State>) {
|
pub fn toggle_tiling(&mut self, seat: &Seat<State>) {
|
||||||
if self.tiling_enabled {
|
if self.tiling_enabled {
|
||||||
for window in self
|
for window in self
|
||||||
|
|
|
||||||
|
|
@ -176,23 +176,38 @@ impl XdgShellHandler for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
fn maximize_request(&mut self, surface: ToplevelSurface) {
|
||||||
let surface = surface.wl_surface();
|
|
||||||
let seat = self.common.last_active_seat();
|
let seat = self.common.last_active_seat();
|
||||||
let output = seat.active_output();
|
let output = seat.active_output();
|
||||||
|
|
||||||
if let Some(mapped) = self.common.shell.element_for_surface(surface).cloned() {
|
if let Some(mapped) = self
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.element_for_surface(surface.wl_surface())
|
||||||
|
.cloned()
|
||||||
|
{
|
||||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||||
//workspace.maximize_request(mapped, &output)
|
let (window, _) = mapped
|
||||||
|
.windows()
|
||||||
|
.find(|(w, _)| matches!(w.toplevel(), Kind::Xdg(s) if s == &surface))
|
||||||
|
.unwrap();
|
||||||
|
workspace.maximize_request(&window, &output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
|
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
|
||||||
let surface = surface.wl_surface();
|
if let Some(mapped) = self
|
||||||
|
.common
|
||||||
if let Some(mapped) = self.common.shell.element_for_surface(surface).cloned() {
|
.shell
|
||||||
|
.element_for_surface(surface.wl_surface())
|
||||||
|
.cloned()
|
||||||
|
{
|
||||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||||
//workspace.unmaximize_request(mapped, &output)
|
let (window, _) = mapped
|
||||||
|
.windows()
|
||||||
|
.find(|(w, _)| matches!(w.toplevel(), Kind::Xdg(s) if s == &surface))
|
||||||
|
.unwrap();
|
||||||
|
workspace.unmaximize_request(&window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -206,22 +221,36 @@ impl XdgShellHandler for State {
|
||||||
seat.active_output()
|
seat.active_output()
|
||||||
});
|
});
|
||||||
|
|
||||||
let surface = surface.wl_surface();
|
if let Some(mapped) = self
|
||||||
if let Some(mapped) = self.common.shell.element_for_surface(surface).cloned() {
|
.common
|
||||||
|
.shell
|
||||||
|
.element_for_surface(surface.wl_surface())
|
||||||
|
.cloned()
|
||||||
|
{
|
||||||
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||||
workspace.fullscreen_request(&mapped.active_window(), &output)
|
let (window, _) = mapped
|
||||||
|
.windows()
|
||||||
|
.find(|(w, _)| matches!(w.toplevel(), Kind::Xdg(s) if s == &surface))
|
||||||
|
.unwrap();
|
||||||
|
workspace.fullscreen_request(&window, &output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
|
fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
|
||||||
if let Some((workspace, window)) = self.common.shell.workspaces.spaces_mut().find_map(|w| {
|
if let Some(mapped) = self
|
||||||
let window = w
|
.common
|
||||||
.windows()
|
.shell
|
||||||
.find(|w| w.toplevel().wl_surface() == surface.wl_surface());
|
.element_for_surface(surface.wl_surface())
|
||||||
window.map(|win| (w, win))
|
.cloned()
|
||||||
}) {
|
{
|
||||||
workspace.unfullscreen_request(&window)
|
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
|
||||||
|
let (window, _) = mapped
|
||||||
|
.windows()
|
||||||
|
.find(|(w, _)| matches!(w.toplevel(), Kind::Xdg(s) if s == &surface))
|
||||||
|
.unwrap();
|
||||||
|
workspace.unfullscreen_request(&window)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue