Commit Graph

107 Commits

Author SHA1 Message Date
Pierre Curto 5ce1e98282 app: use material.Decorations on undecorated platforms
This patch implements a mechanism for customizing window
decorations.
If a window is configured with app.Decorated(true), then
the widget/material.Decorations are applied. On Wayland,
the option is automatically set when the server does not
provide window decorations.

Server side decorations are no longer requested.
The Decorated flag is set according to the
server's requests.

Wayland is now the default driver for UNIX platforms.

References: https://todo.sr.ht/~eliasnaur/gio/318
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2022-01-27 15:32:42 +01:00
Elias Naur 1bad440ef6 app: ensure deferred functions are run outside of FrameEvents
Simplify callbacks.Event a bit while here.

Fixes: https://todo.sr.ht/~eliasnaur/gio/348
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-27 12:13:20 +01:00
Elias Naur 1de8c9f3b0 app: process one event at a time
Commit 11aec807b2 added a waiting flag to avoid
processing platform events recursively. However the flag was only true when the
window goroutine is blocked waiting for client events, so deferred window
functions such as Window.Option may still runs multiple times for recursive
events.

This change renames the flag to busy and sets it during the entire processing
of an event, including recursive events and deferred window functions.

Fixes: https://todo.sr.ht/~eliasnaur/gio/344
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-18 12:27:54 +01:00
Pierre Curto b15a9cb595 app: update Window for macOS, X11 and Wayland
Commit #c4f98d3c1eab201419be255fafb139f7e10ad273 added
the Minimized and Maximized options for the Windows platform.
This change adds those for the remaining desktop platforms.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2022-01-18 12:00:20 +01:00
Jan Kåre Vatne c4f98d3c1e app: [API] add minimized window mode, change methods to options
The window modes are extended, following microsoft conventions.
We have Fullscreen, Overlapping, Maximized and Minimized.
These modes can be set via options when a new window is creates,
or modified later by calling helper functions like w.Maximize() and w.Center()

The window configuration is automatically updated when a user
modifies the window by dragging or clicking the icons on the window's title-bar,
minimizing or maximizing the window.

Any change, either by the user or the application will emit a ConfigChange event.

This is implemented and tested on Windows only.

API change. the app.Window methods Maximize and Center are replaced with similar
options. For example, to maximize a window use

    w.Option(app.Maximized.Option())

Also, Maximize and Center implementations for X11 and macOS are left for a future
change.

Fixes: https://todo.sr.ht/~eliasnaur/gio/315
Signed-off-by: Jan Kåre Vatne <jkvatne@online.no>
2022-01-15 17:30:22 +01:00
Pierre Curto fcaadb3698 app: remove unused types and func arguments
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2022-01-15 16:55:13 +01:00
Elias Naur 23bd7aa1d4 app: don't call Window.driverDefer for cursor updates
Like d951d07c93, calls to Window.updateCursor happens on the
evennt loop thread, and so must not go through Window.driverDefer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-13 19:47:48 +01:00
Elias Naur d951d07c93 app: don't call Window.driverDefer for direct callbacks
The internal calls to ReadClipboard and WriteClipboard happen during a callback
from the event loop. This change avoids the roundtrip through driverDefer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-13 16:03:12 +01:00
Elias Naur b2a99fddca app: run driver callbacks after event processing
Running, for example, Window.Close during a FrameEvent processing doesn't end
well on platforms that immediately destroys the window.  This change defers
callbacks to after the completing the current event.

Fixes: https://todo.sr.ht/~eliasnaur/gio/340
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-11 09:03:18 +01:00
Elias Naur 454e75dd14 app: don't process Window state updates before client is ready for events
On Android, a call to update soft keyboard state may result in focus events.
Before this change, the client would still be blocked in FrameEvent.Frame,
resulting in a deadlock.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-08 16:24:08 +01:00
Elias Naur 11aec807b2 app: deliver one event at a time to client
If the client calls, say, Window.Configure during a frame which in turn results
in a ConfigEvent, the program deadlocks. This change implements a queue of
events to be delivered after processing another.

Fixes: https://todo.sr.ht/~eliasnaur/gio/337
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-07 18:09:18 +01:00
Elias Naur 4f5baa9a51 app: let drivers control Window directly
Before this change, Window driver callbacks would all go through
channels to be processed by Window.run. However, Window.run may call
into the driver, which again may invoke a Window callback. These
re-entrant calls have been a source of deadlocks and subtle errors,
resulting in increasingly complex channel logic. This change eliminates
the goroutine split between Window and the driver, allowing callbacks
between Window and the driver without restrictions.

The goroutine split between Window and the driver is historical and
was meant to tame the complicated callback logic of drivers into a nice
for-select loop. However, the complexity isn't worth the gain, and there is
no concurrency concerns because there is always a 1:1 correspondance between
a driver goroutine and its Window object.

Fixes: https://todo.sr.ht/~eliasnaur/gio/329
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-04 17:01:05 +01:00
Elias Naur 787295a6e8 app: fix typo
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-01-03 16:23:37 +01:00
Elias Naur e6e69812af app: expose semantic information to Android platforms
Previous changes added semantic API and semantic information to Gio
widgets. This change maps the information to Android accessibility
classes so that TalkBack can traverse and interact with Gio programs.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-12-01 17:57:04 +01:00
Pierre Curto ebb7f40e9d app: implement Window.Close for Wayland
This is a followup from a question sent to the mailing list.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-11-26 22:28:47 +01:00
Pierre Curto a699f771c6 app: add Maximize and Center methods support for macOS and X11
Commit 9835cd59 added support for the Window.Maximize and
Window.Center methods for Windows only.
This patch also adds support for macOS and X11.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-11-16 18:41:22 +01:00
Jan Kåre Vatne 9835cd5996 app: add Window.Maximize and Center, add Windows implementation
Signed-off-by: Jan Kare Vatne <jkvatne@online.no>
2021-11-10 17:03:23 +01:00
Elias Naur d6e6ca848a app: don't miss driver defers
Fixes gio#281

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-30 18:21:18 +02:00
Elias Naur 6c1f9c19f5 app,internal/vk: [Vulkan] skip frame with stale window dimensions
While here, add a missing nil check.

Updates gio#280

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-30 17:46:23 +02:00
Elias Naur bdd0893dd0 app,gpu: move errDeviceLost from package app to package gpu
The Vulkan backend can return device lost error from more than just
Present.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-21 17:53:58 +02:00
Elias Naur af6770de18 app: add error result to context.RenderTarget
Vulkan may report VK_ERROR_OUT_OF_DATE_KHR which is not a fatal error.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 15:13:00 +02:00
Elias Naur 18c2ba8e20 app: replace Window.Config with ConfigEvent
Unlike Raise, Close and other fire-and-forget methods on Window,
Config calls driverRun because it needs to wait for the result.
However, driverRun isn't guaranteed to block in all contexts.

This change avoids the synchronization dance altogether by removing the
Config method and introducing a ConfigEvent event. The event also makes
it clear when the configuration changes.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-20 08:18:03 +02:00
Elias Naur c9d85c97e1 app: process driver funcs before queueing more
Window.driverFunc says it can be run from any context. However, running
it from the Window.run event loop may deadlock, at least until an
unrelated event arrives from the driver (e.g. a mouse move).

Example:
Window.Invalidate is called, which caused Window.run to queue a driver
func, and notify the Window.wakeups channel. However, another
Window.Invalidate arrives just in time for Window.run to process that
before Window.wakeups, leading to a deadlock because only one driver
func can be queued.

This change fixes the problem by processing wakeups before potentially
queueing more driver functions.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-16 10:49:42 +02:00
Pierre Curto e92ca233f5 app: ignore app.Size when in fullscreen mode
Setting the window size while in fulscreen mode does not make sense.

Fixes gio#220

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-09 16:24:23 +02:00
Pierre Curto 2f66ed1dc8 app: add Window.Raise to bring a window to the front
Fixes gio#252

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-09 07:46:09 +02:00
Pierre Curto bdc2f3f4e8 app: add Window.Config, export app.Config
A Window configuration with its current option values can now be fetched during a FrameEvent.

The WindowMode and Orientation options have moved to methods on their corresponding types.

Fixes #260

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-09-07 08:06:56 +02:00
Elias Naur 74464f64dc app: use driver defer mechanism for changing animation flag
Now that Window.driverDefer can be run in any context, the special case
of setting the animation flag can use that mechanism instead of a
special purpose channel.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-05 13:58:19 +02:00
Elias Naur 9ffe43bc3a app: delete workarounds for driver callback deadlocks
Driver methods are invoked during event processing, but some of them may
generate events that would in turn deadlock because event processing is
not re-entrant. However, a previous change moved all such calls outside
event processing and so chained events can no longer deadlock.

This change deletes the workarounds.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-05 09:30:47 +02:00
Elias Naur 1796f24a38 app: introduce Window.driverDefer for blocking functions
Window.driverRun is designed to run functions on the driver event
goroutine, to avoid race conditions with internal driver state and,
more importantly, to run on the designated main or UI thread for
platforms that require that.

However, driverRun runs functions during the processing of a driver
event, so if a function in turn triggers another driver event,
deadlock occurs.

This change introduces Window.driverDefer for functions that don't need
to block event processing. Functions passed to driverDefer may
themselves trigger new events.

A few callers of driverRun remain; they need the result of their
functions but are guaranteed not to trigger new events.

Fixes gio#263

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-09-05 09:27:50 +02:00
Elias Naur 4f198b3f87 app: render on event loop thread
Before this change, the renderLoop type implemented a rendering
goroutine for rendering off the event thread. However, it's not worth
the complexity, so remove it and render on the event thread.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-29 22:00:24 +02:00
Elias Naur 45da52cee7 app: merge app/internal/wm into package app
The app and app/internal/wm packages are tightly coupled, requiring
quite a bit of forwarding types, values and constants from the internal
package to export it. Further, no other package imports package wm.

This change merges the two packages.

While here, drop the pre-Go 1.14 SIGPIPE workaround.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-29 22:00:16 +02:00
Pierre Curto 8aac73458a app: set the type of the orientation and Windowed/Fullscreen options
Those variables didn't make it clear that they were Options.

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-08-29 08:54:40 +02:00
Pierre Curto 4c2087d375 app: update comments for Options
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
2021-08-29 08:53:52 +02:00
Elias Naur 23640ec38f app,app/internal/wm: create contexts on the main thread
Instead of handing the internal/wm driver a method to run code on the
(blocked) main thread, just run the necessary driver methods on the main
thread.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-12 15:21:37 +02:00
Elias Naur 811e2b53e0 app: ensure context is nil after release
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-11 16:49:37 +02:00
Elias Naur 0bdc2e0432 app,app/internal/wm: fold context MakeCurrent/ReleaseCurrent into Lock/Unlock
While here, make context Refresh useful and remove the redundant
MakeCurrent from the window loop.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-08-08 13:53:19 +02:00
Elias Naur 13d7a8d760 app: don't release GPU context when minimized
Releasing the renderer is fine, but releasing the underlying context
introduces flicker when restoring a Gio window on macOS.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-07-15 16:15:47 +02:00
Elias Naur 9df56f44e9 app: avoid deadlock on context refresh
The platform GPU context must be Refreshed on the window event thread,
but our rendering loop must not, because it may also want access to the
window event thread.

Fixes gio#236

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-06-22 19:35:00 +02:00
Elias Naur 0e592f8bc6 app,app/internal/wm: [macOS] refresh context on display change
The NSViewGlobalFrameDidChangeNotification notification is documented to
be fired every time [NSOpenGLContext update] needs to be called.
However, the notification fails to fire on my setup when a window is
moved to a display with a different pixel scale, which leads to
incorrectly sized output.

This change gets rid of the notification and updates the context before
every frame.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-06-12 20:07:52 +02:00
Inkeliz 9b4b91fec0 app, io: [wasm, android] add support for numeric/email keyboard mode
Previously, the on-screen keyboard always displays the text keyboard,
(QWERTY or equivalent).

For optimal user experience, it's possible to specify the keyboard type
using `InputHint`. The on-screen keyboard will provide shortcuts or
restrict what the user can input.

Due to some limitations (gio#116), only numeric and text keyboards are
supported on Android.

Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
2021-06-05 17:49:08 +02:00
Elias Naur e68ee35c86 app: don't run driver functions if there's no driver
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-06-04 17:39:39 +02:00
Elias Naur d95e6f2a15 app: avoid race condition on the underlying driver
Instead of a single racy window.driver field, maintain a driver
reference for each goroutine that needs it: the window.run event loop
and the callbacks structure.

Fixes gio#230

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-06-04 10:04:23 +02:00
Elias Naur f8d201b7c2 app: don't deadlock on wakeup arriving after window closure
The previous change wasn't enough, because the `dead` channel wasn't
being closed in an orderly window close.

Add a close of the event output channel in the premature close code path
to match the orderly close.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-19 22:46:53 +02:00
Elias Naur 039b4c4bca app: tolerate delayed WakeupEvents
The event input channel is closed after receiving a DestroyEvent, to
catch any events erronously delivered after window close. However,
the recently introduced WakeupEvent *may* be delivered after window
close. This change leaves the even channel open even after closure,
which effectively ignores such events.

Fixes #227 (again)

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-19 18:29:36 +02:00
Elias Naur 8611894b4b app,app/internal/wm: introduce app.Window.Run and use it internally
app.Window implements a method for safely running functions against the
underlying native window through the driverFuncs channel. However, the
functions still run in a different goroutine than the one driving the
native event loop, which forces the implementations in package wm to do
complicated synchronization.

A previous change added a mechanism to run functions in the native event
loop thread. The macOS port needed this functionality, but with some
care it can be generalized. That's what this change does through the
new Run method.

The advantage is that the thread switch dance is now confined to
app.Window, with the help of a generic wm.Driver.Wakeup method. All
other Driver methods can then assume they run on their event loop
threads.

Run is exported because it is also needed for programs that use
Windows configured with CustomRenderer to control their own rendering.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-18 19:59:01 +01:00
Elias Naur 413bff8766 app: implement CustomRenderer option
CustomRenderer disables the construction and binding of a GPU
context to the Window. Combined with ViewEvent and gpu.New, a Gio
client can mix Gio UI and custom rendering.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-18 14:26:45 +01:00
Elias Naur 351ede917c app: use scale independent values for default window size
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-16 18:17:00 +02:00
Elias Naur 1d4bf04aa1 app/internal/wm: [macOS] use NSView+NSOpenGLContext, not NSOpenGLContextView
NSOpenGLContextView couples the window manager logic tightly with
OpenGL. Use generic NSViews, and attach NSOpenGLContext just like the
other platforms.

This change prepares for supporting GPU contexts created by clients as
well as a future Metal port.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-05-14 20:23:06 +02:00
Inkeliz d51d8b46c3 app, app/internal: [wasm,android] new Option to set Orientation
Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
2021-04-25 21:32:54 +02:00
Elias Naur a06a7a4b3c app: make Fullscreen, Windowed Options
Instead of

app.WindowMode(app.Fullscreen)

programs can now just use

app.Fullscreen

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-04-23 10:25:24 +02:00