Modeling focus change as an operation is awkward, because focus changes
logically happen during event processing, not layout. In particular, you
want to apply focus changes even if a widget is subsequently never laid
out.
Now that input.Source is concrete, it's much more straightforward to
offer focus changes as a command which can be queued through the
Source. A future change may similarly offer a command for directional
focus changes.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
It was a design mistake to make profiling data available to programs.
Rather, profiling should either be a user-configurable debug overlay,
reported through runtime/trace, or both.
This change drops the io/profile package because we're about to overhaul
event routing.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This adds support for nearest neighbor filtering,
which can be useful in quite a few scenarios.
img := paint.NewImageOp(m)
img.Filter = paint.FilterNearest
img.Add(gtx.Ops)
Fixes: https://todo.sr.ht/~eliasnaur/gio/414
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
The double-negative DisabledOp is harder to understand than a
straightforward EnabledOp. Note that the absence of an EnabledOp
implies still means that the widget is enabled.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
When storing a string in an interface value that escapes, Go has to heap
allocate space for the string header, as interface values can only store
pointers. In text-heavy applications, this can lead to hundreds of
allocations per frame due to semantic.LabelOp, the primary user of
string-typed references in ops.
Instead of allocating each string header individually, provide a slice
of strings to store string-typed references in, and store pointers into
this slice as the actual references. This only allocates when resizing
the slice's backing array, and averages out to no allocations, as the
backing array gets reused between calls to Ops.Reset.
We introduce two new functions, Write1String and Write2String, which
make use of this new slice for their last argument. We could've
automated this in the existing Write1 and Write2 methods, but that would
require type assertions on each call, and the vast majority of ops do
not make use of strings.
Signed-off-by: Dominik Honnef <dominik@honnef.co>
Without eglTerminate, using EGL will crash or report spurious errors after
creating and destroying enough contexts. The test program in #528
takes 5-10 window cycles before errors show up for me.
Fixes: https://todo.sr.ht/~eliasnaur/gio/528
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit defines an environment-variable-based debug mechanism allowing
users to toggle various debug features of their applications at runtime. The
only currently supported features are debug logging in the text stack and
suppressing the usage message that would otherwise be printed if you supplied
a malformed GIODEBUG value. The syntax is a comma-delimited list of features
right now. To see the usage, set the variable to the empty string (or any other
unsupported value):
$ GIODEBUG="" go run .
To suppress the usage message, use GIODEBUG=silent. This may be helpful for scripts
trying to activate debug features and inspect their output across versions of Gio
with different debug options available.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
When building GPU vertices from paths, we call stroke.SplitCubic once
per OpCubic. Before this change, each call to stroke.SplitCubic would
allocate a slice, which we would only use to iterate over.
This allocation can be easily avoided by reusing the slice. We can
conveniently store it in gpu.quadSplitter.
In a real application that renders hundreds of paths with tens of
rounded rectangles per path, this saved roughly 4500 allocations (or 1
MB worth) per frame.
Signed-off-by: Dominik Honnef <dominik@honnef.co>
When the line overlaps itself backtracking exactly, e.g.
path.MoveTo(0, 100)
path.LineTo(100, 0)
path.LineTo(0, 100)
then acos calculation is relatively unstable. By using atan2 it avoids
some of such problems in the calculation. Additionally, it simpliflies
the round join calculation.
Fixes: https://todo.sr.ht/~eliasnaur/gio/474
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
All GPU APIs except OpenGL ES 2 can generate mipmaps for textures.
This trades 33% more GPU memory use for improved rendering quality
and speed for downscaled images.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Before that change, Gio could crash when the WebGL context was lost
unexpectedly. Now, Gio will properly handle such situation and
recreate the buffers/resources when context is restored and will
wait until context is recovered.
Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
The Nix version of the macOS toolchain has difficulties compiling
Objective-C modules; disable modules instead of figuring out why.
It also doesn't include any frameworks automatically; add them explicitly.
While here, move suppression of OpenGL deprecation to a GL-specific
file.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Using clean struct creation creates a lot of temporary variables in
assembly. Inline the assignments, which generates less code.
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
Size and NumRefs are always used together, so consolidate info to
a single table to avoid two separate lookups.
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
As suggested by Egon Elbre, passing a large struct of function pointers
forces Cgo checks on all of the pointer on every Cgo call. This
change instead passes only the relevant function pointer.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
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>
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>
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>
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>
vkDeviceWaitIdle and vkQueueWaitIdle are expensive; a vkFence is cheaper
and the usual way to ensure a previous frame has completed before starting
another.
References: https://todo.sr.ht/~eliasnaur/gio/375
Signed-off-by: Elias Naur <mail@eliasnaur.com>
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>