autocommit 2022-03-24 18:27:42 CET
This commit is contained in:
parent
b3a27f889a
commit
3b1b843821
17 changed files with 388 additions and 212 deletions
|
|
@ -1,9 +1,9 @@
|
||||||
use jay_config::embedded::grab_input_device;
|
use jay_config::embedded::grab_input_device;
|
||||||
use jay_config::keyboard::mods::{Modifiers, ALT, CTRL, SHIFT};
|
use jay_config::keyboard::mods::{Modifiers, ALT, CTRL, SHIFT};
|
||||||
use jay_config::keyboard::syms::{
|
use jay_config::keyboard::syms::{
|
||||||
SYM_Super_L, SYM_b, SYM_comma, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_p, SYM_period,
|
SYM_Super_L, SYM_b, SYM_comma, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p,
|
||||||
SYM_q, SYM_r, SYM_t, SYM_v, SYM_y, SYM_F1, SYM_F10, SYM_F11, SYM_F12, SYM_F2, SYM_F3, SYM_F4,
|
SYM_period, SYM_q, SYM_r, SYM_t, SYM_v, SYM_y, SYM_F1, SYM_F10, SYM_F11, SYM_F12, SYM_F2,
|
||||||
SYM_F5, SYM_F6, SYM_F7, SYM_F8, SYM_F9,
|
SYM_F3, SYM_F4, SYM_F5, SYM_F6, SYM_F7, SYM_F8, SYM_F9,
|
||||||
};
|
};
|
||||||
use jay_config::theme::{get_title_height, set_title_color, set_title_height, Color};
|
use jay_config::theme::{get_title_height, set_title_color, set_title_height, Color};
|
||||||
use jay_config::Axis::{Horizontal, Vertical};
|
use jay_config::Axis::{Horizontal, Vertical};
|
||||||
|
|
@ -55,6 +55,10 @@ fn configure_seat(s: Seat) {
|
||||||
s.set_split(s.split().other());
|
s.set_split(s.split().other());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
s.bind(MOD | SYM_m, move || {
|
||||||
|
s.set_mono(!s.mono());
|
||||||
|
});
|
||||||
|
|
||||||
s.bind(MOD | SYM_f, move || {
|
s.bind(MOD | SYM_f, move || {
|
||||||
s.focus_parent();
|
s.focus_parent();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,17 @@ impl Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mono(&self, seat: Seat) -> bool {
|
||||||
|
let res = self.with_response(|| self.send(&ClientMessage::GetMono { seat }));
|
||||||
|
match res {
|
||||||
|
Response::GetMono { mono } => mono,
|
||||||
|
_ => {
|
||||||
|
log::error!("Server did not send a response to a get_mono request");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn split(&self, seat: Seat) -> Axis {
|
pub fn split(&self, seat: Seat) -> Axis {
|
||||||
let res = self.with_response(|| self.send(&ClientMessage::GetSplit { seat }));
|
let res = self.with_response(|| self.send(&ClientMessage::GetSplit { seat }));
|
||||||
match res {
|
match res {
|
||||||
|
|
@ -246,6 +257,10 @@ impl Client {
|
||||||
self.send(&ClientMessage::SetBorderWidth { width })
|
self.send(&ClientMessage::SetBorderWidth { width })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_mono(&self, seat: Seat, mono: bool) {
|
||||||
|
self.send(&ClientMessage::SetMono { seat, mono });
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_split(&self, seat: Seat, axis: Axis) {
|
pub fn set_split(&self, seat: Seat, axis: Axis) {
|
||||||
self.send(&ClientMessage::SetSplit { seat, axis });
|
self.send(&ClientMessage::SetSplit { seat, axis });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,13 @@ pub enum ClientMessage<'a> {
|
||||||
seat: Seat,
|
seat: Seat,
|
||||||
axis: Axis,
|
axis: Axis,
|
||||||
},
|
},
|
||||||
|
GetMono {
|
||||||
|
seat: Seat,
|
||||||
|
},
|
||||||
|
SetMono {
|
||||||
|
seat: Seat,
|
||||||
|
mono: bool,
|
||||||
|
},
|
||||||
RemoveSeat {
|
RemoveSeat {
|
||||||
seat: Seat,
|
seat: Seat,
|
||||||
},
|
},
|
||||||
|
|
@ -136,6 +143,7 @@ pub enum Response {
|
||||||
None,
|
None,
|
||||||
GetSeats { seats: Vec<Seat> },
|
GetSeats { seats: Vec<Seat> },
|
||||||
GetSplit { axis: Axis },
|
GetSplit { axis: Axis },
|
||||||
|
GetMono { mono: bool },
|
||||||
GetRepeatRate { rate: i32, delay: i32 },
|
GetRepeatRate { rate: i32, delay: i32 },
|
||||||
ParseKeymap { keymap: Keymap },
|
ParseKeymap { keymap: Keymap },
|
||||||
CreateSeat { seat: Seat },
|
CreateSeat { seat: Seat },
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,16 @@ impl Seat {
|
||||||
get!().seat_set_repeat_rate(self, rate, delay)
|
get!().seat_set_repeat_rate(self, rate, delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mono(self) -> bool {
|
||||||
|
let mut res = false;
|
||||||
|
(|| res = get!().mono(self))();
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_mono(self, mono: bool) {
|
||||||
|
get!().set_mono(self, mono)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn split(self) -> Axis {
|
pub fn split(self) -> Axis {
|
||||||
let mut res = Axis::Horizontal;
|
let mut res = Axis::Horizontal;
|
||||||
(|| res = get!().split(self))();
|
(|| res = get!().split(self))();
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,22 @@ impl ConfigProxyHandler {
|
||||||
Ok(())
|
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> {
|
fn handle_get_split(&self, seat: Seat) -> Result<(), GetSplitError> {
|
||||||
let seat = self.get_seat(seat)?;
|
let seat = self.get_seat(seat)?;
|
||||||
self.send(&ServerMessage::Response {
|
self.send(&ServerMessage::Response {
|
||||||
|
|
@ -450,6 +466,8 @@ impl ConfigProxyHandler {
|
||||||
self.handle_set_repeat_rate(seat, rate, delay)?
|
self.handle_set_repeat_rate(seat, rate, delay)?
|
||||||
}
|
}
|
||||||
ClientMessage::SetSeat { device, seat } => self.handle_set_seat(device, seat)?,
|
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::GetSplit { seat } => self.handle_get_split(seat)?,
|
||||||
ClientMessage::SetSplit { seat, axis } => self.handle_set_split(seat, axis)?,
|
ClientMessage::SetSplit { seat, axis } => self.handle_set_split(seat, axis)?,
|
||||||
ClientMessage::AddShortcut { seat, mods, sym } => {
|
ClientMessage::AddShortcut { seat, mods, sym } => {
|
||||||
|
|
@ -505,6 +523,10 @@ enum CphError {
|
||||||
FocusError(#[from] FocusError),
|
FocusError(#[from] FocusError),
|
||||||
#[error("Could not process a `move` request")]
|
#[error("Could not process a `move` request")]
|
||||||
MoveError(#[from] MoveError),
|
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")]
|
#[error("Could not process a `set_split` request")]
|
||||||
SetSplitError(#[from] SetSplitError),
|
SetSplitError(#[from] SetSplitError),
|
||||||
#[error("Could not process a `get_split` request")]
|
#[error("Could not process a `get_split` request")]
|
||||||
|
|
@ -601,6 +623,20 @@ enum MoveError {
|
||||||
}
|
}
|
||||||
efrom!(MoveError, CphError);
|
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)]
|
#[derive(Debug, Error)]
|
||||||
enum SetSplitError {
|
enum SetSplitError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
pub fn get_split(&self) -> Option<ContainerSplit> {
|
||||||
self.keyboard_node.get().get_parent_split()
|
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) {
|
pub fn set_split(&self, axis: ContainerSplit) {
|
||||||
self.keyboard_node.get().set_parent_split(axis)
|
self.keyboard_node.get().set_parent_split(axis)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
fn get_parent_split(&self) -> Option<ContainerSplit> {
|
||||||
self.xdg.get().and_then(|x| x.get_split())
|
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) {
|
fn set_parent_split(&self, split: ContainerSplit) {
|
||||||
self.xdg.get().map(|x| x.set_split(split));
|
self.xdg.get().map(|x| x.set_split(split));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,10 +83,18 @@ pub trait XdgSurfaceExt: Debug {
|
||||||
let _ = seat;
|
let _ = seat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_mono(&self) -> Option<bool> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn get_split(&self) -> Option<ContainerSplit> {
|
fn get_split(&self) -> Option<ContainerSplit> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_mono(&self, mono: bool) {
|
||||||
|
let _ = mono;
|
||||||
|
}
|
||||||
|
|
||||||
fn set_split(&self, split: ContainerSplit) {
|
fn set_split(&self, split: ContainerSplit) {
|
||||||
let _ = split;
|
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> {
|
pub fn get_split(&self) -> Option<ContainerSplit> {
|
||||||
self.ext.get().and_then(|e| e.get_split())
|
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) {
|
pub fn set_split(&self, split: ContainerSplit) {
|
||||||
self.ext.get().map(|e| e.set_split(split));
|
self.ext.get().map(|e| e.set_split(split));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@ impl XdgToplevel {
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
let extents = self.xdg.extents.get();
|
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_size_changed(self, extents.width(), extents.height());
|
||||||
parent.child_title_changed(self, self.title.borrow_mut().deref());
|
parent.child_title_changed(self, self.title.borrow_mut().deref());
|
||||||
}
|
}
|
||||||
|
|
@ -503,10 +503,23 @@ impl XdgSurfaceExt for XdgToplevel {
|
||||||
Self::toggle_floating(&self);
|
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> {
|
fn get_split(&self) -> Option<ContainerSplit> {
|
||||||
self.parent_node.get().and_then(|p| p.get_split())
|
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) {
|
fn set_split(&self, split: ContainerSplit) {
|
||||||
self.parent_node.get().map(|p| p.set_split(split));
|
self.parent_node.get().map(|p| p.set_split(split));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ use crate::render::RenderError;
|
||||||
use crate::sighand::SighandError;
|
use crate::sighand::SighandError;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use crate::tree::{
|
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::udev::Udev;
|
||||||
use crate::utils::clonecell::CloneCell;
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
|
@ -176,7 +176,7 @@ fn main_() -> Result<(), MainError> {
|
||||||
input_device_handlers: Default::default(),
|
input_device_handlers: Default::default(),
|
||||||
theme: Default::default(),
|
theme: Default::default(),
|
||||||
pending_container_layout: 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_layout: Default::default(),
|
||||||
pending_float_titles: Default::default(),
|
pending_float_titles: Default::default(),
|
||||||
dbus: Dbus::new(&engine, &run_toplevel),
|
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 _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_do_layout = engine.spawn2(Phase::Layout, container_layout(state.clone()));
|
||||||
let _container_render_titles =
|
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_do_layout = engine.spawn2(Phase::Layout, float_layout(state.clone()));
|
||||||
let _float_render_titles = engine.spawn2(Phase::PostLayout, float_titles(state.clone()));
|
let _float_render_titles = engine.spawn2(Phase::PostLayout, float_titles(state.clone()));
|
||||||
let socket_path = Acceptor::install(&state)?;
|
let socket_path = Acceptor::install(&state)?;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::render::gl::sys::{
|
||||||
};
|
};
|
||||||
use crate::render::renderer::context::RenderContext;
|
use crate::render::renderer::context::RenderContext;
|
||||||
use crate::render::renderer::renderer::Renderer;
|
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::tree::Node;
|
||||||
use crate::State;
|
use crate::State;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
@ -74,6 +74,9 @@ impl Framebuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsafe {
|
||||||
|
glFlush();
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,24 +16,11 @@ use crate::render::sys::{glDisable, glEnable, GL_BLEND};
|
||||||
use crate::render::Texture;
|
use crate::render::Texture;
|
||||||
use crate::theme::Color;
|
use crate::theme::Color;
|
||||||
use crate::tree::{
|
use crate::tree::{
|
||||||
ContainerFocus, ContainerNode, ContainerSplit, FloatNode, Node, OutputNode, WorkspaceNode,
|
ContainerNode, FloatNode, Node, OutputNode, WorkspaceNode,
|
||||||
};
|
};
|
||||||
use crate::State;
|
use crate::State;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
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 struct Renderer<'a> {
|
||||||
pub(super) ctx: &'a Rc<RenderContext>,
|
pub(super) ctx: &'a Rc<RenderContext>,
|
||||||
|
|
@ -82,16 +69,21 @@ impl Renderer<'_> {
|
||||||
2.0 * (y as f32 / self.fb.height as f32) - 1.0
|
2.0 * (y as f32 / self.fb.height as f32) - 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn fill_boxes(&self, boxes: &[Rect], color: &Color) {
|
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() {
|
if boxes.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut pos = Vec::with_capacity(boxes.len() * 12);
|
let mut pos = Vec::with_capacity(boxes.len() * 12);
|
||||||
for bx in boxes {
|
for bx in boxes {
|
||||||
let x1 = self.x_to_f(bx.x1());
|
let x1 = self.x_to_f(bx.x1() + dx);
|
||||||
let y1 = self.y_to_f(bx.y1());
|
let y1 = self.y_to_f(bx.y1() + dy);
|
||||||
let x2 = self.x_to_f(bx.x2());
|
let x2 = self.x_to_f(bx.x2() + dx);
|
||||||
let y2 = self.y_to_f(bx.y2());
|
let y2 = self.y_to_f(bx.y2() + dy);
|
||||||
pos.extend_from_slice(&[
|
pos.extend_from_slice(&[
|
||||||
// triangle 1
|
// triangle 1
|
||||||
x2, y1, // top right
|
x2, y1, // top right
|
||||||
|
|
@ -121,128 +113,35 @@ impl Renderer<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_container(&mut self, container: &ContainerNode, x: i32, y: i32) {
|
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 rd = container.render_data.borrow_mut();
|
||||||
let cwidth = container.width.get();
|
let c = self.state.theme.title_color.get();
|
||||||
let cheight = container.height.get();
|
self.fill_boxes2(&rd.title_rects, &c, x, y);
|
||||||
let num_children = container.num_children();
|
let c = self.state.theme.active_title_color.get();
|
||||||
let title_rect = Rect::new_sized(x, y, container.width.get(), title_height).unwrap();
|
self.fill_boxes2(&rd.active_title_rects, &c, x, y);
|
||||||
let underline_rect =
|
let c = self.state.theme.underline_color.get();
|
||||||
Rect::new_sized(x, y + title_height, container.width.get(), 1).unwrap();
|
self.fill_boxes2(&rd.underline_rects, &c, x, y);
|
||||||
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 c = self.state.theme.border_color.get();
|
let c = self.state.theme.border_color.get();
|
||||||
self.fill_boxes(slice::from_ref(&underline_rect), &c);
|
self.fill_boxes2(&rd.border_rects, &c, x, y);
|
||||||
for child in container.children.iter() {
|
for title in &rd.titles {
|
||||||
let focus = child.focus.get();
|
self.render_texture(&title.tex, x + title.x, y + title.y, ARGB8888);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if let Some(child) = container.mono_child.get() {
|
||||||
unsafe {
|
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();
|
let content = container.mono_content.get();
|
||||||
child.node.render(self, x + content.x1(), y + content.y1());
|
child.node.render(self, x + content.x1(), y + content.y1());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} 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() {
|
for child in container.children.iter() {
|
||||||
let body = child.body.get();
|
let body = child.body.get();
|
||||||
if body.x1() >= cwidth || body.y1() >= cheight {
|
if body.x1() >= container.width.get() || body.y1() >= container.height.get() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let body = body.move_(container.abs_x1.get(), container.abs_y1.get());
|
let body = body.move_(x, y);
|
||||||
unsafe {
|
unsafe {
|
||||||
with_scissor(&body, || {
|
with_scissor(&body, || {
|
||||||
let content = child.content.get();
|
let content = child.content.get();
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ pub struct State {
|
||||||
pub config: CloneCell<Option<Rc<ConfigProxy>>>,
|
pub config: CloneCell<Option<Rc<ConfigProxy>>>,
|
||||||
pub theme: Theme,
|
pub theme: Theme,
|
||||||
pub pending_container_layout: AsyncQueue<Rc<ContainerNode>>,
|
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_layout: AsyncQueue<Rc<FloatNode>>,
|
||||||
pub pending_float_titles: AsyncQueue<Rc<FloatNode>>,
|
pub pending_float_titles: AsyncQueue<Rc<FloatNode>>,
|
||||||
pub dbus: Dbus,
|
pub dbus: Dbus,
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,6 @@ impl Color {
|
||||||
a: to_f32(a),
|
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 {
|
impl From<jay_config::theme::Color> for Color {
|
||||||
|
|
|
||||||
18
src/tree.rs
18
src/tree.rs
|
|
@ -84,18 +84,34 @@ pub trait Node {
|
||||||
let _ = title;
|
let _ = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_parent_mono(&self) -> Option<bool> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn get_parent_split(&self) -> Option<ContainerSplit> {
|
fn get_parent_split(&self) -> Option<ContainerSplit> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_parent_mono(&self, mono: bool) {
|
||||||
|
let _ = mono;
|
||||||
|
}
|
||||||
|
|
||||||
fn set_parent_split(&self, split: ContainerSplit) {
|
fn set_parent_split(&self, split: ContainerSplit) {
|
||||||
let _ = split;
|
let _ = split;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_mono(&self) -> Option<bool> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn get_split(&self) -> Option<ContainerSplit> {
|
fn get_split(&self) -> Option<ContainerSplit> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_mono(self: Rc<Self>, child: Option<&dyn Node>) {
|
||||||
|
let _ = child;
|
||||||
|
}
|
||||||
|
|
||||||
fn set_split(self: Rc<Self>, split: ContainerSplit) {
|
fn set_split(self: Rc<Self>, split: ContainerSplit) {
|
||||||
let _ = split;
|
let _ = split;
|
||||||
}
|
}
|
||||||
|
|
@ -209,7 +225,7 @@ pub trait Node {
|
||||||
let _ = (child, width, height);
|
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);
|
let _ = (child, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,21 @@ pub enum ContainerFocus {
|
||||||
|
|
||||||
tree_id!(ContainerNodeId);
|
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 struct ContainerNode {
|
||||||
pub id: ContainerNodeId,
|
pub id: ContainerNodeId,
|
||||||
pub parent: CloneCell<Rc<dyn Node>>,
|
pub parent: CloneCell<Rc<dyn Node>>,
|
||||||
|
|
@ -71,7 +86,7 @@ pub struct ContainerNode {
|
||||||
pub content_height: Cell<i32>,
|
pub content_height: Cell<i32>,
|
||||||
pub sum_factors: Cell<f64>,
|
pub sum_factors: Cell<f64>,
|
||||||
layout_scheduled: Cell<bool>,
|
layout_scheduled: Cell<bool>,
|
||||||
render_titles_scheduled: Cell<bool>,
|
compute_render_data_scheduled: Cell<bool>,
|
||||||
num_children: NumCell<usize>,
|
num_children: NumCell<usize>,
|
||||||
pub children: LinkedList<ContainerChild>,
|
pub children: LinkedList<ContainerChild>,
|
||||||
child_nodes: RefCell<AHashMap<NodeId, LinkedNode<ContainerChild>>>,
|
child_nodes: RefCell<AHashMap<NodeId, LinkedNode<ContainerChild>>>,
|
||||||
|
|
@ -79,6 +94,7 @@ pub struct ContainerNode {
|
||||||
workspace: CloneCell<Rc<WorkspaceNode>>,
|
workspace: CloneCell<Rc<WorkspaceNode>>,
|
||||||
seats: RefCell<AHashMap<SeatId, SeatState>>,
|
seats: RefCell<AHashMap<SeatId, SeatState>>,
|
||||||
state: Rc<State>,
|
state: Rc<State>,
|
||||||
|
pub render_data: RefCell<ContainerRenderData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ContainerNode {
|
impl Debug for ContainerNode {
|
||||||
|
|
@ -94,9 +110,7 @@ pub struct ContainerChild {
|
||||||
pub body: Cell<Rect>,
|
pub body: Cell<Rect>,
|
||||||
pub content: Cell<Rect>,
|
pub content: Cell<Rect>,
|
||||||
factor: Cell<f64>,
|
factor: Cell<f64>,
|
||||||
pub focus: Cell<ContainerFocus>,
|
|
||||||
title: RefCell<String>,
|
title: RefCell<String>,
|
||||||
pub title_texture: CloneCell<Option<Rc<Texture>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SeatState {
|
struct SeatState {
|
||||||
|
|
@ -143,9 +157,7 @@ impl ContainerNode {
|
||||||
body: Cell::new(Default::default()),
|
body: Cell::new(Default::default()),
|
||||||
content: Cell::new(Default::default()),
|
content: Cell::new(Default::default()),
|
||||||
factor: Cell::new(1.0),
|
factor: Cell::new(1.0),
|
||||||
focus: Cell::new(ContainerFocus::None),
|
|
||||||
title: Default::default(),
|
title: Default::default(),
|
||||||
title_texture: Default::default(),
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
let slf = Rc::new(Self {
|
let slf = Rc::new(Self {
|
||||||
|
|
@ -165,7 +177,7 @@ impl ContainerNode {
|
||||||
content_height: Cell::new(0),
|
content_height: Cell::new(0),
|
||||||
sum_factors: Cell::new(1.0),
|
sum_factors: Cell::new(1.0),
|
||||||
layout_scheduled: Cell::new(false),
|
layout_scheduled: Cell::new(false),
|
||||||
render_titles_scheduled: Cell::new(false),
|
compute_render_data_scheduled: Cell::new(false),
|
||||||
num_children: NumCell::new(1),
|
num_children: NumCell::new(1),
|
||||||
children,
|
children,
|
||||||
child_nodes: RefCell::new(child_nodes),
|
child_nodes: RefCell::new(child_nodes),
|
||||||
|
|
@ -173,15 +185,12 @@ impl ContainerNode {
|
||||||
workspace: CloneCell::new(workspace.clone()),
|
workspace: CloneCell::new(workspace.clone()),
|
||||||
seats: RefCell::new(Default::default()),
|
seats: RefCell::new(Default::default()),
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
|
render_data: Default::default(),
|
||||||
});
|
});
|
||||||
child.set_parent(slf.clone());
|
child.set_parent(slf.clone());
|
||||||
slf
|
slf
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_children(&self) -> usize {
|
|
||||||
self.num_children.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prepend_child(self: &Rc<Self>, new: Rc<dyn Node>) {
|
pub fn prepend_child(self: &Rc<Self>, new: Rc<dyn Node>) {
|
||||||
if let Some(child) = self.children.first() {
|
if let Some(child) = self.children.first() {
|
||||||
self.add_child_before_(&child, new);
|
self.add_child_before_(&child, new);
|
||||||
|
|
@ -248,9 +257,7 @@ impl ContainerNode {
|
||||||
body: Default::default(),
|
body: Default::default(),
|
||||||
content: Default::default(),
|
content: Default::default(),
|
||||||
factor: Cell::new(0.0),
|
factor: Cell::new(0.0),
|
||||||
focus: Cell::new(ContainerFocus::None),
|
|
||||||
title: Default::default(),
|
title: Default::default(),
|
||||||
title_texture: Default::default(),
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -287,7 +294,7 @@ impl ContainerNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_colors_changed(self: &Rc<Self>) {
|
pub fn on_colors_changed(self: &Rc<Self>) {
|
||||||
self.schedule_render_titles();
|
self.schedule_compute_render_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schedule_layout(self: &Rc<Self>) {
|
fn schedule_layout(self: &Rc<Self>) {
|
||||||
|
|
@ -297,6 +304,23 @@ impl ContainerNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_layout(self: &Rc<Self>) {
|
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 sum_factors = self.sum_factors.get();
|
||||||
let border_width = self.state.theme.border_width.get();
|
let border_width = self.state.theme.border_width.get();
|
||||||
let title_height = self.state.theme.title_height.get();
|
let title_height = self.state.theme.title_height.get();
|
||||||
|
|
@ -363,13 +387,11 @@ impl ContainerNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.sum_factors.set(1.0);
|
self.sum_factors.set(1.0);
|
||||||
self.layout_scheduled.set(false);
|
|
||||||
for child in self.children.iter() {
|
for child in self.children.iter() {
|
||||||
let body = child.body.get().move_(self.abs_x1.get(), self.abs_y1.get());
|
let body = child.body.get().move_(self.abs_x1.get(), self.abs_y1.get());
|
||||||
child.node.clone().change_extents(&body);
|
child.node.clone().change_extents(&body);
|
||||||
child.position_content();
|
child.position_content();
|
||||||
}
|
}
|
||||||
self.schedule_render_titles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_content_size(&self) {
|
fn update_content_size(&self) {
|
||||||
|
|
@ -393,6 +415,15 @@ impl ContainerNode {
|
||||||
self.content_width.set(self.width.get());
|
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) {
|
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>) {
|
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();
|
let mut title = self.title.borrow_mut();
|
||||||
title.clear();
|
title.clear();
|
||||||
title.push_str(split);
|
if let Some(mc) = self.mono_child.get() {
|
||||||
title.push_str("[");
|
title.push_str("M[");
|
||||||
for (i, c) in self.children.iter().enumerate() {
|
title.push_str(mc.title.borrow_mut().deref());
|
||||||
if i > 0 {
|
title.push_str("]");
|
||||||
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.parent.get().child_title_changed(&**self, &title);
|
||||||
self.schedule_render_titles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schedule_render_titles(self: &Rc<Self>) {
|
fn schedule_compute_render_data(self: &Rc<Self>) {
|
||||||
if !self.render_titles_scheduled.replace(true) {
|
if !self.compute_render_data_scheduled.replace(true) {
|
||||||
self.state.pending_container_titles.push(self.clone());
|
self.state.pending_container_render_data.push(self.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_titles(&self) {
|
fn compute_render_data(&self) {
|
||||||
self.render_titles_scheduled.set(false);
|
self.compute_render_data_scheduled.set(false);
|
||||||
|
let mut rd = self.render_data.borrow_mut();
|
||||||
let theme = &self.state.theme;
|
let theme = &self.state.theme;
|
||||||
let th = theme.title_height.get();
|
let th = theme.title_height.get();
|
||||||
|
let bw = theme.border_width.get();
|
||||||
let font = theme.font.borrow_mut();
|
let font = theme.font.borrow_mut();
|
||||||
for c in self.children.iter() {
|
let cwidth = self.width.get();
|
||||||
c.title_texture.set(None);
|
let cheight = self.height.get();
|
||||||
let title = c.title.borrow_mut();
|
let num_children = self.num_children.get() as i32;
|
||||||
let body = c.body.get();
|
let ctx = self.state.render_ctx.get();
|
||||||
if title.is_empty() || th == 0 || body.width() == 0 {
|
rd.titles.clear();
|
||||||
continue;
|
rd.title_rects.clear();
|
||||||
}
|
rd.active_title_rects.clear();
|
||||||
let ctx = match self.state.render_ctx.get() {
|
rd.border_rects.clear();
|
||||||
Some(c) => c,
|
rd.underline_rects.clear();
|
||||||
_ => continue,
|
if self.mono_child.get().is_some() {
|
||||||
};
|
let content_width = self.width.get().sub(bw * (num_children - 1)).max(0);
|
||||||
let texture = match text::render(&ctx, body.width(), th, &font, &title, Color::GREY) {
|
let space_per_child = content_width / num_children;
|
||||||
Ok(t) => t,
|
let mut rem = content_width % num_children;
|
||||||
Err(e) => {
|
let mut pos = 0;
|
||||||
log::error!("Could not render title {}: {}", title, ErrorFmt(e));
|
for (i, c) in self.children.iter().enumerate() {
|
||||||
continue;
|
if i > 0 {
|
||||||
|
rd.border_rects.push(Rect::new_sized(pos - bw, 0, bw, th).unwrap());
|
||||||
}
|
}
|
||||||
};
|
let mut width = space_per_child;
|
||||||
c.title_texture.set(Some(texture));
|
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 {
|
loop {
|
||||||
let container = state.pending_container_titles.pop().await;
|
let container = state.pending_container_render_data.pop().await;
|
||||||
if container.render_titles_scheduled.get() {
|
if container.compute_render_data_scheduled.get() {
|
||||||
container.render_titles();
|
container.compute_render_data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -617,12 +715,33 @@ impl Node for ContainerNode {
|
||||||
ct.push_str(title);
|
ct.push_str(title);
|
||||||
}
|
}
|
||||||
self.update_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> {
|
fn get_split(&self) -> Option<ContainerSplit> {
|
||||||
Some(self.split.get())
|
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) {
|
fn set_split(self: Rc<Self>, split: ContainerSplit) {
|
||||||
if self.split.replace(split) != split {
|
if self.split.replace(split) != split {
|
||||||
self.update_content_size();
|
self.update_content_size();
|
||||||
|
|
@ -636,11 +755,15 @@ impl Node for ContainerNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
fn do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||||
let node = match direction {
|
let node = if let Some(cn) = self.mono_child.get() {
|
||||||
Direction::Left => self.children.last(),
|
Some(cn)
|
||||||
Direction::Down => self.children.first(),
|
} else {
|
||||||
Direction::Up => self.children.last(),
|
match direction {
|
||||||
Direction::Right => self.children.first(),
|
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 {
|
if let Some(node) = node {
|
||||||
node.node.clone().do_focus(seat, direction);
|
node.node.clone().do_focus(seat, direction);
|
||||||
|
|
@ -671,9 +794,14 @@ impl Node for ContainerNode {
|
||||||
Some(c) => c.to_ref(),
|
Some(c) => c.to_ref(),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
let in_line = match self.split.get() {
|
let mc = self.mono_child.get();
|
||||||
ContainerSplit::Horizontal => matches!(direction, Direction::Left | Direction::Right),
|
let in_line = if mc.is_some() {
|
||||||
ContainerSplit::Vertical => matches!(direction, Direction::Up | Direction::Down),
|
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 {
|
if !in_line {
|
||||||
self.parent
|
self.parent
|
||||||
|
|
@ -700,6 +828,12 @@ impl Node for ContainerNode {
|
||||||
return;
|
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);
|
sibling.node.clone().do_focus(seat, direction);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
@ -902,9 +1036,7 @@ impl Node for ContainerNode {
|
||||||
body: Cell::new(node.body.get()),
|
body: Cell::new(node.body.get()),
|
||||||
content: Cell::new(node.content.get()),
|
content: Cell::new(node.content.get()),
|
||||||
factor: Cell::new(node.factor.get()),
|
factor: Cell::new(node.factor.get()),
|
||||||
focus: Cell::new(node.focus.get()),
|
|
||||||
title: Default::default(),
|
title: Default::default(),
|
||||||
title_texture: Default::default(),
|
|
||||||
});
|
});
|
||||||
let body = link.body.get();
|
let body = link.body.get();
|
||||||
drop(node);
|
drop(node);
|
||||||
|
|
@ -954,15 +1086,22 @@ impl Node for ContainerNode {
|
||||||
let rect = Rect::new(0, 0, width, height).unwrap();
|
let rect = Rect::new(0, 0, width, height).unwrap();
|
||||||
node.content.set(rect);
|
node.content.set(rect);
|
||||||
node.position_content();
|
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()) {
|
let node = match self.child_nodes.borrow_mut().get(&child.id()) {
|
||||||
Some(l) => l.to_ref(),
|
Some(l) => l.to_ref(),
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
node.active.set(active);
|
node.active.set(active);
|
||||||
|
self.schedule_compute_render_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
fn pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||||
|
|
@ -1027,9 +1166,14 @@ impl Node for ContainerNode {
|
||||||
.get()
|
.get()
|
||||||
.child_size_changed(&*self, rect.width(), rect.height());
|
.child_size_changed(&*self, rect.width(), rect.height());
|
||||||
} else {
|
} else {
|
||||||
for child in self.children.iter() {
|
if let Some(c) = self.mono_child.get() {
|
||||||
let body = child.body.get().move_(self.abs_x1.get(), self.abs_y1.get());
|
let body = self.mono_body.get().move_(self.abs_x1.get(), self.abs_y1.get());
|
||||||
child.node.clone().change_extents(&body);
|
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>) {
|
fn set_parent(self: Rc<Self>, parent: Rc<dyn Node>) {
|
||||||
self.parent.set(parent.clone());
|
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.child_size_changed(&*self, self.width.get(), self.height.get());
|
||||||
parent
|
parent
|
||||||
.clone()
|
.clone()
|
||||||
|
|
|
||||||
|
|
@ -437,7 +437,7 @@ impl Node for FloatNode {
|
||||||
self.workspace_link.set(None);
|
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);
|
self.active.set(active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue