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

@ -60,6 +60,16 @@ impl CursorSurface {
pub fn update_hardware_cursor(&self) {
self.user.update_hardware_cursor();
}
pub fn needs_damage_tracking(&self) -> bool {
self.user.software_cursor()
}
pub fn surface_position(&self) -> (i32, i32) {
let (x, y) = self.user.position();
let (dx, dy) = self.hotspot.get();
(x.to_int() - dx, y.to_int() - dy)
}
}
impl Cursor for CursorSurface {

View file

@ -18,9 +18,13 @@ impl DndIcon {
}
fn update_visible(&self) {
let was_visible = self.surface.visible.get();
let is_visible =
self.surface.dnd_icons.is_not_empty() && self.surface.client.state.root_visible();
self.surface.set_visible(is_visible);
if was_visible != is_visible {
self.damage();
}
}
pub fn enable(self: &Rc<Self>) {
@ -45,6 +49,16 @@ impl DndIcon {
self.surface.extents.get().move_(x, y)
}
pub fn damage(&self) {
let (x, y) = self.seat.pointer_cursor().position_int();
self.damage_at(x, y);
}
pub fn damage_at(&self, x: i32, y: i32) {
let extents = self.extents(x, y);
self.surface.client.state.damage(extents);
}
pub fn render(&self, renderer: &mut Renderer<'_>, cursor_rect: &Rect, x: i32, y: i32) {
let extents = self.extents(x, y);
if extents.intersects(&cursor_rect) {

View file

@ -352,6 +352,9 @@ impl SurfaceExt for WlSubsurface {
if self.had_buffer.replace(has_buffer) != has_buffer {
if has_buffer {
if self.parent.visible.get() {
let (x, y) = self.surface.buffer_abs_pos.get().position();
let extents = self.surface.extents.get();
self.surface.client.state.damage(extents.move_(x, y));
self.surface.set_visible(true);
}
} else {

View file

@ -252,6 +252,7 @@ impl Xwindow {
pub fn map_status_changed(self: &Rc<Self>) {
let map_change = self.map_change();
let override_redirect = self.data.info.override_redirect.get();
match map_change {
Change::None => return,
Change::Unmap => {
@ -261,7 +262,7 @@ impl Xwindow {
.set(self.data.info.extents.take());
self.tl_destroy();
}
Change::Map if self.data.info.override_redirect.get() => {
Change::Map if override_redirect => {
self.clone()
.tl_change_extents(&self.data.info.pending_extents.get());
*self.display_link.borrow_mut() =
@ -284,12 +285,17 @@ impl Xwindow {
match map_change {
Change::Unmap => self.tl_set_visible(false),
Change::Map => {
self.tl_set_visible(true);
if override_redirect {
self.tl_set_visible(true);
}
self.toplevel_data.broadcast(self.clone());
}
Change::None => {}
}
self.data.state.tree_changed();
if override_redirect {
self.data.state.damage(self.data.info.pending_extents.get());
}
}
}
@ -414,7 +420,10 @@ impl ToplevelNodeBase for Xwindow {
// log::info!("xwin {} change_extents {:?}", self.data.window_id, rect);
let old = self.data.info.extents.replace(*rect);
if old != *rect {
if !self.data.info.override_redirect.get() {
if self.data.info.override_redirect.get() {
self.data.state.damage(old);
self.data.state.damage(*rect);
} else {
self.data
.state
.xwayland

View file

@ -167,6 +167,10 @@ pub trait XdgSurfaceExt: Debug {
fn extents_changed(&self) {
// nothing
}
fn geometry_changed(&self) {
// nothing
}
}
impl XdgSurface {
@ -258,6 +262,12 @@ impl XdgSurface {
}
}
pub fn damage(&self) {
let (x, y) = self.surface.buffer_abs_pos.get().position();
let extents = self.surface.extents.get();
self.surface.client.state.damage(extents.move_(x, y));
}
pub fn geometry(&self) -> Option<Rect> {
self.geometry.get()
}
@ -497,6 +507,9 @@ impl SurfaceExt for XdgSurface {
if prev != Some(geometry) {
self.update_extents();
self.update_surface_position();
if let Some(ext) = self.ext.get() {
ext.geometry_changed();
}
}
}
}

View file

@ -407,11 +407,13 @@ impl XdgToplevel {
}
self.toplevel_data.broadcast(self.clone());
self.tl_set_visible(self.state.root_visible());
self.xdg.damage();
}
self.extents_changed();
} else {
if self.is_mapped.replace(false) {
self.tl_set_visible(false);
self.xdg.damage();
}
}
return;
@ -677,6 +679,14 @@ impl XdgSurfaceExt for XdgToplevel {
self.toplevel_data.pos.set(self.xdg.extents.get());
self.tl_extents_changed();
}
fn geometry_changed(&self) {
self.xdg
.surface
.client
.state
.damage(self.node_absolute_position());
}
}
#[derive(Debug, Error)]

View file

@ -588,6 +588,11 @@ impl SurfaceExt for ZwlrLayerSurfaceV1 {
}
if self.mapped.get() != was_mapped {
output.update_visible();
if self.mapped.get() {
let (x, y) = self.surface.buffer_abs_pos.get().position();
let extents = self.surface.extents.get().move_(x, y);
self.client.state.damage(extents);
}
}
if self.mapped.get() {
match self.keyboard_interactivity.get() {

View file

@ -44,17 +44,24 @@ pub async fn input_popup_positioning(state: Rc<State>) {
}
impl ZwpInputPopupSurfaceV2 {
fn damage(&self) {
let (x, y) = self.surface.buffer_abs_pos.get().position();
let extents = self.surface.extents.get();
self.client.state.damage(extents.move_(x, y));
}
pub fn update_visible(self: &Rc<Self>) {
let was_visible = self.surface.visible.get();
let is_visible = self.surface.buffer.is_some()
&& self.input_method.connection.is_some()
&& self.client.state.root_visible();
self.surface.set_visible(is_visible);
if was_visible || is_visible {
self.client.state.damage();
}
if !was_visible && is_visible {
self.schedule_positioning();
if was_visible != is_visible {
if is_visible {
self.schedule_positioning();
} else {
self.damage();
}
}
}
@ -132,6 +139,9 @@ impl ZwpInputPopupSurfaceV2 {
}
fn detach(&self) {
if self.surface.visible.get() {
self.damage();
}
self.surface.destroy_node();
self.surface.unset_ext();
self.input_method.popups.remove(&self.id);