Commit Graph

187 Commits

Author SHA1 Message Date
Chris Waldon b1942f64b0 io/system: implement Stringer on TextDirection
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-11-09 08:45:44 -06:00
Inkeliz 90688fdd17 app,io/system: [API] add StageInactive when window is not in focus
Now, Gio will send one system.StageEvent with system.StageInactive when
the window is not active. It is implemented on macOS and Windows.

This change is not fully backward compatible, if your code compares
the Stage (`stage < system.StageRunning`), you need to consider
the new system.StageInactive.

Signed-off-by: inkeliz <inkeliz@inkeliz.com>
2022-09-19 11:07:41 -06:00
Dominik Honnef e37deed8bb io/router: fix pointer positions of Enter and Leave events for nested areas
Before this change, inverse transformations of pointer positions would
stack up, leading to incorrect positions when an enter or leave event
was delivered to multiple areas.

Signed-off-by: Dominik Honnef <dominik@honnef.co>
2022-09-15 06:41:08 -06:00
Elias Naur 96d6fd2791 Revert "io/router: [API] don't emit Enter and Leave events for touch input"
This reverts commit cd0c9dab9f. It turns out
that Enter/Leave is important for cancelling press-then-release-outside
for clickables.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-08-08 14:25:34 +02:00
Elias Naur 61b2e37691 all: format comments with go fmt ./... using Go 1.19
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-08-06 12:26:03 +02:00
Dominik Honnef b67bef3e0d io/pointer: fix order of Cursor comments
Signed-off-by: Dominik Honnef <dominik@honnef.co>
2022-07-21 10:25:42 +02:00
Elias Naur 28c206fc78 io/router: try all handlers if a key don't match the focus ancestor tree
When a key.InputOp is focused, a key.Event is matched to it and its ancestors.
If there is no focus, every handler is matched.
This change always matches to every handler, after checking the focus and
its ancestors.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-07-20 10:37:28 +02:00
Elias Naur 0057e871d0 io/router: search all key handlers when there is no focus
Fixes: https://todo.sr.ht/~eliasnaur/gio/434
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-07-02 20:51:26 +02:00
Elias Naur 3f38e67ce0 io/system: add ActionInputOp to register window move gesture areas
The app.Window.Perform(ActionMove) is the wrong abstraction for
initiating a move gesture: Windows needs to know the move gesture
area at pointer move, and macOS needs to know the pointer button
down event that triggers the move gesture. This change replaces
Perform(ActionMove) with a new system.ActionInputOp that marks an
area movable.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-06-25 19:40:46 +02:00
Elias Naur b53cdfef8d io/system: remove resize actions
Allowing clients to initiate resize gestures is a waste: macOS
doesn't support them, and the only reason we added them was to
implement client-side decorations for Wayland. Now all desktop
platforms implement resize gestures as needed, and we no longer
need the system.Action actions.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-06-25 18:41:32 +02:00
Chris Waldon 44ec48d325 io/router: fix focused key event propagation
When a key.InputOp is focused, keypresses that it does not explicitly
include in its key set should check for ancestor clip areas that are
interested in them. Previously this check only included ancestors of
the final clip area in the hit tree, and could fail to find ancestors
of the focused key.InputOp because they were in a different branch.

This commit also adds a test to lock in the new behavior.

This can likely be made more efficient by adding a rapid way to map
from the focused key tag to its index in the hit tree. I wasn't sure
whether the complexity was warranted, but I'm happy to do that if
it's desired.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-06-01 19:52:59 +02:00
Elias Naur b5f12c5f26 f32: [API] unexport Rectangle
There are no public API that uses f32.Rectangle anymore. Move Rectangle
to an internal package for internal use.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-05-31 10:24:09 +02:00
Elias Naur 3d37491342 all: [API] replace unit.Value with separate unit.Dp, unit.Sp types
The unit.Value is a struct and thus more inconvenient to use than its
underlying float32 type. In addition, most uses don't need a general
value, but rather a specific unit given by the context. This change
replaces unit.Value with two float32 units, Dp and Sp. It also changes
variables and parameters of unit.Value to a specific unit type matching
the context. That is, unit.Dp everywhere except for text sizes which are
in Sp.

Switching to typed float32s has multiple advantages

- They can be constants:

const touchSlop = unit.Dp(16)

- Casting untyped constants is no longer necessary:

insets := layout.UniformInset(16)

- Calculation with values is natural:

func (s ScrollbarStyle) Width() unit.Dp {
	return s.Indicator.MinorWidth + s.Track.MinorPadding + s.Track.MinorPadding
}

The main API change is that calls to gtx.Px must be replaced with either
gtx.Dp or gtx.Sp depending on the unit.

Idea by Christophe Meessen.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-05-31 10:24:09 +02:00
Elias Naur 48a8540a68 all: [API] change clip.RRect and UniformRRect to take integer coordinates
Like the change to op.Offset before this, clip.RRect and UniformRRect
is usually used with integer coordinates. Change to integer coordinates
to eliminate many useless conversions to float32.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-05-31 10:24:09 +02:00
Elias Naur 7fc594fa4b io/key: remove key.NameUp/Down/Left/Right
They're no longer used now that Android directional keys are mapped
to key.Name*Arrow.

References: https://todo.sr.ht/~eliasnaur/gio/410
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-05-10 16:49:59 +02:00
Elias Naur aa14056350 io/router: remove unused frect function
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-25 09:12:42 +02:00
Elias Naur 8630fee623 io/pointer: remove unused functions
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-23 16:18:32 +02:00
Elias Naur 2381c5ad70 io/router,widget: give every key.InputOp a chance to process events
If the currently focused handler don't want the key event, try every
other handler, from top to bottom. This change requires widgets to
only react when focused.

Fixes: https://todo.sr.ht/~eliasnaur/gio/406
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-23 15:36:45 +02:00
Elias Naur 0273203743 app,io/router: expand IME snippets if a new range overlaps the old
Instead of cmpletely replacing the IME snippet for every update, expand
the old range if there is overlap. This change avoids never-ending
restarts of the IME on Android where snippets are expanded in two
calls, one for expanding before the selection and one for exanding after
the selection.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-23 13:20:46 +02:00
Elias Naur 30fa85f518 io/router: send key events to root handlers if nothing else wants them
Fixes: https://todo.sr.ht/~eliasnaur/gio/403
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-04-23 09:40:23 +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 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 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 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 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 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 6389b1a384 io/router: add ScrollGesture
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 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
Chris Waldon 512900c9b1 system: define new Locale type
This commit adds a Locale struct that captures language and layout
flow direction for the system. This information can be leveraged
by text shaping and layout code to make better choices.

References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2022-03-18 07:58:00 +01:00
Elias Naur 3e18a310af io/router: replace cursor stack with area field
There's no need to track cursors separately from areas.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-07 13:19:38 +01:00
Elias Naur 99bb542960 io/router: always choose the topmost cursor among candidates
Fixes: https://todo.sr.ht/~eliasnaur/gio/373
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-07 13:05:59 +01:00
Elias Naur 68544111c1 io/router: ensure root pointer area in deferred calls
Fixes: https://todo.sr.ht/~eliasnaur/gio/372
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-03-07 12:08:08 +01:00
Egon Elbre cdb288d1f9 app,io/pointer: [API] remove CursorNameOp and rename CursorName -> Cursor
It's now possible to directly user pointer.Cursor to add to the ops.

   pointer.CursorText.Add(gtx.Ops)

This is an API change. Use pointer.Cursor directly instead of CursorNameOp.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2022-03-01 14:05:46 +01:00
Egon Elbre 4172566aad io/pointer: [API] make cursor name into a byte
Add most of the common cursors defined by different systems.

Normalize cursor names to match CSS.

This is API change: some cursor names have changed, and the
underlying type is no longer a string.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2022-03-01 14:04:21 +01:00
Elias Naur 21431975de app,io/router: map Androids' DPAD_CENTER to a click
Mapping it to key.NameReturn confuses widgets such as Editor that
treats clicks separate from return key presses.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-02-28 17:28:13 +01:00
Elias Naur 73eabb352d io/router,app: add support for directional focus moves
Implement support for up/down/right/left directional focus moves
and map Android directional pad keys to focus moves.

Fixes: https://todo.sr.ht/~eliasnaur/gio/195
References: https://github.com/tailscale/tailscale/issues/1611
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-02-27 19:01:32 +01:00
Elias Naur 2e9df04a7b io/router: move focus on tab and shift+tab
Fixes: https://todo.sr.ht/~eliasnaur/gio/195
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-02-27 18:42:33 +01:00
Inkeliz 730e04630c io/pointer: rename cursors to match the JavaScript DOM
The names are a better match for layout.Direction.

Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
2022-02-22 17:55:48 +01:00
Egon Elbre b7a42da386 app: [windows] add missing cursors
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2022-02-22 10:39:12 +01:00
Elias Naur 845d35dd50 io/key: update stale comment
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-02-15 18:00:32 +01:00
Elias Naur 31f55232bf app,widget,io: implement IME positioning
This change implements reporting of the caret position from Editor, as well
as Windows, macOS, Android support. As a result, the IME composition window
on Windows and macOS is now positioned correctly.

References: https://todo.sr.ht/~eliasnaur/gio/246
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-02-13 20:09:06 +01:00