Skip to content
Open
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
13 changes: 0 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions packages/wm-macros/src/subenum/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,13 @@ fn from_sub_to_main_impl(
}
});

let clone_variants = sub_enum.variants.iter().map(|v| {
let var_name = &v.name;
quote::quote! {
#sub_name::#var_name(v) => #name::#var_name(v.clone())
}
});

quote::quote! {
impl From<#sub_name> for #name {
fn from(value: #sub_name) -> Self {
Expand All @@ -273,6 +280,14 @@ fn from_sub_to_main_impl(
}
}
}

impl From<&#sub_name> for #name {
fn from(value: &#sub_name) -> Self {
match value {
#(#clone_variants),*
}
}
}
}
}

Expand All @@ -290,6 +305,13 @@ fn try_from_main_to_sub_impl(
}
});

let clone_variants = sub_enum.variants.iter().map(|v| {
let var_name = &v.name;
quote::quote! {
#name::#var_name(v) => Ok(#sub_name::#var_name(v.clone()))
}
});

let error = format!(
"Cannot convert this variant of sub enum `{sub_name}` to main enum `{name}`."
);
Expand All @@ -305,5 +327,16 @@ fn try_from_main_to_sub_impl(
}
}
}

impl TryFrom<&#name> for #sub_name {
type Error = &'static str;

fn try_from(value: &#name) -> Result<Self, Self::Error> {
match value {
#(#clone_variants),*,
_ => Err(#error),
}
}
}
}
}
1 change: 0 additions & 1 deletion packages/wm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ tauri-winres = { workspace = true }
anyhow = { workspace = true }
ambassador = "0.4"
clap = { workspace = true }
enum-as-inner = "0.6"
futures-util = { workspace = true }
home = { workspace = true }
serde = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions packages/wm/src/commands/container/detach_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use anyhow::Context;

use super::flatten_split_container;
use crate::{
models::Container,
models::{Container, SplitContainer},
traits::{CommonGetters, TilingSizeGetters, MIN_TILING_SIZE},
};

Expand All @@ -16,7 +16,7 @@ pub fn detach_container(child_to_remove: Container) -> anyhow::Result<()> {
// the child.
if let Some(split_parent) = child_to_remove
.parent()
.and_then(|parent| parent.as_split().cloned())
.and_then(|parent| SplitContainer::try_from(parent.clone()).ok())
{
if split_parent.child_count() == 1 {
flatten_split_container(split_parent)?;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::flatten_split_container;
use crate::{
models::Container,
models::{Container, SplitContainer},
traits::{CommonGetters, TilingDirectionGetters},
};

Expand All @@ -21,20 +21,24 @@ pub fn flatten_child_split_containers(
let tiling_children = parent
.children()
.into_iter()
.filter(|child| child.is_tiling_window() || child.is_split())
.filter(|child| {
matches!(child, Container::TilingWindow(_) | Container::Split(_))
})
.collect::<Vec<_>>();

if tiling_children.len() == 1 {
// Handle case where the parent is a split container and has a
// single split container child.
if let Some(split_child) = tiling_children[0].as_split() {
if let Ok(split_child) =
<&SplitContainer>::try_from(&tiling_children[0])
{
flatten_split_container(split_child.clone())?;
parent.set_tiling_direction(parent.tiling_direction().inverse());
}
} else {
let split_children = tiling_children
.into_iter()
.filter_map(|child| child.as_split().cloned())
.filter_map(|child| SplitContainer::try_from(child.clone()).ok())
.collect::<Vec<_>>();

for split_child in split_children.iter().filter(|split_child| {
Expand All @@ -43,8 +47,8 @@ pub fn flatten_child_split_containers(
// Additionally flatten redundant top-level split containers in
// the child.
if split_child.child_count() == 1 {
if let Some(split_grandchild) =
split_child.children()[0].as_split()
if let Ok(split_grandchild) =
<&SplitContainer>::try_from(&split_child.children()[0])
{
flatten_split_container(split_grandchild.clone())?;
}
Expand Down
6 changes: 3 additions & 3 deletions packages/wm/src/commands/container/focus_in_direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use wm_common::{Direction, TilingDirection, WindowState};

use super::set_focused_descendant;
use crate::{
models::{Container, TilingContainer},
models::{Container, NonTilingWindow, TilingContainer},
traits::{CommonGetters, TilingDirectionGetters, WindowGetters},
wm_state::WmState,
};
Expand Down Expand Up @@ -53,7 +53,7 @@ fn floating_focus_target(
direction: &Direction,
) -> Option<Container> {
let is_floating = |sibling: &Container| {
sibling.as_non_tiling_window().is_some_and(|window| {
<&NonTilingWindow>::try_from(sibling).is_ok_and(|window| {
matches!(window.state(), WindowState::Floating(_))
})
};
Expand Down Expand Up @@ -87,7 +87,7 @@ fn tiling_focus_target(

// Traverse upwards from the focused container. Stop searching when a
// workspace is encountered.
while !origin_or_ancestor.is_workspace() {
while !matches!(origin_or_ancestor, Container::Workspace(_)) {
let parent = origin_or_ancestor
.parent()
.and_then(|parent| parent.as_direction_container().ok())
Expand Down
2 changes: 1 addition & 1 deletion packages/wm/src/commands/window/manage_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ fn insertion_target(
Container::TilingWindow(_) => Some(focused_container),
_ => focused_workspace
.descendant_focus_order()
.find(Container::is_tiling_window),
.find(|c| matches!(c, Container::TilingWindow(_))),
};

if let Some(sibling) = sibling {
Expand Down
4 changes: 2 additions & 2 deletions packages/wm/src/commands/window/move_window_in_direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn move_tiling_window(
// Flatten the parent split container if it only contains the window.
if let Some(split_parent) = window_to_move
.parent()
.and_then(|parent| parent.as_split().cloned())
.and_then(|parent| SplitContainer::try_from(parent).ok())
{
if split_parent.child_count() == 1 {
flatten_split_container(split_parent)?;
Expand Down Expand Up @@ -87,7 +87,7 @@ fn move_tiling_window(
// Attempt to move the window to workspace in given direction.
if (has_matching_tiling_direction
|| window_to_move.tiling_siblings().count() == 0)
&& parent.is_workspace()
&& matches!(parent, DirectionContainer::Workspace(_))
{
return move_to_workspace_in_direction(
&window_to_move.into(),
Expand Down
4 changes: 2 additions & 2 deletions packages/wm/src/commands/window/move_window_to_workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ pub fn move_window_to_workspace(
.find(|descendant| descendant.state() == WindowState::Tiling);

// Insert the window into the target workspace.
match (window.is_tiling_window(), insertion_sibling.is_some()) {
(true, true) => {
match (&window, insertion_sibling.is_some()) {
(WindowContainer::TilingWindow(_), true) => {
if let Some(insertion_sibling) = insertion_sibling {
move_container_within_tree(
&window.clone().into(),
Expand Down
8 changes: 4 additions & 4 deletions packages/wm/src/commands/window/update_window_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
commands::container::{
move_container_within_tree, replace_container, resize_tiling_container,
},
models::{Container, InsertionTarget, WindowContainer},
models::{Container, InsertionTarget, NonTilingWindow, WindowContainer},
traits::{CommonGetters, TilingSizeGetters, WindowGetters},
user_config::UserConfig,
wm_state::WmState,
Expand Down Expand Up @@ -41,8 +41,8 @@ fn set_tiling(
state: &mut WmState,
config: &UserConfig,
) -> anyhow::Result<WindowContainer> {
let window = window
.as_non_tiling_window()
let window = <&NonTilingWindow>::try_from(window)
.map_err(|s| anyhow::anyhow!(s))
.context("Invalid window state.")?
.clone();

Expand Down Expand Up @@ -73,7 +73,7 @@ fn set_tiling(
.or_else(|| {
let focused_window = workspace
.descendant_focus_order()
.find(Container::is_tiling_window)?;
.find(|c| matches!(c, Container::TilingWindow(_)))?;

Some((focused_window.parent()?, focused_window.index() + 1))
})
Expand Down
6 changes: 3 additions & 3 deletions packages/wm/src/events/handle_window_location_changed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
container::{flatten_split_container, move_container_within_tree},
window::update_window_state,
},
models::{TilingWindow, WindowContainer},
models::{SplitContainer, TilingWindow, WindowContainer},
traits::{CommonGetters, PositionGetters, WindowGetters},
user_config::UserConfig,
wm_state::WmState,
Expand Down Expand Up @@ -56,7 +56,7 @@ pub fn handle_window_location_changed(
.context("Failed to get workspace of nearest monitor.")?;

// TODO: Include this as part of the `match` statement below.
if let Some(tiling_window) = window.as_tiling_window() {
if let Ok(tiling_window) = <&TilingWindow>::try_from(&window) {
update_drag_state(
tiling_window,
&frame_position,
Expand Down Expand Up @@ -220,7 +220,7 @@ fn update_drag_state(
.dequeue_container_from_redraw(window.clone());

// Flatten the parent split container if it only contains the window.
if let Some(split_parent) = parent.as_split() {
if let Ok(split_parent) = SplitContainer::try_from(parent) {
if split_parent.child_count() == 1 {
flatten_split_container(split_parent.clone())?;

Expand Down
31 changes: 17 additions & 14 deletions packages/wm/src/events/handle_window_moved_or_resized_end.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use crate::{
window::{resize_window, update_window_state},
},
models::{
DirectionContainer, NonTilingWindow, SplitContainer, TilingContainer,
WindowContainer,
Container, DirectionContainer, NonTilingWindow, SplitContainer,
TilingContainer, WindowContainer,
},
traits::{
CommonGetters, PositionGetters, TilingDirectionGetters, WindowGetters,
Expand Down Expand Up @@ -65,7 +65,9 @@ pub fn handle_window_moved_or_resized_end(

// Snap window to its original position if it's the only window in
// the workspace.
if parent.is_workspace() && window.tiling_siblings().count() == 0 {
if matches!(parent, Container::Workspace(_))
&& window.tiling_siblings().count() == 0
{
state.pending_sync.queue_container_to_redraw(window.clone());
return Ok(());
}
Expand Down Expand Up @@ -157,17 +159,18 @@ fn drop_as_tiling_window(
config,
)?;

let should_split = nearest_container.is_tiling_window()
&& match tiling_direction {
TilingDirection::Horizontal => {
drop_position == DropPosition::Top
|| drop_position == DropPosition::Bottom
}
TilingDirection::Vertical => {
drop_position == DropPosition::Left
|| drop_position == DropPosition::Right
}
};
let should_split =
matches!(nearest_container, TilingContainer::TilingWindow(_))
&& match tiling_direction {
TilingDirection::Horizontal => {
drop_position == DropPosition::Top
|| drop_position == DropPosition::Bottom
}
TilingDirection::Vertical => {
drop_position == DropPosition::Left
|| drop_position == DropPosition::Right
}
};

if should_split {
let split_container = SplitContainer::new(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use wm_common::ActiveDrag;
use wm_platform::NativeWindow;

use crate::{traits::WindowGetters, wm_state::WmState};
use crate::{
models::WindowContainer, traits::WindowGetters, wm_state::WmState,
};

/// Handles the event for when a window is started being moved or resized
/// by the user (e.g. via the window's drag handles).
Expand All @@ -19,7 +21,10 @@ pub fn handle_window_moved_or_resized_start(
if let Some(found_window) = found_window {
found_window.set_active_drag(Some(ActiveDrag {
operation: None,
is_from_tiling: found_window.is_tiling_window(),
is_from_tiling: matches!(
found_window,
WindowContainer::TilingWindow(_)
),
}));
}
}
10 changes: 2 additions & 8 deletions packages/wm/src/models/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::{
};

use ambassador::Delegate;
use enum_as_inner::EnumAsInner;
use uuid::Uuid;
use wm_common::{
ActiveDrag, ContainerDto, Direction, DisplayState, GapsConfig, Rect,
Expand Down Expand Up @@ -56,18 +55,13 @@ use crate::{
/// }
/// ```
#[derive(
Clone,
Debug,
EnumAsInner,
wm_macros::EnumFromInner,
Delegate,
wm_macros::SubEnum,
Clone, Debug, wm_macros::EnumFromInner, Delegate, wm_macros::SubEnum,
)]
#[delegate(CommonGetters)]
#[delegate(PositionGetters)]
#[subenum(defaults, {
/// Subenum of [Container]
#[derive(Clone, Debug, EnumAsInner, Delegate, wm_macros::EnumFromInner)]
#[derive(Clone, Debug, Delegate, wm_macros::EnumFromInner)]
#[delegate(CommonGetters)]
#[delegate(PositionGetters)]
})]
Expand Down
Loading
Loading