fix some bugs relating to tab behavior and border rendering
This commit is contained in:
parent
f056727621
commit
206a5fb19e
12 changed files with 240 additions and 172 deletions
|
|
@ -389,17 +389,15 @@ impl ContainerNode {
|
|||
let mb = self.mono_body.get();
|
||||
return (mb.width(), mb.height());
|
||||
}
|
||||
let gap = self.state.theme.sizes.gap.get();
|
||||
let bw = self.state.theme.sizes.border_width.get();
|
||||
let nc = self.num_children.get() as i32 + 1;
|
||||
match self.split.get() {
|
||||
ContainerSplit::Horizontal => {
|
||||
let spacing = gap.max(bw);
|
||||
let spacing = self.child_spacing();
|
||||
let content_w = self.width.get().sub((nc - 1) * spacing).max(0);
|
||||
(content_w / nc, self.height.get())
|
||||
}
|
||||
ContainerSplit::Vertical => {
|
||||
let spacing = gap.max(bw);
|
||||
let spacing = self.child_spacing();
|
||||
let content_h = self.height.get().sub((nc - 1) * spacing).max(0);
|
||||
(self.width.get(), content_h / nc)
|
||||
}
|
||||
|
|
@ -431,6 +429,12 @@ impl ContainerNode {
|
|||
));
|
||||
}
|
||||
|
||||
fn child_spacing(&self) -> i32 {
|
||||
let gap = self.state.theme.sizes.gap.get();
|
||||
let bw = self.state.theme.sizes.border_width.get();
|
||||
if gap == 0 { bw } else { gap + 2 * bw }
|
||||
}
|
||||
|
||||
fn schedule_layout(self: &Rc<Self>) {
|
||||
if !self.layout_scheduled.replace(true) {
|
||||
self.state.pending_container_layout.push(self.clone());
|
||||
|
|
@ -494,10 +498,8 @@ impl ContainerNode {
|
|||
|
||||
fn perform_split_layout(self: &Rc<Self>) {
|
||||
let sum_factors = self.sum_factors.get();
|
||||
let gap = self.state.theme.sizes.gap.get();
|
||||
let border_width = self.state.theme.sizes.border_width.get();
|
||||
let split = self.split.get();
|
||||
let spacing = gap.max(border_width);
|
||||
let spacing = self.child_spacing();
|
||||
let (content_size, other_content_size) = match split {
|
||||
ContainerSplit::Horizontal => (self.content_width.get(), self.content_height.get()),
|
||||
ContainerSplit::Vertical => (self.content_height.get(), self.content_width.get()),
|
||||
|
|
@ -558,18 +560,15 @@ impl ContainerNode {
|
|||
}
|
||||
|
||||
fn update_content_size(&self) {
|
||||
let gap = self.state.theme.sizes.gap.get();
|
||||
let border_width = self.state.theme.sizes.border_width.get();
|
||||
let nc = self.num_children.get();
|
||||
let spacing = self.child_spacing();
|
||||
match self.split.get() {
|
||||
ContainerSplit::Horizontal => {
|
||||
let spacing = gap.max(border_width);
|
||||
let new_content_size = self.width.get().sub((nc - 1) as i32 * spacing).max(0);
|
||||
self.content_width.set(new_content_size);
|
||||
self.content_height.set(self.height.get());
|
||||
}
|
||||
ContainerSplit::Vertical => {
|
||||
let spacing = gap.max(border_width);
|
||||
let new_content_size = self.height.get().sub((nc - 1) as i32 * spacing).max(0);
|
||||
self.content_height.set(new_content_size);
|
||||
self.content_width.set(self.width.get());
|
||||
|
|
@ -983,7 +982,9 @@ impl ContainerNode {
|
|||
let was_ephemeral = self.ephemeral.replace(Ephemeral::Off);
|
||||
self.clone().cnode_remove_child2(&*focused_node, true);
|
||||
self.ephemeral.set(was_ephemeral);
|
||||
let focused_active = focused_node.tl_data().active();
|
||||
let sub = ContainerNode::new(&self.state, &self.workspace.get(), focused_node, split);
|
||||
let sub_id = sub.node_id();
|
||||
if ephemeral {
|
||||
sub.ephemeral.set(Ephemeral::On);
|
||||
}
|
||||
|
|
@ -994,6 +995,11 @@ impl ContainerNode {
|
|||
// Was the last child — append.
|
||||
self.append_child(sub);
|
||||
}
|
||||
if focused_active
|
||||
&& let Some(group) = self.child_nodes.borrow().get(&sub_id).map(|n| n.to_ref())
|
||||
{
|
||||
self.update_child_active(&group, true, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Change this container's split direction (hy3's `changegroup`).
|
||||
|
|
@ -1226,6 +1232,37 @@ impl ContainerNode {
|
|||
return;
|
||||
}
|
||||
let (split, prev) = direction_to_split(direction);
|
||||
if self.mono_child.is_some() && split == ContainerSplit::Horizontal {
|
||||
let cc = match self.child_nodes.borrow().get(&child.node_id()) {
|
||||
Some(l) => l.to_ref(),
|
||||
None => return,
|
||||
};
|
||||
let neighbor = match prev {
|
||||
true => cc.prev(),
|
||||
false => cc.next(),
|
||||
};
|
||||
if let Some(neighbor) = neighbor {
|
||||
if let Some(cn) = neighbor.node.clone().node_into_container()
|
||||
&& cn.cnode_accepts_child(&*child)
|
||||
{
|
||||
if let Some(mc) = self.mono_child.get()
|
||||
&& mc.node.node_id() == child.node_id()
|
||||
{
|
||||
self.activate_child2(&neighbor, true);
|
||||
}
|
||||
self.cnode_remove_child2(&*child, true);
|
||||
cn.insert_child_from_direction(child, direction);
|
||||
return;
|
||||
}
|
||||
match prev {
|
||||
true => neighbor.prepend_existing(&cc),
|
||||
false => neighbor.append_existing(&cc),
|
||||
}
|
||||
self.rebuild_tab_bar();
|
||||
self.damage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// CASE 2: We're moving the child within the container.
|
||||
if split == self.split.get()
|
||||
|| (split == ContainerSplit::Horizontal && self.mono_child.is_some())
|
||||
|
|
@ -1248,7 +1285,7 @@ impl ContainerNode {
|
|||
self.activate_child2(&neighbor, true);
|
||||
}
|
||||
self.cnode_remove_child2(&*child, true);
|
||||
cn.insert_child(child, direction);
|
||||
cn.insert_child_from_direction(child, direction);
|
||||
return;
|
||||
}
|
||||
match prev {
|
||||
|
|
@ -1277,11 +1314,14 @@ impl ContainerNode {
|
|||
return;
|
||||
}
|
||||
};
|
||||
self.cnode_remove_child2(&*child, true);
|
||||
let was_ephemeral = self.ephemeral.replace(Ephemeral::Off);
|
||||
self.clone().cnode_remove_child2(&*child, true);
|
||||
match prev {
|
||||
true => parent.add_child_before(&*neighbor, child.clone()),
|
||||
false => parent.add_child_after(&*neighbor, child.clone()),
|
||||
}
|
||||
self.ephemeral.set(was_ephemeral);
|
||||
self.collapse_ephemeral();
|
||||
}
|
||||
|
||||
pub fn insert_child(self: &Rc<Self>, node: Rc<dyn ToplevelNode>, direction: Direction) {
|
||||
|
|
@ -1329,6 +1369,17 @@ impl ContainerNode {
|
|||
}
|
||||
}
|
||||
|
||||
fn insert_child_from_direction(
|
||||
self: &Rc<Self>,
|
||||
node: Rc<dyn ToplevelNode>,
|
||||
direction: Direction,
|
||||
) {
|
||||
match direction {
|
||||
Direction::Right | Direction::Down => self.prepend_child(node),
|
||||
Direction::Left | Direction::Up | Direction::Unspecified => self.append_child(node),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_child_active(
|
||||
self: &Rc<Self>,
|
||||
node: &NodeRef<ContainerChild>,
|
||||
|
|
@ -1386,6 +1437,26 @@ impl ContainerNode {
|
|||
}
|
||||
}
|
||||
|
||||
fn collapse_ephemeral(self: &Rc<Self>) {
|
||||
if self.ephemeral.get() != Ephemeral::On
|
||||
|| self.num_children.get() != 1
|
||||
|| self.toplevel_data.is_fullscreen.get()
|
||||
{
|
||||
return;
|
||||
}
|
||||
if let Some(parent) = self.toplevel_data.parent.get()
|
||||
&& let Some(only_child) = self.children.first()
|
||||
{
|
||||
let child_node = only_child.node.clone();
|
||||
if parent.cnode_accepts_child(&*child_node) {
|
||||
parent.cnode_replace_child(self.deref(), child_node);
|
||||
self.toplevel_data.parent.take();
|
||||
self.child_nodes.borrow_mut().clear();
|
||||
self.tl_destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mod_attention_requests(&self, set: bool) {
|
||||
let propagate = self.attention_requests.adj(set);
|
||||
if set || propagate {
|
||||
|
|
@ -1722,7 +1793,6 @@ impl ContainerNode {
|
|||
if let Some(s) = scale {
|
||||
texture_height = (bar_height as f64 * s).round() as _;
|
||||
}
|
||||
let mut scheduled = 0;
|
||||
let mut texture_refs = Vec::new();
|
||||
for (title, (_, _, text_color), title_texture) in &entries {
|
||||
let mut tex_ref = title_texture.borrow_mut();
|
||||
|
|
@ -1737,7 +1807,6 @@ impl ContainerNode {
|
|||
scale,
|
||||
);
|
||||
texture_refs.push(title_texture.clone());
|
||||
scheduled += 1;
|
||||
}
|
||||
(on_completed.event(), texture_refs)
|
||||
}
|
||||
|
|
@ -2137,23 +2206,10 @@ impl ContainingNode for ContainerNode {
|
|||
}
|
||||
}
|
||||
self.sum_factors.set(sum);
|
||||
// Ephemeral collapse: if this container is ephemeral and has exactly
|
||||
// one child remaining, replace this container with that child in the parent.
|
||||
if self.ephemeral.get() == Ephemeral::On
|
||||
&& num_children == 1
|
||||
&& !self.toplevel_data.is_fullscreen.get()
|
||||
{
|
||||
if let Some(parent) = self.toplevel_data.parent.get() {
|
||||
if let Some(only_child) = self.children.first() {
|
||||
let child_node = only_child.node.clone();
|
||||
if parent.cnode_accepts_child(&*child_node) {
|
||||
parent.cnode_replace_child(self.deref(), child_node);
|
||||
self.toplevel_data.parent.take();
|
||||
self.child_nodes.borrow_mut().clear();
|
||||
self.tl_destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if self.ephemeral.get() == Ephemeral::On && num_children == 1 {
|
||||
self.collapse_ephemeral();
|
||||
if self.toplevel_data.parent.is_none() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// log::info!("cnode_remove_child2");
|
||||
|
|
@ -2234,8 +2290,6 @@ impl ContainingNode for ContainerNode {
|
|||
new_y2: Option<i32>,
|
||||
) {
|
||||
let theme = &self.state.theme;
|
||||
let bw = theme.sizes.border_width.get();
|
||||
let gap = theme.sizes.gap.get();
|
||||
let mut left_outside = false;
|
||||
let mut right_outside = false;
|
||||
let mut top_outside = false;
|
||||
|
|
@ -2280,9 +2334,10 @@ impl ContainingNode for ContainerNode {
|
|||
if ci == 0 {
|
||||
ci = 1;
|
||||
}
|
||||
let between = self.child_spacing();
|
||||
let (new_delta, between) = match split {
|
||||
ContainerSplit::Horizontal => (self.abs_x1.get(), gap.max(bw)),
|
||||
ContainerSplit::Vertical => (self.abs_y1.get(), gap.max(bw)),
|
||||
ContainerSplit::Horizontal => (self.abs_x1.get(), between),
|
||||
ContainerSplit::Vertical => (self.abs_y1.get(), between),
|
||||
};
|
||||
let new_i1 = new_i1.map(|v| v - new_delta);
|
||||
let new_i2 = new_i2.map(|v| v - new_delta);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue