Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/input/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,26 @@ impl State {
}
}

Action::TileWindow(zone) => {
use cosmic_settings_config::shortcuts::action::TilingZone;
use crate::shell::layout::floating::TiledCorners;

let corner = match zone {
TilingZone::Top => TiledCorners::Top,
TilingZone::TopRight => TiledCorners::TopRight,
TilingZone::Right => TiledCorners::Right,
TilingZone::BottomRight => TiledCorners::BottomRight,
TilingZone::Bottom => TiledCorners::Bottom,
TilingZone::BottomLeft => TiledCorners::BottomLeft,
TilingZone::Left => TiledCorners::Left,
TilingZone::TopLeft => TiledCorners::TopLeft,
TilingZone::Center => TiledCorners::Center,
};

let mut shell = self.common.shell.write();
shell.tile_window(corner, seat);
}

Action::Fullscreen => {
let Some(focused_output) = seat.focused_output() else {
return;
Expand Down
69 changes: 68 additions & 1 deletion src/shell/layout/floating/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ pub enum TiledCorners {
BottomLeft,
Left,
TopLeft,
Center,
}

impl TiledCorners {
Expand Down Expand Up @@ -258,6 +259,16 @@ impl TiledCorners {
output_geometry.size.h - inner * 2,
)),
),
TiledCorners::Center => (
Point::from((
output_geometry.loc.x + output_geometry.size.w / 4 + inner,
output_geometry.loc.y + inner,
)),
Size::from((
output_geometry.size.w / 2 - inner * 2,
output_geometry.size.h - inner * 2,
)),
),
};

Rectangle::new(loc, size).as_local()
Expand Down Expand Up @@ -1099,6 +1110,56 @@ impl FloatingLayout {
self.toggle_stacking(&elem, focus_stack)
}

pub fn tile_window(
&mut self,
window: &CosmicMapped,
corner: TiledCorners,
theme: &cosmic::Theme,
) {
// Store previous geometry for animation
if let Some(geo) = self.space.element_geometry(window) {
let previous_geo = geo.as_local();

// Set the tiled corner state
*window.floating_tiled.lock().unwrap() = Some(corner);

// Clear any maximized state
*window.maximized_state.lock().unwrap() = None;

// Get output geometry for calculating new position
let output = self.space.outputs().next().unwrap().clone();
let layers = layer_map_for_output(&output);
let output_geometry = layers.non_exclusive_zone();

// Calculate new geometry based on corner
let gaps = (theme.cosmic().gaps.0 as i32, theme.cosmic().gaps.1 as i32);
let new_geo = corner.relative_geometry(output_geometry, gaps);

// Set window properties for tiled state
window.set_tiled(true);
window.set_maximized(false);
window.set_geometry(new_geo.to_global(&output));
window.configure();

window.moved_since_mapped.store(true, Ordering::SeqCst);

// Trigger animation
self.animations.insert(
window.clone(),
Animation::Tiled {
start: Instant::now(),
previous_geometry: previous_geo,
},
);
self.dirty.store(true, Ordering::SeqCst);

// Update space mapping
self.space
.map_element(window.clone(), new_geo.loc.as_logical(), true);
self.space.refresh();
}
}

pub fn move_element(
&mut self,
direction: Direction,
Expand Down Expand Up @@ -1193,7 +1254,8 @@ impl FloatingLayout {
(Direction::Up, Some(TiledCorners::Bottom))
| (Direction::Down, Some(TiledCorners::Top))
| (Direction::Left, Some(TiledCorners::Right))
| (Direction::Right, Some(TiledCorners::Left)) => {
| (Direction::Right, Some(TiledCorners::Left))
| (Direction::Up, Some(TiledCorners::Center)) => {
std::mem::drop(tiled_state);

let mut maximized_state = element.maximized_state.lock().unwrap();
Expand All @@ -1207,6 +1269,11 @@ impl FloatingLayout {
return MoveResult::Done;
}

// center transitions
(Direction::Left, Some(TiledCorners::Center)) => TiledCorners::Left,
(Direction::Right, Some(TiledCorners::Center)) => TiledCorners::Right,
(Direction::Down, Some(TiledCorners::Center)) => TiledCorners::Bottom,

// figure out if we need to quater tile
(Direction::Up, Some(TiledCorners::Left))
| (Direction::Left, Some(TiledCorners::Top)) => TiledCorners::TopLeft,
Expand Down
20 changes: 20 additions & 0 deletions src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4124,6 +4124,26 @@ impl Shell {
}
}

pub fn tile_window(&mut self, corner: layout::floating::TiledCorners, seat: &Seat<State>) {
let output = seat.active_output();
let Some(workspace) = self.workspaces.active_mut(&output) else {
return;
};

let Some(KeyboardFocusTarget::Element(window)) =
seat.get_keyboard().and_then(|k| k.current_focus())
else {
return;
};

// Only works on floating windows
if workspace.floating_layer.mapped().any(|w| w == &window) {
workspace
.floating_layer
.tile_window(&window, corner, &self.theme);
}
}

pub fn minimize_request<S>(&mut self, surface: &S)
where
CosmicSurface: PartialEq<S>,
Expand Down
Loading