all: implement damage tracking
This commit is contained in:
parent
76a3c50560
commit
bb66abb817
28 changed files with 473 additions and 82 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue