Skip to content

Commit

Permalink
Allow resize in both direcitons on Meta+Right click
Browse files Browse the repository at this point in the history
Fixes pop-os#858

This is just an initial implementation, it seems to work alright but I'm unfamilar with this codebase so may have done something in a silly way.
  • Loading branch information
russelltg committed Sep 24, 2024
1 parent afdb656 commit feee063
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 51 deletions.
118 changes: 84 additions & 34 deletions src/shell/layout/tiling/grabs/resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ impl PointerTarget<State> for ResizeForkTarget {
location.as_global(),
node,
left_up_idx,
None,
orientation,
output,
ReleaseMode::NoMouseButtons,
Expand Down Expand Up @@ -148,6 +149,7 @@ impl TouchTarget<State> for ResizeForkTarget {
location.as_global(),
node,
left_up_idx,
None, // only resizing in one dimension when dragging resize targets
orientation,
output,
ReleaseMode::NoMouseButtons,
Expand Down Expand Up @@ -184,9 +186,11 @@ pub struct ResizeForkGrab {
last_loc: Point<f64, Global>,
old_tree: Option<Tree<Data>>,
accumulated_delta: f64,
accumulated_delta_parent: f64,
node: NodeId,
output: WeakOutput,
left_up_idx: usize,
parent_left_up_idx: Option<usize>,
orientation: Orientation,
release: ReleaseMode,
}
Expand All @@ -196,7 +200,8 @@ impl ResizeForkGrab {
start_data: GrabStartData,
pointer_loc: Point<f64, Global>,
node: NodeId,
idx: usize,
left_up_idx: usize,
parent_left_up_idx: Option<usize>,
orientation: Orientation,
output: WeakOutput,
release: ReleaseMode,
Expand All @@ -206,9 +211,11 @@ impl ResizeForkGrab {
last_loc: pointer_loc,
old_tree: None,
accumulated_delta: 0.0,
accumulated_delta_parent: 0.0,
node,
output,
left_up_idx: idx,
left_up_idx,
parent_left_up_idx,
orientation,
release,
}
Expand Down Expand Up @@ -254,6 +261,7 @@ impl ResizeForkGrab {
if !equal {
*old_tree = tree.copy_clone();
self.accumulated_delta = 0.0;
self.accumulated_delta_parent = 0.0;
} else {
*tree = old_tree.copy_clone();
}
Expand All @@ -263,12 +271,16 @@ impl ResizeForkGrab {
}
};
if tree.get(&self.node).is_ok() {
let delta = match self.orientation {
Orientation::Vertical => delta.x,
Orientation::Horizontal => delta.y,
match self.orientation {
Orientation::Horizontal => {
self.accumulated_delta += delta.y.round();
self.accumulated_delta_parent += delta.x.round();
}
Orientation::Vertical => {
self.accumulated_delta += delta.x.round();
self.accumulated_delta_parent += delta.y.round();
}
}
.round();
self.accumulated_delta += delta;

// check that we are still alive
let mut iter = tree
Expand All @@ -281,39 +293,42 @@ impl ResizeForkGrab {
return true;
};

match tree.get_mut(&self.node).unwrap().data_mut() {
let node = tree.get_mut(&self.node).unwrap();
let parent = node.parent().cloned();

let child_orientation = match node.data_mut() {
Data::Group {
sizes, orientation, ..
} => {
if sizes[self.left_up_idx] + sizes[self.left_up_idx + 1]
< match orientation {
Orientation::Vertical => 720,
Orientation::Horizontal => 480,
}
{
if !perform_fork_grab_resize(
&mut sizes[..],
self.left_up_idx,
*orientation,
self.accumulated_delta,
) {
return false;
};

let old_size = sizes[self.left_up_idx];
sizes[self.left_up_idx] = (old_size
+ self.accumulated_delta.round() as i32)
.max(if self.orientation == Orientation::Vertical {
360
} else {
240
});
let diff = old_size - sizes[self.left_up_idx];
let next_size = sizes[self.left_up_idx + 1] + diff;
sizes[self.left_up_idx + 1] =
next_size.max(if self.orientation == Orientation::Vertical {
360
} else {
240
});
let next_diff = next_size - sizes[self.left_up_idx + 1];
sizes[self.left_up_idx] += next_diff;
}

*orientation
}
_ => unreachable!(),
};

if let Some(parent_left_up_idx) = self.parent_left_up_idx {
if let Some(Data::Group {
orientation, sizes, ..
}) = parent.map(|p| tree.get_mut(&p).unwrap().data_mut())
{
if *orientation == child_orientation {
return false; // definitely want it to be the other direction, strange situation if not...
}
perform_fork_grab_resize(
&mut sizes[..],
parent_left_up_idx,
*orientation,
self.accumulated_delta_parent,
);
}
}

self.last_loc = location.as_global();
Expand Down Expand Up @@ -557,3 +572,38 @@ impl TouchGrab<State> for ResizeForkGrab {

fn unset(&mut self, _data: &mut State) {}
}

fn perform_fork_grab_resize(
sizes: &mut [i32],
left_up_idx: usize,
orientation: Orientation,
delta: f64,
) -> bool {
if sizes[left_up_idx] + sizes[left_up_idx + 1]
< match orientation {
Orientation::Vertical => 720,
Orientation::Horizontal => 480,
}
{
return false;
};

let old_size = sizes[left_up_idx];
sizes[left_up_idx] =
(old_size + delta.round() as i32).max(if orientation == Orientation::Vertical {
360
} else {
240
});
let diff = old_size - sizes[left_up_idx];
let next_size = sizes[left_up_idx + 1] + diff;
sizes[left_up_idx + 1] = next_size.max(if orientation == Orientation::Vertical {
360
} else {
240
});
let next_diff = next_size - sizes[left_up_idx + 1];
sizes[left_up_idx] += next_diff;

true
}
65 changes: 50 additions & 15 deletions src/shell/layout/tiling/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2467,7 +2467,7 @@ impl TilingLayout {
&self,
mut node_id: NodeId,
edge: ResizeEdge,
) -> Option<(NodeId, usize, Orientation)> {
) -> Option<(NodeId, usize, Option<usize>, Orientation)> {
let tree = self.tree();

while let Some(group_id) = tree.get(&node_id).unwrap().parent().cloned() {
Expand All @@ -2478,20 +2478,30 @@ impl TilingLayout {
.position(|id| id == &node_id)
.unwrap();
let total = tree.children_ids(&group_id).unwrap().count();
if orientation == Orientation::Vertical {
if node_idx > 0 && edge.contains(ResizeEdge::LEFT) {
return Some((group_id, node_idx - 1, orientation));
}
if node_idx < total - 1 && edge.contains(ResizeEdge::RIGHT) {
return Some((group_id, node_idx, orientation));
}
} else {
if node_idx > 0 && edge.contains(ResizeEdge::TOP) {
return Some((group_id, node_idx - 1, orientation));
}
if node_idx < total - 1 && edge.contains(ResizeEdge::BOTTOM) {
return Some((group_id, node_idx, orientation));
}
if let Some(left_up_idx) =
resize_edge_to_left_up_idx(orientation, node_idx, total, edge)
{
let parent_left_up_idx =
if let Some(group_parent) = tree.get(&group_id).unwrap().parent() {
let group_idx = tree
.children_ids(&group_parent)
.unwrap()
.position(|id| id == &group_id)
.unwrap();
let group_parent_orientation =
tree.get(&group_parent).unwrap().data().orientation();
let group_parent_total = tree.children_ids(&group_parent).unwrap().count();
resize_edge_to_left_up_idx(
group_parent_orientation,
group_idx,
group_parent_total,
edge,
)
} else {
None
};

return Some((group_id, left_up_idx, parent_left_up_idx, orientation));
}

node_id = group_id;
Expand Down Expand Up @@ -5413,3 +5423,28 @@ fn scale_to_center<C>(
)
}
}

fn resize_edge_to_left_up_idx(
orientation: Orientation,
node_idx: usize,
total: usize,
edge: ResizeEdge,
) -> Option<usize> {
if orientation == Orientation::Vertical {
if node_idx > 0 && edge.contains(ResizeEdge::LEFT) {
return Some(node_idx - 1);
}
if node_idx < total - 1 && edge.contains(ResizeEdge::RIGHT) {
return Some(node_idx);
}
} else {
if node_idx > 0 && edge.contains(ResizeEdge::TOP) {
return Some(node_idx - 1);
}
if node_idx < total - 1 && edge.contains(ResizeEdge::BOTTOM) {
return Some(node_idx);
}
}

None
}
7 changes: 5 additions & 2 deletions src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3262,12 +3262,14 @@ impl Shell {
grab.into()
} else if let Some(ws) = self.space_for_mut(&mapped) {
let node_id = mapped.tiling_node_id.lock().unwrap().clone()?;
let (node, left_up_idx, orientation) = ws.tiling_layer.resize_request(node_id, edge)?;
let (node, left_up_idx, parent_left_up_idx, orientation) =
ws.tiling_layer.resize_request(node_id, edge)?;
ResizeForkGrab::new(
start_data,
new_loc.to_f64(),
node,
left_up_idx,
parent_left_up_idx,
orientation,
ws.output.downgrade(),
ReleaseMode::Click,
Expand Down Expand Up @@ -3464,13 +3466,14 @@ impl Shell {
grab.into()
} else if let Some(ws) = self.space_for_mut(&mapped) {
let node_id = mapped.tiling_node_id.lock().unwrap().clone()?;
let (node, left_up_idx, orientation) =
let (node, left_up_idx, parent_left_up_idx, orientation) =
ws.tiling_layer.resize_request(node_id, edges)?;
ResizeForkGrab::new(
start_data,
seat.get_pointer().unwrap().current_location().as_global(),
node,
left_up_idx,
parent_left_up_idx,
orientation,
ws.output.downgrade(),
ReleaseMode::NoMouseButtons,
Expand Down

0 comments on commit feee063

Please sign in to comment.