shell/tiling: Fix next_focus for different orientation
This commit is contained in:
parent
634319a823
commit
3588978f68
1 changed files with 39 additions and 42 deletions
|
|
@ -435,13 +435,14 @@ impl TilingLayout {
|
||||||
// TODO: Rather use something like seat.current_keyboard_focus
|
// TODO: Rather use something like seat.current_keyboard_focus
|
||||||
// TODO https://github.com/Smithay/smithay/pull/777
|
// TODO https://github.com/Smithay/smithay/pull/777
|
||||||
if let Some(last_active) = TilingLayout::last_active_window(tree, focus_stack) {
|
if let Some(last_active) = TilingLayout::last_active_window(tree, focus_stack) {
|
||||||
let (last_window, mut node_id) = last_active;
|
let (last_window, last_node_id) = last_active;
|
||||||
|
|
||||||
// stacks may handle focus internally
|
// stacks may handle focus internally
|
||||||
if last_window.handle_focus(direction) {
|
if last_window.handle_focus(direction) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut node_id = last_node_id.clone();
|
||||||
while let Some(group) = tree.get(&node_id).unwrap().parent() {
|
while let Some(group) = tree.get(&node_id).unwrap().parent() {
|
||||||
let child = node_id.clone();
|
let child = node_id.clone();
|
||||||
let group_data = tree.get(&group).unwrap().data();
|
let group_data = tree.get(&group).unwrap().data();
|
||||||
|
|
@ -511,50 +512,46 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
Data::Group { .. } => {
|
Data::Group { .. } => {
|
||||||
let center = {
|
let center = {
|
||||||
let geo = tree.get(&child).unwrap().data().geometry();
|
let geo = tree.get(&last_node_id).unwrap().data().geometry();
|
||||||
let mut point = geo.loc;
|
let mut point = geo.loc;
|
||||||
match direction {
|
match direction {
|
||||||
FocusDirection::Down => {
|
FocusDirection::Down => {
|
||||||
point += Point::from((geo.size.w / 2, geo.size.h))
|
point += Point::from((geo.size.w / 2 - 1, geo.size.h))
|
||||||
}
|
}
|
||||||
FocusDirection::Up => point.x += geo.size.w,
|
FocusDirection::Up => point.x += geo.size.w / 2 - 1,
|
||||||
FocusDirection::Left => point.y += geo.size.h / 2,
|
FocusDirection::Left => point.y += geo.size.h / 2 - 1,
|
||||||
FocusDirection::Right => {
|
FocusDirection::Right => {
|
||||||
point += Point::from((geo.size.w, geo.size.h / 2))
|
point += Point::from((geo.size.w, geo.size.h / 2 - 1))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
point.to_f64()
|
point.to_f64()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let distance = |candidate: &&NodeId| -> f64 {
|
||||||
|
let geo = tree.get(candidate).unwrap().data().geometry();
|
||||||
|
let mut point = geo.loc;
|
||||||
|
match direction {
|
||||||
|
FocusDirection::Up => {
|
||||||
|
point += Point::from((geo.size.w / 2, geo.size.h))
|
||||||
|
}
|
||||||
|
FocusDirection::Down => point.x += geo.size.w,
|
||||||
|
FocusDirection::Right => point.y += geo.size.h / 2,
|
||||||
|
FocusDirection::Left => {
|
||||||
|
point += Point::from((geo.size.w, geo.size.h / 2))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let point = point.to_f64();
|
||||||
|
((point.x - center.x).powi(2) + (point.y - center.y).powi(2))
|
||||||
|
.sqrt()
|
||||||
|
};
|
||||||
|
|
||||||
node_id = tree
|
node_id = tree
|
||||||
.children_ids(node_id.as_ref().unwrap())
|
.children_ids(node_id.as_ref().unwrap())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.min_by(|node1, node2| {
|
.min_by(|node1, node2| {
|
||||||
let distance = |candidate: &&NodeId| -> f64 {
|
distance(node1).abs().total_cmp(&distance(node2).abs())
|
||||||
let geo =
|
|
||||||
tree.get(candidate).unwrap().data().geometry();
|
|
||||||
let mut point = geo.loc;
|
|
||||||
match direction {
|
|
||||||
FocusDirection::Up => {
|
|
||||||
point +=
|
|
||||||
Point::from((geo.size.w / 2, geo.size.h))
|
|
||||||
}
|
|
||||||
FocusDirection::Down => point.x += geo.size.w,
|
|
||||||
FocusDirection::Right => point.y += geo.size.h / 2,
|
|
||||||
FocusDirection::Left => {
|
|
||||||
point +=
|
|
||||||
Point::from((geo.size.w, geo.size.h / 2))
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
let point = point.to_f64();
|
|
||||||
((point.x - center.x).powi(2)
|
|
||||||
+ (point.y - center.y).powi(2))
|
|
||||||
.sqrt()
|
|
||||||
};
|
|
||||||
|
|
||||||
distance(node1).total_cmp(&distance(node2))
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Data::Mapped { mapped, .. } => {
|
Data::Mapped { mapped, .. } => {
|
||||||
|
|
@ -745,7 +742,7 @@ impl TilingLayout {
|
||||||
.map(|(output_data, tree)| (&output_data.output, tree))
|
.map(|(output_data, tree)| (&output_data.output, tree))
|
||||||
{
|
{
|
||||||
if let Some(root) = tree.root_node_id() {
|
if let Some(root) = tree.root_node_id() {
|
||||||
let mut stack = VecDeque::new();
|
let mut stack = Vec::new();
|
||||||
|
|
||||||
let mut geo = Some(layer_map_for_output(&output).non_exclusive_zone());
|
let mut geo = Some(layer_map_for_output(&output).non_exclusive_zone());
|
||||||
// TODO saturate? minimum?
|
// TODO saturate? minimum?
|
||||||
|
|
@ -763,7 +760,7 @@ impl TilingLayout {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
{
|
{
|
||||||
let node = tree.get_mut(&node_id).unwrap();
|
let node = tree.get_mut(&node_id).unwrap();
|
||||||
let geo = stack.pop_front().unwrap_or(geo);
|
let geo = stack.pop().unwrap_or(geo);
|
||||||
if let Some(geo) = geo {
|
if let Some(geo) = geo {
|
||||||
let data = node.data_mut();
|
let data = node.data_mut();
|
||||||
data.update_geometry(geo);
|
data.update_geometry(geo);
|
||||||
|
|
@ -772,23 +769,23 @@ impl TilingLayout {
|
||||||
orientation, sizes, ..
|
orientation, sizes, ..
|
||||||
} => match orientation {
|
} => match orientation {
|
||||||
Orientation::Horizontal => {
|
Orientation::Horizontal => {
|
||||||
let mut previous = 0;
|
let mut previous: i32 = sizes.iter().sum();
|
||||||
for size in sizes {
|
for size in sizes.iter().rev() {
|
||||||
stack.push_back(Some(Rectangle::from_loc_and_size(
|
previous -= *size;
|
||||||
|
stack.push(Some(Rectangle::from_loc_and_size(
|
||||||
(geo.loc.x, geo.loc.y + previous),
|
(geo.loc.x, geo.loc.y + previous),
|
||||||
(geo.size.w, *size),
|
(geo.size.w, *size),
|
||||||
)));
|
)));
|
||||||
previous += *size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Orientation::Vertical => {
|
Orientation::Vertical => {
|
||||||
let mut previous = 0;
|
let mut previous: i32 = sizes.iter().sum();
|
||||||
for size in sizes {
|
for size in sizes.iter().rev() {
|
||||||
stack.push_back(Some(Rectangle::from_loc_and_size(
|
previous -= *size;
|
||||||
|
stack.push(Some(Rectangle::from_loc_and_size(
|
||||||
(geo.loc.x + previous, geo.loc.y),
|
(geo.loc.x + previous, geo.loc.y),
|
||||||
(*size, geo.size.h),
|
(*size, geo.size.h),
|
||||||
)));
|
)));
|
||||||
previous += *size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -803,8 +800,8 @@ impl TilingLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if node.data().is_group() {
|
} else if node.data().is_group() {
|
||||||
stack.push_back(None);
|
stack.push(None);
|
||||||
stack.push_back(None);
|
stack.push(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue