shell: Lift/refactor (un)maximize, consider sticky windows

This commit is contained in:
Victoria Brekenfeld 2023-12-20 20:45:47 +00:00 committed by Victoria Brekenfeld
parent d0136194f4
commit 807f63bb72
7 changed files with 86 additions and 86 deletions

View file

@ -2039,9 +2039,9 @@ impl State {
let current_output = seat.active_output();
let workspace = self.common.shell.active_space_mut(&current_output);
let focus_stack = workspace.focus_stack.get(seat);
let focused_window = focus_stack.last();
if let Some(window) = focused_window.map(|f| f.active_window()) {
workspace.maximize_toggle(&window);
let focused_window = focus_stack.last().cloned();
if let Some(window) = focused_window {
self.common.shell.maximize_toggle(&window);
}
}
Action::Resizing(direction) => self.common.shell.set_resize_mode(

View file

@ -274,13 +274,7 @@ impl Program for CosmicWindowInternal {
if let Some(mapped) =
state.common.shell.element_for_wl_surface(&surface).cloned()
{
if let Some(workspace) = state.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped
.windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(&surface))
.unwrap();
workspace.maximize_toggle(&window)
}
state.common.shell.maximize_toggle(&mapped)
}
});
}

View file

@ -30,16 +30,6 @@ fn stack(state: &mut State, mapped: &CosmicMapped) {
}
}
fn maximize_toggle(state: &mut State, mapped: &CosmicMapped) {
if let Some(space) = state.common.shell.space_for_mut(mapped) {
if mapped.is_maximized(false) {
space.unmaximize_request(&mapped.active_window());
} else {
space.maximize_request(&mapped.active_window());
}
}
}
fn move_prev_workspace(state: &mut State, mapped: &CosmicMapped) {
let seat = state.common.last_active_seat().clone();
let (current_handle, output) = {
@ -138,7 +128,7 @@ pub fn tab_items(
.collect::<Vec<_>>()
.into_iter()
{
workspace.unmaximize_request(&mapped.active_window());
workspace.unmaximize_request(&mapped);
}
let focus_stack = workspace.focus_stack.get(&seat);
workspace
@ -202,7 +192,8 @@ pub fn window_items(
Some(
Item::new(fl!("window-menu-maximize"), move |handle| {
let mapped = maximize_clone.clone();
let _ = handle.insert_idle(move |state| maximize_toggle(state, &mapped));
let _ =
handle.insert_idle(move |state| state.common.shell.maximize_toggle(&mapped));
})
.shortcut(config.get_shortcut_for_action(&Action::Maximize))
.toggled(window.is_maximized(false)),

View file

@ -71,7 +71,7 @@ use self::{
element::{
resize_indicator::{resize_indicator, ResizeIndicator},
swap_indicator::{swap_indicator, SwapIndicator},
CosmicWindow,
CosmicWindow, MaximizedState,
},
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
grabs::{
@ -2402,6 +2402,71 @@ impl Shell {
}
}
pub fn maximize_toggle(&mut self, window: &CosmicMapped) {
if window.is_maximized(true) {
self.unmaximize_request(window);
} else {
self.maximize_request(window);
}
}
pub fn maximize_request(&mut self, mapped: &CosmicMapped) {
let (managed_layer, floating_layer) = if let Some(set) = self
.workspaces
.sets
.values_mut()
.find(|set| set.sticky_layer.mapped().any(|m| m == mapped))
{
(ManagedLayer::Sticky, &mut set.sticky_layer)
} else if let Some(workspace) = self.space_for_mut(&mapped) {
let layer = if workspace.is_floating(&mapped) {
ManagedLayer::Floating
} else {
ManagedLayer::Tiling
};
(layer, &mut workspace.floating_layer)
} else {
return;
};
let mut state = mapped.maximized_state.lock().unwrap();
if state.is_none() {
*state = Some(MaximizedState {
original_geometry: floating_layer.element_geometry(&mapped).unwrap(),
original_layer: managed_layer,
});
std::mem::drop(state);
floating_layer.map_maximized(mapped.clone());
}
}
pub fn unmaximize_request(&mut self, mapped: &CosmicMapped) -> Option<Size<i32, Logical>> {
if let Some(set) = self
.workspaces
.sets
.values_mut()
.find(|set| set.sticky_layer.mapped().any(|m| m == mapped))
{
let mut state = mapped.maximized_state.lock().unwrap();
if let Some(state) = state.take() {
assert_eq!(state.original_layer, ManagedLayer::Sticky);
mapped.set_maximized(false);
set.sticky_layer.map_internal(
mapped.clone(),
Some(state.original_geometry.loc),
Some(state.original_geometry.size.as_logical()),
);
Some(state.original_geometry.size.as_logical())
} else {
None
}
} else if let Some(workspace) = self.space_for_mut(mapped) {
workspace.unmaximize_request(mapped)
} else {
None
}
}
pub fn resize_request(
state: &mut State,
surface: &WlSurface,

View file

@ -64,7 +64,6 @@ use super::{
element::{
resize_indicator::ResizeIndicator, stack::CosmicStackRenderElement,
swap_indicator::SwapIndicator, window::CosmicWindowRenderElement, CosmicMapped,
MaximizedState,
},
focus::{
target::{KeyboardFocusTarget, PointerFocusTarget, WindowGroup},
@ -379,7 +378,7 @@ impl Workspace {
if mapped.maximized_state.lock().unwrap().is_some() {
// If surface is maximized then unmaximize it, so it is assigned to only one layer
let _ = self.unmaximize_request(&mapped.active_window());
let _ = self.unmaximize_request(mapped);
}
let was_floating = self.floating_layer.unmap(&mapped);
@ -449,30 +448,7 @@ impl Workspace {
self.floating_layer.refresh();
}
pub fn maximize_request(&mut self, window: &CosmicSurface) {
if self.fullscreen.is_some() {
return;
}
if let Some(elem) = self.element_for_surface(window).cloned() {
let mut state = elem.maximized_state.lock().unwrap();
if state.is_none() {
*state = Some(MaximizedState {
original_geometry: self.element_geometry(&elem).unwrap(),
original_layer: if self.is_floating(&elem) {
ManagedLayer::Floating
} else {
ManagedLayer::Tiling
},
});
std::mem::drop(state);
self.floating_layer.map_maximized(elem);
}
}
}
pub fn unmaximize_request(&mut self, window: &CosmicSurface) -> Option<Size<i32, Logical>> {
if let Some(elem) = self.element_for_surface(window).cloned() {
pub fn unmaximize_request(&mut self, elem: &CosmicMapped) -> Option<Size<i32, Logical>> {
let mut state = elem.maximized_state.lock().unwrap();
if let Some(state) = state.take() {
match state.original_layer {
@ -484,10 +460,9 @@ impl Workspace {
elem.set_geometry(state.original_geometry.to_global(&self.output));
elem.configure();
self.tiling_layer.recalculate();
return self
.tiling_layer
self.tiling_layer
.element_geometry(&elem)
.map(|geo| geo.size.as_logical());
.map(|geo| geo.size.as_logical())
}
ManagedLayer::Floating => {
elem.set_maximized(false);
@ -496,12 +471,13 @@ impl Workspace {
Some(state.original_geometry.loc),
Some(state.original_geometry.size.as_logical()),
);
return Some(state.original_geometry.size.as_logical());
Some(state.original_geometry.size.as_logical())
}
ManagedLayer::Sticky => unreachable!(),
}
}
}
} else {
None
}
}
pub fn fullscreen_request(
@ -611,14 +587,6 @@ impl Workspace {
}
}
pub fn maximize_toggle(&mut self, window: &CosmicSurface) {
if window.is_maximized(true) {
self.unmaximize_request(window);
} else {
self.maximize_request(window);
}
}
pub fn get_fullscreen(&self) -> Option<&CosmicSurface> {
self.fullscreen
.as_ref()
@ -710,7 +678,7 @@ impl Workspace {
pub fn toggle_floating_window(&mut self, seat: &Seat<State>, window: &CosmicMapped) {
if self.tiling_enabled {
if window.is_maximized(false) {
self.unmaximize_request(&window.active_window());
self.unmaximize_request(window);
}
if self.tiling_layer.mapped().any(|(_, m, _)| m == window) {
self.tiling_layer.unmap(window);

View file

@ -169,13 +169,7 @@ impl XdgShellHandler for State {
.element_for_wl_surface(surface.wl_surface())
.cloned()
{
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped
.windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
.unwrap();
workspace.maximize_request(&window)
}
self.common.shell.maximize_request(&mapped)
}
}
@ -186,13 +180,7 @@ impl XdgShellHandler for State {
.element_for_wl_surface(surface.wl_surface())
.cloned()
{
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped
.windows()
.find(|(w, _)| w.wl_surface().as_ref() == Some(surface.wl_surface()))
.unwrap();
workspace.unmaximize_request(&window);
}
self.common.shell.unmaximize_request(&mapped);
}
}

View file

@ -426,20 +426,14 @@ impl XwmHandler for State {
fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
let surface = CosmicSurface::X11(window);
if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() {
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
workspace.maximize_request(&window);
}
self.common.shell.maximize_request(&mapped);
}
}
fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
let surface = CosmicSurface::X11(window);
if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() {
if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
workspace.unmaximize_request(&window);
}
self.common.shell.unmaximize_request(&mapped);
}
}