Commit Graph

2516 Commits

Author SHA1 Message Date
Elias Naur 7629874237 widget/material: remove redundant offset op
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-19 08:47:15 +02:00
Elias Naur 3a4b8b81ec io/system: describe FrameEvent.Insets more precisely
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-19 08:47:15 +02:00
Elias Naur 6c76fa6dec app,io/key,io/system: [API] replace system.CommandEvent with key.Event
It's much simpler to map the Android back button to a key.Event and
let the usual key filtering determine whether to block its default
behaviour.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-19 08:47:15 +02:00
Elias Naur ad7c1eb78d app,io/key: introduce keys for directional navigation
This change adds key.NameUp/Down/Left/Right and maps the Android TV
remote directional keys to them. As a side-effect a key.InputOp can
now receive directional keys (and block their focus movement).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-14 19:09:08 +02:00
Elias Naur d37197f45b app: give key handlers a chance to process Tab and Shift-Tab
Before this change, Tab and Shift-Tab would always result in focus
movement. This this change, a key.InputOp with a matching Keys set
will block focus movement and deliver the events to it.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-14 19:09:08 +02:00
Elias Naur 380f96b3fc io/key: [API] implement key event propagation
Before this change, every Event would be passed to the focused InputOp
tag, making it impossible to implement, say, program-wide shortcuts.
This change implements key.Event routing similar to how pointer.Events
are routed: every InputOp describes the set of keys it can handle, and
the router use that information to deliver an Event to the matching
handler.

This is an API change, because every InputOp must now include a filter
matching the keys it wants to handle.

Fixes: https://todo.sr.ht/~eliasnaur/gio/395
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-14 19:09:00 +02:00
Elias Naur bec0283e54 io/router: deliver synthetic events to sibling pointer handlers
Before this change, synthetic events such as scrolling caused by
focus movement would use semantic information to determine potential
receivers. However, there can only be one handler per area so sibling
handlers would not be considered. This change makes the event delivery
traverse the entire tree of handlers, including siblings.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-14 18:51:39 +02:00
Elias Naur 9c59612e08 io/key: change Modifiers.String separator to "-"
We're about the express sets of key combinations as <modifiers>-<keys>
where modifiers are separated by dashes as well. To make Modifers.String
useful for expressing key sets, change its separator to "-".

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-14 11:48:55 +02:00
Elias Naur ed8d3e8566 io/key: [API] rename tab and modifier keys, introduce NameCommand
We already have precedence for word-named keys ("Space") and the new
names are less obscure and matches Modifiers.String.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-14 11:45:08 +02:00
Elias Naur dc25afda07 app: don't panic when the client doesn't call FrameEvent.Frame
Fixes: https://todo.sr.ht/~eliasnaur/gio/396
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-14 09:16:49 +02:00
Elias Naur 6a14269682 gpu/internal/opengl: add fallback for sparse OpenGL ES 2.0 ReadPixels
OpenGL ES 2.0 doesn't support GL_PACK_ROW_LENGTH, so this change implements
a fallback using a temporary buffer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-13 17:28:36 +02:00
Elias Naur 43865ddabd app: don't delay FrameEvent.Frame by v-sync latency
We should return as soon as possible from FrameEvent.Frame to allow the main
goroutine to continue processing other tasks.  Whereas GPU.Frame may touch
the frame ops, GPU.Present will not, so this change moves Present to after
returning from FrameEvent.Frame.

This is a variant of 38ff78df5d that
works on OpenGL where context locking is required.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-13 16:05:28 +02:00
Elias Naur 405215f862 Revert "app: don't delay FrameEvent.Frame by v-sync latency"
This reverts commit 38ff78df5d, because
it broke OpenGL by moving eglSwapBuffers outside the MakeCurrent
context scope.

Fixes: https://todo.sr.ht/~eliasnaur/gio/393
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-13 16:01:25 +02:00
Elias Naur 6e66203881 gpu/headless: return error if NewTexture fails
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-13 12:58:33 +02:00
Elias Naur 38ff78df5d app: don't delay FrameEvent.Frame by v-sync latency
We should return as soon as possible from FrameEvent.Frame to
allow the main goroutine to continue processing other tasks.
Whereas GPU.Frame may touch the frame ops, GPU.Present will not,
so this change moves Present to after returning from FrameEvent.Frame.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-12 18:21:23 +02:00
Chris Waldon 25fae8de30 deps: update golang.org/x/text and go-text
Fixes a panic parsing language tags.

References: https://go-review.googlesource.com/c/text/+/340830
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-04-12 09:11:42 +02:00
Elias Naur 49bd5787e4 app: [macOS] fix caret position calculation after IME text insert
Fixes: https://todo.sr.ht/~eliasnaur/gio/385
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-08 13:05:27 +02:00
Jack Mordaunt 4e488f4c70 app: [API] don't relay raw input events from app.Window
Avoid sending raw inputs events over the window channel.

If the caller wants to access events, they should be
using input handlers and querying for events.

This change avoids saturating the channel with less important
messages which can affect frame event latency, especially in
the case of custom rendering.

See also

https://lists.sr.ht/~eliasnaur/gio/%3CCAFcc3FQNTp_UXr7oA97SsVPD7D91jSw30ZtALcT9vmopFDTeZQ%40mail.gmail.com%3E

Signed-off-by: Jack Mordaunt <jackmordaunt.dev@gmail.com>
2022-04-07 13:18:59 +02:00
Elias Naur 69f982e26f io/router: don't panic on focus moves when there is nothing to focus
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-05 13:12:03 +02:00
Elias Naur f07537335a app: clip client area
On Wayland, app.Window provides fallback window decorations but clients
are not prohibited from drawing over the decorations or capturing events.
This change adds a clip operation to ensure no unwanted interaction between
client content and decorations.

Fixes issue described in

https://lists.sr.ht/~eliasnaur/gio/%3C092fa6a19894af3306fab568fb919c965e98c4da.camel%40gmail.com%3E

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-04 10:56:01 +02:00
Elias Naur bd7f50438a io/router: account for parent clip areas when scrolling focus into view
Fixes: https://todo.sr.ht/~eliasnaur/gio/389
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-02 15:49:41 +02:00
Elias Naur 36919ef756 layout: don't clip List children
Clipping all children once to the entire List area is enough. The
change was motivated by #389 where individual child clips would
make it harder for focus scroll heuristics to work.

References: https://todo.sr.ht/~eliasnaur/gio/389
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-02 15:46:27 +02:00
Elias Naur a1b5ff059c io/router,app: scroll a bit when reaching the end in a focus direction
List was recently changed to include an extra child at each end, to
automatically scroll when reaching the end of a focus direction. However,
if List includes unfocusable children that strategy may fail. This change
adds another fallback where app.Window will scroll a constant amount in
the focus direction, to reveal more children.

For https://github.com/tailscale/tailscale/issues/4278.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 12:58:29 +02:00
Elias Naur cd0c9dab9f io/router: [API] don't emit Enter and Leave events for touch input
Enter/Leave events make sense for mouse pointers, to track hover
status. It doesn't make sense to track hover for touch input, so
this change stops pointer.Enter and pointer.Leave from being
emitted for pointer.Touch sources.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:55:48 +02:00
Elias Naur afd39a6bfe layout: compute Position.Offset correctly for ScrollToEnd Lists
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:55:48 +02:00
Elias Naur 508330e818 layout: layout one invisible child at each end of a List
A recent change added automatic scrolling to move focused widgets
into view. This change modifies List to layout an extra child at
each of its ends, to enable focus to move to them and trigger
automatic scrolling of the list.

For https://github.com/tailscale/tailscale/issues/4278.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:55:48 +02:00
Elias Naur a699fb89ac layout: default List scroll bounds to infinity
Before, List would only report the remaining scrollable area of the visible
children when positioned close to either end. Now, List always report infinite
scroll bounds *unless* it is positioned at an extremum.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:54:53 +02:00
Elias Naur d34544cc22 io/router: merge pointerQueue.deliverScrollEvents and deliverEvent
They're similar except for a bit of special handling for scroll events.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:52:31 +02:00
Elias Naur e8603ba59e io/router: use areas to determine targets for synthetic clicks
Before this change, semantic clicks would be delivered according to
the center of the targeted widget, which could result in a different
widget receiving the click. Or in worst case, no widget in case the
center is not visible because of clipping.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:52:31 +02:00
Elias Naur 4326fee704 app,io/router: scroll focused widgets into view
A focused widget may be partially or completely off-screen in which case
the user will have difficulty interacting with it. This change attempts to
scroll the focused widget into view by issuing synthetic scroll events.

For https://github.com/tailscale/tailscale/issues/4278, but doesn't completely
solve it because layout.Lists won't layout focusable widgets outside its visible
bounds. A follow-up change deals with that.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:52:31 +02:00
Elias Naur 2069d5cb2e gesture: don't rely on Enter events to determine validity of click
We're about to not emit Enter and Leave events for touch input, and
this change changes the Click gesture to no longer rely on those
events to determine whether a Release is inside its bounds.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-31 11:52:31 +02:00
Elias Naur 6389b1a384 io/router: add ScrollGesture
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-30 22:20:27 +02:00
Elias Naur b2d10c2f28 widget: include the Editor key handler in the editor clip area
A meaningful clip area for a key handler will matter when we start
auto-scrolling to move focused handlers into view.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-30 22:20:27 +02:00
Elias Naur e72c46f13c io/router: use integer coordinates for bounds
There is no need for floating point coordinates, except for transforming
bounds and hit testing.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-30 22:20:27 +02:00
Elias Naur 1f11a5a17b f32,gpu,op/clip: add f32.Rectangle method for converting to image.Rectangle
Creating an image.Rectangle from a f32.Rectangle is used by two packages in Gio
and about to be used for a third. Add a Round method to f32.Rectangle to avoid
duplicating the implementation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-30 22:20:27 +02:00
Elias Naur 920e6dd004 io/router,app: move Tab-to-focus conversion to app.Window
This is a refactor to make it easier to add higher level logic to
focus moves. A follow-up will add automatic scrolling to bring
focused widgets into view.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-30 22:20:22 +02:00
Elias Naur 0175779148 flake.nix: enable Vulkan support
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-29 15:46:27 +02:00
Elias Naur b6ee02646a flake.nix: remove emulator from environment
The emulator needs android system images to run, each of which takes
up a lot of space. Remove emulator from the Nix flake environment and
let something else provide emulator support, maybe even a custom
Nix devShell.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-29 14:45:18 +02:00
Elias Naur 75d487fa34 cmd: update Gio version
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-28 18:15:22 +02:00
Elias Naur a3f147541f flake.*: add Nix development environment
This change adds a Nix flake capable of setting up an environment
for building Gio programs for Linux and Android, on top of the
platforms that only needs Go (Windows, WASM).

To use the flake, install Nix 2.4 or later and enable experimental
support for flakes. Then, you can launch a development shell with

$ alias nix='nix --extra-experimental-features "nix-command flakes"'
$ nix develop sourcehut:~eliasnaur/gio

The environment can also be applied to the current shell, which is
useful in combination with direnv:

$ . <(nix print-dev-env sourcehut:~eliasnaur/gio)

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-28 17:48:13 +02:00
Elias Naur 4a061a7d40 .builds: use Android SDK for 32-bit build test
With GOARCH=386, we can't readily build packages that use Cgo. However,
we already have the Android SDK available, so use that to test for 32-bit
issues such as #384.

References: https://todo.sr.ht/~eliasnaur/gio/384
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-28 17:47:57 +02:00
Chris Waldon 3406a6da39 deps,font/opentype: update dependencies to fix 32-bit build
This commit updates to a newer version of textlayout
and switches to a fork of the UAX library that builds
properly on 32-bit machines. This should fix 32-bit Gio
compilation for the time being. I hope to switch back
to npillmayer's UAX as soon as he has time to review
the pending pull requests.

Fixes: https://todo.sr.ht/~eliasnaur/gio/384
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-26 08:36:32 +01:00
Chris Waldon 3fb522caff ci: test non-cgo packages in 32-bit mode
This commit runs Gio's test harness in 32-bit mode as well as 64-bit. This helps
catch bugs in Gio and its dependencies where integer overflow causes build or
runtime problems.

The complexities of cross-compiling CGO made it prohibitively difficult to test
all of Gio, so these changes only run tests for packages in pure Go.

References: https://todo.sr.ht/~eliasnaur/gio/384
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-26 08:36:14 +01:00
Chris Waldon 8833a6738a widget: drop debug prints from tests
This commit removes some lingering editor debug prints
from the test code.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-18 08:05:19 +01:00
Chris Waldon 7daab97fab widget: [API] make text.Alignment direction-sensitive
This commit ensures that text.Alignment is intuitive for
the direction of the text being aligned. RTL text with
Alignment Start will be aligned to the right edge of the area,
whereas LTR text with Alignment Start will continue to be
aligned to the left edge. Vice versa for the End alignment.

References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-18 08:05:06 +01:00
Chris Waldon e14bbee252 font/gofont: [API] use new opentype impl for Collection()
This commit switches gofont.Collection from returning
a collection of fonts using the old text shaper to
using the new harfbuzz-based shaper. The underlying type
of gofont.Collection() has changed, which may break users
who dug into the font data.

References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-18 08:04:43 +01:00
Chris Waldon 9576b659d7 text: [API] remove Text and Advances from Layout
These fields are no longer needed with the new text shaper.
Advances is redundant to the glyph information, and Text
should never be used during layout, as you should
traverse the cluster list instead. This commit also removed
the now-unused string field from the path LRU cache key.

References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-18 08:04:27 +01:00
Chris Waldon 01276238df font/opentype: [API] replace old font type with harfbuzz
This commit replaces the previous opentype.Font with
an implementation that uses the new text shaper. In
order to keep the implementation simple, support for
opentype font collections was dropped. It should be
possible to re-add this support after some changes
to the text shaper's line wrapping algorithm.

To expand on the above, doing proper font fallback with
harfbuzz will require splitting the input text on font
glyph support boundaries, changing the input from a
simple shaping.Input to []shaping.Input with each input
matched against the font that supports its language.
The line wrapping then needs to be able to properly
consume that slice. Since the line wrapping algorithm is
really complex, I'm hoping to defer that modification
until this simple version is accepted.

References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-18 08:04:14 +01:00
Chris Waldon 42c99a5cb2 widget{,/material}: [API] update editor to support complex scripts
This commit updates material.Editor and material.Label to support the
new text shaper. This requires breaking their assumption that glyphs
of font data map 1:1 to runes of text data.

References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-18 08:03:46 +01:00
Chris Waldon 938179d293 font/gofont: add font collection using the new shaper
This commit adds a font collection that uses the new
text shaper so that constructing material.Themes atop
it is equally simple to using the old shaper.

You can use material.NewTheme(gofont.CollectionHB()) with
this commit applied.

References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-18 08:01:59 +01:00