1
0
Fork 0
forked from wry/wry

autocommit 2022-03-24 18:27:42 CET

This commit is contained in:
Julian Orth 2022-03-24 18:27:42 +01:00
parent b3a27f889a
commit 3b1b843821
17 changed files with 388 additions and 212 deletions

View file

@ -204,6 +204,22 @@ impl ConfigProxyHandler {
Ok(())
}
fn handle_get_mono(&self, seat: Seat) -> Result<(), GetMonoError> {
let seat = self.get_seat(seat)?;
self.send(&ServerMessage::Response {
response: Response::GetMono {
mono: seat.get_mono().unwrap_or(false).into(),
},
});
Ok(())
}
fn handle_set_mono(&self, seat: Seat, mono: bool) -> Result<(), SetMonoError> {
let seat = self.get_seat(seat)?;
seat.set_mono(mono);
Ok(())
}
fn handle_get_split(&self, seat: Seat) -> Result<(), GetSplitError> {
let seat = self.get_seat(seat)?;
self.send(&ServerMessage::Response {
@ -450,6 +466,8 @@ impl ConfigProxyHandler {
self.handle_set_repeat_rate(seat, rate, delay)?
}
ClientMessage::SetSeat { device, seat } => self.handle_set_seat(device, seat)?,
ClientMessage::GetMono { seat } => self.handle_get_mono(seat)?,
ClientMessage::SetMono { seat, mono } => self.handle_set_mono(seat, mono)?,
ClientMessage::GetSplit { seat } => self.handle_get_split(seat)?,
ClientMessage::SetSplit { seat, axis } => self.handle_set_split(seat, axis)?,
ClientMessage::AddShortcut { seat, mods, sym } => {
@ -505,6 +523,10 @@ enum CphError {
FocusError(#[from] FocusError),
#[error("Could not process a `move` request")]
MoveError(#[from] MoveError),
#[error("Could not process a `set_mono` request")]
SetMonoError(#[from] SetMonoError),
#[error("Could not process a `get_mono` request")]
GetMonoError(#[from] GetMonoError),
#[error("Could not process a `set_split` request")]
SetSplitError(#[from] SetSplitError),
#[error("Could not process a `get_split` request")]
@ -601,6 +623,20 @@ enum MoveError {
}
efrom!(MoveError, CphError);
#[derive(Debug, Error)]
enum SetMonoError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(SetMonoError, CphError);
#[derive(Debug, Error)]
enum GetMonoError {
#[error(transparent)]
CphError(#[from] Box<CphError>),
}
efrom!(GetMonoError, CphError);
#[derive(Debug, Error)]
enum SetSplitError {
#[error(transparent)]

View file

@ -204,10 +204,18 @@ impl WlSeatGlobal {
}
}
pub fn get_mono(&self) -> Option<bool> {
self.keyboard_node.get().get_parent_mono()
}
pub fn get_split(&self) -> Option<ContainerSplit> {
self.keyboard_node.get().get_parent_split()
}
pub fn set_mono(&self, mono: bool) {
self.keyboard_node.get().set_parent_mono(mono)
}
pub fn set_split(&self, axis: ContainerSplit) {
self.keyboard_node.get().set_parent_split(axis)
}

View file

@ -641,10 +641,18 @@ impl Node for WlSurface {
}
}
fn get_parent_mono(&self) -> Option<bool> {
self.xdg.get().and_then(|x| x.get_mono())
}
fn get_parent_split(&self) -> Option<ContainerSplit> {
self.xdg.get().and_then(|x| x.get_split())
}
fn set_parent_mono(&self, mono: bool) {
self.xdg.get().map(|x| x.set_mono(mono));
}
fn set_parent_split(&self, split: ContainerSplit) {
self.xdg.get().map(|x| x.set_split(split));
}

View file

@ -83,10 +83,18 @@ pub trait XdgSurfaceExt: Debug {
let _ = seat;
}
fn get_mono(&self) -> Option<bool> {
None
}
fn get_split(&self) -> Option<ContainerSplit> {
None
}
fn set_mono(&self, mono: bool) {
let _ = mono;
}
fn set_split(&self, split: ContainerSplit) {
let _ = split;
}
@ -166,10 +174,18 @@ impl XdgSurface {
}
}
pub fn get_mono(&self) -> Option<bool> {
self.ext.get().and_then(|e| e.get_mono())
}
pub fn get_split(&self) -> Option<ContainerSplit> {
self.ext.get().and_then(|e| e.get_split())
}
pub fn set_mono(&self, mono: bool) {
self.ext.get().map(|e| e.set_mono(mono));
}
pub fn set_split(&self, split: ContainerSplit) {
self.ext.get().map(|e| e.set_split(split));
}

View file

@ -327,7 +327,7 @@ impl XdgToplevel {
_ => return,
};
let extents = self.xdg.extents.get();
parent.child_active_changed(self, self.active_surfaces.get() > 0);
parent.clone().child_active_changed(self, self.active_surfaces.get() > 0);
parent.child_size_changed(self, extents.width(), extents.height());
parent.child_title_changed(self, self.title.borrow_mut().deref());
}
@ -503,10 +503,23 @@ impl XdgSurfaceExt for XdgToplevel {
Self::toggle_floating(&self);
}
fn get_mono(&self) -> Option<bool> {
self.parent_node.get().and_then(|p| p.get_mono())
}
fn get_split(&self) -> Option<ContainerSplit> {
self.parent_node.get().and_then(|p| p.get_split())
}
fn set_mono(&self, mono: bool) {
let node = if mono {
Some(self as &dyn Node)
} else {
None
};
self.parent_node.get().map(move |p| p.set_mono(node));
}
fn set_split(&self, split: ContainerSplit) {
self.parent_node.get().map(|p| p.set_split(split));
}

View file

@ -34,7 +34,7 @@ use crate::render::RenderError;
use crate::sighand::SighandError;
use crate::state::State;
use crate::tree::{
container_layout, container_titles, float_layout, float_titles, DisplayNode, NodeIds,
container_layout, container_render_data, float_layout, float_titles, DisplayNode, NodeIds,
};
use crate::udev::Udev;
use crate::utils::clonecell::CloneCell;
@ -176,7 +176,7 @@ fn main_() -> Result<(), MainError> {
input_device_handlers: Default::default(),
theme: Default::default(),
pending_container_layout: Default::default(),
pending_container_titles: Default::default(),
pending_container_render_data: Default::default(),
pending_float_layout: Default::default(),
pending_float_titles: Default::default(),
dbus: Dbus::new(&engine, &run_toplevel),
@ -189,7 +189,7 @@ fn main_() -> Result<(), MainError> {
let _slow_client_handler = engine.spawn(tasks::handle_slow_clients(state.clone()));
let _container_do_layout = engine.spawn2(Phase::Layout, container_layout(state.clone()));
let _container_render_titles =
engine.spawn2(Phase::PostLayout, container_titles(state.clone()));
engine.spawn2(Phase::PostLayout, container_render_data(state.clone()));
let _float_do_layout = engine.spawn2(Phase::Layout, float_layout(state.clone()));
let _float_render_titles = engine.spawn2(Phase::PostLayout, float_titles(state.clone()));
let socket_path = Acceptor::install(&state)?;

View file

@ -5,7 +5,7 @@ use crate::render::gl::sys::{
};
use crate::render::renderer::context::RenderContext;
use crate::render::renderer::renderer::Renderer;
use crate::render::sys::{glBlendFunc, GL_ONE, GL_ONE_MINUS_SRC_ALPHA};
use crate::render::sys::{glBlendFunc, GL_ONE, GL_ONE_MINUS_SRC_ALPHA, glFlush};
use crate::tree::Node;
use crate::State;
use std::fmt::{Debug, Formatter};
@ -74,6 +74,9 @@ impl Framebuffer {
}
}
}
unsafe {
glFlush();
}
Ok(())
});
}

View file

@ -16,24 +16,11 @@ use crate::render::sys::{glDisable, glEnable, GL_BLEND};
use crate::render::Texture;
use crate::theme::Color;
use crate::tree::{
ContainerFocus, ContainerNode, ContainerSplit, FloatNode, Node, OutputNode, WorkspaceNode,
ContainerNode, FloatNode, Node, OutputNode, WorkspaceNode,
};
use crate::State;
use std::ops::Deref;
use std::rc::Rc;
use std::slice;
const NON_COLOR: Color = Color::from_rgbaf(0.2, 0.2, 0.2, 1.0);
const CHILD_COLOR: Color = Color::from_rgbaf(0.8, 0.8, 0.8, 1.0);
const YES_COLOR: Color = Color::from_rgbaf(0.0, 0.0, 1.0, 1.0);
fn focus_color(focus: ContainerFocus) -> Color {
match focus {
ContainerFocus::None => NON_COLOR,
ContainerFocus::Child => CHILD_COLOR,
ContainerFocus::Yes => YES_COLOR,
}
}
pub struct Renderer<'a> {
pub(super) ctx: &'a Rc<RenderContext>,
@ -82,16 +69,21 @@ impl Renderer<'_> {
2.0 * (y as f32 / self.fb.height as f32) - 1.0
}
fn fill_boxes(&self, boxes: &[Rect], color: &Color) {
self.fill_boxes2(boxes, color, 0, 0);
}
fn fill_boxes2(&self, boxes: &[Rect], color: &Color, dx: i32, dy: i32) {
if boxes.is_empty() {
return;
}
let mut pos = Vec::with_capacity(boxes.len() * 12);
for bx in boxes {
let x1 = self.x_to_f(bx.x1());
let y1 = self.y_to_f(bx.y1());
let x2 = self.x_to_f(bx.x2());
let y2 = self.y_to_f(bx.y2());
let x1 = self.x_to_f(bx.x1() + dx);
let y1 = self.y_to_f(bx.y1() + dy);
let x2 = self.x_to_f(bx.x2() + dx);
let y2 = self.y_to_f(bx.y2() + dy);
pos.extend_from_slice(&[
// triangle 1
x2, y1, // top right
@ -121,128 +113,35 @@ impl Renderer<'_> {
}
pub fn render_container(&mut self, container: &ContainerNode, x: i32, y: i32) {
let border_width = self.state.theme.border_width.get();
let title_height = self.state.theme.title_height.get();
let cwidth = container.width.get();
let cheight = container.height.get();
let num_children = container.num_children();
let title_rect = Rect::new_sized(x, y, container.width.get(), title_height).unwrap();
let underline_rect =
Rect::new_sized(x, y + title_height, container.width.get(), 1).unwrap();
let mut titles = vec![];
if let Some(child) = container.mono_child.get() {
let space_per_child = cwidth / num_children as i32;
let mut rem = cwidth % num_children as i32;
let mut pos = x;
let color = focus_color(ContainerFocus::None);
self.fill_boxes(slice::from_ref(&title_rect), &color);
{
let rd = container.render_data.borrow_mut();
let c = self.state.theme.title_color.get();
self.fill_boxes2(&rd.title_rects, &c, x, y);
let c = self.state.theme.active_title_color.get();
self.fill_boxes2(&rd.active_title_rects, &c, x, y);
let c = self.state.theme.underline_color.get();
self.fill_boxes2(&rd.underline_rects, &c, x, y);
let c = self.state.theme.border_color.get();
self.fill_boxes(slice::from_ref(&underline_rect), &c);
for child in container.children.iter() {
let focus = child.focus.get();
let color = focus_color(focus);
let mut width = space_per_child;
if rem > 0 {
rem -= 1;
width += 1;
}
if let Some(title) = child.title_texture.get() {
titles.push((pos, 0, title));
}
if focus != ContainerFocus::None {
let rect = Rect::new_sized(pos, y, width, title_height).unwrap();
self.fill_boxes(slice::from_ref(&rect), &color);
}
pos += width as i32;
self.fill_boxes2(&rd.border_rects, &c, x, y);
for title in &rd.titles {
self.render_texture(&title.tex, x + title.x, y + title.y, ARGB8888);
}
}
if let Some(child) = container.mono_child.get() {
unsafe {
with_scissor(&container.mono_body.get(), || {
let body = container.mono_body.get().move_(x, y);
with_scissor(&body, || {
let content = container.mono_content.get();
child.node.render(self, x + content.x1(), y + content.y1());
});
}
} else {
let split = container.split.get();
let num_title_rects = if split == ContainerSplit::Horizontal {
1
} else {
num_children
};
let mut title_rects = Vec::with_capacity(num_title_rects);
let mut underline_rects = Vec::with_capacity(num_title_rects);
let mut border_rects = Vec::with_capacity(num_children - 1);
let mut active_rects = Vec::new();
title_rects.push(title_rect);
underline_rects.push(underline_rect);
for (i, child) in container.children.iter().enumerate() {
let body = child.body.get();
if let Some(title) = child.title_texture.get() {
titles.push((body.x1(), body.y1() - title_height - 1, title));
}
if child.active.get() {
active_rects.push(
Rect::new_sized(
x + body.x1(),
y + body.y1() - title_height - 1,
body.width(),
title_height,
)
.unwrap(),
);
}
if i + 1 < num_children {
let border_rect = if split == ContainerSplit::Horizontal {
Rect::new_sized(
x + body.x2(),
y + body.y1() - title_height - 1,
border_width,
container.height.get(),
)
.unwrap()
} else {
title_rects.push(
Rect::new_sized(
x,
y + body.y2() + border_width,
container.width.get(),
title_height,
)
.unwrap(),
);
underline_rects.push(
Rect::new_sized(
x,
y + body.y2() + border_width + title_height,
container.width.get(),
1,
)
.unwrap(),
);
Rect::new_sized(x, y + body.y2(), container.width.get(), border_width)
.unwrap()
};
border_rects.push(border_rect);
}
}
{
let c = self.state.theme.title_color.get();
self.fill_boxes(&title_rects, &c);
let c = self.state.theme.active_title_color.get();
self.fill_boxes(&active_rects, &c);
let c = self.state.theme.underline_color.get();
self.fill_boxes(&underline_rects, &c);
let c = self.state.theme.border_color.get();
self.fill_boxes(&border_rects, &c);
for (tx, ty, tex) in titles {
self.render_texture(&tex, x + tx, y + ty, ARGB8888);
}
}
for child in container.children.iter() {
let body = child.body.get();
if body.x1() >= cwidth || body.y1() >= cheight {
if body.x1() >= container.width.get() || body.y1() >= container.height.get() {
break;
}
let body = body.move_(container.abs_x1.get(), container.abs_y1.get());
let body = body.move_(x, y);
unsafe {
with_scissor(&body, || {
let content = child.content.get();

View file

@ -60,7 +60,7 @@ pub struct State {
pub config: CloneCell<Option<Rc<ConfigProxy>>>,
pub theme: Theme,
pub pending_container_layout: AsyncQueue<Rc<ContainerNode>>,
pub pending_container_titles: AsyncQueue<Rc<ContainerNode>>,
pub pending_container_render_data: AsyncQueue<Rc<ContainerNode>>,
pub pending_float_layout: AsyncQueue<Rc<FloatNode>>,
pub pending_float_titles: AsyncQueue<Rc<FloatNode>>,
pub dbus: Dbus,

View file

@ -30,10 +30,6 @@ impl Color {
a: to_f32(a),
}
}
pub const fn from_rgbaf(r: f32, g: f32, b: f32, a: f32) -> Self {
Self { r, g, b, a }
}
}
impl From<jay_config::theme::Color> for Color {

View file

@ -84,18 +84,34 @@ pub trait Node {
let _ = title;
}
fn get_parent_mono(&self) -> Option<bool> {
None
}
fn get_parent_split(&self) -> Option<ContainerSplit> {
None
}
fn set_parent_mono(&self, mono: bool) {
let _ = mono;
}
fn set_parent_split(&self, split: ContainerSplit) {
let _ = split;
}
fn get_mono(&self) -> Option<bool> {
None
}
fn get_split(&self) -> Option<ContainerSplit> {
None
}
fn set_mono(self: Rc<Self>, child: Option<&dyn Node>) {
let _ = child;
}
fn set_split(self: Rc<Self>, split: ContainerSplit) {
let _ = split;
}
@ -209,7 +225,7 @@ pub trait Node {
let _ = (child, width, height);
}
fn child_active_changed(&self, child: &dyn Node, active: bool) {
fn child_active_changed(self: Rc<Self>, child: &dyn Node, active: bool) {
let _ = (child, active);
}

View file

@ -54,6 +54,21 @@ pub enum ContainerFocus {
tree_id!(ContainerNodeId);
pub struct ContainerTitle {
pub x: i32,
pub y: i32,
pub tex: Rc<Texture>,
}
#[derive(Default)]
pub struct ContainerRenderData {
pub title_rects: Vec<Rect>,
pub active_title_rects: Vec<Rect>,
pub border_rects: Vec<Rect>,
pub underline_rects: Vec<Rect>,
pub titles: Vec<ContainerTitle>,
}
pub struct ContainerNode {
pub id: ContainerNodeId,
pub parent: CloneCell<Rc<dyn Node>>,
@ -71,7 +86,7 @@ pub struct ContainerNode {
pub content_height: Cell<i32>,
pub sum_factors: Cell<f64>,
layout_scheduled: Cell<bool>,
render_titles_scheduled: Cell<bool>,
compute_render_data_scheduled: Cell<bool>,
num_children: NumCell<usize>,
pub children: LinkedList<ContainerChild>,
child_nodes: RefCell<AHashMap<NodeId, LinkedNode<ContainerChild>>>,
@ -79,6 +94,7 @@ pub struct ContainerNode {
workspace: CloneCell<Rc<WorkspaceNode>>,
seats: RefCell<AHashMap<SeatId, SeatState>>,
state: Rc<State>,
pub render_data: RefCell<ContainerRenderData>,
}
impl Debug for ContainerNode {
@ -94,9 +110,7 @@ pub struct ContainerChild {
pub body: Cell<Rect>,
pub content: Cell<Rect>,
factor: Cell<f64>,
pub focus: Cell<ContainerFocus>,
title: RefCell<String>,
pub title_texture: CloneCell<Option<Rc<Texture>>>,
}
struct SeatState {
@ -143,9 +157,7 @@ impl ContainerNode {
body: Cell::new(Default::default()),
content: Cell::new(Default::default()),
factor: Cell::new(1.0),
focus: Cell::new(ContainerFocus::None),
title: Default::default(),
title_texture: Default::default(),
}),
);
let slf = Rc::new(Self {
@ -165,7 +177,7 @@ impl ContainerNode {
content_height: Cell::new(0),
sum_factors: Cell::new(1.0),
layout_scheduled: Cell::new(false),
render_titles_scheduled: Cell::new(false),
compute_render_data_scheduled: Cell::new(false),
num_children: NumCell::new(1),
children,
child_nodes: RefCell::new(child_nodes),
@ -173,15 +185,12 @@ impl ContainerNode {
workspace: CloneCell::new(workspace.clone()),
seats: RefCell::new(Default::default()),
state: state.clone(),
render_data: Default::default(),
});
child.set_parent(slf.clone());
slf
}
pub fn num_children(&self) -> usize {
self.num_children.get()
}
pub fn prepend_child(self: &Rc<Self>, new: Rc<dyn Node>) {
if let Some(child) = self.children.first() {
self.add_child_before_(&child, new);
@ -248,9 +257,7 @@ impl ContainerNode {
body: Default::default(),
content: Default::default(),
factor: Cell::new(0.0),
focus: Cell::new(ContainerFocus::None),
title: Default::default(),
title_texture: Default::default(),
}),
);
}
@ -287,7 +294,7 @@ impl ContainerNode {
}
pub fn on_colors_changed(self: &Rc<Self>) {
self.schedule_render_titles();
self.schedule_compute_render_data();
}
fn schedule_layout(self: &Rc<Self>) {
@ -297,6 +304,23 @@ impl ContainerNode {
}
fn perform_layout(self: &Rc<Self>) {
self.layout_scheduled.set(false);
if let Some(child) = self.mono_child.get() {
self.perform_mono_layout(&child);
} else {
self.perform_split_layout();
}
self.schedule_compute_render_data();
}
fn perform_mono_layout(self: &Rc<Self>, child: &ContainerChild) {
let mb = self.mono_body.get();
child.node.clone().change_extents(&mb.move_(self.abs_x1.get(), self.abs_y1.get()));
self.mono_content
.set(child.content.get().at_point(mb.x1(), mb.y1()));
}
fn perform_split_layout(self: &Rc<Self>) {
let sum_factors = self.sum_factors.get();
let border_width = self.state.theme.border_width.get();
let title_height = self.state.theme.title_height.get();
@ -363,13 +387,11 @@ impl ContainerNode {
}
}
self.sum_factors.set(1.0);
self.layout_scheduled.set(false);
for child in self.children.iter() {
let body = child.body.get().move_(self.abs_x1.get(), self.abs_y1.get());
child.node.clone().change_extents(&body);
child.position_content();
}
self.schedule_render_titles();
}
fn update_content_size(&self) {
@ -393,6 +415,15 @@ impl ContainerNode {
self.content_width.set(self.width.get());
}
}
self.mono_body.set(
Rect::new_sized(
0,
title_height + 1,
self.width.get(),
self.height.get().sub(title_height + 1).max(0),
)
.unwrap(),
);
}
fn pointer_move(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, mut x: i32, mut y: i32) {
@ -482,55 +513,122 @@ impl ContainerNode {
}
fn update_title(self: &Rc<Self>) {
let split = match self.split.get() {
ContainerSplit::Horizontal => "H",
ContainerSplit::Vertical => "V",
};
let mut title = self.title.borrow_mut();
title.clear();
title.push_str(split);
title.push_str("[");
for (i, c) in self.children.iter().enumerate() {
if i > 0 {
title.push_str(", ");
if let Some(mc) = self.mono_child.get() {
title.push_str("M[");
title.push_str(mc.title.borrow_mut().deref());
title.push_str("]");
} else {
let split = match self.split.get() {
ContainerSplit::Horizontal => "H",
ContainerSplit::Vertical => "V",
};
title.push_str(split);
title.push_str("[");
for (i, c) in self.children.iter().enumerate() {
if i > 0 {
title.push_str(", ");
}
title.push_str(c.title.borrow_mut().deref());
}
title.push_str(c.title.borrow_mut().deref());
title.push_str("]");
}
title.push_str("]");
self.parent.get().child_title_changed(&**self, &title);
self.schedule_render_titles();
}
fn schedule_render_titles(self: &Rc<Self>) {
if !self.render_titles_scheduled.replace(true) {
self.state.pending_container_titles.push(self.clone());
fn schedule_compute_render_data(self: &Rc<Self>) {
if !self.compute_render_data_scheduled.replace(true) {
self.state.pending_container_render_data.push(self.clone());
}
}
fn render_titles(&self) {
self.render_titles_scheduled.set(false);
fn compute_render_data(&self) {
self.compute_render_data_scheduled.set(false);
let mut rd = self.render_data.borrow_mut();
let theme = &self.state.theme;
let th = theme.title_height.get();
let bw = theme.border_width.get();
let font = theme.font.borrow_mut();
for c in self.children.iter() {
c.title_texture.set(None);
let title = c.title.borrow_mut();
let body = c.body.get();
if title.is_empty() || th == 0 || body.width() == 0 {
continue;
}
let ctx = match self.state.render_ctx.get() {
Some(c) => c,
_ => continue,
};
let texture = match text::render(&ctx, body.width(), th, &font, &title, Color::GREY) {
Ok(t) => t,
Err(e) => {
log::error!("Could not render title {}: {}", title, ErrorFmt(e));
continue;
let cwidth = self.width.get();
let cheight = self.height.get();
let num_children = self.num_children.get() as i32;
let ctx = self.state.render_ctx.get();
rd.titles.clear();
rd.title_rects.clear();
rd.active_title_rects.clear();
rd.border_rects.clear();
rd.underline_rects.clear();
if self.mono_child.get().is_some() {
let content_width = self.width.get().sub(bw * (num_children - 1)).max(0);
let space_per_child = content_width / num_children;
let mut rem = content_width % num_children;
let mut pos = 0;
for (i, c) in self.children.iter().enumerate() {
if i > 0 {
rd.border_rects.push(Rect::new_sized(pos - bw, 0, bw, th).unwrap());
}
};
c.title_texture.set(Some(texture));
let mut width = space_per_child;
if rem > 0 {
rem -= 1;
width += 1;
}
let rect = Rect::new_sized(pos, 0, width, th).unwrap();
if c.active.get() {
rd.active_title_rects.push(rect);
} else {
rd.title_rects.push(rect);
}
if let Some(ctx) = &ctx {
let title = c.title.borrow_mut();
match text::render(&ctx, width, th, &font, &title, Color::GREY) {
Ok(t) => rd.titles.push(ContainerTitle {
x: pos,
y: 0,
tex: t,
}),
Err(e) => {
log::error!("Could not render title {}: {}", title, ErrorFmt(e));
}
}
}
pos += width + bw;
}
rd.underline_rects.push(Rect::new_sized(0, th, cwidth, 1).unwrap());
} else {
let split = self.split.get();
for (i, c) in self.children.iter().enumerate() {
let body = c.body.get();
if i > 0 {
let rect = if split == ContainerSplit::Horizontal {
Rect::new_sized(body.x1() - bw, 0, bw, cheight).unwrap()
} else {
Rect::new_sized(0, body.y1() - th - 1 - bw, cwidth, bw).unwrap()
};
rd.border_rects.push(rect);
}
let rect = Rect::new_sized(body.x1(), body.y1() - th - 1, body.width(), th).unwrap();
if c.active.get() {
rd.active_title_rects.push(rect);
} else {
rd.title_rects.push(rect);
}
let rect = Rect::new_sized(body.x1(), body.y1() - 1, body.width(), 1).unwrap();
rd.underline_rects.push(rect);
if let Some(ctx) = &ctx {
let title = c.title.borrow_mut();
match text::render(&ctx, body.width(), th, &font, &title, Color::GREY) {
Ok(t) => rd.titles.push(ContainerTitle {
x: body.x1(),
y: body.y1() - th - 1,
tex: t,
}),
Err(e) => {
log::error!("Could not render title {}: {}", title, ErrorFmt(e));
}
}
}
}
}
}
}
@ -555,11 +653,11 @@ pub async fn container_layout(state: Rc<State>) {
}
}
pub async fn container_titles(state: Rc<State>) {
pub async fn container_render_data(state: Rc<State>) {
loop {
let container = state.pending_container_titles.pop().await;
if container.render_titles_scheduled.get() {
container.render_titles();
let container = state.pending_container_render_data.pop().await;
if container.compute_render_data_scheduled.get() {
container.compute_render_data();
}
}
}
@ -617,12 +715,33 @@ impl Node for ContainerNode {
ct.push_str(title);
}
self.update_title();
self.schedule_compute_render_data();
}
fn get_mono(&self) -> Option<bool> {
Some(self.mono_child.get().is_some())
}
fn get_split(&self) -> Option<ContainerSplit> {
Some(self.split.get())
}
fn set_mono(self: Rc<Self>, child: Option<&dyn Node>) {
if self.mono_child.get().is_some() != child.is_some() {
let children = self.child_nodes.borrow_mut();
let child = match child {
Some(c) => match children.get(&c.id()) {
Some(c) => Some(c.to_ref()),
_ => return,
},
_ => None,
};
self.mono_child.set(child);
self.schedule_layout();
self.update_title();
}
}
fn set_split(self: Rc<Self>, split: ContainerSplit) {
if self.split.replace(split) != split {
self.update_content_size();
@ -636,11 +755,15 @@ impl Node for ContainerNode {
}
fn do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
let node = match direction {
Direction::Left => self.children.last(),
Direction::Down => self.children.first(),
Direction::Up => self.children.last(),
Direction::Right => self.children.first(),
let node = if let Some(cn) = self.mono_child.get() {
Some(cn)
} else {
match direction {
Direction::Left => self.children.last(),
Direction::Down => self.children.first(),
Direction::Up => self.children.last(),
Direction::Right => self.children.first(),
}
};
if let Some(node) = node {
node.node.clone().do_focus(seat, direction);
@ -671,9 +794,14 @@ impl Node for ContainerNode {
Some(c) => c.to_ref(),
_ => return,
};
let in_line = match self.split.get() {
ContainerSplit::Horizontal => matches!(direction, Direction::Left | Direction::Right),
ContainerSplit::Vertical => matches!(direction, Direction::Up | Direction::Down),
let mc = self.mono_child.get();
let in_line = if mc.is_some() {
matches!(direction, Direction::Left | Direction::Right)
} else {
match self.split.get() {
ContainerSplit::Horizontal => matches!(direction, Direction::Left | Direction::Right),
ContainerSplit::Vertical => matches!(direction, Direction::Up | Direction::Down),
}
};
if !in_line {
self.parent
@ -700,6 +828,12 @@ impl Node for ContainerNode {
return;
}
};
if mc.is_some() {
self.mono_child.set(Some(sibling.clone()));
let body = self.mono_body.get();
self.mono_content.set(sibling.content.get().at_point(body.x1(), body.y1()));
sibling.node.clone().change_extents(&body.move_(self.abs_x1.get(), self.abs_y1.get()));
}
sibling.node.clone().do_focus(seat, direction);
}
//
@ -902,9 +1036,7 @@ impl Node for ContainerNode {
body: Cell::new(node.body.get()),
content: Cell::new(node.content.get()),
factor: Cell::new(node.factor.get()),
focus: Cell::new(node.focus.get()),
title: Default::default(),
title_texture: Default::default(),
});
let body = link.body.get();
drop(node);
@ -954,15 +1086,22 @@ impl Node for ContainerNode {
let rect = Rect::new(0, 0, width, height).unwrap();
node.content.set(rect);
node.position_content();
if let Some(mono) = self.mono_child.get() {
if mono.node.id() == node.node.id() {
let body = self.mono_body.get();
self.mono_content.set(rect.at_point(body.x1(), body.y1()));
}
}
}
}
fn child_active_changed(&self, child: &dyn Node, active: bool) {
fn child_active_changed(self: Rc<Self>, child: &dyn Node, active: bool) {
let node = match self.child_nodes.borrow_mut().get(&child.id()) {
Some(l) => l.to_ref(),
None => return,
};
node.active.set(active);
self.schedule_compute_render_data();
}
fn pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
@ -1027,9 +1166,14 @@ impl Node for ContainerNode {
.get()
.child_size_changed(&*self, rect.width(), rect.height());
} else {
for child in self.children.iter() {
let body = child.body.get().move_(self.abs_x1.get(), self.abs_y1.get());
child.node.clone().change_extents(&body);
if let Some(c) = self.mono_child.get() {
let body = self.mono_body.get().move_(self.abs_x1.get(), self.abs_y1.get());
c.node.clone().change_extents(&body);
} else {
for child in self.children.iter() {
let body = child.body.get().move_(self.abs_x1.get(), self.abs_y1.get());
child.node.clone().change_extents(&body);
}
}
}
}
@ -1043,7 +1187,7 @@ impl Node for ContainerNode {
fn set_parent(self: Rc<Self>, parent: Rc<dyn Node>) {
self.parent.set(parent.clone());
parent.child_active_changed(&*self, self.active.get());
parent.clone().child_active_changed(&*self, self.active.get());
parent.child_size_changed(&*self, self.width.get(), self.height.get());
parent
.clone()

View file

@ -437,7 +437,7 @@ impl Node for FloatNode {
self.workspace_link.set(None);
}
fn child_active_changed(&self, _child: &dyn Node, active: bool) {
fn child_active_changed(self: Rc<Self>, _child: &dyn Node, active: bool) {
self.active.set(active);
}