moving: Add stacking indicator

This commit is contained in:
Victoria Brekenfeld 2023-07-24 19:31:31 +02:00
parent 85edfc7141
commit 37c530c691
6 changed files with 213 additions and 36 deletions

View file

@ -1,3 +1,4 @@
grow-window = Grow grow-window = Grow
shrink-window = Shrink shrink-window = Shrink
unknown-keybinding = <unset> unknown-keybinding = <unset>
stack-windows = Stack Windows

View file

@ -83,6 +83,7 @@ pub type GlMultiError = MultiError<GbmGlesBackend<GlowRenderer>, GbmGlesBackend<
pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0]; pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0];
pub static GROUP_COLOR: [f32; 3] = [0.788, 0.788, 0.788]; pub static GROUP_COLOR: [f32; 3] = [0.788, 0.788, 0.788];
pub static ACTIVE_GROUP_COLOR: [f32; 3] = [0.58, 0.922, 0.922];
pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921]; pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921];
pub static OUTLINE_SHADER: &str = include_str!("./shaders/rounded_outline.frag"); pub static OUTLINE_SHADER: &str = include_str!("./shaders/rounded_outline.frag");

View file

@ -13,6 +13,7 @@ use smithay::{
input::KeyState, input::KeyState,
renderer::{ renderer::{
element::{ element::{
memory::MemoryRenderBufferRenderElement,
utils::{CropRenderElement, RelocateRenderElement, RescaleRenderElement}, utils::{CropRenderElement, RelocateRenderElement, RescaleRenderElement},
Element, RenderElement, UnderlyingStorage, Element, RenderElement, UnderlyingStorage,
}, },
@ -55,6 +56,7 @@ pub use self::stack::CosmicStack;
pub mod window; pub mod window;
pub use self::window::CosmicWindow; pub use self::window::CosmicWindow;
pub mod resize_indicator; pub mod resize_indicator;
pub mod stack_hover;
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
use egui::plot::{Corner, Legend, Plot, PlotPoints, Polygon}; use egui::plot::{Corner, Legend, Plot, PlotPoints, Polygon};
@ -972,7 +974,8 @@ where
), ),
GrabbedStack(RescaleRenderElement<self::stack::CosmicStackRenderElement<R>>), GrabbedStack(RescaleRenderElement<self::stack::CosmicStackRenderElement<R>>),
GrabbedWindow(RescaleRenderElement<self::window::CosmicWindowRenderElement<R>>), GrabbedWindow(RescaleRenderElement<self::window::CosmicWindowRenderElement<R>>),
Indicator(PixelShaderElement), FocusIndicator(PixelShaderElement),
StackHoverIndicator(MemoryRenderBufferRenderElement<R>),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
Egui(TextureRenderElement<GlesTexture>), Egui(TextureRenderElement<GlesTexture>),
} }
@ -990,7 +993,8 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.id(), CosmicMappedRenderElement::TiledWindow(elem) => elem.id(),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.id(), CosmicMappedRenderElement::GrabbedStack(elem) => elem.id(),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.id(), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.id(),
CosmicMappedRenderElement::Indicator(elem) => elem.id(), CosmicMappedRenderElement::FocusIndicator(elem) => elem.id(),
CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.id(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.id(), CosmicMappedRenderElement::Egui(elem) => elem.id(),
} }
@ -1004,7 +1008,8 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.current_commit(), CosmicMappedRenderElement::TiledWindow(elem) => elem.current_commit(),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.current_commit(), CosmicMappedRenderElement::GrabbedStack(elem) => elem.current_commit(),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.current_commit(), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.current_commit(),
CosmicMappedRenderElement::Indicator(elem) => elem.current_commit(), CosmicMappedRenderElement::FocusIndicator(elem) => elem.current_commit(),
CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.current_commit(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.current_commit(), CosmicMappedRenderElement::Egui(elem) => elem.current_commit(),
} }
@ -1018,7 +1023,8 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.src(), CosmicMappedRenderElement::TiledWindow(elem) => elem.src(),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.src(), CosmicMappedRenderElement::GrabbedStack(elem) => elem.src(),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.src(), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.src(),
CosmicMappedRenderElement::Indicator(elem) => elem.src(), CosmicMappedRenderElement::FocusIndicator(elem) => elem.src(),
CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.src(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.src(), CosmicMappedRenderElement::Egui(elem) => elem.src(),
} }
@ -1032,7 +1038,8 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.geometry(scale), CosmicMappedRenderElement::TiledWindow(elem) => elem.geometry(scale),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.geometry(scale), CosmicMappedRenderElement::GrabbedStack(elem) => elem.geometry(scale),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.geometry(scale), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.geometry(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.geometry(scale), CosmicMappedRenderElement::FocusIndicator(elem) => elem.geometry(scale),
CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.geometry(scale),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale), CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale),
} }
@ -1046,7 +1053,8 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.location(scale), CosmicMappedRenderElement::TiledWindow(elem) => elem.location(scale),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.location(scale), CosmicMappedRenderElement::GrabbedStack(elem) => elem.location(scale),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.location(scale), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.location(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.location(scale), CosmicMappedRenderElement::FocusIndicator(elem) => elem.location(scale),
CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.location(scale),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.location(scale), CosmicMappedRenderElement::Egui(elem) => elem.location(scale),
} }
@ -1060,7 +1068,8 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.transform(), CosmicMappedRenderElement::TiledWindow(elem) => elem.transform(),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.transform(), CosmicMappedRenderElement::GrabbedStack(elem) => elem.transform(),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.transform(), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.transform(),
CosmicMappedRenderElement::Indicator(elem) => elem.transform(), CosmicMappedRenderElement::FocusIndicator(elem) => elem.transform(),
CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.transform(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.transform(), CosmicMappedRenderElement::Egui(elem) => elem.transform(),
} }
@ -1078,7 +1087,10 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::TiledWindow(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::GrabbedStack(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::Indicator(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::FocusIndicator(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::StackHoverIndicator(elem) => {
elem.damage_since(scale, commit)
}
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit),
} }
@ -1092,7 +1104,8 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::TiledWindow(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::GrabbedStack(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::FocusIndicator(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.opaque_regions(scale),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale),
} }
@ -1106,7 +1119,8 @@ where
CosmicMappedRenderElement::TiledWindow(elem) => elem.alpha(), CosmicMappedRenderElement::TiledWindow(elem) => elem.alpha(),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.alpha(), CosmicMappedRenderElement::GrabbedStack(elem) => elem.alpha(),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.alpha(), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.alpha(),
CosmicMappedRenderElement::Indicator(elem) => elem.alpha(), CosmicMappedRenderElement::FocusIndicator(elem) => elem.alpha(),
CosmicMappedRenderElement::StackHoverIndicator(elem) => elem.alpha(),
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.alpha(), CosmicMappedRenderElement::Egui(elem) => elem.alpha(),
} }
@ -1128,7 +1142,10 @@ impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
CosmicMappedRenderElement::TiledWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::TiledWindow(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::GrabbedStack(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Indicator(elem) => { CosmicMappedRenderElement::FocusIndicator(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
}
CosmicMappedRenderElement::StackHoverIndicator(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage) RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
} }
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
@ -1146,7 +1163,10 @@ impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
CosmicMappedRenderElement::TiledWindow(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::TiledWindow(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::GrabbedStack(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Indicator(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::FocusIndicator(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::StackHoverIndicator(elem) => {
elem.underlying_storage(renderer)
}
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer),
} }
@ -1170,10 +1190,13 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
CosmicMappedRenderElement::TiledWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::TiledWindow(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::GrabbedStack(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Indicator(elem) => { CosmicMappedRenderElement::FocusIndicator(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame.glow_frame_mut(), src, dst, damage) RenderElement::<GlowRenderer>::draw(elem, frame.glow_frame_mut(), src, dst, damage)
.map_err(|err| GlMultiError::Render(err)) .map_err(|err| GlMultiError::Render(err))
} }
CosmicMappedRenderElement::StackHoverIndicator(elem) => {
elem.draw(frame, src, dst, damage)
}
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => { CosmicMappedRenderElement::Egui(elem) => {
let glow_frame = frame.glow_frame_mut(); let glow_frame = frame.glow_frame_mut();
@ -1194,9 +1217,12 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
CosmicMappedRenderElement::TiledWindow(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::TiledWindow(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::GrabbedStack(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::GrabbedStack(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::GrabbedWindow(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::GrabbedWindow(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Indicator(elem) => { CosmicMappedRenderElement::FocusIndicator(elem) => {
elem.underlying_storage(renderer.glow_renderer_mut()) elem.underlying_storage(renderer.glow_renderer_mut())
} }
CosmicMappedRenderElement::StackHoverIndicator(elem) => {
elem.underlying_storage(renderer)
}
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => { CosmicMappedRenderElement::Egui(elem) => {
let glow_renderer = renderer.glow_renderer_mut(); let glow_renderer = renderer.glow_renderer_mut();
@ -1239,7 +1265,18 @@ where
CosmicMappedRenderElement<R>: RenderElement<R>, CosmicMappedRenderElement<R>: RenderElement<R>,
{ {
fn from(elem: PixelShaderElement) -> Self { fn from(elem: PixelShaderElement) -> Self {
CosmicMappedRenderElement::Indicator(elem) CosmicMappedRenderElement::FocusIndicator(elem)
}
}
impl<R> From<MemoryRenderBufferRenderElement<R>> for CosmicMappedRenderElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
fn from(elem: MemoryRenderBufferRenderElement<R>) -> Self {
CosmicMappedRenderElement::StackHoverIndicator(elem)
} }
} }

View file

@ -0,0 +1,74 @@
use crate::{
fl,
utils::iced::{IcedElement, Program},
};
use apply::Apply;
use calloop::LoopHandle;
use cosmic::{
iced::widget::{container, row},
iced_core::{Background, Color, Length},
theme,
widget::{icon, text},
};
use smithay::utils::{Logical, Size};
pub type StackHover = IcedElement<StackHoverInternal>;
pub fn stack_hover(
evlh: LoopHandle<'static, crate::state::Data>,
size: Size<i32, Logical>,
) -> StackHover {
StackHover::new(StackHoverInternal, size, evlh)
}
pub struct StackHoverInternal;
impl Program for StackHoverInternal {
type Message = ();
fn view(&self) -> crate::utils::iced::Element<'_, Self::Message> {
row(vec![
icon("window-stack-symbolic", 24)
.force_svg(true)
.style(theme::Svg::Symbolic)
.apply(container)
.padding(8)
.width(Length::Shrink)
.apply(container)
.center_y()
.height(Length::Fill)
.into(),
text(fl!("stack-windows"))
.font(cosmic::font::FONT)
.size(24)
.line_height(24.)
.apply(container)
.padding(8)
.width(Length::Shrink)
.apply(container)
.center_y()
.height(Length::Fill)
.into(),
])
.width(Length::Shrink)
.height(Length::Shrink)
.apply(container)
.padding(4)
.style(theme::Container::custom(|theme| container::Appearance {
text_color: Some(Color::from(theme.cosmic().palette.neutral_9)),
background: Some(Background::Color(theme.cosmic().palette.neutral_3.into())),
border_radius: 24.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}))
.width(Length::Shrink)
.height(Length::Fixed(48.))
.apply(container)
.center_x()
.center_y()
.width(Length::Fill)
.height(Length::Fill)
.into()
}
}

View file

@ -7,7 +7,10 @@ use crate::{
IndicatorShader, IndicatorShader,
}, },
shell::{ shell::{
element::CosmicMappedRenderElement, element::{
stack_hover::{stack_hover, StackHover},
CosmicMappedRenderElement,
},
focus::target::{KeyboardFocusTarget, PointerFocusTarget}, focus::target::{KeyboardFocusTarget, PointerFocusTarget},
CosmicMapped, CosmicSurface, CosmicMapped, CosmicSurface,
}, },
@ -16,7 +19,7 @@ use crate::{
use smithay::{ use smithay::{
backend::renderer::{ backend::renderer::{
element::{utils::RescaleRenderElement, RenderElement}, element::{utils::RescaleRenderElement, AsRenderElements, RenderElement},
ImportAll, ImportMem, Renderer, ImportAll, ImportMem, Renderer,
}, },
desktop::space::SpaceElement, desktop::space::SpaceElement,
@ -47,6 +50,7 @@ pub struct MoveGrabState {
window_offset: Point<i32, Logical>, window_offset: Point<i32, Logical>,
indicator_thickness: u8, indicator_thickness: u8,
start: Instant, start: Instant,
stacking_indicator: Option<(StackHover, Point<i32, Logical>)>,
} }
impl MoveGrabState { impl MoveGrabState {
@ -114,8 +118,17 @@ impl MoveGrabState {
1.0, 1.0,
); );
popup_elements self.stacking_indicator
.into_iter() .iter()
.flat_map(|(indicator, location)| {
indicator.render_elements(
renderer,
location.to_physical_precise_round(output_scale),
output_scale,
1.0,
)
})
.chain(popup_elements)
.chain(focus_element) .chain(focus_element)
.chain(window_elements.into_iter().map(|elem| match elem { .chain(window_elements.into_iter().map(|elem| match elem {
CosmicMappedRenderElement::Stack(stack) => { CosmicMappedRenderElement::Stack(stack) => {
@ -179,21 +192,49 @@ impl PointerGrab<State> for MoveGrab {
_focus: Option<(PointerFocusTarget, Point<i32, Logical>)>, _focus: Option<(PointerFocusTarget, Point<i32, Logical>)>,
event: &MotionEvent, event: &MotionEvent,
) { ) {
let borrow = self let mut borrow = self
.seat .seat
.user_data() .user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
.map(|s| s.borrow()); .map(|s| s.borrow_mut());
if let Some(grab_state) = borrow.as_ref().and_then(|s| s.as_ref()) { if let Some(grab_state) = borrow.as_mut().and_then(|s| s.as_mut()) {
let mut window_geo = self.window.geometry(); let mut window_geo = self.window.geometry();
window_geo.loc += event.location.to_i32_round() + grab_state.window_offset; window_geo.loc += event.location.to_i32_round() + grab_state.window_offset;
for output in state.common.shell.outputs() { for output in state.common.shell.outputs() {
if let Some(overlap) = output.geometry().intersection(window_geo) { if let Some(overlap) = output.geometry().intersection(window_geo) {
if self.outputs.insert(output.clone()) { if self.outputs.insert(output.clone()) {
self.window.output_enter(output, overlap); self.window.output_enter(output, overlap);
if let Some(indicator) =
grab_state.stacking_indicator.as_ref().map(|x| &x.0)
{
indicator.output_enter(output, overlap);
}
} }
} else if self.outputs.remove(&output) { } else if self.outputs.remove(&output) {
self.window.output_leave(output); self.window.output_leave(output);
if let Some(indicator) = grab_state.stacking_indicator.as_ref().map(|x| &x.0) {
indicator.output_leave(output);
}
}
}
let output = state.common.last_active_seat().active_output();
if self.tiling {
let indicator_location = state
.common
.shell
.active_space(&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);
for output in &self.outputs {
element.output_enter(output, output.geometry());
}
(element, geo.loc)
});
} }
} }
} }
@ -263,6 +304,7 @@ impl MoveGrab {
window_offset: initial_window_location - initial_cursor_location.to_i32_round(), window_offset: initial_window_location - initial_cursor_location.to_i32_round(),
indicator_thickness, indicator_thickness,
start: Instant::now(), start: Instant::now(),
stacking_indicator: None,
}; };
*seat *seat

View file

@ -1,7 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use crate::{ use crate::{
backend::render::{element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, GROUP_COLOR}, backend::render::{
element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, ACTIVE_GROUP_COLOR,
GROUP_COLOR,
},
shell::{ shell::{
element::{ element::{
resize_indicator::ResizeIndicator, resize_indicator::ResizeIndicator,
@ -127,7 +130,7 @@ pub enum MoveResult {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
enum TargetZone { enum TargetZone {
InitialPlaceholder(NodeId), InitialPlaceholder(NodeId),
WindowStack(NodeId), WindowStack(NodeId, Rectangle<i32, Logical>),
WindowSplit(NodeId, Direction), WindowSplit(NodeId, Direction),
GroupEdge(NodeId, Direction), GroupEdge(NodeId, Direction),
GroupInterior(NodeId, usize), GroupInterior(NodeId, usize),
@ -137,7 +140,7 @@ impl TargetZone {
fn is_window_zone(&self) -> bool { fn is_window_zone(&self) -> bool {
matches!( matches!(
self, self,
TargetZone::WindowStack(_) | TargetZone::WindowSplit(_, _) TargetZone::WindowStack(..) | TargetZone::WindowSplit(_, _)
) )
} }
} }
@ -1625,6 +1628,16 @@ impl TilingLayout {
true true
} }
pub fn stacking_indicator(&self) -> Option<Rectangle<i32, Logical>> {
if let Some(TargetZone::WindowStack(_, geo)) =
self.last_overview_hover.as_ref().map(|(_, zone)| zone)
{
Some(*geo)
} else {
None
}
}
pub fn drop_window( pub fn drop_window(
&mut self, &mut self,
window: CosmicMapped, window: CosmicMapped,
@ -2082,7 +2095,7 @@ impl TilingLayout {
1.0, 1.0,
overview.alpha().unwrap(), overview.alpha().unwrap(),
placeholder_id, placeholder_id,
true, Some(None),
) )
.map(|x| x.0) .map(|x| x.0)
.unwrap_or_default(); .unwrap_or_default();
@ -2182,7 +2195,7 @@ impl TilingLayout {
); );
if stack_region.contains(location) { if stack_region.contains(location) {
TargetZone::WindowStack(res_id) TargetZone::WindowStack(res_id, last_geometry)
} else { } else {
let left_right = { let left_right = {
let relative_loc = (location.x - last_geometry.loc.x) as f64; let relative_loc = (location.x - last_geometry.loc.x) as f64;
@ -2703,7 +2716,8 @@ impl TilingLayout {
let mut window_elements = Vec::new(); let mut window_elements = Vec::new();
let mut popup_elements = Vec::new(); let mut popup_elements = Vec::new();
let is_mouse_tiling = matches!(overview, OverviewMode::Started(Trigger::Pointer(_), _)); let is_mouse_tiling = (matches!(overview, OverviewMode::Started(Trigger::Pointer(_), _)))
.then(|| self.last_overview_hover.as_ref().map(|x| &x.1));
// all gone windows and fade them out // all gone windows and fade them out
let old_geometries = if let Some(reference_tree) = reference_tree.as_ref() { let old_geometries = if let Some(reference_tree) = reference_tree.as_ref() {
@ -2805,7 +2819,7 @@ fn geometries_for_groupview<'a, R>(
alpha: f32, alpha: f32,
transition: f32, transition: f32,
placeholder_id: &Id, placeholder_id: &Id,
mouse_tiling: bool, mouse_tiling: Option<Option<&TargetZone>>,
) -> Option<( ) -> Option<(
HashMap<NodeId, Rectangle<i32, Logical>>, HashMap<NodeId, Rectangle<i32, Logical>>,
Vec<CosmicMappedRenderElement<R>>, Vec<CosmicMappedRenderElement<R>>,
@ -2818,14 +2832,14 @@ where
{ {
// we need to recalculate geometry for all elements, if we are drawing groups // we need to recalculate geometry for all elements, if we are drawing groups
if let Some(root) = tree.root_node_id() { if let Some(root) = tree.root_node_id() {
let outer_gap: i32 = (if mouse_tiling { let outer_gap: i32 = (if mouse_tiling.is_some() {
OUTER_GAP_MOUSE OUTER_GAP_MOUSE
} else { } else {
OUTER_GAP_KEYBOARD OUTER_GAP_KEYBOARD
} as f32 } as f32
* transition) * transition)
.round() as i32; .round() as i32;
let inner_gap: i32 = (if mouse_tiling { let inner_gap: i32 = (if mouse_tiling.is_some() {
INNER_GAP_MOUSE INNER_GAP_MOUSE
} else { } else {
INNER_GAP_KEYBOARD INNER_GAP_KEYBOARD
@ -2967,7 +2981,7 @@ where
) )
.into(), .into(),
); );
} else if mouse_tiling && node.parent() == Some(&root) { } else if mouse_tiling.is_some() && node.parent() == Some(&root) {
elements.push( elements.push(
IndicatorShader::element( IndicatorShader::element(
*renderer, *renderer,
@ -3185,8 +3199,16 @@ where
.unwrap() .unwrap()
.any(|id| id == focused_id) .any(|id| id == focused_id)
}) })
.unwrap_or(mouse_tiling) .unwrap_or(mouse_tiling.is_some())
{ {
let color = match mouse_tiling {
Some(Some(TargetZone::WindowStack(stack_id, _)))
if *stack_id == node_id =>
{
ACTIVE_GROUP_COLOR
}
_ => GROUP_COLOR,
};
elements.push( elements.push(
BackdropShader::element( BackdropShader::element(
*renderer, *renderer,
@ -3197,13 +3219,13 @@ where
* if focused * if focused
.as_ref() .as_ref()
.map(|focused_id| focused_id == &node_id) .map(|focused_id| focused_id == &node_id)
.unwrap_or(false) .unwrap_or(color == ACTIVE_GROUP_COLOR)
{ {
0.4 0.4
} else { } else {
0.15 0.15
}, },
GROUP_COLOR, color,
) )
.into(), .into(),
); );