Skip to content

Commit

Permalink
all: implement damage tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
mahkoh committed Jul 11, 2024
1 parent b654c5f commit 5a4803a
Show file tree
Hide file tree
Showing 26 changed files with 465 additions and 82 deletions.
1 change: 0 additions & 1 deletion docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,5 @@ Jay supports the following wayland protocols:

The following features are currently not supported but might get implemented in the future:

- Fine-grained damage tracking.
- Touch support.
- Tearing updates of fullscreen games.
2 changes: 2 additions & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Add fine-grained damage tracking.

# 1.4.0 (2024-07-07)

- Add window management mode.
Expand Down
2 changes: 2 additions & 0 deletions src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,11 @@ fn create_dummy_output(state: &Rc<State>) {
screencasts: Default::default(),
hardware_cursor_needs_render: Cell::new(false),
screencopies: Default::default(),
title_visible: Cell::new(false),
});
let dummy_workspace = Rc::new(WorkspaceNode {
id: state.node_ids.next(),
state: state.clone(),
is_dummy: true,
output: CloneCell::new(dummy_output.clone()),
position: Default::default(),
Expand Down
7 changes: 2 additions & 5 deletions src/config/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,6 @@ impl ConfigProxyHandler {
if let Some(ws) = self.state.workspaces.get(name.as_str()) {
ws.may_capture.set(capture);
ws.update_has_captures();
ws.output.get().schedule_update_render_data();
self.state.damage();
}
Ok(())
}
Expand Down Expand Up @@ -863,7 +861,6 @@ impl ConfigProxyHandler {
move_ws_to_output(&link, &output, config);
ws.desired_output.set(output.global.output_id.clone());
self.state.tree_changed();
self.state.damage();
Ok(())
}

Expand Down Expand Up @@ -1032,7 +1029,6 @@ impl ConfigProxyHandler {
let scale = Scale::from_f64(scale);
let connector = self.get_output_node(connector)?;
connector.set_preferred_scale(scale);
self.state.damage();
Ok(())
}

Expand All @@ -1043,7 +1039,6 @@ impl ConfigProxyHandler {
) -> Result<(), CphError> {
let connector = self.get_output_node(connector)?;
connector.update_transform(transform);
self.state.damage();
Ok(())
}

Expand Down Expand Up @@ -1371,6 +1366,7 @@ impl ConfigProxyHandler {
}
}
self.state.root.clone().node_visit(&mut V);
self.state.damage(self.state.root.extents.get());
}

fn colors_changed(&self) {
Expand All @@ -1386,6 +1382,7 @@ impl ConfigProxyHandler {
}
}
self.state.root.clone().node_visit(&mut V);
self.state.damage(self.state.root.extents.get());
}

fn get_sized(&self, sized: Resizable) -> Result<ThemeSized, CphError> {
Expand Down
49 changes: 44 additions & 5 deletions src/cursor_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use {
cursor::{Cursor, KnownCursor, DEFAULT_CURSOR_SIZE},
fixed::Fixed,
rect::Rect,
scale::Scale,
state::State,
tree::OutputNode,
utils::{
Expand Down Expand Up @@ -74,13 +75,26 @@ impl CursorUserGroup {
group
}

fn damage_active(&self) {
if let Some(active) = self.active.get() {
if let Some(cursor) = active.cursor.get() {
let (x, y) = active.pos.get();
let x_int = x.round_down();
let y_int = y.round_down();
let extents = cursor.extents_at_scale(Scale::default());
self.state.damage(extents.move_(x_int, y_int));
}
}
}

pub fn deactivate(&self) {
if self.hardware_cursor.get() {
self.remove_hardware_cursor();
} else {
self.damage_active();
}
self.active_id.take();
self.active.take();
self.state.damage();
}

pub fn latest_output(&self) -> Rc<OutputNode> {
Expand Down Expand Up @@ -150,13 +164,15 @@ impl CursorUserGroup {
if self.hardware_cursor.replace(hardware_cursor) == hardware_cursor {
return;
}
self.damage_active();
if hardware_cursor {
let prev = self
.state
.cursor_user_group_hardware_cursor
.set(Some(self.clone()));
if let Some(prev) = prev {
prev.hardware_cursor.set(false);
prev.damage_active();
}
match self.active.get() {
None => self.remove_hardware_cursor(),
Expand Down Expand Up @@ -230,20 +246,23 @@ impl CursorUser {
self.owner.take();
self.group.users.remove(&self.id);
if self.group.active_id.get() == Some(self.id) {
self.group.active_id.take();
self.group.active.take();
self.group.state.damage();
self.group.deactivate();
}
}

pub fn activate(self: &Rc<Self>) {
if self.group.active_id.replace(Some(self.id)) == Some(self.id) {
return;
}
if self.software_cursor() {
self.group.damage_active();
}
self.group.latest_output.set(self.output.get());
self.group.active.set(Some(self.clone()));
self.update_hardware_cursor();
self.group.state.damage();
if self.software_cursor() {
self.group.damage_active();
}
}

#[cfg_attr(not(feature = "it"), allow(dead_code))]
Expand Down Expand Up @@ -341,13 +360,19 @@ impl CursorUser {
}
}
old.handle_unset();
if self.software_cursor() {
self.group.damage_active();
}
}
if let Some(cursor) = cursor.as_ref() {
cursor.clone().handle_set();
cursor.set_output(&self.output.get());
}
self.cursor.set(cursor.clone());
self.update_hardware_cursor();
if self.software_cursor() {
self.group.damage_active();
}
}

pub fn position(&self) -> (Fixed, Fixed) {
Expand All @@ -368,6 +393,16 @@ impl CursorUser {
x = x.apply_fract(x_tmp);
y = y.apply_fract(y_tmp);
}
if self.software_cursor() {
if let Some(cursor) = self.cursor.get() {
let (old_x, old_y) = self.pos.get();
let old_x_int = old_x.round_down();
let old_y_int = old_y.round_down();
let extents = cursor.extents_at_scale(Scale::default());
self.group.state.damage(extents.move_(old_x_int, old_y_int));
self.group.state.damage(extents.move_(x_int, y_int));
}
}
self.pos.set((x, y));
self.update_hardware_cursor_(false);
(x, y)
Expand All @@ -381,6 +416,10 @@ impl CursorUser {
self.is_active() && self.group.hardware_cursor.get()
}

pub fn software_cursor(&self) -> bool {
self.is_active() && !self.group.hardware_cursor.get()
}

fn update_hardware_cursor_(&self, render: bool) {
if !self.hardware_cursor() {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/ifs/ext_session_lock_manager_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl ExtSessionLockManagerV1RequestHandler for ExtSessionLockManagerV1 {
state.lock.locked.set(true);
state.lock.lock.set(Some(new.clone()));
state.tree_changed();
state.damage();
state.damage(state.root.extents.get());
new.send_locked();
} else {
new.finish();
Expand Down
24 changes: 14 additions & 10 deletions src/ifs/jay_screencast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,6 @@ impl JayScreencast {
Target::Toplevel(tl) => {
let data = tl.tl_data();
data.jay_screencasts.remove(&(self.client.id, self.id));
if data.jay_screencasts.is_empty() {
self.client.state.damage();
}
}
}
}
Expand Down Expand Up @@ -418,10 +415,16 @@ impl JayScreencast {

fn damage(&self) {
if let Some(target) = self.target.get() {
match target {
Target::Output(o) => o.global.connector.connector.damage(),
Target::Toplevel(_) => self.client.state.damage(),
}
let rect = match target {
Target::Output(o) => o.global.pos.get(),
Target::Toplevel(t) => {
if !t.node_visible() {
return;
}
t.node_absolute_position()
}
};
self.client.state.damage(rect);
}
}
}
Expand Down Expand Up @@ -535,9 +538,6 @@ impl JayScreencastRequestHandler for JayScreencast {
}
let t = t.toplevel.clone();
let data = t.tl_data();
if data.jay_screencasts.is_empty() {
data.state.damage();
}
data.jay_screencasts
.set((self.client.id, self.id), slf.clone());
new_target = Some(Target::Toplevel(t));
Expand Down Expand Up @@ -577,6 +577,10 @@ impl JayScreencastRequestHandler for JayScreencast {
}
}

if self.running.get() {
self.damage();
}

Ok(())
}

Expand Down
1 change: 0 additions & 1 deletion src/ifs/wl_seat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,6 @@ impl WlSeatGlobal {
if let Some(parent) = tl.tl_data().parent.get() {
if let Some(tl) = parent.node_toplevel() {
self.focus_node(tl.tl_into_node());
self.state.damage();
}
}
}
Expand Down
13 changes: 10 additions & 3 deletions src/ifs/wl_seat/event_handling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,18 @@ impl WlSeatGlobal {
}

fn set_pointer_cursor_position(&self, x: Fixed, y: Fixed) -> (Fixed, Fixed) {
let dnd_icon = self.pointer_owner.dnd_icon();
if let Some(dnd_icon) = &dnd_icon {
let (x_old, y_old) = self.pointer_cursor.position_int();
dnd_icon.damage_at(x_old, y_old);
}
let (x, y) = self.pointer_cursor.set_position(x, y);
let x_int = x.round_down();
let y_int = y.round_down();
if let Some(dnd_icon) = &dnd_icon {
dnd_icon.damage_at(x_int, y_int);
}
if let Some(td) = self.pointer_owner.toplevel_drag() {
let x_int = x.round_down();
let y_int = y.round_down();
td.move_(x_int, y_int);
}
(x, y)
Expand Down Expand Up @@ -894,7 +902,6 @@ impl WlSeatGlobal {
}

pub(super) fn apply_changes(self: &Rc<Self>) {
self.state.damage();
self.pointer_owner.apply_changes(self);
if self.changes.get().contains(CHANGE_TREE) {
self.tablet_apply_changes();
Expand Down
21 changes: 6 additions & 15 deletions src/ifs/wl_seat/pointer_owner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ impl<T: SimplePointerOwnerUsecase> PointerOwner for SimplePointerOwner<T> {
if !T::IS_DEFAULT {
seat.pointer_owner.set_default_pointer_owner(seat);
seat.trigger_tree_changed();
seat.state.damage();
}
}

Expand Down Expand Up @@ -763,21 +762,17 @@ impl<S: ToplevelSelector> NodeSelectorUsecase for SelectToplevelUsecase<S> {
}

fn node_focus(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, node: &Rc<dyn Node>) {
let mut damage = false;
let tl = node.clone().node_into_toplevel();
if let Some(tl) = &tl {
tl.tl_data().render_highlight.fetch_add(1);
if !tl.tl_admits_children() {
seat.pointer_cursor().set_known(KnownCursor::Pointer);
}
damage = true;
seat.state.damage(tl.node_absolute_position());
}
if let Some(prev) = self.latest.set(tl) {
prev.tl_data().render_highlight.fetch_sub(1);
damage = true;
}
if damage {
seat.state.damage();
seat.state.damage(prev.node_absolute_position());
}
}
}
Expand All @@ -787,7 +782,7 @@ impl<S: ?Sized> Drop for SelectToplevelUsecase<S> {
if let Some(prev) = self.latest.take() {
prev.tl_data().render_highlight.fetch_sub(1);
if let Some(seat) = self.seat.upgrade() {
seat.state.damage();
seat.state.damage(prev.node_absolute_position());
}
}
}
Expand All @@ -812,19 +807,15 @@ impl<S: WorkspaceSelector> NodeSelectorUsecase for SelectWorkspaceUsecase<S> {
}

fn node_focus(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, node: &Rc<dyn Node>) {
let mut damage = false;
let ws = node.clone().node_into_workspace();
if let Some(ws) = &ws {
ws.render_highlight.fetch_add(1);
seat.pointer_cursor().set_known(KnownCursor::Pointer);
damage = true;
seat.state.damage(ws.position.get());
}
if let Some(prev) = self.latest.set(ws) {
prev.render_highlight.fetch_sub(1);
damage = true;
}
if damage {
seat.state.damage();
seat.state.damage(prev.position.get());
}
}
}
Expand All @@ -834,7 +825,7 @@ impl<S: ?Sized> Drop for SelectWorkspaceUsecase<S> {
if let Some(prev) = self.latest.take() {
prev.render_highlight.fetch_sub(1);
if let Some(seat) = self.seat.upgrade() {
seat.state.damage();
seat.state.damage(prev.position.get());
}
}
}
Expand Down
Loading

0 comments on commit 5a4803a

Please sign in to comment.