It appears that NVIDIA does not implement EGL_EXT_swap_buffers_with_damage
on their EGL implementation, but does implement the KHR variant of it.
This checks for a suitable implementation and stores a pointer to the
compatible implementation within the GdkGLContextPrivate struct.
We want to ensure that we recalculate the sort order of windows before
processing the motion. Generally this would be done in response from the
display server in GdkMacosWindow, but I've seen it possible to race there.
We need to handle the case where we might be racing against an incoming
configure event due to how notifications are queued from the display
server. Rather than calling configure (and possibly causing other things
to move around) this just queries the display server directly for the
coordinates that we care about.
Additionally, we can display:NO as we are in control of all the display
process now using CALayer.
We failed to handle the toplevel with transient-for case here which could
cause our X/Y calculations to be off in other areas such as best monitor
detection.
We do actually need the parent frame clock here because it is the way we
ensure that we get layout called for our popup surfaces at the same time
as the parent surface.
This doesn't appear to happen much, but if it does it is nice to setup
the window placement initially. Generally, transient-for is set after
the creation of the toplevel rather than here.
The GdkMacosBuffer object already has storage for tracking the damage
region as it is used in GdkMacosCairoContext to manually copy regions from
the front buffer to the back buffer. This makes the GdkMacosGLContext also
use that field so that we can easily drop old damage regions when the
buffer is lost. This happens during resizes, monitor changes, etc.
This helper is useful to ensure we are consistent with how we keep a
window clamped to the workarea of a monitor when placing windows on
screen. (This does not affect snap-to-edges).
Currently, we have all the plumbing in place so that GTK consumes the
startup notification ID when focusing a window through the xdg-activation
protocol.
This however misses the case that a window might be requested to be
focused with no startup ID (i.e. via interaction with the application,
not through GApplication or other application launching logic).
In this case, we let the application create a token that will be
consumed by itself. The serial used is that from the last
interaction, so the compositor will still be able to do focus prevention
logic if it applies.
Since we already do have a last serial at hand, prefer xdg-activation
all the way over the now stale gtk-shell focusing support. The timestamp
argument becomes unused, but that is a weak argument to prefer the
private protocol over the standard one. The gtk-shell protocol support
is so far left for interaction with older Mutter.
If _gdk_macos_surface_move_resize() was called with various -1 parameters
we really want to avoid changing anything even if we think we know what
the value might be. Otherwise, we risk messing up in-flight operations that
we have not yet been notified of yet.
This improves the chances we place windows in an appropriate location as
they don't et screwed up before window-manager placement.
We need to bring the application to the foreground in multiple ways, and
this call to [NSApp activateIgnoringOtherApps:YES] ensures that we become
foreground before the first window is opened. Otherwise we end up starting
applications in the background.
Fixes#4736
If we are double buffering surfaces with IOSurface then we need to copy
the area that was damaged in the previous frame to the back buffer. This
can be done with IOSurface but we need to hold the read-only lock so that
we don't cause the underlying IOSurface contents to be invalidated.
Additionally, since this is only used in the context of rendering to a
GdkMacosSurface, we know the life-time of the cairo_surface_t and can
simply lock/unlock the IOSurface buffer from begin_frame/end_frame to have
the buffer flushing semantics we want.
To ensure that we don't over damage, we store the damage in begin_frame
(and copy it) and then subtract it from the next frames damage to determine
the smallest amount we need to copy (taking scale factor into account).
We don't care to modify the damage region to swapBuffers because they
already have the right contents and could potentially fall into another
tile anyway and we'd like to avoid damaging that.
Fixes#4735
This can be used to lock a surface for reading to avoid causing the
surface contents to be invalidated. This is needed when reading back from
a front-buffer to the back-buffer as is needed when using Cairo surfaces
to implement something similar to BufferAge.
Previously, a single CVDisplayLink was used to drive updates for all
surfaces across all monitors. It used a 'best guess' rate which would
allow for updates across monitors of mixed rates. This is undesirable for
situations where you might have a 144hz monitor as it does not allow for
reaching up to that frame rate.
Instead, we want to use a per-monitor CVDisplayLink which will fire at the
rate of the monitor down to the level of updates we require. This commit
does just that.
When a surface crosses onto a new monitor, that monitor is used to drive
the GdkFrameClock.
Fixes#4732
Using the mode allows better detection of refresh rate and refresh
interval for the CVDisplayLink bridge to GdkFrameClock. Using it can help
ensure that our 144hz displays can actually reach that rather than falling
back to just 60hz.
This will also need future commits to rework the displaylink source to be
per-monitor.
When the fingers are placed on the touchpad, we get a scroll event with
the phase NSEventPhaseMayBegin. We can use this to synthesize an is_stop
event. This results in the scrolledwindow stopping scroll with stop
gestures.
This can cause another warning as well, however, which should be addressed
from #4730.
Fixes#4733
Windows can end up on different monitors despite having a parent or
transient-for ancestor. We want them to be driven by the CVDisplayLink
for the best-monitor, and so this needs to be unshared.
Currently we're using a display link that is for all active displays which
is just the display server trying to find some timings that try to overlap
as many as possible.
That was fine for a prototype, but we really need to do better for
situations with mixed frame rate (such as 60hz and 120hz promotion
displays). Additionally, the 144hz external monitor I have will never
reach 144hz using the current design.
This is just the first step in changing this, but the goal is to have
one of these attached to each GdkMacosMonitor which we can then use to
thaw surfaces specific to that monitor.
We will eventually be needing additional feedback from the display server
which would be nice to keep away from the rest of GdkMacosDisplay for
cleanliness sake. Particularly for feedback from mission control and other
environment factors that requires private API for proper integration.
This may come from different sources at around the same time, e.g.
a hold gesture while on overshoot. Avoid doing that if an
animation is already set.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4730