nitpicker: fix stale pixels on view removal

Sometimes when removing the popup window in Sculpt's Leitzentrale, a few
residual pixels remained. This is caused by the too strict coupling of
drawing and sync handling, effectively executing the fb-sync handler
repeatedly via 'Main::mark_as_damaged' during 'refresh_view' calls.
This tight coupling has two unwelcome effects. First, the sync handling
is executed more often than needed. Second, the sync handling (and fb
flushing) happens at intermediate states when view-stack changes are
applied (like changing a view geometry).

This patch uses a local signal handler to defer the execution of the
sync code until all drawing has finished.

Issue #5347
Issue #5356
This commit is contained in:
Norman Feske 2024-10-21 18:46:06 +02:00 committed by Christian Helmuth
parent 5f4e1db576
commit 2d7cd1c736
2 changed files with 23 additions and 1 deletions

View File

@ -165,9 +165,10 @@ class Nitpicker::Capture_session : public Session_object<Capture::Session>
void mark_as_damaged(Rect rect) void mark_as_damaged(Rect rect)
{ {
_dirty_rect.mark_as_dirty(rect); _dirty_rect.mark_as_dirty(rect);
_wakeup_if_needed();
} }
void process_damage() { _wakeup_if_needed(); }
void screen_size_changed() void screen_size_changed()
{ {
if (_screen_size_sigh.valid()) if (_screen_size_sigh.valid())

View File

@ -348,6 +348,12 @@ class Nitpicker::Capture_root : public Root_component<Capture_session>
session.mark_as_damaged(rect); }); session.mark_as_damaged(rect); });
} }
void process_damage()
{
_sessions.for_each([&] (Capture_session &session) {
session.process_damage(); });
}
void report_displays(Xml_generator &xml, Rect const domain_panorama) const void report_displays(Xml_generator &xml, Rect const domain_panorama) const
{ {
gen_attr(xml, domain_panorama); gen_attr(xml, domain_panorama);
@ -524,7 +530,10 @@ struct Nitpicker::Main : Focus_updater, Hover_updater,
void mark_as_dirty(Rect rect) void mark_as_dirty(Rect rect)
{ {
_dirty_rect.mark_as_dirty(rect); _dirty_rect.mark_as_dirty(rect);
}
void process_damage()
{
if (_main._now().ms - _previous_sync.ms > 40) if (_main._now().ms - _previous_sync.ms > 40)
_handle_sync(); _handle_sync();
} }
@ -641,6 +650,16 @@ struct Nitpicker::Main : Focus_updater, Hover_updater,
} }
} }
Signal_handler<Main> _damage_handler { _env.ep(), *this, &Main::_handle_damage };
void _handle_damage()
{
if (_fb_screen.constructed())
_fb_screen->process_damage();
_capture_root.process_damage();
}
/** /**
* View_stack::Damage interface * View_stack::Damage interface
*/ */
@ -650,6 +669,8 @@ struct Nitpicker::Main : Focus_updater, Hover_updater,
_fb_screen->mark_as_dirty(rect); _fb_screen->mark_as_dirty(rect);
_capture_root.mark_as_damaged(rect); _capture_root.mark_as_damaged(rect);
_damage_handler.local_submit();
} }
void _update_input_connection() void _update_input_connection()