From 69a97685b70272b8d5988b0b8cc7aeb63bbf04d4 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 8 Jan 2024 18:09:43 +0000 Subject: [PATCH 1/7] shell: Unify mapping windows into stacks logic --- src/shell/grabs/menu/default.rs | 2 +- src/shell/layout/mod.rs | 6 +++- src/shell/layout/tiling/mod.rs | 37 ++++-------------------- src/shell/mod.rs | 50 ++++++++++++++++++++------------- src/shell/workspace.rs | 4 +-- 5 files changed, 43 insertions(+), 56 deletions(-) diff --git a/src/shell/grabs/menu/default.rs b/src/shell/grabs/menu/default.rs index 678253e27..9d4ad67dc 100644 --- a/src/shell/grabs/menu/default.rs +++ b/src/shell/grabs/menu/default.rs @@ -124,7 +124,7 @@ pub fn tab_items( let focus_stack = workspace.focus_stack.get(&seat); workspace .tiling_layer - .map(mapped, Some(focus_stack.iter()), None, false); + .map(mapped, Some(focus_stack.iter()), None); } else { workspace.floating_layer.map(mapped, None) } diff --git a/src/shell/layout/mod.rs b/src/shell/layout/mod.rs index 9652802ef..bdae6ed3c 100644 --- a/src/shell/layout/mod.rs +++ b/src/shell/layout/mod.rs @@ -98,7 +98,7 @@ lazy_static::lazy_static! { ]).unwrap(); } -pub fn should_be_floating(window: &CosmicSurface) -> bool { +pub fn is_dialog(window: &CosmicSurface) -> bool { // Check "window type" match window { CosmicSurface::Wayland(window) => { @@ -136,6 +136,10 @@ pub fn should_be_floating(window: &CosmicSurface) -> bool { return true; } + false +} + +pub fn has_floating_exception(window: &CosmicSurface) -> bool { // else take a look at our exceptions let appid_matches = EXCEPTIONS_APPID.matches(&window.app_id()); let title_matches = EXCEPTIONS_TITLE.matches(&window.title()); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index f68f9b749..3d83c47bb 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -367,11 +367,10 @@ impl TilingLayout { window: CosmicMapped, focus_stack: Option + 'a>, direction: Option, - add_to_stack: bool, ) { window.output_enter(&self.output, window.bbox()); window.set_bounds(self.output.geometry().size.as_logical()); - self.map_internal(window, focus_stack, direction, add_to_stack); + self.map_internal(window, focus_stack, direction); } pub fn map_internal<'a>( @@ -379,21 +378,13 @@ impl TilingLayout { window: impl Into, focus_stack: Option + 'a>, direction: Option, - add_to_stack: bool, ) { let gaps = self.gaps(); let mut tree = self.queue.trees.back().unwrap().0.copy_clone(); let last_active = focus_stack .and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack)); - TilingLayout::map_to_tree( - &mut tree, - window, - &self.output, - last_active, - direction, - add_to_stack, - ); + TilingLayout::map_to_tree(&mut tree, window, &self.output, last_active, direction); let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps); self.queue.push_tree(tree, ANIMATION_DURATION, blocker); } @@ -404,7 +395,6 @@ impl TilingLayout { output: &Output, node: Option<(NodeId, CosmicMapped)>, direction: Option, - add_to_stack: bool, ) { let window = window.into(); let new_window = Node::new(Data::Mapped { @@ -434,16 +424,7 @@ impl TilingLayout { tree.insert(new_window, InsertBehavior::AsRoot).unwrap() } } else { - if let Some((ref node_id, mut last_active_window)) = node { - if add_to_stack && window.is_window() && last_active_window.is_stack() { - let surface = window.active_window(); - last_active_window - .stack_ref_mut() - .unwrap() - .add_window(surface, None); - return; - } - + if let Some((ref node_id, _)) = node { let orientation = { let window_size = tree.get(node_id).unwrap().data().geometry().size; if window_size.w > window_size.h { @@ -543,7 +524,7 @@ impl TilingLayout { } mapped.set_tiled(true); - other.map(mapped.clone(), Some(focus_stack), None, true); + other.map(mapped.clone(), Some(focus_stack), None); return Some(KeyboardFocusTarget::Element(mapped)); } None => { @@ -1974,7 +1955,6 @@ impl TilingLayout { &self.output, Some(current_node), None, - false, ); let node = window.tiling_node_id.lock().unwrap().clone().unwrap(); @@ -2505,14 +2485,7 @@ impl TilingLayout { } } _ => { - TilingLayout::map_to_tree( - &mut tree, - window.clone(), - &self.output, - None, - None, - false, - ); + TilingLayout::map_to_tree(&mut tree, window.clone(), &self.output, None, None); window } }; diff --git a/src/shell/mod.rs b/src/shell/mod.rs index d984b0f05..4f2f26b72 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1587,12 +1587,11 @@ impl Shell { .map(mapped, None) } ManagedLayer::Floating => new_workspace.floating_layer.map(mapped, None), - ManagedLayer::Tiling => new_workspace.tiling_layer.map( - mapped, - Option::>::None, - None, - false, - ), + ManagedLayer::Tiling => { + new_workspace + .tiling_layer + .map(mapped, Option::>::None, None) + } }; } @@ -1714,6 +1713,26 @@ impl Shell { .toplevel_info_state .toplevel_enter_workspace(&window, &workspace.handle); + let workspace_output = workspace.output.clone(); + let was_activated = workspace_handle.is_some() + && (workspace_output != seat.active_output() || active_handle != workspace.handle); + let workspace_handle = workspace.handle; + let is_dialog = layout::is_dialog(&window); + let floating_exception = layout::has_floating_exception(&window); + + let maybe_focused = workspace.focus_stack.get(&seat).iter().next().cloned(); + if let Some(focused) = maybe_focused { + if (focused.is_stack() && !is_dialog && !should_be_fullscreen) + && !(workspace.is_tiled(&focused) && floating_exception) + { + focused.stack_ref().unwrap().add_window(window, None); + if was_activated { + state.common.shell.set_urgent(&workspace_handle); + } + return; + } + } + let mapped = CosmicMapped::from(CosmicWindow::new( window.clone(), state.common.event_loop_handle.clone(), @@ -1725,8 +1744,7 @@ impl Shell { } let workspace_empty = workspace.mapped().next().is_none(); - - if layout::should_be_floating(&window) || !workspace.tiling_enabled { + if is_dialog || floating_exception || !workspace.tiling_enabled { workspace.floating_layer.map(mapped.clone(), None); } else { for mapped in workspace @@ -1741,17 +1759,13 @@ impl Shell { let focus_stack = workspace.focus_stack.get(&seat); workspace .tiling_layer - .map(mapped.clone(), Some(focus_stack.iter()), None, true); + .map(mapped.clone(), Some(focus_stack.iter()), None); } if !parent_is_sticky && should_be_fullscreen { workspace.fullscreen_request(&mapped.active_window(), None); } - let was_activated = workspace_handle.is_some(); - let workspace_handle = workspace.handle; - let workspace_output = workspace.output.clone(); - if parent_is_sticky { let seats = state.common.seats().cloned().collect::>(); state @@ -1923,7 +1937,6 @@ impl Shell { mapped.clone(), focus_stack.as_ref().map(|x| x.iter()), direction, - true, ); } @@ -2891,12 +2904,9 @@ impl Shell { } ManagedLayer::Tiling => { let focus_stack = workspace.focus_stack.get(seat); - workspace.tiling_layer.map( - mapped.clone(), - Some(focus_stack.iter()), - None, - false, - ); + workspace + .tiling_layer + .map(mapped.clone(), Some(focus_stack.iter()), None); } ManagedLayer::Sticky => unreachable!(), } diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index c459ac0f8..f30147d2c 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -637,7 +637,7 @@ impl Workspace { { self.floating_layer.unmap(&window); self.tiling_layer - .map(window, Some(focus_stack.iter()), None, false) + .map(window, Some(focus_stack.iter()), None) } self.tiling_enabled = true; } @@ -655,7 +655,7 @@ impl Workspace { let focus_stack = self.focus_stack.get(seat); self.floating_layer.unmap(&window); self.tiling_layer - .map(window.clone(), Some(focus_stack.iter()), None, false) + .map(window.clone(), Some(focus_stack.iter()), None) } } } From 400291efcf9b9f1659609938e911522d0954ef52 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 8 Jan 2024 21:22:57 +0000 Subject: [PATCH 2/7] stack: Fix dragging out to the top (or the sides) --- src/shell/element/stack.rs | 39 +++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index a978ad346..c188b1127 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -1152,12 +1152,43 @@ impl PointerTarget for CosmicStack { } }) { event.location.y += TAB_HEIGHT as f64; - event.location -= self + let active_window_geo = self .0 - .with_program(|p| p.windows.lock().unwrap()[active].geometry().loc.to_f64()); + .with_program(|p| p.windows.lock().unwrap()[active].geometry()); + event.location -= active_window_geo.loc.to_f64(); match (previous, next) { (Focus::Header, Focus::Header) => { - PointerTarget::motion(&self.0, seat, data, &event) + PointerTarget::motion(&self.0, seat, data, &event); + if event.location.y < 0.0 + || event.location.x < 64.0 + || event.location.x > (active_window_geo.size.w as f64 - 64.0) + { + if let Some(dragged_out) = self + .0 + .with_program(|p| p.potential_drag.lock().unwrap().take()) + { + if let Some(surface) = self.0.with_program(|p| { + p.windows.lock().unwrap().get(dragged_out).cloned() + }) { + let seat = seat.clone(); + surface.try_force_undecorated(false); + surface.send_configure(); + if let Some(surface) = surface.wl_surface() { + let _ = + data.common.event_loop_handle.insert_idle(move |state| { + Shell::move_request( + state, + &surface, + &seat, + None, + ReleaseMode::NoMouseButtons, + true, + ) + }); + } + } + } + } } (_, Focus::Header) => PointerTarget::enter(&self.0, seat, data, &event), (Focus::Header, _) => { @@ -1171,6 +1202,8 @@ impl PointerTarget for CosmicStack { .with_program(|p| p.windows.lock().unwrap().get(dragged_out).cloned()) { let seat = seat.clone(); + surface.try_force_undecorated(false); + surface.send_configure(); if let Some(surface) = surface.wl_surface() { let _ = data.common.event_loop_handle.insert_idle(move |state| { Shell::move_request( From 56e5ba2503af164f85808b5292f8e07de21b7500 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 8 Jan 2024 21:23:51 +0000 Subject: [PATCH 3/7] stack: Fix mouse offset on windows with non-zero geometry --- src/shell/element/stack.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index c188b1127..8eb7c19a0 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -918,7 +918,12 @@ impl SpaceElement for CosmicStack { } fn is_in_input_region(&self, point: &Point) -> bool { let mut point = *point; - if point.y < TAB_HEIGHT as f64 { + let offset = self.0.with_program(|p| { + p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)] + .geometry() + .loc + }); + if (point.y.round() as i32 - offset.y) < TAB_HEIGHT { return true; } point.y -= TAB_HEIGHT as f64; From b8ad74a44a304db32438b21caf5cfa49def55325 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 8 Jan 2024 21:24:09 +0000 Subject: [PATCH 4/7] stack: Fix rendering of inactive windows --- src/shell/element/stack.rs | 107 ++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 19 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 8eb7c19a0..ea18f2cb3 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -24,8 +24,9 @@ use smithay::{ renderer::{ element::{ memory::MemoryRenderBufferRenderElement, surface::WaylandSurfaceRenderElement, - AsRenderElements, + AsRenderElements, Element, Id as ElementId, Kind, RenderElement, }, + utils::CommitCounter, ImportAll, ImportMem, Renderer, }, }, @@ -42,7 +43,7 @@ use smithay::{ }, output::Output, render_elements, - utils::{IsAlive, Logical, Point, Rectangle, Serial, Size}, + utils::{Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform}, wayland::seat::WaylandFocus, }; use std::{ @@ -516,8 +517,8 @@ impl CosmicStack { pub fn split_render_elements( &self, renderer: &mut R, - location: smithay::utils::Point, - scale: smithay::utils::Scale, + location: Point, + scale: Scale, alpha: f32, ) -> (Vec, Vec) where @@ -525,15 +526,15 @@ impl CosmicStack { ::TextureId: 'static, C: From>, { - let stack_loc = location - + self - .0 - .with_program(|p| { - p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)] - .geometry() - .loc - }) - .to_physical_precise_round(scale); + let offset = self + .0 + .with_program(|p| { + p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)] + .geometry() + .loc + }) + .to_physical_precise_round(scale); + let stack_loc = location + offset; let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32)); let elements = AsRenderElements::::render_elements::>( @@ -549,17 +550,24 @@ impl CosmicStack { renderer, window_loc, scale, alpha, ); // preparing the other windows will fix their x11 stacking order. - // they won't actually be drawn, but discarded due to the overlap anyway, - // the performance impact is neglible. + // they won't actually be drawn due to the placeholder element. for window in windows .iter() .enumerate() .filter(|(i, _)| *i != active) .map(|(_, w)| w) { - let (elements, _) = - window.split_render_elements(renderer, window_loc, scale, alpha); - window_elements.extend(elements); + let location = + window_loc + offset - window.geometry().loc.to_physical_precise_round(scale); + let (elements, _) = window + .split_render_elements::>( + renderer, location, scale, alpha, + ); + window_elements.extend( + elements + .into_iter() + .map(|e| PlaceholderElement(e.id().clone()).into()), + ); } (window_elements, popup_elements) @@ -865,7 +873,7 @@ impl Program for CosmicStackInternal { fn foreground( &self, pixels: &mut tiny_skia::PixmapMut<'_>, - damage: &[Rectangle], + damage: &[Rectangle], scale: f32, ) { if self.group_focused.load(Ordering::SeqCst) { @@ -1465,8 +1473,69 @@ impl PointerTarget for CosmicStack { } } +pub struct PlaceholderElement(ElementId); + +impl Element for PlaceholderElement { + fn id(&self) -> &ElementId { + &self.0 + } + + fn current_commit(&self) -> CommitCounter { + 0.into() + } + + fn src(&self) -> Rectangle { + Rectangle::from_loc_and_size((0., 0.), (0., 0.)) + } + + fn geometry(&self, _: Scale) -> Rectangle { + Rectangle::from_loc_and_size((0, 0), (0, 0)) + } + + fn location(&self, _: Scale) -> Point { + (0, 0).into() + } + + fn transform(&self) -> Transform { + Transform::Normal + } + + fn damage_since( + &self, + _: Scale, + _: Option, + ) -> Vec> { + vec![] + } + + fn opaque_regions(&self, _scale: Scale) -> Vec> { + vec![] + } + + fn alpha(&self) -> f32 { + 1.0 + } + + fn kind(&self) -> Kind { + Kind::default() + } +} + +impl RenderElement for PlaceholderElement { + fn draw( + &self, + _: &mut ::Frame<'_>, + _: Rectangle, + _: Rectangle, + _: &[Rectangle], + ) -> Result<(), ::Error> { + Ok(()) + } +} + render_elements! { pub CosmicStackRenderElement where R: ImportAll + ImportMem; Header = MemoryRenderBufferRenderElement, Window = WaylandSurfaceRenderElement, + Placeholder = PlaceholderElement, } From 54af0a4fb1aefc7dc057cab11c725e1bff933f9c Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 8 Jan 2024 21:37:06 +0000 Subject: [PATCH 5/7] floating: Allow dragging windows into stacks --- src/shell/grabs/moving.rs | 65 ++++++++++++++------------------ src/shell/layout/floating/mod.rs | 51 ++++++++++++++++++++++++- src/shell/mod.rs | 19 ++++++++++ src/shell/workspace.rs | 4 +- 4 files changed, 97 insertions(+), 42 deletions(-) diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 68052826f..d7ae34ca2 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -293,33 +293,28 @@ impl PointerGrab for MoveGrab { } } - if self.previous == ManagedLayer::Tiling { - let indicator_location = state - .common - .shell - .active_space(¤t_output) - .tiling_layer - .stacking_indicator(); - - if indicator_location.is_some() != grab_state.stacking_indicator.is_some() { - grab_state.stacking_indicator = indicator_location.map(|geo| { - let element = stack_hover( - state.common.event_loop_handle.clone(), - geo.size.as_logical(), - state.common.theme.clone(), + let indicator_location = state + .common + .shell + .stacking_indicator(¤t_output, self.previous); + if indicator_location.is_some() != grab_state.stacking_indicator.is_some() { + grab_state.stacking_indicator = indicator_location.map(|geo| { + let element = stack_hover( + state.common.event_loop_handle.clone(), + geo.size.as_logical(), + state.common.theme.clone(), + ); + for output in &self.window_outputs { + element.output_enter( + output, + Rectangle::from_loc_and_size( + (0, 0), + output.geometry().size.as_logical(), + ), ); - for output in &self.window_outputs { - element.output_enter( - output, - Rectangle::from_loc_and_size( - (0, 0), - output.geometry().size.as_logical(), - ), - ); - } - (element, geo.loc.as_logical()) - }); - } + } + (element, geo.loc.as_logical()) + }); } } drop(borrow); @@ -566,13 +561,11 @@ impl Drop for MoveGrab { grab_state.window.geometry().size.as_global(), )); let workspace = state.common.shell.active_space_mut(&output); - workspace.floating_layer.map_internal( + let (window, location) = workspace.floating_layer.drop_window( grab_state.window, - Some(window_location.to_local(&workspace.output)), - None, + window_location.to_local(&workspace.output), ); - - Some((window.clone(), window_location)) + Some((window, location.to_global(&output))) } ManagedLayer::Sticky => { grab_state.window.set_geometry(Rectangle::from_loc_and_size( @@ -580,13 +573,11 @@ impl Drop for MoveGrab { grab_state.window.geometry().size.as_global(), )); let set = state.common.shell.workspaces.sets.get_mut(&output).unwrap(); - set.sticky_layer.map_internal( - grab_state.window, - Some(window_location.to_local(&output)), - None, - ); + let (window, location) = set + .sticky_layer + .drop_window(grab_state.window, window_location.to_local(&output)); - Some((window.clone(), window_location)) + Some((window, location.to_global(&output))) } } } else { diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 41ed12afa..886fb20e5 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -27,11 +27,14 @@ use crate::{ shell::{ element::{ resize_indicator::ResizeIndicator, - stack::{CosmicStackRenderElement, MoveResult as StackMoveResult}, + stack::{CosmicStackRenderElement, MoveResult as StackMoveResult, TAB_HEIGHT}, window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement, CosmicWindow, }, - focus::{target::KeyboardFocusTarget, FocusStackMut}, + focus::{ + target::{KeyboardFocusTarget, PointerFocusTarget}, + FocusStackMut, + }, grabs::{ReleaseMode, ResizeEdge}, CosmicSurface, Direction, MoveResult, ResizeDirection, ResizeMode, }, @@ -50,6 +53,7 @@ pub struct FloatingLayout { pub(crate) space: Space, spawn_order: Vec, tiling_animations: HashMap)>, + hovered_stack: Option<(CosmicMapped, Rectangle)>, dirty: AtomicBool, pub theme: cosmic::Theme, } @@ -449,10 +453,53 @@ impl FloatingLayout { was_unmaped } + pub fn drop_window( + &mut self, + window: CosmicMapped, + position: Point, + ) -> (CosmicMapped, Point) { + if let Some((mapped, geo)) = self.hovered_stack.take() { + let stack = mapped.stack_ref().unwrap(); + for surface in window.windows().map(|s| s.0) { + stack.add_window(surface, None); + } + (mapped, geo.loc) + } else { + self.map_internal(window.clone(), Some(position), None); + (window, position) + } + } + pub fn element_geometry(&self, elem: &CosmicMapped) -> Option> { self.space.element_geometry(elem).map(RectExt::as_local) } + pub fn element_under( + &mut self, + location: Point, + ) -> Option<(PointerFocusTarget, Point)> { + let res = self + .space + .element_under(location.as_logical()) + .map(|(mapped, p)| (mapped.clone(), p.as_local())); + if let Some((mapped, _)) = res.as_ref() { + let geometry = self.space.element_geometry(mapped).unwrap(); + let offset = location.y.round() as i32 - geometry.loc.y; + if mapped.is_stack() && offset.is_positive() && offset <= TAB_HEIGHT { + self.hovered_stack = Some((mapped.clone(), geometry.as_local())); + } else { + self.hovered_stack.take(); + } + } else { + self.hovered_stack.take(); + } + res.map(|(m, p)| (m.into(), p)) + } + + pub fn stacking_indicator(&self) -> Option> { + self.hovered_stack.as_ref().map(|(_, geo)| geo.clone()) + } + pub fn resize_request( &mut self, mapped: &CosmicMapped, diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 4f2f26b72..8c0333f56 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1510,6 +1510,25 @@ impl Shell { (self.resize_mode.clone(), self.resize_indicator.clone()) } + pub fn stacking_indicator( + &self, + output: &Output, + layer: ManagedLayer, + ) -> Option> { + match layer { + ManagedLayer::Sticky => self + .workspaces + .sets + .get(output) + .and_then(|set| set.sticky_layer.stacking_indicator()), + ManagedLayer::Floating => self + .active_space(output) + .floating_layer + .stacking_indicator(), + ManagedLayer::Tiling => self.active_space(output).tiling_layer.stacking_indicator(), + } + } + pub fn refresh(&mut self) { #[cfg(feature = "debug")] puffin::profile_function!(); diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index f30147d2c..72ec94ed0 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -424,9 +424,7 @@ impl Workspace { ) -> Option<(PointerFocusTarget, Point)> { let location = location.to_local(&self.output); self.floating_layer - .space - .element_under(location.as_logical()) - .map(|(mapped, p)| (mapped.clone().into(), p.as_local())) + .element_under(location) .or_else(|| self.tiling_layer.element_under(location, overview)) .map(|(m, p)| (m, p.to_global(&self.output))) } From b2bfb038f6f1b1db9e883ef9dfdfb672492e02bb Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 8 Jan 2024 21:43:46 +0000 Subject: [PATCH 6/7] floating: Fix broken size check --- src/shell/layout/floating/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 886fb20e5..5565c1cf9 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -333,7 +333,7 @@ impl FloatingLayout { geometry.loc.x = offset; // do we need to resize? if geometry.loc.y as i32 + win_geo.size.h - <= output_geometry.loc.y + output_geometry.size.h - 16 + > output_geometry.loc.y + output_geometry.size.h - 16 { win_geo.size.h = (output_geometry.loc.y + output_geometry.size.h - 16) From eb6d482e61eee52396fd1f0d88cbf63b2a790789 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 15 Jan 2024 09:35:38 +0000 Subject: [PATCH 7/7] tiling: Fix focus toggling stacking --- src/shell/layout/tiling/mod.rs | 39 +++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 3d83c47bb..b9f70300d 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -383,7 +383,8 @@ impl TilingLayout { let mut tree = self.queue.trees.back().unwrap().0.copy_clone(); let last_active = focus_stack - .and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack)); + .and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack)) + .map(|(node_id, _)| node_id); TilingLayout::map_to_tree(&mut tree, window, &self.output, last_active, direction); let blocker = TilingLayout::update_positions(&self.output, &mut tree, gaps); self.queue.push_tree(tree, ANIMATION_DURATION, blocker); @@ -393,7 +394,7 @@ impl TilingLayout { mut tree: &mut Tree, window: impl Into, output: &Output, - node: Option<(NodeId, CosmicMapped)>, + node: Option, direction: Option, ) { let window = window.into(); @@ -424,7 +425,7 @@ impl TilingLayout { tree.insert(new_window, InsertBehavior::AsRoot).unwrap() } } else { - if let Some((ref node_id, _)) = node { + if let Some(ref node_id) = node { let orientation = { let window_size = tree.get(node_id).unwrap().data().geometry().size; if window_size.w > window_size.h { @@ -1909,11 +1910,10 @@ impl TilingLayout { match tree.get_mut(&node_id).unwrap().data_mut() { Data::Mapped { mapped, .. } => { mapped.convert_to_stack((&self.output, mapped.bbox()), self.theme.clone()); + KeyboardFocusTarget::Element(mapped.clone()) } _ => unreachable!(), - }; - - KeyboardFocusTarget::Element(mapped.clone()) + } } else { // if we have a stack let mut surfaces = mapped.windows().map(|(s, _)| s); @@ -1933,7 +1933,7 @@ impl TilingLayout { }; // map the rest - let mut current_node = (node_id.clone(), mapped.clone()); + let mut current_node = node_id.clone(); for other in surfaces { other.try_force_undecorated(false); other.set_tiled(false); @@ -1958,23 +1958,28 @@ impl TilingLayout { ); let node = window.tiling_node_id.lock().unwrap().clone().unwrap(); - current_node = (node, window); + current_node = node; } - // TODO: Focus the new group - if let Some(parent) = tree.get(&node_id).unwrap().parent() { - let Data::Group { alive, .. } = tree.get(&parent).unwrap().data() else { unreachable!() }; - KeyboardFocusTarget::Group(WindowGroup { - node: parent.clone(), + let node = tree.get(&node_id).unwrap(); + let node_id = if current_node != node_id { + node.parent().cloned().unwrap_or(node_id) + } else { + node_id + }; + + match tree.get(&node_id).unwrap().data() { + Data::Group { alive, .. } => KeyboardFocusTarget::Group(WindowGroup { + node: node_id.clone(), alive: Arc::downgrade(alive), focus_stack: tree - .children_ids(parent) + .children_ids(&node_id) .unwrap() .cloned() .collect::>(), - }) - } else { - KeyboardFocusTarget::Element(mapped.clone()) + }), + Data::Mapped { mapped, .. } => KeyboardFocusTarget::Element(mapped.clone()), + _ => unreachable!(), } };