Commit Graph

149 Commits

Author SHA1 Message Date
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
Elias Naur 58cdb3e1da app,widget: implement Editor IME support, add Android implementation
Fixes: https://todo.sr.ht/~eliasnaur/gio/116
References: https://todo.sr.ht/~eliasnaur/gio/246
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-02-06 10:31:53 +01:00
Pierre Curto 74acc90789 app: [API] add Window.Perform, replacing Close, Raise, Centered
This new method performs user related actions on the Window, supporting custom window decorations.
It supersedes the Close and Raise methods as well as the Centered window option.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2022-01-31 18:56:29 +01:00
Pierre Curto 2cf7c5b949 io/system,widget/material: add decorations
Add the Decorations material widget and the related system
elements in preparation for the automatic window decoration
patch.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2022-01-22 08:11:59 +01:00
Pierre Curto c0f3ec88e9 io/pointer: add new pointers
Add resize pointer cursor names for resize operations
in preparation for the window decorations patch.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2022-01-19 10:39:32 +01:00
Jeff Williams 13183522dd app: send keypress events for modifier keys
This change causes modifier keys (Control, Shift, Alt, Super) to be sent
to the application as key.Event events. These will still continue to be
used as modifiers for other key and pointer events as they are today.

This commit also adds a minor cleanup to use constants for function
keys in the OS-specific keypress handling functions.

Signed-off-by: Jeff Williams <kanobe@gmail.com>
2022-01-15 16:56:47 +01:00
Elias Naur 5860fbbe8e io/key: remove "Mod" prefix from Modifiers.String names, concatenate by "+"
"Mod" is implied by the type, and "+" is the natural concatenation character
for displaying shortcuts.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-04 17:46:14 +01:00
Elias Naur cce0a121e1 io/router: don't panic if AppendSemantics is called without a frame
Fixes: https://todo.sr.ht/~eliasnaur/gio/328
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-12-30 10:23:23 +01:00
Elias Naur 6534639276 io/pointer,op/clip: remove clip.Circle, pointer.Rect, pointer.Ellipse
They've been deprecated for a while, and gio-x is updated to not use
them.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-12-20 16:23:16 +01:00
Pierre Curto 3db11cbaad io/router: make transfer targets hovering easier to detect
In commit 929e4dc12, the rules to send pointer.{Enter,Leave}
events were relaxed. Unfortunately, to be able to make use
of them was not straight forward as it required the transfer
target op to use the same handle as the hover one.
This patch eases this by allowing any handle for the target
as well as not requiring the hover op to be defined on the same
clip op as the target (then requiring a PassOp though), making
it much easier to use.

Also added a test for pointer.Enter events not being generated
if the target type does not match the source one.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-12-19 13:22:11 +01:00
Pierre Curto 929e4dc120 io/router: deliver enter/leave events to transfer participants
When a drag and drop gesture is ongoing, let the potential target
handlers receive enter/leave events so that they can react to them (e.g.
highlight themselves when the dragged item is over them).

Fixes #321.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-12-14 11:43:23 +01:00
Pierre Curto 294ecfbe9d io/router: avoid extra work when dealing with EnterLeave events
When computing the set of Enter/Leave events to be
delivered to handlers, skip non mouse pointers
right away instead of processing hit events.

Also, remove use of pointer to slice use in opHit.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-12-10 06:25:48 +01:00
Pierre Curto 27e38154a0 io/transfer: fix package description formatting
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-12-10 06:25:35 +01:00
Pierre Curto 03016f0c69 widget: add drag and drop support
This patch adds internal Drag and Drop support to app.Windows.

The new package io/transfer adds the ability to
define draggable and droppable targets, which
are leveraged by the new widget.Draggable type.

The API is generic and could handle future use
cases, such as external Drag and Drop.

Updates gio#153

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-12-07 12:45:53 +01:00
Elias Naur 8a90074d04 io/semantic: add package for adding semantic descriptions to UI components
Software such as screen readers require semantic descriptions of user
interfaces to effectively present and interact with them. Package
semantic, combined with the existing package clip provide the operations
for Gio programs to describe themselves.

This change implements the semantic package and the routing changes for
accessing semantic trees; follow-ups add semantic information to widgets
and implement mapping semantic tree to platform representations.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-12-01 17:23:54 +01:00
Elias Naur 48a96305c8 io/router: move transform state tracking from pointerCollector to Router
We're going to need transform tracking for the upcoming meta ops.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-12-01 17:23:54 +01:00
Pierre Curto 858e9930c4 io/router: cleanup
Remove unused function and func argument.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-11-26 22:27:10 +01:00
Pierre Curto 218a9588d6 io/router, internal/ops: minor refactoring
Rename the assertEventSequence helper to assertEventPointerTypeSequence.
Fix typos.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-11-26 22:26:38 +01:00
Jon Egil Strand e82438e53d io/router: fix spelling
Signed-off-by: Jon Egil Strand <jon.egil.strand@gmail.com>
2021-11-26 21:56:02 +01:00
Elias Naur 303b819539 io/router: don't panic for nil op.Ops arguements to Router.Frame
Fixes gio#306

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-11-10 15:24:22 +01:00
Elias Naur 3e0b72304a all: replace deprecated pointer.Rect with clip.Rect
Converted with

gofmt -w -r 'pointer.Rect(r) -> clip.Rect(r)' .
gofmt -w -r 'pointer.Ellipse(r) -> clip.Ellipse(layout.FRect(r))' .

combined with 'goimports -w .' to clean up imports.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-11-03 14:12:31 +01:00
Elias Naur 29cea1db49 io/pointer,io/router: replace AreaOp with clip.Op
Pointer hit areas and paint clip areas are separate concepts, but
similar enough to warrant merging. This change replaces pointer hit
areas with clip areas, so Gio is left with just one area concept (in
package op/clip).

The reason for separating the concepts in the original Gio release was
because of my being unsure general path/stroke hit areas would ever be
implemented, let alone efficient.

This change represents a change of mind, in the sense that it's better
to have an incomplete API than two separate area concepts.

Leave the deprecated pointer.Rect, pointer.Ellipse for temporary
backwards compatibility.

This is an API change. Most existing programs should continue to build
with this change, but may have to adjust to having all clip.Ops participate
in InputOp hit areas.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-11-03 14:12:31 +01:00
Elias Naur 8cafbd309f io/pointer,io/router: make PassOp apply to InputOps, not areas
We're about to make clip.Ops act as pointer areas, in which case we'd
like to contain the effect of PassOp to just pointer InputOps.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-26 12:13:11 +02:00
Elias Naur 382eabc0a8 io/pointer: fix PassOp documentation
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-25 19:47:55 +02:00
Pierre Curto 241e566053 io/router: remove unnecessary panics while routing key ops
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-10-24 08:31:31 +02:00
Elias Naur e4b96cb779 io/router: avoid a decode round for key ops
Like a previous change for pointer ops, process key ops during the
router decode of ops. This is a performance optimization and preparation
for processing future accessibility ops without without another decode
loop.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-22 15:17:05 +02:00
Elias Naur 60846d112b io/router: introduce pointerCollector to avoid an ops decode
The router package decodes the entire ops list thrice: once for pointer
ops, once for key ops, once for other ops. This change removes one
decode round by merging other ops and pointer ops decoding.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-21 18:16:12 +02:00
Elias Naur a4626d9304 io/router: make the zero value collectState the reset state
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-20 11:31:00 +02:00
Pierre Curto 6b0e00b9aa io/pointer: change Type to uint
This is to allow for future new Types.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-10-20 10:09:58 +02:00
Pierre Curto e6ed25bb1f io/router: deduplicate pointer handlers
When the same handler is added several times
and that handler sets pointer.Grabbed, it gets lost.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-10-19 15:00:29 +02:00
Pierre Curto e5d8a4b8d0 io/router: reuse scratch space in pointerQueue.Frame
This removes the allocation needed to drop all handlers except one.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-10-18 11:47:49 +02:00
Pierre Curto 9be171190e io/router: convert pointerQueue.dropHandlers to pointerQueue.dropHandler
dropHandlers is mainly used for single tag removal except in one instance.
In that case, simply use a loop.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-10-18 11:47:36 +02:00
Pierre Curto ae5219e4d4 io/pointer: print all types in Type.String
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-10-17 14:50:28 +02:00
Elias Naur 0048f7be1d internal/ops: hide Ops methods by converting them to package functions
Ops is in the internal package ops, but external clients can reach its
method through op.Ops.Internal. Hide them by converting them to internal
package functions.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-12 14:50:15 +02:00
Elias Naur 87d050bcc7 internal/ops: remove Data, Version, Refs methods from Ops
They're only used internally.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-12 14:28:05 +02:00
Elias Naur 960f3068a1 io/pointer: re-introduce PassOp
A previous change merged PassOp with AreaOp under the assumption that
the pass mode would be set on a particular area. That assumption turns
out not to hold, so this change brings back PassOp as an independent
stack operation.

This is an API change: replace AreaOp{Pass: true} with a separate
pointer.PassOp operation.

Fixes gio#288

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-09 16:31:54 +02:00
Elias Naur 391725b9d0 op: move Ops internal methods and state to internal package ops
Merge package opconsts into ops as well; it only existed to break
import cycles.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-08 17:21:56 +02:00
Elias Naur 936c266b03 all: [API] split operation stack into per-state stacks
The op.Save and Load methods exist to support the need for
transformation, clip, pointer area state to behave as stacks. For
example, layout needs to apply an offset to its children but not
subsequent operations.

Before this change, op.Save and Load were used to save and restore the
state:

    ops := new(op.Ops)
    // Save state.
    state := op.Save(ops)
    // Apply offset.
    op.Offset(...).Add(ops)
    // Draw with offset applied.
    draw(ops)
    // Restore state.
    state.Load()

A drawback with the op.Save mechanism is that there is no direct
connection between the state change and the saving and loading of state.
This causes confusion as to when a Save/Load is needed and who is
responsible for performing them, which leads to subtle bugs and over-use
of Save/Loads.

This change gets rid of the general state stack and replaces it with
per-state stacks. There is now a stack for transformation, clip, pointer
areas, and they can only be restored by the code pushing state to them.
The example above now becomes:

    ops := new(op.Ops)
    // Push offset to the transformation stack.
    stack := op.Offset(...).Push(ops)
    // Draw with offset applied.
    draw(ops)
    // Restore state.
    stack.Pop()

For convenience, transformation also be Add'ed if the stack operation is
not required.

Simple state such as the current material no longer has a way to be
restored; it is assumed the client of a PaintOp adds their desired
material operation before it.

API change: replace op.Save/Load with explicit Push/Pop scopes for
op.TransformOps, pointer.AreaOps, clip.Ops.

To ease porting, this change retains a version of op.Save/Load that
saves and restores the transformation and clip stacks. It also retains
an Add method for clip.Op.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-08 17:21:56 +02:00
Elias Naur 6f80b94b4a io/pointer,io/router: [API] make pass-through a property of AreaOp
We're about to make operation scopes explicit, which would result in
both AreaOp and PassOp be scoped. However, PassOp seems to light to have
its separate stack, so this change instead makes pass-through a property
of an area. We're assuming that clients that want pass-through are also
aware of the affected hit area.

API change: replace PassOps with the AreaOp.PassThrough field.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-10-08 15:54:50 +02:00