The feature was apparently missing, as monitors were always fullscreened at the surface best monitor.
Keep using best monitor if the selected monitor is not specified, otherwise move the window to the selected monitor before going fullscreen.
gdk_vulkan_context_check_swapchain uses priv->current_format,
so we must update it first, and undo that if check_swapchain
falls. This fixes handling of high-depth back buffers in gsk.
This is useful in debugging.
The names I chose are shortened a bit from the enum values. We
use just a single depth, * for premultiplied, and f for float.
VkShaderModule's may or may not be pointers depending on the target
platform, so use pointers to hash those handles to be safe, and retrieve
them from hashes accordingly.
Fixes build on 32-bit Windows at least.
As they are generated by gi-docgen thanks to the newly added async annotations.
It allows bindings that don't expose the _finish
functions to propose less-confusing docs
This protocol lifts some functionality from the gtk-shell protocol,
namely the ability to tag dialogs as modal. Ensure to use this
new protocol if available for the task, instead of the gtk-shell
protocol.
Make the info about the required protocols an array of definitions
again (a dict instead of an array this time) and add a field that
may be used for version checks of the wayland-protocols found.
Also, make it possible to have versioned protocols in-tree. Both
of these things will allow us to ship in-tree copies of wayland-protocols
without necessarily having to bump the version we depend on.
'XPointerUngrabInfo' appears unused since
commit 26cbf87d7d ("New approach for grab tracking code")
Remove it.
Signed-off-by: Dr. David Alan Gilbert <dave@treblig.org>
Copy what gcc's libstdc++ does for vectors to avoid overflows:
1. Define a max size macro and assert against it
Note that we don't assert but actually check, because this needs
to abort even if assertions are disabled.
2. Don't do fancy math to compute new capacity.
Just size *= 2 instead and be careful about overflow.
In case the context's only reference was held by being the current
context, setting the new context would free it.
Resetting it later would then be a use-after-free.
Fixes#6694
Currently, GTK does not check the result of vkAcquireNextImageKHR() and
assumes that it always succeeds. As a result, the vkQueuePresentKHR() is
unconditionally set to wait for the semaphore passed to
vkAcquireNextImageKHR() earlier.
However, if vkAcquireNextImageKHR() fails for some reason, the semaphore
passed to it does not get signalled. This causes the presentation
command to wait for the semaphore to be signalled indefinitely, which
causes GTK to hang.
This change adds error handling around vkAcquireNextImageKHR() to make
GTK recreate the Vulkan swapchain when it is necessary or beneficial and
helps avoiding situations that could cause indefinite waits.
This reverts commit 84a304e66e.
This produces marks that are confusing to me. They don't correlate
with actual gaps in the frame cycle and often overlap with regular
'window presented' marks. Also, the function we are emitting these
marks from is called from the get_frame_time getter, and we
definitely don't want to emit marks from there.
In order for the size change check to make sense, vk_pipeline_cache_size
needs to correspond to the size of the cache we last wrote to disk.
We were forgetting to update it after saving the cache, so the
check was ineffective.
We want to store some metadata in our symbolic pngs, so make it
possible to get options when loading a png, along with the texture.
Update all callers.
Use different codepaths for known formats vs unknown formats.
Be more careful with unknown formats and always import them as
GL_TEXTURE_EXTERNAL_OES when possible (GL can't do EXTERNAL) to avoid
problems.
This is a more defensive approach towards older drivers that don't
support modifiers.
This fixes importing YUV textures on AMD Gen8.
Another approach would be to check for YUV and never try
GL_TEXTURE_2D with them, but I decided to go this way first.
Fixes#6668
Use a format of
[XXX] SYMBOL DETAILS
where SYMBOL indicates the offloading status:
🗙 - no offload
▲ - offload above, with background
△ - offload above, no background
▼ - offload below, with background
▽ - offload below, no background
For completeness' sake, also specifiy in the PIXELFORMATDESCRIPTOR to use no
depth, stencil and accum bits to initializing WGL when we can't (yet) use
wglChoosePixelFormatARB(), as we must always fist have a base legacy WGL
context using ChoosePixelFormat() before we can use that to use
wglChoosePixelFormatARB(), or if wglChoosePixelFormatARB() is somehow not
available for us.
Some drivers, however, enforces enabling depth buffers, so if we can't
acquire a pixel format that disables depth buffers, retry acquiring one
with that, which sadly is not optimal but we must make do.
Attempts to complete fix for issue #6401.
Popping an event of the queue in the IMContext handler
prevents it from being forwarded to the NSApp, in case the
(key) event was not handled by IMContext.
So I reverted to a mix of the original (4.13) and new (4.14.1) behavior
for fetching events: NSEvent lookup for IMContext uses loose matching,
so it can work with rewritten events. When sending events to NSApp, only
we're checking for an exact match.
Now in-app keyboard shortcuts (e.g. Ctrl-F2) work from within text
fields again.
We prefer it over the old DESKTOP_STARTUP_ID environment variable if we
have it and it is valid.
We have to stash and unset XDG_ACTIVATION_TOKEN in addition to
DESKTOP_STARTUP_ID now as well. This makes sure that we don't call any
library functions which might rely on some environment variables. This
way unsetting the environment variables is safe and we can then
afterwards validate and print warnings.
in the old approach it was possible that one NSEvent was
sent to the underlying NSApp multiple times. This resulted in
those events being forwarded to our (glib) event queue again.
The visual result was that no screen updates were done. Under the hood
the application was very busy with passing events around.
By popping the events off of our event queue, we make sure they're sent
only once.
Do the same checks for background coordinates that we do for the
subsurface coordinates themselves: they must be integral in both
application and device pixels.
Spew a bit less per-frame. Unfortunately, we still spew for
every frame, and fixing that would require more extensive
refactoring to centralize all logging in gskoffload.c
Add a high-level setting that gives us more freedom to tweak
font rendering knobs according to our needs. It has a 'manual'
value that lets users continue to influence font rendering using
the low-level font-related settings as before.
Once the schemas have this, we can support setting this session-wide.
See https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas/-/merge_requests/79
The initial implementation of 'automatic' font rendering is fairly
simplistic: if the monitor dpi is less than 200, prefer sharpness,
so turn on metrics hinting and slight hinting. If the monitor dpi
is at least 200, we both off.
GdkVulkanContext is deprecated and only exposed in the api because
we need it as return type of the (deprecated)
gdk_surface_create_vulkan_context() API.
In fetch_net_wm_check_window(), before updating the wmspec_check_window, a
check is performed to verify a 15s difference between last_wmspec_check_time
and the current monotonic time.
The comment suggests that this check is done to ensure that it doesn't check
for a new check window repeatedly over and over again. While that was the case
origionally, currently the last_wmspec_check_time only gets updated when
wmspec_check_window is set, which is already checked earlier, making the time
check useless.
This check causes issues on cold boots where gtk4 applications are not able
to obtain the wmspec_check_window until 15 seconds after boot, making gtk
unable to check for extended wm_hints during that time.
Fixes: #6558
Do the backend call before changing the stacking order in the
frontend. This is necessary so the backend can look at the current
stacking order to determine if it will change.
Only commit things that have changed. In the ideal scenario, only
the texture changes from frame to frame, and all the sizing related
setup and the background stay the same, causing the least amount
of work in the compositor.
Rename things so they make more sense. The dest/source naming got
a bit unclear when we added background into the mix. Now we're going
for:
source_rect - the texture region to display
texture_rect - dimensions of the subsurface showing the texture
background_rect - dimensions of the background subsurface
bounds - union of texture_rect and background_rect
Also use this opportunity to add some api docs.
Make it possible for subsurfaces to have a black background on a
secondary subsurface below the actual subsurface. Using a single-pixel
buffer for that background increases the changes that the compositor
will use direct scanout for the actual subsurface.
This changes the private subsurface API. All callers have been
updated to pass an empty background rect.
This is useful for debugging offloading without having to rely
on gstreamer giving us dmabufs. To use it, set
GDK_DEBUG=force-offload
in the environment.
If there somehow end up being no `supported_versions`, `ctx` would end
up being dereferenced before being initialised. While I think that’s
unlikely, the compiler doesn’t know that, so let’s just initialise the
variable unconditionally.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
This drops cursor and eraser source names to account for their removal
from GdkInputSource so that GDK_DEBUG=input debug message correctly
prints source type in X11 environment.
Fixes: c1d90273 ("gdk: Drop GDK_SOURCE_ERASER")
Fixes: 3285f52d ("gdk: Drop GDK_SOURCE_CURSOR")
Closes: #6619
Allow to specify a D₂ transform when attaching a texture to a
subsurface, to handle flipped and rotated content. The Wayland
implementation handles these transforms by setting a buffer
transform on the subsurface.
All callers have been updated to pass GDK_TEXTURE_TRANSFORM_NORMAL.
This should give us more flexibility for buffer size vs surface
size.
Unfortunately, mutter doesn't play along currently, so this is
only useful for kwin, weston or sway.
Add a variant of GdkCursor that obtains the texture for the cursor
via a callback. The callback gives us the flexibility to handle
fractional scales and update the cursor for cursor theme size
changes as well as scale changes.
This attempts to improve the accuracy for the "presentation_time" of an
individual GdkFrameTimings. That information is currently filled in as soon
as we get a frame callback. However, if presentation-time wayland protocol
is available, that will be used to supliment a more accurate time which
may improve future presentation-time predictions within GdkFrameClockIdle.
The protocol states that all related and sub surfaces will receive the
same information so it is safe that this could be registered for more
than just the toplevel. The information becomes idempotent.
When no action is selected, use the default cursor, and only
switch to one of the action-indicating cursors when we are over
a drop target.
Fixes: #6337Fixes: #6511
If glBufferStorage() is available, we can replace our usage of
glBufferSubData() with persistently mapped storage via
glMappedBufferRange().
This has 1 disadvantage:
1. It's not supported everywhere, it requires GL 4.4 or
GL_EXT_buffer_storage. But every GPU of the last 10 years should
implement it. So we check for it and keep the old code.
The old code can also be forced via GDK_GL_DISABLE=buffer-storage.
But it has 2 advantages:
1. It is what Vulkan does, so it unifies the two renderers' buffer
handling.
2. It is a significant performance boost in use cases with large vertex
buffers. Those are pretty rare, but do happen with lots of text at a
small font size. An example would be a small font in a maximized VTE
terminal or the overview in gnome-text-editor.
A custom benchmark tailored for this problem can be created with:
tests/rendernode-create-tests 1000000 text.node
This creates a node file called "text.node" that draws 1 million text
nodes.
(Creating that test takes a minute or so. A smaller number may be useful
on less powerful hardware than my Intel Tigerlake laptop.)
The difference can then be compared via:
tools/gtk4-rendernode-tool benchmark --runs=20 text.node
and
GDK_GL_DISABLE=buffer-storage tools/gtk4-rendernode-tool benchmark --runs=20 text.node
For my laptop, the difference is:
before: 1.1s
after: 0.8s
Related: !7021
We cannot depend on the exact event, since some events (e.g. for popups)
are rewritten. Therefore we need to determine the NSEvent based on
heuristics. The usual suspects are event type, device and timestamp.
This allows us to fix IMContext for popups.
Keep at least 1 second of frame timings.
This is necessary for 2 reasons - a real one and a fun one.
First, with the difference in monitor refresh rates, we can have 48Hz
latops as well as 240Hz high refresh rate monitors. That's a factor of
4, and tracking frame rates in both situations reliably is kind of hard
- either we track over too many frames and the fps take a lot of time to
adjust, or we track too little time and the fps fluctuate wildly.
Second, when benchmarking with GDK_DEBUG=no-vsync with a somewhat fast
renderer (*cough*Vulkan*cough*) frame rates can go into insane dimensions
and only very few frames are actually getting presentation times
reported. So to report accurate frame rates in those cases, we need a
*very* large history that can be 1000s of times larger than the usual
history. And that's just a waste for normal usage.
Previously, our reported fps numbers could be too low when the start
timings weren't complete. In that case we would use the frame time, but
the frame time is the time when the frame was rendered, which is quite a
few milliseconds before it is presented.
So in that case we would not report the difference in presentation
times, but the difference from start of rendering. However, those times
are way more variable and can smear over the whole frame because they
depend on when we received the frame callbacks to high priority GSources
as well as our own render time predictions.
This happened in particular with GDK_DEBUG=no-vsync and could report
number that are off by a factor of 2.
Now we skip any incomplete frames, because those frames never have
presentation times reported. This makes it theoretically more likely to
not being able to report fps at all, but I'd rather have no fps than fps
off by a factor of 2.
This is done with a NSCursor whose content is an NSImage. Image pixels are filled by a NSBitmap, and the format is premultiplied RGBA. So we can just use the texture downloader with GDK_MEMORY_R8G8B8A8_PREMULTIPLIED format.
While it’s documented as being safe, it triggers warnings from ubsan.
While we work out the best way to deal with that inside the
implementation of `G_ADD_PRIVATE` in GLib, let’s pragmatically just
short-circuit the code which triggers the warning here. This is helpful
because `gdk_display_get_debug_flags()` is called from a number of
locations within GTK, so is likely to be hit if anyone is running a UI
app under ubsan.
See https://gitlab.gnome.org/GNOME/glib/-/issues/3267#note_2033550
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/3267
It turns out that the workaround in 7b380b2ffc was insufficient.
During initialization, we end up calling apply_monitor_changes()
while xdg_output is set, but xdg_output_geometry isn't. Be more
careful and prevent that from wreaking havoc with negative scales.
Fixes: #6472
unsigned char is promoted to int, which lacks the 32nd bit to
make 0xff << 24 work. Explicitly cast to unsigned int to make
it clear what we want to happen.
Unspecified attributes are not interpreted as "leave this feature out",
rather as "pick a default value". For depth, stencil and accum bits the
defaults may be different than 0. For example, with AMD drivers we get:
* WGL_DEPTH_BITS_ARB: 32
* WGL_STENCIL_BITS_ARB: 8
* WGL_ACCUM_BITS_ARB: 0
Set the attributes to 0 as a hint that depth, stencil and accum buffers
should not be created.
The driver may still create them (matching criteria is "minimum" [1]),
but that's outside of our control (and unlikely to happen).
References:
[1] - WGL_ARB_pixel_format specification
https://registry.khronos.org/OpenGL/extensions/ARB/WGL_ARB_pixel_format.txt
See #6401
This fixes monitor enter and leave events on X11, and probably other
things. Previously, it looks like the coordinates were relative to the
top left corner of the window shadow and so never changed.
With our custom logic out of the way, this just works.
Maximized state is also update on move, since a moved maximized
window is no longer considered maximized in macOS land.
In macOS, when moving a maximized window, it's not automatically
restored to its default size.
In addition, GdkMacosWindow should not check surface layout properties,
since those properties are lagging, e.i. are set after the (native)
window state has been updated.
GdkSurface maintains state that shadows the actual window state.
This state is not always updated in the macos backend.
In our case, when a window is initially maximized, `setFrame:display:`
was called and `inMaximizeTransition` was set. However,
`windowDidEndLiveResize:` was never called and `inMaximizeTransition`
was never unset, making the application think the window is still
maximized.
Additionally, `windowShouldZoom:toFrame:` is only called when the window
is maximized, not when it's unmaximized.
By checking and setting the state in `windowDidResize:` we can at least
be sure that the internal maximized state is only set if the window
takes up all desktop space: the screen's visible frame.
Currently dmabuf_dep is found when the following conditions are met:
- linux/dma-buf.h is present;
- libdrm is found.
This is because Linux dmabuf support requires drm_fourcc.h which is part
of libdrm.
However, dmabuf_dep is used for two purposes:
- define HAVE_DMABUF to state dmabuf support;
- ensure the presence of drm_fourcc.h for gdk and for the
media-gstreamer module.
Decouple this, unconditionally check for libdrm and require it on
Linux. Then, use libdrm_dep only to state the drm_fourcc.h presence.
Given that now we unconditionally require libdrm on Linux, HAVE_DMABUF
depends only on the linux/dma-buf.h presence.
This will let us use a subset of the full texture, which can
be necessary in the case that converters put padding around
content in dmabufs. The naming follows the Wayland viewporter
spec.
For now, make all callers pass the full texture rect.
We are going to introduce another rect, so better to be clear in
naming. We are following the naming of the Wayland viewporter spec
and call the rectangle that we drawing into the dest(ination).
Random code can call that function and cause unexpected GL context
changes. This is especially bad because it can happen nested.
Fixes the NGL renderer breaking in the inspector when importing a dmabuf
initializes the dmabuf backend which creates a GL renderer which creates
a GL context and makes it current causing the NGL renderer to break when
it continues rendering.
Fixes#6398
The 'icon_list' implementation of gtk+3 was somehow dropped
during the early conversion of GdkWindow to GdkSurface for gtk4.
Add it again, with minor tweaks to support GdkSurface.
Share the GdkTexture-to-HICON internal API with GdkCursor.
This allows 'gtk_window_set_icon_name()' to work on win32.
Expose information about if an event is handled to the backends.
This will allow a backend to deal with unhandled events, such as
macOS' default key bindings.
The first time this function is called, has_xdg_output() returns
true, but haven't yet received all the xdg-output events, so wait
for that to be done. Otherwise, the logical size is 0, and nothing
useful comes from that.
This fixes a problem that is apparent in
https://bugzilla.mozilla.org/show_bug.cgi?id=1869724, but that also
reproduces on any GTK application as described in
https://bugzilla.mozilla.org/show_bug.cgi?id=1869724#c16.
xdg_output sizes might be physical if the compositor doesn't scale them,
it seems. So to report the correct logical geometry in GDK pixels, we
need to detect this case. We do this by checking whether the wl_output
size matches the xdg_output size.
According to the Mesa developers, the correct way to determine
disjointness is to check the actual inode of the fd because dup()ing can
cause these duplications to happen when planes are carelessly copied or
when planes are sent over dbus or other unix sockets.
Related: https://bugs.webkit.org/show_bug.cgi?id=267578
We keep various pieces of double-buffered state on our side,
and then explicitly sync it over to the Wayland side.
Add a function to find out if we have any.
The ngl renderer has good support for fractional scaling, so we
can enable this by default now.
If you are using the gl renderer, you can disable fractional
scaling with the
GDK_DEBUG=gl-no-fractional
environment variable.
When a toplevel is focused programmatically and there is no
underlying seat, we cannot attempt to focus it with no
focus to be obtained, nor serials serials to use.
Related: https://gitlab.gnome.org/GNOME/gtk/-/issues/6335
In GLES, BGRA is still done by GL_EXT_texture_format_BGRA8888 which is
an extension that is older than GLES 2.0.
And back then, internal formats had to be specified unsized. And when
that was changed with GLES3, nobody updated the extension.
However, on OpenGL, this extension doesn't exist, and internal formats
need to be sized.
So let's use different internal formats depending on GL version.
Fixes#6333
Whether or not switches include shapes to indicate their ON/OFF
state is currently controlled by the stylesheet (in particular
the HighContrast style).
However there are use cases for both using the HighContrast style
without shapes, and for using shapes with the regular stylesheet,
so follow the newly added "show-status-shapes" setting instead.
https://gitlab.gnome.org/GNOME/gtk/-/issues/5354
For tablet tools if we have NULL cursor, we use the default cursor
instead. This provides us with a tablet cursor when an application never
sets the cursor.
However, on proximity out when we clear said cursor we also
need to toggle off cursor_is_default, otherwise on the next proximity in
we assume we already have a cursor and never update it again.
This leads to an invisible cursor over GTK application when the tablet
tool is brought into proximity over the widget (but not when moving into
the widget from the outside).
Closes: #6312