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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>