mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-22 01:53:00 +00:00
window layouter: fix glitch after window resize
This patch improves the transition from an interactive window geometry change (dragging a window element) to the point where the resulting new layout rules come into effect. During this short time, no resize request must be issued because such a resize request would be based on stale rules. Fixes #3227
This commit is contained in:
parent
baf46db287
commit
d75c5f6722
@ -4,3 +4,4 @@ input_session
|
||||
report_session
|
||||
nitpicker_session
|
||||
framebuffer_session
|
||||
timer_session
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <input_session/client.h>
|
||||
#include <input/event.h>
|
||||
#include <input/keycodes.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include <window_list.h>
|
||||
@ -45,6 +46,13 @@ struct Window_layouter::Main : Operations,
|
||||
Signal_handler<Main> _config_handler {
|
||||
_env.ep(), *this, &Main::_handle_config };
|
||||
|
||||
Timer::Connection _drop_timer { _env };
|
||||
|
||||
bool _defer_layout_change = false;
|
||||
|
||||
Signal_handler<Main> _drop_timer_handler {
|
||||
_env.ep(), *this, &Main::_handle_drop_timer };
|
||||
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
Area _screen_size { };
|
||||
@ -126,7 +134,24 @@ struct Window_layouter::Main : Operations,
|
||||
/**
|
||||
* Layout_rules::Change_handler interface
|
||||
*/
|
||||
void layout_rules_changed() override { _update_window_layout(); }
|
||||
void layout_rules_changed() override
|
||||
{
|
||||
/*
|
||||
* When re-importing rules generated by the drop operation, issue an
|
||||
* updated resize request immediately instead of waiting for the
|
||||
* '_drop_timer_handler'. Clear '_defer_layout_change' before calling
|
||||
* '_update_window_layout' because '_gen_window_layout' evaluates
|
||||
* this flag.
|
||||
*/
|
||||
bool const issue_resize_request = _defer_layout_change;
|
||||
|
||||
_defer_layout_change = false;
|
||||
|
||||
_update_window_layout();
|
||||
|
||||
if (issue_resize_request)
|
||||
_gen_resize_request();
|
||||
}
|
||||
|
||||
/**
|
||||
* Window_list::Change_handler interface
|
||||
@ -216,6 +241,12 @@ struct Window_layouter::Main : Operations,
|
||||
_gen_resize_request();
|
||||
}
|
||||
|
||||
void _handle_drop_timer()
|
||||
{
|
||||
/* discharge '_defer_layout_change' */
|
||||
layout_rules_changed();
|
||||
}
|
||||
|
||||
void finalize_drag(Window_id id, Window::Element, Point, Point) override
|
||||
{
|
||||
/*
|
||||
@ -229,10 +260,15 @@ struct Window_layouter::Main : Operations,
|
||||
_window_list.with_window(id, [&] (Window &window) {
|
||||
window.finalize_drag_operation(); });
|
||||
|
||||
_gen_resize_request();
|
||||
/*
|
||||
* Mask the generation of resize requests until the updated rules are
|
||||
* imported the next time. Discharge the masking after a timeout for
|
||||
* the case where rules fixed and not fed back to the layouter.
|
||||
*/
|
||||
_defer_layout_change = true;
|
||||
_drop_timer.trigger_once(250*1000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Install handler for responding to hover changes
|
||||
*/
|
||||
@ -340,6 +376,8 @@ struct Window_layouter::Main : Operations,
|
||||
_nitpicker.mode_sigh(_mode_change_handler);
|
||||
_handle_mode_change();
|
||||
|
||||
_drop_timer.sigh(_drop_timer_handler);
|
||||
|
||||
_hover.sigh(_hover_handler);
|
||||
_decorator_margins_rom.sigh(_decorator_margins_handler);
|
||||
_input.sigh(_input_handler);
|
||||
@ -360,6 +398,9 @@ struct Window_layouter::Main : Operations,
|
||||
|
||||
void Window_layouter::Main::_gen_window_layout()
|
||||
{
|
||||
if (_defer_layout_change)
|
||||
return;
|
||||
|
||||
/* update hover and focus state of each window */
|
||||
_window_list.for_each_window([&] (Window &window) {
|
||||
|
||||
@ -377,6 +418,9 @@ void Window_layouter::Main::_gen_window_layout()
|
||||
|
||||
void Window_layouter::Main::_gen_resize_request()
|
||||
{
|
||||
if (_defer_layout_change)
|
||||
return;
|
||||
|
||||
bool resize_needed = false;
|
||||
_window_list.for_each_window([&] (Window const &window) {
|
||||
if (window.resize_request_needed())
|
||||
|
Loading…
x
Reference in New Issue
Block a user