A program might choose to process events that affect UI state already laid out.
For example, a button click might switch to a completely different UI page, but
the click might be processed during the drawing of the current page.
Avoiding that require either processing events very early during layout or
adding InvalidateOps whenever events are handled late.
Early event processing is awkward and InvalidateOps are easy to forget and
their absence masked by any other cause of redraw.
This change adds an implicit InvalidateOp for each frame where events have been
delivered to the program, allowing late event handling without use of
InvalidateOps.
In the worst case we waste a frame, increasing power use. I hope that future
optimizations will detect and discard the duplicate frame before it reaches
the GPU.
A similar situation applies to the delayed delivery of Editor events, but
since Editor.Layout flushes remaining events, extra InvalidateOps are not
required. Add a comment.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The Queue interface was changed from
type Queue interface {
Events(k Key) []Event
}
to the more complex single-step protocol
type Queue interface {
Next(k Key) (Event, bool)
}
to cater for a particular use case: Editor's SubmitEvent. When a
SubmitEvent is passed to a caller of Editor.Next, the Editor state,
in particular the current text, must not have changed by edits
later in the command stream. For example, pressing the keys <E>,
<Enter>, <E> should result in a SubmitEvent where the Editor has
a single 'e' in Text(), not two.
However, there is no reason to push the more complex Queue to every user.
Rather, store remaining input events inside Editor and process them as
Editor.Event (or Layout) is called.
Finally, revert the Queue interface to the simpler Events method.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Add decode functions to the packages that need them instead. For
TransformOp that is used in multiple packages, add the decode
function to the internal ops package.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
By returning all events, widgets that might return early from its
event loop might throw away subsequent events. Instead of requiring
those widgets to store the event list, convert input.Queue to step
through the available events one at a time.
Functional revert of 1735d5ced8.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Delete a redundant loop; dropHandlers already does the required work.
Fixes pointer event issues found after pointer events with no side
effects no longer trigger redraws.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
And add ProfileOp and ProfileEvent for registering and receiving
profile data.
Remove the Profiling field and Timings method from app.Window.
Signed-off-by: Elias Naur <mail@eliasnaur.com>