If GLES support is enabled on Windows, force GLES mode if we are running
on a ARM64 version of Windows (i.e. Windows 10 for ARM).
This is required as ARM64 versions of Windows only provide a software
implementation of OpenGL 1.1/1.2, which is not enough for our purposes.
Thus, we could make instead use the GLES support provided via Google's
libANGLE (which emulates OpenGL/ES 3 with Direct3D 9/11), so that we
can run GtkGLArea programs under OpenGL/ES in ARM64 versions of Windows.
Note that eventually we could update the libepoxy build files for Windows
to not check nor enable WGL when building for ARM64 Windows, as the WGL
items do not work, although they do build.
The Quartz Window Manager adds to the Windows menu all NSWindows with
titles. Since we assign a default title to all windows that produced a
rather cluttered Windows menu containing among other things dialogs.
Setting aside that dialogs don't belong in the Windows menu, if
a dialog was hidden for reuse instead of destroyed it would persist in
the Windows menu and if clicked there would show, but because it wasn't
running wouldn't respond to events and so couldn't be hidden again and
would remain on top of its parent window.
Ref: https://bugs.gnucash.org/show_bug.cgi?id=797807
Fix scheduling of the frame clock when we don't receive "frame drawn"
messages from the compositor.
If we received "frame drawn" events recently, then the "smooth frame
time" would be in sync with the vsync time. When we don't receive frame
drawn events, the "smooth frame time" is simply incremented by constant
multiples of the refresh interval. In both cases we can use this smooth
time as the basis for scheduling the next clock cycle.
By only using the "smooth frame time" as a basis we also benefit from
more consistent scheduling cadence. If, for example, we got "frame
drawn" events, then didn't receive them for a few frames, we would still
be in sync when we start receiving these events again.
When an animation is started while the application is idle, that often
happens as a result of some external event. This can be an input event,
an expired timer, data arriving over the network etc. The result is that
the first animation clock cycle could be scheduled at some random time,
as opposed to follow up cycles which are usually scheduled right after a
vsync.
Since the frame time we report to the application is correlated to the
time when the frame clock was scheduled to run, this can result in
uneven times reported in the first few animation frames. In order to fix
that, we measure the phase of the first clock cycle - i.e. the offset
between the first cycle and the preceding vsync. Once we start receiving
"frame drawn" signals, the cadence of the frame clock scheduling becomes
tied to the vsync. In order to maintain the regularity of the reported
frame times, we adjust subsequent reported frame times with the
aforementioned phase.
This adds a "release" destructor for the gtk_surface1 interface which
signals to the server that a surface has been destroyed on the client
side, which the current "destroy" does not do.
Ideally the protocol would have specified a destroy request marked as
destructor to handle this automatically, however this is no longer
possible due to the destroy method being implicitly generated in the
absence of an explicit request in the protocol. Adding a destroy request
marked as destructor now would generate a new destroy method that
unconditionally would send the request to the server, which would break
clients running on servers not supporting that request.
When the application does not receive "frame drawn" signals we schedule
the clock to run more or less at intervals equal to the last known
refresh interval. In order to minimize clock skew we have to aim for
exact intervals.
(cherry picked from commit f5de46670b)
We try to step the frame clock in whole refresh_interval steps, but to
avoid drift and rounding issues we additionally try to converge it to
be synced to the physical vblank (actually the time we get the
frame-drawn message from the compositor, but these are tied together).
However, the convergence to vsync only really makes sense if the new
frame_time actually is tied to the vsync. It may very well be that
some other kind of event (say a network or mouse event) triggered
the redraw, and not a vsync presentation.
We used to assume that all frames that are close in time (< 4 frames
apart) were regular and thus tied to the vsync, but there is really no
guarantee of that. Even non regular times could be rapid.
This commit changes the code to only do the convergence-to-real-time
if the cause of the clock cycle was a thaw (i.e. last frame drawn and
animating). Paint cycles for any other kind of reason are always
scheduled an integer number of frames after the last cycle that was
caused by a thaw.
(cherry picked from commit 91af8a705b)
When we get to a paint cycle we now know if this was caused by a
thaw, which typically means last frame was drawn, or some other event.
In the first case the time of the cycle is tied to the vblank in some
sense, and in the others it is essentially random. We can use this
information to compute better frame times. (Will be done in later
commits.)
(cherry picked from commit 82c314f1af)
When we run the frameclock RUN_FLUSH_IDLE idle before the paint,
then gdk_frame_clock_flush_idle() sets
```
priv->phase = GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT
```
at the end if there is a paint comming.
But, before doing the paint cycle it may handle other X events, and
during that time the phase is set to BEFORE_PAINT. This means that the
current check on whether we're inside a paint is wrong:
```
if (priv->phase != GDK_FRAME_CLOCK_PHASE_NONE &&
priv->phase != GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS)
return priv->smoothed_frame_time_base;
```
This caused us to sometimes use this smoothed_frame_time_base even
though we previously reported a later value during PHASE_NONE, thus
being non-monotonic.
We can't just additionally check for the BEGIN_PAINT phase though,
becasue if we are in the paint loop actually doing that phase we
should use the time base. Instead we check for `!(BEFORE_PAINT &&
in_paint_idle)`.
(cherry picked from commit a36e2bc764)
The included fribidi header is not used in gdkkeys-wayland.c and already
included in gdk.c which causes linker issues due to the header defining
a global variable.
A call to frame gdk_frame_clock_get_frame_time() outside of the paint
cycle could report an un-error-corrected frame time, and later a
corrected value could be earlier than the previously reported value.
We now always store the latest reported time so we can ensure
monotonicity.
(cherry picked from commit a27fed47e0)
In commit c6901a8b, the frame clock reported time was changed from
simply reporting the time we ran the frame clock cycle to reporting a
smoothed value that increased by the frame interval each time it was
called.
However, this change caused some problems, such as:
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/1415https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/1416https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/1482
I think a lot of this is caused by the fact that we just overwrote the
old frame time with the smoothed, monotonous timestamp, breaking
some things that relied on knowing the actual time something happened.
This is a new approach to doing the smoothing that is more explicit.
The "frame_time" we store is the actual time we ran the update cycle,
and then we separately compute and store the derived smoothed time and
its period, allowing us to easily return a smoothed time at any time
by rounding the time difference to an integer number of frames.
The initial frame_time can be somewhat arbitrary, as it depends on the
first cycle which is not driven by the frame clock. But follow-up
cycles are typically tied to the the compositor sending the drawn
signal. It may happen that the initial frame is exactly in the middle
between two frames where jitter causes us to randomly round in
different directions when rounding to nearest frame. To fix this we
additionally do a quadratic convergence towards the "real" time,
during presentation driven clock cycles (i.e. when the frame times are
small).
(cherry picked from commit 9ef3e70040)
On my X11 + nvidia setup gnome-shell doesn't report presentation times.
However it does report refresh rate. We were mostly using this in our
calculation except when computing predicted presentation time, were
it fell back on the default 60Hz.
(cherry picked from commit f1215d2d77)
If the tablet gets removed/freed while there are pad events in flight,
we leave a dangling pointer from the pad to the tablet, which may
lead to invalid reads/writes when handling the pad event(s).
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2748
Reading form the back buffer is not allowed on software renderers,
and this is reported by the buffer age, so reading from GL_BACK
should not be done when the age is 0
Closes#64
Instead of hardcoding gtk-xft-antialias, use SPI_GETFONTSMOOTHING to
determine whether antialiasing is enabled.
Make gtk-xft-rgba query more complex - try to determine display
orientation, then use that to rotate subpixel structure. This
won't help with monitors that have naturally vertical subpixels,
but should improve things for monitors that are rotated (as long
as Windows display settings are adjusted accordingly).
Partially fixes#1774
This reverts commit fc2008f240.
Turns out, we *don't* have code to maintain Z-order. Restacking
code is not doint that, it just enforces a few weird Z-order-related
behaviours.
The order in which the resources get embedded matters for reproducible
builds. In the Meson build system, gen-gdk-gresources-xml already sorts
the list, but in the Autotools build system they were previously taken
in readdir() order.
Signed-off-by: Simon McVittie <smcv@debian.org>
This means it'll always be as up to date GdkWindow::width/height. We
still skip the resize for non-configured windows though, to avoid
mapping with the wrong size.
The commit f06ee688fe also accidentally
removed the unconfigured size setting completely, so this essentially
adds it back, but always sets it.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2582
So now we essentially only inhibit the premature resize for toplevel
windows, where it is most crucial. For popups, this didn't work for two
reasons: we relied on the owner of the popup (application) to resize
according to the configured size. For custom popup operators like
Epiphany and LibreOffice, this didn't work out well, since they simply
didn't.
Making gdk do it for them in case they didn't themself did make the
popups show up properly, but there were still some weirdness in
LibreOffice where tooltips didn't still didn't get the right size. So,
even though the size set by application may be different from the one
later configured by the display server, let the applications have their
way and see their resize result immediately. It's fairly likely to be
what they eventually get anyway.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2583
Who knows who might use this for something, so lets make the
unconfigured size slightly more predictable. This doesn't fix anything
known to be broken though.
With the fixes from !1638, it shouldn't be possible for this to happen
any more. However, non-positive sizes make no sense regardless, so if
this does somehow happen, let's make sure *something* reasonable happens.
The practical result of this assertion being hit is that we emit a
critical warning and then behave the same as if !1634 had been merged,
which is known to solve the issue for the submitter.
Signed-off-by: Simon McVittie <smcv@debian.org>
We get the unconfigured size request either with or without the shadow
margin already configured, so to get some consistency with the 'saved
size', cut away any potential shadow margin from the size before
storing.
Then when using, add it back, so we always create a configure event with
the correct size.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2576
There is no way for custom Wayland surfaces to get configure events, so an
initial configure event should not be required to resize a custom surface.
Fixes#2578.
With C compilers defaulting to -fcommon, this isn't an issue, but
upcoming compilers (GCC 10 and Clang 11) will default to -fno-common,
ending up with duplicate definitions of this variable.
When we `Alt+Tab` away from a GTK application, it loses keyboard focus.
If we don't clear the modifiers, events from other devices that we
receive while unfocused will assume `Alt` is still pressed. This results
in e.g. Firefox navigating through the history instead of scrolling the
page when using the mouse wheel on it.
We don't get any information about modifiers while we are missing
keyboard focus, so assuming no modifiers are active is the best we can
do.
The shell sends us a modifier update immediately before we regain
keyboard focus, so the state shouldn't get out of sync.
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/2112
We're normally going from a fixed size to a floating state when we're
using the saved size, meaning we're practically always going towards a
state where the shadow margin will non-empty. However, if we don't
include any margin when creating a new configure request, we'll end up
resizing to a slightly smaller size as gtk will cut off the margin from
the configure request when changing the window widget size.
This wasn't visible when e.g. going from maximized to floating, as we'd
add the shadow margin at a later point, which would effectively "grow"
the widnow size, but when we're going from tiled to floating, we both
start and end with a non-empty shadow margin, meaning we'd shrink ever
so slightly every time going between tiled and floating.
We should never save a size when we're tiled, just as we shouldn't when
we're maximized. This fixes returning to the correct floating size after
having been tiled or maximized.
If a window is configured with a fixed size (it's tiled, maximized, or
fullscreen), ignore any resize call that doesn't respect this. The set
size will instead be saved, when appropriate, so that the new size is
used when e.g. unmaximizing.
This makes it possible to call 'gtk_window_resize()' while the window is
maximized, without the window actually changing size until it's
unmaximized. Changing size to a non-maximized size is a violation of the
xdg-shell protocol.
An application may want to set a fallback size of a window while still
mapping maximized. This is done by calling gtk_window_resize() before
gtk_window_maximize() and before gtk_window_show(). When the window is
mapped, it should have a maximized size, and if it eventually is
unmaximized, it should fall back to the size from the earlier
gtk_window_resize() call.
What happens before this commit is that the initial window size ends up
respecting the first gtk_window_resize() dimensions, and not the window
dimension configured by the Wayland display server (i.e. maximized
dimensions).
Fix this by postponing any configure events until we received our
configuration from the display server. If we got one with a fixed size
(e.g. we're maximized, tiled etc), we use that, otherwise we look at the
one that was previously configured by gtk which corresponds to the
"preferred" size when not being maximized.
This fixes Firefox being started in a maximized state when using the
Wayland backend.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2538
gtk+-3.24.14 with quartz backend fails to compile on macOS when using
a case-sensitive file system. The cause for the compilation error is a
simple typo in line 26 of `gdk/quartz/gdkquartz-gtk-only.h`. The
AppKit framework is included there with `<Appkit/Appkit.h>` instead of
`<AppKit/AppKit.h>`, which is fixed with this commit.
References: https://trac.macports.org/ticket/60168
Fixes: https://gitlab.gnome.org/GNOME/gtk/issues/2503
If NULL is returned, probably the client shouldn't advertise the
mimetype. Make it sure we forget entirely about the attempt to
cache this mimetype, as it'll be mistaken as pending otherwise.
Dropping this cached selection will in consequence close the fd
of all pending readers, which seems appropriate for NULL content.
https://gitlab.gnome.org/GNOME/gtk/issues/2456
The only way to have G_IO_ERROR_CANCELLED in the write callback
goes through having the array of pending writers already cleared.
It should not access the invalid AsyncWriteData and StoredSelection
in that case.
gdk_window_impl_quartz_release_context () can be called with a NULL CGContextRef. This causes CoreGraphics assertion failures when debugging a Gtk application in Xcode, as the code was blindly passing that NULL to CGContextRestoreGState () and CGContextSetAllowsAntialiasing (). Given that the matching pair of CGContextSaveGState () and CGContextSetAllowsAntialiasing () calls are already checking for a NULL CGContextRef, it seems reasonable to wrap these calls in a NULL check.
Cache separately the selection contents for each given window/selection/atom
combination, and keep the requestors separate for each of those.
This allows us to incrementally request multiple mimetypes, and dispatch
the requestors as soon as the data is up. This stored selection content is
cached until the selection owner changes, at which point all pending readers
could get their transfers cancelled, and the stored content for the selection
forgotten.
For a given OpenGL context, macOS in particular does not support enumeration / detection of OpenGL features that have been promoted to core OpenGL functionality. It is possible other drivers are the same. This change assumes support for GL_ARB_texture_non_power_of_two with OpenGL 2.0+, GL_ARB_texture_rectangle with OpenGL 3.1+ and GL_EXT_framebuffer_blit with OpenGL 3.0+. I failed to find definitive information on whether GL_GREMEDY_frame_terminator has been promoted to OpenGL core, or whether GL_ANGLE_framebuffer_blit or GL_EXT_unpack_subimage have been promoted to core in OpenGL ES. This change results in a significant GtkGLArea performance boost on macOS.
Closes#2428
When a device is added, there are two references to it by the device
manager, the initial one and the one used for the id_table. Removing a
device only removed the reference added by the id_table resulting in the
GdkDevice being leaked.
https://gitlab.gnome.org/GNOME/gtk/merge_requests/1359
On Wayland, opening and closing a `GdkDisplay` generates a coupe of
warnings at runtime:
```
GLib-GObject-WARNING **:
invalid cast from 'GdkWindowImplWayland' to 'GdkWindow'
GLib-GObject-WARNING **:
invalid cast from 'GdkWaylandWindow' to 'GdkWindowImplWayland'
```
This is from `gdk_window_impl_wayland_finalize()` which tries to cast
the given GObject to a `GdkWindow` while it's a `GdkWindowImplWayland`.
Use the correct type casting of objects to avoid the warnings.
The sed -i flag is non-standard, and may not be available in all
implementations.
The meson build already requires wayland >= 1.14.91 and uses
private-code, so just do that in the autotools build as well.
Window scale can change at runtime. If cairo_surface is already
created for root window gdk_pixbuf_get_from_window will return
wrong image.
_gdk_x11_screen_set_window_scale already updates window_scale for
root window, update also cairo_surface device scale.
https://gitlab.gnome.org/GNOME/gtk/merge_requests/1208
Also ensure that gdkquartz-gtk-only.h is included in distribution
tarballs.
Failing to include gdkquartz-gtk-only.h in gdkselection-quartz.c
caused the compiler to not set the extern storage class on the
functions, in turn causing them to be not exported by libgdk-3.0.dylib.
Fixes https://gitlab.gnome.org/GNOME/gtk/issues/32 again.
Otherwise the icon "jumps" to the cursor position with its top left when
the animation starts.
This is especially visible if the dragged item is big, like when dragging
mails in Thunderbird.
With some GL drivers, it may be the case that menus are not shown
correctly in fullscreen GL windows because DWM is deactivated in the
process.
Force WS_BORDER to be applied to the fullscreen GL window so that we have
a small 1px border when needed (by setting an envvar), so that DWM does
not get deactivated, hence enabling the menus to show. Also, when we
force WS_BORDER to be applied in this situation, we also deliberately
place the window just outside the top lefthand corner of the screen by
1px and make the window 1px larger than the screen size, so that we
effectively hide the 1px border from view.
Fixes issue #1702.
We also need to force redraw of the whole window when we are using
EGL/ANGLE during un-fullscreen, so that we do not get glitches in the
resulting window.
_gdk_win32_display_convert_selection() does not return anything,
it generates a selection notify event instead. Depending on how
successful it was, the event will have property=GDK_NONE or
property="GDK_SELECTION".
property="GDK_SELECTION" is the default return value for successful
cases, and it tells GTK to grab the data that GDK previously deposited
using selection_property_store().
The problem is that the clipboard branch of this function calls
open_clipboard_timeout(), which can't return anything meaningful (it's
normally a timeout function), and thus doesn't know whether the function
succeeded or failed. Due to my oversight, this resulted in GDK
generating two selection notification events - one from inside of
open_clipboard_timeout() (with the right property, if successful),
and one from the catch-all last line (always defaulting to "GDK_SELECTION").
This caused issue #2223, where GTK only expected exactly one
notification per request, and got confused because it was getting two.
I've looked at the code in open_clipboard_timeout(), and it seems to me
that it always generates a notification (a successful one or an
unsuccessful one). Thus the branch of the function that calls it
directly does not need to follow up with a catch-all notification and
can just return.
This seems to be fixing issue #2223, at least for me, but i'm not
entirely sure that this will not have any adverse side-effects.
Clipboard handling in GTK3 is a complicated mess.
Instead, use the standard library().
This is a meson best practice.
Fixes#2248.
Fixes -Ddefault_library=static not having any effect.
Cherry-Picked-From: bb9c07d8fe
It can be tricky to deal with both, so let's give an example of using
both gdk_event_get_scroll_direction() and gdk_event_get_scroll_deltas().
Closes: #2048
For page up/down events (Fn+up_arrow and Fn+down_arrow on macOS)
gtk_im_context_filter_keypress() currently returns TRUE when im-quartz is
used. This means these events get removed when this function is used
(happens e.g. with the Scintilla text editing library).
Adding scrollPageDown: and scrollPageUp: into GdkQuartzView seems to
resolve the issue as these seem to get called instead of the already
present pageUp: and pageDown:.
We are interested in changing the owner window, so the upper bits know
that it is not this client who owns the selection. We are still not
interested in unsetting the selection desktop-wide though, so only avoid
emitting the relevant events then.
The same reasonings than in commit 7a891eeb6d apply otherwise.
Use RemoveClipboardFormatListener() and AddClipboardFormatListener().
These APIs remove the need for us to maintain the integrity of the
clipboard chain, which turned out to be problematic for some reason
that is yet to be identified.
Fixes#2215Fixes#442
This should just be called by the upper layers (and result in
wl_data_device.set_selection, etc). We should not trigger this within
the backend otherwise.
Related: https://gitlab.gnome.org/GNOME/mutter/issues/878
This should only be explicitly unset (face to the windowing) on
gdk_selection_owner_set() with a NULL window. Other circumstances
(eg. selection being taken over by another client) should just
trigger the SelectionClear event in GDK internally.
Related: https://gitlab.gnome.org/GNOME/mutter/issues/878