1
0
Fork 0
forked from wry/wry

all: implement damage tracking

This commit is contained in:
Julian Orth 2024-07-10 19:58:17 +02:00
parent 76a3c50560
commit bb66abb817
28 changed files with 473 additions and 82 deletions

View file

@ -355,9 +355,24 @@ impl ContainerNode {
self.schedule_compute_render_data();
}
fn damage(&self) {
self.state.damage(
Rect::new_sized(
self.abs_x1.get(),
self.abs_y1.get(),
self.width.get(),
self.height.get(),
)
.unwrap(),
);
}
fn schedule_layout(self: &Rc<Self>) {
if !self.layout_scheduled.replace(true) {
self.state.pending_container_layout.push(self.clone());
if self.toplevel_data.visible.get() {
self.damage();
}
}
}
@ -677,8 +692,13 @@ impl ContainerNode {
let split = self.split.get();
let have_active = self.children.iter().any(|c| c.active.get());
let scales = self.state.scales.lock();
let abs_x = self.abs_x1.get();
let abs_y = self.abs_y1.get();
for (i, child) in self.children.iter().enumerate() {
let rect = child.title_rect.get();
if self.toplevel_data.visible.get() {
self.state.damage(rect.move_(abs_x, abs_y));
}
if i > 0 {
let rect = if mono {
Rect::new_sized(rect.x1() - bw, 0, bw, th)
@ -1471,6 +1491,7 @@ impl ContainingNode for ContainerNode {
if let Some(body) = body {
let body = body.move_(self.abs_x1.get(), self.abs_y1.get());
new.clone().tl_change_extents(&body);
self.state.damage(body);
}
}

View file

@ -79,6 +79,9 @@ impl DisplayNode {
for seat in state.globals.seats.lock().values() {
seat.set_visible(visible);
}
if visible {
state.damage(self.extents.get());
}
}
}

View file

@ -135,6 +135,9 @@ impl FloatNode {
child.tl_set_visible(floater.visible.get());
child.tl_restack_popups();
floater.schedule_layout();
if floater.visible.get() {
state.damage(position);
}
floater
}
@ -199,11 +202,12 @@ impl FloatNode {
_ => return,
};
let scales = self.state.scales.lock();
let tr = Rect::new_sized(pos.x1() + bw, pos.y1() + bw, pos.width() - 2 * bw, th).unwrap();
for (scale, _) in scales.iter() {
let old_tex = self.title_textures.remove(scale);
let mut th = th;
let mut th = tr.height();
let mut scalef = None;
let mut width = pos.width() - 2 * bw;
let mut width = tr.width();
if *scale != 1 {
let scale = scale.to_f64();
th = (th as f64 * scale).round() as _;
@ -222,6 +226,9 @@ impl FloatNode {
};
self.title_textures.set(*scale, texture);
}
if self.visible.get() {
self.state.damage(tr);
}
}
fn pointer_move(
@ -307,8 +314,12 @@ impl FloatNode {
y2 = y2.max(y1 + 2 * bw + th + 1);
}
}
self.position.set(Rect::new(x1, y1, x2, y2).unwrap());
self.state.damage();
let new_pos = Rect::new(x1, y1, x2, y2).unwrap();
self.position.set(new_pos);
if self.visible.get() {
self.state.damage(pos);
self.state.damage(new_pos);
}
self.schedule_layout();
return;
}
@ -684,6 +695,9 @@ impl ContainingNode for FloatNode {
self.pull_child_properties();
new.tl_set_visible(self.visible.get());
self.schedule_layout();
if self.visible.get() {
self.state.damage(self.position.get());
}
}
fn cnode_remove_child2(self: Rc<Self>, _child: &dyn Node, _preserve_focus: bool) {
@ -691,6 +705,9 @@ impl ContainingNode for FloatNode {
self.child.set(None);
self.display_link.borrow_mut().take();
self.workspace_link.set(None);
if self.visible.get() {
self.state.damage(self.position.get());
}
}
fn cnode_accepts_child(&self, _node: &dyn Node) -> bool {
@ -716,8 +733,10 @@ impl ContainingNode for FloatNode {
let (x, y) = (x - bw, y - th - bw - 1);
let pos = self.position.get();
if pos.position() != (x, y) {
self.position.set(pos.at_point(x, y));
self.state.damage();
let new_pos = pos.at_point(x, y);
self.position.set(new_pos);
self.state.damage(pos);
self.state.damage(new_pos);
self.schedule_layout();
}
}
@ -753,7 +772,10 @@ impl ContainingNode for FloatNode {
let new_pos = Rect::new(x1, y1, x2, y2).unwrap();
if new_pos != pos {
self.position.set(new_pos);
self.state.damage();
if self.visible.get() {
self.state.damage(pos);
self.state.damage(new_pos);
}
self.schedule_layout();
}
}

View file

@ -76,6 +76,7 @@ pub struct OutputNode {
pub update_render_data_scheduled: Cell<bool>,
pub screencasts: CopyHashMap<(ClientId, JayScreencastId), Rc<JayScreencast>>,
pub screencopies: CopyHashMap<(ClientId, ZwlrScreencopyFrameV1Id), Rc<ZwlrScreencopyFrameV1>>,
pub title_visible: Cell<bool>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
@ -114,6 +115,9 @@ impl OutputNode {
if let Some(c) = self.workspace.get() {
c.change_extents(&self.workspace_rect.get());
}
if self.node_visible() {
self.state.damage(self.global.pos.get());
}
}
}
@ -307,7 +311,8 @@ impl OutputNode {
texture_height = (th as f64 * scale).round() as _;
}
let active_id = self.workspace.get().map(|w| w.id);
let output_width = self.non_exclusive_rect.get().width();
let non_exclusive_rect = self.non_exclusive_rect.get();
let output_width = non_exclusive_rect.width();
rd.underline = Rect::new_sized(0, th, output_width, 1).unwrap();
for ws in self.workspaces.iter() {
let old_tex = ws.title_texture.take();
@ -414,7 +419,16 @@ impl OutputNode {
tex: title,
});
}
self.state.damage();
if self.title_visible.get() {
let title_rect = Rect::new_sized(
non_exclusive_rect.x1(),
non_exclusive_rect.y1(),
non_exclusive_rect.width(),
th,
)
.unwrap();
self.state.damage(title_rect);
}
}
pub fn ensure_workspace(self: &Rc<Self>) -> Rc<WorkspaceNode> {
@ -460,12 +474,16 @@ impl OutputNode {
for seat in seats {
ws.clone().node_do_focus(&seat, Direction::Unspecified);
}
if self.node_visible() {
self.state.damage(self.global.pos.get());
}
true
}
pub fn create_workspace(self: &Rc<Self>, name: &str) -> Rc<WorkspaceNode> {
let ws = Rc::new(WorkspaceNode {
id: self.state.node_ids.next(),
state: self.state.clone(),
is_dummy: false,
output: CloneCell::new(self.clone()),
position: Cell::new(Default::default()),
@ -582,6 +600,11 @@ impl OutputNode {
}
fn change_extents_(self: &Rc<Self>, rect: &Rect) {
if self.node_visible() {
let old_pos = self.global.pos.get();
self.state.damage(old_pos);
self.state.damage(*rect);
}
self.global.persistent.pos.set((rect.x1(), rect.y1()));
self.global.pos.set(*rect);
self.state.root.update_extents();
@ -702,6 +725,13 @@ impl OutputNode {
prev
}
pub fn fullscreen_changed(&self) {
self.update_visible();
if self.node_visible() {
self.state.damage(self.global.pos.get());
}
}
pub fn update_visible(&self) {
let mut visible = self.state.root_visible();
if self.state.lock.locked.get() {
@ -722,6 +752,7 @@ impl OutputNode {
have_fullscreen = ws.fullscreen.is_some();
}
let lower_visible = visible && !have_fullscreen;
self.title_visible.set(lower_visible);
set_layer_visible!(self.layers[0], lower_visible);
set_layer_visible!(self.layers[1], lower_visible);
if let Some(ws) = self.workspace.get() {
@ -822,7 +853,7 @@ impl Node for OutputNode {
}
fn node_visible(&self) -> bool {
true
self.state.root_visible()
}
fn node_absolute_position(&self) -> Rect {

View file

@ -435,7 +435,6 @@ impl ToplevelData {
.tl_into_node()
.node_do_focus(&seat, Direction::Unspecified);
}
state.damage();
}
pub fn unset_fullscreen(&self, state: &Rc<State>, node: Rc<dyn ToplevelNode>) {
@ -480,7 +479,6 @@ impl ToplevelData {
fd.placeholder
.node_seat_state()
.destroy_node(fd.placeholder.deref());
state.damage();
}
pub fn set_visible(&self, node: &dyn Node, visible: bool) {
@ -496,7 +494,6 @@ impl ToplevelData {
if let Some(parent) = self.parent.get() {
parent.cnode_child_attention_request_changed(node, false);
}
self.state.damage();
}
pub fn request_attention(&self, node: &dyn Node) {
@ -510,6 +507,5 @@ impl ToplevelData {
if let Some(parent) = self.parent.get() {
parent.cnode_child_attention_request_changed(node, true);
}
self.state.damage();
}
}

View file

@ -11,6 +11,7 @@ use {
},
rect::Rect,
renderer::Renderer,
state::State,
text::TextTexture,
tree::{
container::ContainerNode, walker::NodeVisitor, ContainingNode, Direction,
@ -38,6 +39,7 @@ tree_id!(WorkspaceNodeId);
pub struct WorkspaceNode {
pub id: WorkspaceNodeId,
pub state: Rc<State>,
pub is_dummy: bool,
pub output: CloneCell<Rc<OutputNode>>,
pub position: Cell<Rect>,
@ -85,6 +87,7 @@ impl WorkspaceNode {
}
if self.has_capture.replace(has_capture) != has_capture {
output.schedule_update_render_data();
output.state.damage(output.global.pos.get());
}
}
@ -117,6 +120,7 @@ impl WorkspaceNode {
container.tl_set_parent(self.clone());
container.tl_set_visible(self.container_visible());
self.container.set(Some(container.clone()));
self.state.damage(self.position.get());
}
pub fn is_empty(&self) -> bool {
@ -168,7 +172,7 @@ impl WorkspaceNode {
}
self.pull_child_properties(&**node);
if self.visible.get() {
self.output.get().update_visible();
self.output.get().fullscreen_changed();
} else {
node.tl_set_visible(false);
}
@ -183,7 +187,7 @@ impl WorkspaceNode {
if let Some(node) = self.fullscreen.take() {
self.discard_child_properties(&*node);
if self.visible.get() {
self.output.get().update_visible();
self.output.get().fullscreen_changed();
}
if let Some(surface) = node.tl_scanout_surface() {
if let Some(fb) = surface.client.state.drm_feedback.get() {
@ -324,6 +328,7 @@ impl ContainingNode for WorkspaceNode {
if container.node_id() == child.node_id() {
self.discard_child_properties(&*container);
self.container.set(None);
self.state.damage(self.position.get());
return;
}
}
@ -387,4 +392,10 @@ pub fn move_ws_to_output(
if !source.is_dummy {
source.schedule_update_render_data();
}
if source.node_visible() {
target.state.damage(source.global.pos.get());
}
if target.node_visible() {
target.state.damage(target.global.pos.get());
}
}