Click and Hover both stored the first PointerID they observed in
their internal pid field and only updated it when not currently
hovered/entered. Once the gesture became hovered, any later event
under a different PointerID was effectively ignored: Click.Press
fell through 'c.pid != e.PointerID' and was silently dropped, and
Hover could never reset entered when the matching Leave arrived
under a new ID.
The Windows backend enables EnableMouseInPointer
(app/os_windows.go), under which Windows reassigns the same
physical mouse's PointerID across focus changes, window
leave/re-enter, and similar events. Once a widget had been hovered,
every subsequent press on it failed to register, including
widget.Editor's internal clicker that positions the caret on press.
Multi-line editors silently refused to move the caret on click
after the window had received any focus event.
Always take the latest PointerID on Hover.Enter and Click.Press.
The Press/Release handshake still works because Press now records
the press's own PointerID and Release continues to gate on
'c.pid != e.PointerID' so an unrelated pointer's release can't end
the press tracking.
Signed-off-by: Eugene <eugenebosyakov@gmail.com>
Previously, using SVG fonts will cause Gio to render invisible
"characters".
Now, some fonts (like Noto Sans Emoji) will be rendered
based on "Outline". Gio don't support SVG fonts, but now
it will show the outline ("black-and-white") alternative.
Signed-off-by: Lucas Rodrigues <inkeliz@inkeliz.com>
Fix several issues in the IME implementation
- Typing after an editor regains focus will not add text at the begging of the Editor.
- On Safari iOS, selecting a keyboard suggestion no longer duplicates the text.
- Replacing selected text now occurs at the correct position.
This patch change how "input" event is handled, instead of consider all events the
same.
Signed-off-by: Lucas Rodrigues <inkeliz@inkeliz.com>
Config.Focused represents window interaction focus, which should only
change when the window gains or loses user interaction capability.
The focus state is already correctly handled in:
- onResume → focused = true (window gains interaction focus)
- onPause → focused = false (window loses interaction focus)
Therefore, sending additional ConfigEvent in onStop and onSurfaceDestroyed
is redundant because:
- onStop is always preceded by onPause
- onSurfaceDestroyed is a low-level surface event unrelated to focus
This cleanup aligns the Android implementation with the correct semantic
that Config.Focused = window interaction focus, not view focus or
surface state.
Signed-off-by: CoyAce <akeycoy@gmail.com>
UIScene notifications are the correct way to track window focus on
iOS 13.0+, because the Key Window API is scene-level on iOS 13.0+,
but we need to maintain support for iOS 12 and earlier.
Implementation strategy:
- iOS 13.0+: Use UIScene notifications (DidActivate/WillDeactivate)
- iOS 12 and earlier: Keep existing UIWindow notifications as fallback
- Add runtime version checks to select the appropriate API
Key changes in os_ios.m:
- Add @available(iOS 13.0, *) checks
- Register both notification types with conditional logic
- Ensure proper cleanup of observers when moving between windows
See: https://developer.apple.com/documentation/uikit/uiscene?language=objc
Fixes: https://lists.sr.ht/~eliasnaur/gio/%3CCAMAFT9Uyh_JWrkQQt+AmekJWFBqhZPsP_3ZxC1fUNB+=VGGorw@mail.gmail.com%3E
Signed-off-by: CoyAce <akeycoy@gmail.com>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
1. When selecting multiple lines of text, the rendered selection area does not include the last character of the first line.
2. When selecting a specific line (other than the last line) in multiline text, the last character of that line cannot be selected.
Signed-off-by: CoyAce <AkeyCoy@gmail.com>
This commit fixes the association of diacritical marks with the proper script
during text segmentation, as well as fixing the visual position of diacritical
marks. The prior code inverted the Y axis positioning for diacritics, which made
them frequently overlap the glyph they were meant to appear above or below.
Signed-off-by: runitclean <runitclean@disroot.org>
since dataDir() must call after main(), it's redundant to use channel to send path
Signed-off-by: CoyAce <AkeyCoy@gmail.com>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Now, it's possible to launch one Gio app using a custom URI scheme, such as `gio://some/data`.
This feature is supported on Android, iOS, macOS and Windows, issuing a new transfer.URLEvent,
containing the URL launched. If the program is already open, one transfer.URLEvent will be
sent to the current app.
Limitations:
On Windows, if the program listen to schemes (compiled with `-schemes`), then just a single
instance of the app can be open. In other words, just a single `myprogram.exe` can
be active.
Security:
Deeplinking have the same level of security of clipboard. Any other software can send such
information and read the content, without any restriction. That should not be used to transfer
sensible data, and can't be fully trusted.
Setup/Compiling:
In order to set the custom scheme, you need to use the new `-schemes` flag in `gogio`, using
as `-schemes gio` will listen to `gio://`.
If you are not using gogio you need to defined some values, which varies for each OS:
macOS/iOS - You need to define the following Properly List:
```
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>yourCustomScheme</string>
</array>
</dict>
</array>
```
Windows - You need to compiling using -X argument:
```
-ldflags="-X "gioui.org/app.schemesURI=yourCustomScheme" -H=windowsgui"
```
Android - You need to add IntentFilter in GioActivity:
```
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="yourCustomScheme"></data>
</intent-filter>
```
That assumes that you still using GioActivity and GioAppDelegate, otherwise more
changes are required.
Events are routed to a new app.Events, which are not linked to a specific window.
Signed-off-by: inkeliz <inkeliz@inkeliz.com>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Also replace calls to the deprecated StringToUTF16Ptr syscall.
Signed-off-by: inkeliz <inkeliz@inkeliz.com>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
We're about to send messages between multiple instances of the same
program, and we need something to distinguish Gio programs. Use the
app ID.
Signed-off-by: inkeliz <inkeliz@inkeliz.com>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
When Gio is embedded (such as on Android and iOS), we pretend that the
Go library is the main program by running Go main on the main thread.
To avoid deadlock, `app.Main` returns immediately to relinquish control
of the main thread.
This behaviour is suprising (what if something else runs after `app.Main`?)
and more importantly is not compatible with app global events received
by the main goroutine.
Something had to give, and this change starts a new goroutine for calling
Go's main.
Signed-off-by: inkeliz <inkeliz@inkeliz.com>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Inspired by the discussion at golang.org/issue/70089, this change makes
our particular NSApplicationDelegate implementation optional.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Using cgo.Handle allows us to pass a reference to a Go function through
the GCD API for running main thread code, saving a goroutine and a channel.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Fixes the 1px overlap of curve quads. Without this patch the rendered quads
were skewed vertically and were 2 pixels shorter in height. The NorthWest
pixels were moved to the SouthWest instead of NorthWest and the SouthEast
pixels were moved to the NorthEast instead of SouthEast.
References: https://todo.sr.ht/~eliasnaur/gio/339
Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
Signed-off-by: Elias Naur <mail@eliasnaur.com>