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>
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>
According to @kkeybbs, pressing the maximize button on Windows only
resizes the window up to its maximum bounds. That means we can leave the
button available, and only hide it when the window has a fixed size.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
There are two max window size settings on macOS, `contentMaxSize` and
`maxFullScreenContentSize`. Set the latter to avoid a window being
resized larger than its maximum in full screen mode.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The Windows Pointer API
(https://learn.microsoft.com/en-us/windows/win32/api/_inputmsg/) was used
to allow the detection of events when interacting with touch screens. This
also opens the gates for supporting other types of input devices (e.g. pens
and touchpads). Mouse events are now part of the pointer events (primary
events trigger WM_POINTER<DOWN|UP>, whereas secondary ones vanilla
WM_POINTERUPDATE, and cancellations WM_POINTERCAPTURECHANGED).
A fourth and fifth button (usually found in modern mice) has also been added
for completeness, though their integration in other OS-es shall be the
objective of future patches.
Signed-off-by: Marc <marc.leroy@samantree.com>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
When the window is created position it *before* processing the actions
to perform (which may include system.ActionCenter). Note that the
actions are performed in the callback windowProc().
Fixes: https://todo.sr.ht/~eliasnaur/gio/646
Signed-off-by: Marcel Juffermans <mjuffermans@paradigmone.com.au>
An IME session must be discarded when its text content no longer matches
the underlying text component content. However, the check for matching
was too pessimistic; the IME session would be discarded if the new
snippet from the text component was not equal to the snippet reported to
the IME. This change implements a refined check that only discards a
session if the content of the overlap between the new and old snippets
don't match.
Fixes an IME issue reported by Zhang Zj.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
By propagation, we restore the system behaviour for shortcuts the program
don't want, for example the system beep.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The fix for #616 went to far by attempting to support macOS key bindings
through doCommandBySelector. Issue #625 is a consequence, but more
fundamentally, key bindings does not work with support for key.Release
events.
Remove key binding translation and fix#626, and add a check whether an
IME swallowed a key event, keeping #616 fixed.
While here, replace the KEY_ constants with ASCII codes.
Fixes: https://todo.sr.ht/~eliasnaur/gio/625
References: https://todo.sr.ht/~eliasnaur/gio/616
Signed-off-by: Elias Naur <mail@eliasnaur.com>
In order to avoid DLL preloading attacks, we should always load our system
dependencies using the helper that only searches the system library path.
Thanks to Mohsen Mirzakhani and Utkarsh Satya Prakash for bringing this to
our attention.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This change generates keypress and release events for modifier keys in macOS.
Specifically the Control, Alt, Shift and Command keys.
Signed-off-by: Jeff Williams <kanobe@gmail.com>
Setting the callback handler to nil in DestroyEvent should have no effect,
but may help debugging #603.
Also don't call the default window handler for WM_DESTROY since we're
already handling it.
References: https://todo.sr.ht/~eliasnaur/gio/603
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Widgets such as Editor use certain key events such as the backspace key
to implement text editing. On macOS, such key events are sometimes used
by an input method, and in those cases the key effect would be applied
twice: first by the IME and then the Editor.
Report such key events through the doCommandBySelector callback, which
receives key events not handled by the IME.
References: https://todo.sr.ht/~eliasnaur/gio/616
Signed-off-by: Elias Naur <mail@eliasnaur.com>