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>
A Window can now be requested to change its options after
it has been started via its Option method.
All options are supported on macOS, Windows and X11.
On Wayland, only the Size and Title options can be changed
at runtime.
Signed-off-by: pierre <pierre.curto@gmail.com>
Switching to pointer values in Options, including using window manager defaults for size and title, in preparation for updating options on the fly.
Signed-off-by: pierre <pierre.curto@gmail.com>
The option field WindowMode allows changing the window mode of an application in either Windowed or Fullscreen.
Only macOS, Windows and X11 platforms are currently supported.
Updates gio#89.
Signed-off-by: pierre <pierre.curto@gmail.com>
Package wm (for "window manager") is a better fit for the package, and
distinguishes it from the low-level package windows for the Windows API.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Add support to Router so that the cursor can be changed with CursorNameOp without any mouse movement.
Enter and Leave events are also delivered as areas change.
Signed-off-by: pierre <pierre.curto@gmail.com>
Using Window.Invalidate for animation with, say
var w Window
var e FrameEvent
w.Invalidate()
e.Frame(...)
stops and immediately starts animation mode which is inefficient
and may cause jitter in the redraw timing.
InvalidateOp is the efficient and sure way to achieve smooth animation,
and Invalidate only exists for external events where there is nowhere to
add an InvalidateOp.
We can do better, so this change makes Invalidate almost as efficient as
InvalidateOp by checking for Invalidates at the same time we check for
InvalidateOps.
Note that we can't avoid the inefficiency in all cases, for example
when the calls above are swapped,
e.Frame(...)
w.Invalidate()
the Invalidate may not be registered before the check during Frame.
While here, add a note to Invalidate that it's meant for externally
triggered redraws.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Previously, the only way to manipulate the clipboard (read or write) is
using the `app.Window`.
The new `clipboard.ReadOp` and `clipboard.WriteOp`makes possible to
read/write from the widget.
Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
API change. Update your code with gofmt rule and goimports:
gofmt -r "system.ClipboardEvent -> clipboard.Event"
goimports
Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The Window creates the context, and should also be responsible for
destroying it.
As a bonus, the wrong release ordering of loop.renderLoop is fixed.
Before this change, the context would be destroyed before the renderer
got a chance to destroy its resources.
Signed-off-by: Elias Naur <mail@eliasnaur.com>