mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 13:26:27 +00:00
decorator: use timer for animation timing
This patch changes the precision of the configuration's motion attribute to a multiple of 10 ms (centi-seconds). The previous version used steps of 20 ms. Hence, one needs to adjust existing configurations by doubling the motion attribute values of the themed decorator. Issue #5347
This commit is contained in:
parent
58d20c7751
commit
e69ade5299
@ -178,15 +178,15 @@
|
||||
</dir>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
</vfs>
|
||||
<policy label="log" decoration="yes" motion="20"/>
|
||||
<policy label="runtime -> leitzentrale -> settings_dialog" decoration="no" motion="20"/>
|
||||
<policy label="runtime -> leitzentrale -> system_dialog" decoration="no" motion="20"/>
|
||||
<policy label="runtime -> leitzentrale -> file_browser_dialog" decoration="no" motion="30"/>
|
||||
<policy label="runtime -> leitzentrale -> network_dialog" decoration="no" motion="20"/>
|
||||
<policy label="runtime -> leitzentrale -> runtime_dialog" decoration="no" motion="30"/>
|
||||
<policy label="runtime -> leitzentrale -> diag_dialog" decoration="no" motion="30"/>
|
||||
<policy label="runtime -> leitzentrale -> popup_dialog" decoration="no" motion="20"/>
|
||||
<policy label="runtime -> leitzentrale -> panel_dialog" decoration="no" motion="20"/>
|
||||
<policy label="log" decoration="yes" motion="40"/>
|
||||
<policy label="runtime -> leitzentrale -> settings_dialog" decoration="no" motion="40"/>
|
||||
<policy label="runtime -> leitzentrale -> system_dialog" decoration="no" motion="40"/>
|
||||
<policy label="runtime -> leitzentrale -> file_browser_dialog" decoration="no" motion="60"/>
|
||||
<policy label="runtime -> leitzentrale -> network_dialog" decoration="no" motion="40"/>
|
||||
<policy label="runtime -> leitzentrale -> runtime_dialog" decoration="no" motion="60"/>
|
||||
<policy label="runtime -> leitzentrale -> diag_dialog" decoration="no" motion="60"/>
|
||||
<policy label="runtime -> leitzentrale -> popup_dialog" decoration="no" motion="40"/>
|
||||
<policy label="runtime -> leitzentrale -> panel_dialog" decoration="no" motion="40"/>
|
||||
<policy label_prefix="logo" decoration="no"/>
|
||||
<default-policy/>
|
||||
</config>
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <gui_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/pixel_rgb888.h>
|
||||
#include <os/reporter.h>
|
||||
|
||||
@ -39,6 +40,18 @@ struct Decorator::Main : Window_factory_base
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
/*
|
||||
* Time base for animations, which are computed in steps of 10 ms
|
||||
*/
|
||||
struct Ticks { uint64_t cs; /* centi-seconds (10 ms) */ };
|
||||
|
||||
Ticks _now()
|
||||
{
|
||||
return { .cs = _timer.curr_time().trunc_to_plain_ms().value / 10 };
|
||||
}
|
||||
|
||||
Gui::Connection _gui { _env };
|
||||
|
||||
struct Canvas
|
||||
@ -104,33 +117,31 @@ struct Decorator::Main : Window_factory_base
|
||||
|
||||
Animator _animator { };
|
||||
|
||||
/**
|
||||
* Process the update every 'frame_period' GUI sync signals. The
|
||||
* 'frame_cnt' holds the counter of the GUI sync signals.
|
||||
*
|
||||
* A lower 'frame_period' value makes the decorations more responsive
|
||||
* but it also puts more load on the system.
|
||||
*
|
||||
* If the GUI sync signal fires every 10 milliseconds, a
|
||||
* 'frame_period' of 2 results in an update rate of 1000/20 = 50 frames per
|
||||
* second.
|
||||
*/
|
||||
unsigned _frame_cnt = 0;
|
||||
unsigned _frame_period = 2;
|
||||
|
||||
/**
|
||||
* Install handler for responding to GUI sync events
|
||||
*/
|
||||
void _handle_gui_sync();
|
||||
|
||||
void _trigger_sync_handling()
|
||||
{
|
||||
_gui.framebuffer.sync_sigh(_gui_sync_handler);
|
||||
}
|
||||
Ticks _previous_sync { };
|
||||
|
||||
Signal_handler<Main> _gui_sync_handler = {
|
||||
_env.ep(), *this, &Main::_handle_gui_sync };
|
||||
|
||||
void _handle_gui_sync();
|
||||
|
||||
bool _gui_sync_enabled = false;
|
||||
|
||||
void _trigger_gui_sync()
|
||||
{
|
||||
Ticks const now = _now();
|
||||
bool const idle = now.cs - _previous_sync.cs > 3;
|
||||
|
||||
if (!_gui_sync_enabled) {
|
||||
_gui.framebuffer.sync_sigh(_gui_sync_handler);
|
||||
_gui_sync_enabled = true;
|
||||
}
|
||||
|
||||
if (idle) {
|
||||
_previous_sync = now;
|
||||
_gui_sync_handler.local_submit();
|
||||
}
|
||||
}
|
||||
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
@ -267,16 +278,15 @@ void Decorator::Main::_handle_window_layout_update()
|
||||
|
||||
_window_layout_update_needed = true;
|
||||
|
||||
_trigger_sync_handling();
|
||||
_trigger_gui_sync();
|
||||
}
|
||||
|
||||
|
||||
void Decorator::Main::_handle_gui_sync()
|
||||
{
|
||||
if (_frame_cnt++ < _frame_period)
|
||||
return;
|
||||
Ticks const now = _now();
|
||||
|
||||
_frame_cnt = 0;
|
||||
Ticks const passed_ticks { now.cs - _previous_sync.cs };
|
||||
|
||||
bool model_updated = false;
|
||||
|
||||
@ -300,31 +310,30 @@ void Decorator::Main::_handle_gui_sync()
|
||||
|
||||
bool const windows_animated = _window_stack.schedule_animated_windows();
|
||||
|
||||
/*
|
||||
* To make the perceived animation speed independent from the setting of
|
||||
* 'frame_period', we update the animation as often as the GUI
|
||||
* sync signal occurs.
|
||||
*/
|
||||
for (unsigned i = 0; i < _frame_period; i++)
|
||||
for (unsigned i = 0; i < passed_ticks.cs; i++)
|
||||
_animator.animate();
|
||||
|
||||
if (!model_updated && !windows_animated)
|
||||
return;
|
||||
if (model_updated || windows_animated) {
|
||||
|
||||
Dirty_rect dirty = _window_stack.draw(_canvas->canvas);
|
||||
Dirty_rect dirty = _window_stack.draw(_canvas->canvas);
|
||||
|
||||
_window_stack.update_gui_views();
|
||||
_window_stack.update_gui_views();
|
||||
|
||||
_gui.execute();
|
||||
_gui.execute();
|
||||
|
||||
dirty.flush([&] (Rect const &r) {
|
||||
_gui.framebuffer.refresh(r.x1(), r.y1(), r.w(), r.h()); });
|
||||
dirty.flush([&] (Rect const &r) {
|
||||
_gui.framebuffer.refresh(r.x1(), r.y1(), r.w(), r.h()); });
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable sync handling when becoming idle
|
||||
*/
|
||||
if (!_animator.active())
|
||||
if (!_animator.active()) {
|
||||
_gui.framebuffer.sync_sigh(Signal_context_capability());
|
||||
_gui_sync_enabled = false;
|
||||
}
|
||||
|
||||
_previous_sync = now;
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,10 +99,10 @@ class Decorator::Window_element : public Animator::Item
|
||||
/* medium fade-in when gaining the focus or hover highlight */
|
||||
if ((!_state.focused && state.focused)
|
||||
|| (!_state.highlighted && state.highlighted))
|
||||
return 15;
|
||||
return 30;
|
||||
|
||||
/* slow fade-out when leaving focus or hover highlight */
|
||||
return 20;
|
||||
return 40;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <os/reporter.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* decorator includes */
|
||||
#include <decorator/window_stack.h>
|
||||
@ -36,6 +37,18 @@ struct Decorator::Main : Window_factory_base
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
/*
|
||||
* Time base for animations, which are computed in steps of 10 ms
|
||||
*/
|
||||
struct Ticks { uint64_t cs; /* centi-seconds (10 ms) */ };
|
||||
|
||||
Ticks _now()
|
||||
{
|
||||
return { .cs = _timer.curr_time().trunc_to_plain_ms().value / 10 };
|
||||
}
|
||||
|
||||
Window_stack _window_stack = { *this };
|
||||
|
||||
/**
|
||||
@ -77,19 +90,7 @@ struct Decorator::Main : Window_factory_base
|
||||
|
||||
Reporter _decorator_margins_reporter = { _env, "decorator_margins" };
|
||||
|
||||
/**
|
||||
* Process the update every 'frame_period' GUI sync signals. The
|
||||
* 'frame_cnt' holds the counter of the GUI sync signals.
|
||||
*
|
||||
* A lower 'frame_period' value makes the decorations more responsive
|
||||
* but it also puts more load on the system.
|
||||
*
|
||||
* If the GUI sync signal fires every 10 milliseconds, a
|
||||
* 'frame_period' of 2 results in an update rate of 1000/20 = 50 frames per
|
||||
* second.
|
||||
*/
|
||||
unsigned _frame_cnt = 0;
|
||||
unsigned _frame_period = 2;
|
||||
Ticks _previous_sync { };
|
||||
|
||||
/**
|
||||
* Install handler for responding to GUI sync events
|
||||
@ -99,9 +100,22 @@ struct Decorator::Main : Window_factory_base
|
||||
Signal_handler<Main> _gui_sync_handler = {
|
||||
_env.ep(), *this, &Main::_handle_gui_sync };
|
||||
|
||||
void _trigger_sync_handling()
|
||||
bool _gui_sync_enabled = false;
|
||||
|
||||
void _trigger_gui_sync()
|
||||
{
|
||||
_gui.framebuffer.sync_sigh(_gui_sync_handler);
|
||||
Ticks const now = _now();
|
||||
bool const idle = now.cs - _previous_sync.cs > 3;
|
||||
|
||||
if (!_gui_sync_enabled) {
|
||||
_gui.framebuffer.sync_sigh(_gui_sync_handler);
|
||||
_gui_sync_enabled = true;
|
||||
}
|
||||
|
||||
if (idle) {
|
||||
_previous_sync = now;
|
||||
_gui_sync_handler.local_submit();
|
||||
}
|
||||
}
|
||||
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
@ -141,7 +155,7 @@ struct Decorator::Main : Window_factory_base
|
||||
Genode::log("pointer information unavailable");
|
||||
}
|
||||
|
||||
_trigger_sync_handling();
|
||||
_trigger_gui_sync();
|
||||
|
||||
_hover_reporter.enabled(true);
|
||||
|
||||
@ -252,16 +266,15 @@ void Decorator::Main::_handle_window_layout_update()
|
||||
|
||||
_window_layout_update_needed = true;
|
||||
|
||||
_trigger_sync_handling();
|
||||
_trigger_gui_sync();
|
||||
}
|
||||
|
||||
|
||||
void Decorator::Main::_handle_gui_sync()
|
||||
{
|
||||
if (_frame_cnt++ < _frame_period)
|
||||
return;
|
||||
Ticks const now = _now();
|
||||
|
||||
_frame_cnt = 0;
|
||||
Ticks const passed_ticks { now.cs - _previous_sync.cs };
|
||||
|
||||
bool model_updated = false;
|
||||
|
||||
@ -286,25 +299,23 @@ void Decorator::Main::_handle_gui_sync()
|
||||
|
||||
bool const windows_animated = _window_stack.schedule_animated_windows();
|
||||
|
||||
/*
|
||||
* To make the perceived animation speed independent from the setting of
|
||||
* 'frame_period', we update the animation as often as the GUI sync signal
|
||||
* occurs.
|
||||
*/
|
||||
for (unsigned i = 0; i < _frame_period; i++)
|
||||
for (unsigned i = 0; i < passed_ticks.cs; i++)
|
||||
_animator.animate();
|
||||
|
||||
if (!model_updated && !windows_animated)
|
||||
return;
|
||||
|
||||
_window_stack.update_gui_views();
|
||||
_gui.execute();
|
||||
if (model_updated || windows_animated) {
|
||||
_window_stack.update_gui_views();
|
||||
_gui.execute();
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable sync handling when becoming idle
|
||||
*/
|
||||
if (!_animator.active())
|
||||
if (!_animator.active()) {
|
||||
_gui.framebuffer.sync_sigh(Signal_context_capability());
|
||||
_gui_sync_enabled = false;
|
||||
}
|
||||
|
||||
_previous_sync = now;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user