Commit a0f6ff101e made sure that a
context was bound before calling glClientWaitSync, but it doesn't
check that the context shares objects with the context that created
the fence.
This commit does a little more validation before deciding the current
context is good enough.
Since commit 972134abe4 we now call
glClientWaitSync for the vendor nvidia driver, to know when a frame
is ready for the compositor to process.
glClientWaitSync can be called regardless of which context is currently
bound, but if no context is bound at all, it returns 0 without
doing anything.
This commit checks for that edge case, and ensures a context gets
made current in the event no context is already current, before calling
glClientWaitSync.
When given a 0 timeout, glClientWaitSync is only supposed to return one
of three possible values:
- GL_ALREADY_SIGNALED - fence fired
- GL_WAIT_FAILED - there was an error
- GL_TIMEOUT_EXPIRED - fence hasn't fired yet
In addition, it can also return GL_CONDITION_SATISFIED if a non-zero
timeout is passed, and the fence fires while waiting on the timeout.
Since commit 972134abe4 we now call
glClientWaitSync (with a 0 timeout), but one user is reporting it's
returning some value that's not one of the above four.
This commit changes the g_assert to a g_error so we can see what
value is getting returned.
May help with https://gitlab.gnome.org/GNOME/gtk/-/issues/2858
With the vendor provided Nvidia driver there is a small window of time
after drawing to a GL surface before the updates to that surface
can be used by the compositor.
Drawing is already coordinated with the compositor through the frame
synchronization protocol detailed here:
https://fishsoup.net/misc/wm-spec-synchronization.html
Unfortunately, at the moment, GdkX11Surface tells the compositor the
frame is ready immediately after drawing to the surface, not later,
when it's consumable by the compositor.
This commit defers announcing the frame as ready until it's consumable
by the compositor. It does this by listening for the X server to announce
damage events associated with the frame drawing. It tries to find the
right damage event by waiting until fence placed at buffer swap time
signals.
This commit moves some of the end frame sync counter handling
code to subroutines.
It's a minor readability win, but the main motivation is to
make it easier in a subsequent commit to defer updating the
sync counter until a more appropriate time.
commit 14bf58ec5d dropped support
for using the DAMAGE extension since there was no code that
needed it.
We're going to need it again, however, to address an NVidia
vendor driver issue.
This commit does the plumbing to add it back.
This is not used anymore now that surfaces are always toplevel in the
semantics of GdkWindow where child windows were available. We can drop
that and simplify the vfunc just a bit more.
Fixes#2765
On X11, shortcuts inhibition is emulated using a grab on the keyboard.
So if another widget ungrabs the keyboard behind our back (for example
when a popup window is dismissed) that effectively disables the effects
of the shortcut inhibition on the surface and we need to update the
shortcut inhibition status accordingly.
Check for "grab-broken" events on the surface and clear existing
shortcuts inhibition for the matching seat, so that the client can be
notified and may decide to re-enable shortcut inhibition if desired.
In the gtk-demo drag-and-drop demo i can't drag anything, all I get
is:
(gtk4-demo:358993): Gdk-CRITICAL **: 09:36:19.617: Surface 0x7e1bb0 has not been mapped in GdkSeatGrabPrepareFunc
This is because GdkX11Drag.ipc_surface is not considered mapped, even
though we called gdk_x11_surface_show() on it, because the
GDK_SURFACE_STATE_WITHDRAWN flag is still set.
I added calls to gdk_synthesize_surface_state() to match what
e.g. show_popup() and gdk_x11_toplevel_present() does.
We currently calling gdk_display_map_keyval up to
once per key event per shortcut trigger, and that function
does an expensive loop over the entire keymap and
allocates an array. Avoid this by caching the entries
in a single array, and have a lookup table for finding
the entries for a keyval.
To do this, change the GdkKeymap.get_entries_for_keyval
signature, and change the ::keys-changed signal to be
RUN_FIRST, since we want to clear the cache in the class
handler before running signal handlers. These changes are
possible now, since keymaps are no longer public API.
The api to configure surfaces is now GdkToplevelLayout
and GdkPopupLayout. Unfortunately, there's still quite
a bit of internal use of GdkGeometry that will take some
time to clean up, so move it go gdkinternals.h for now.
GdkEvent has been a "I-can't-believe-this-is-not-OOP" type for ages,
using a union of sub-types. This has always been problematic when it
comes to implementing accessor functions: either you get generic API
that takes a GdkEvent and uses a massive switch() to determine which
event types have the data you're looking for; or you create namespaced
accessors, but break language bindings horribly, as boxed types cannot
have derived types.
The recent conversion of GskRenderNode (which had similar issues) to
GTypeInstance, and the fact that GdkEvent is now a completely opaque
type, provide us with the chance of moving GdkEvent to GTypeInstance,
and have sub-types for GdkEvent.
The change from boxed type to GTypeInstance is pretty small, all things
considered, but ends up cascading to a larger commit, as we still have
backends and code in GTK trying to access GdkEvent structures directly.
Additionally, the naming of the public getter functions requires
renaming all the data structures to conform to the namespace/type-name
pattern.
For the X11 backend, keep a list of monitors for which the surface
intersects the monitor area.
Whenever the X11 surface is configured, check against the list of
monitors to determine whether it enters a new monitor or if it left a
monitor, to emit the corresponding ::enter/leave-monitor signals just
like a Wayland compositor would.
As monitors can be added, removed or reconfigured at any time, redo
those checks whenever any of these events occur.
We don't need all of them, only the ones that contain public API. This
allows us to reduce the chance of a stray symbol getting incorrectly
added to the introspection data.
Add all of the keyboard translation results in the key event,
so we can translate the keyboard state at the time the event
is created, and avoid doing state translation at match time.
We actually need to carry two sets of translation results,
since we ignore CapsLock when matching accelerators, in
gdk_event_matches().
At the same time, drop the scancode field - it is only ever
set on win32, and is basically unused in GTK.
Update all callers.
On X11, there is no such equivalent to the inhibit shortcut protocol
found on Wayland.
To implement the inhibit_system_shortcuts API on X11, we emulate the
same behavior using grabs on the keyboard.
To avoid keeping active grabs on the keyboard that would affect other
X11 applications even when the surface isn't focused, the X11
implementation takes care of releasing the grabs as soon as the toplevel
loses focus.
Without this, the back buffers of the wrong size
keep being used, causing flickery misdraws, as
seen when expanding the expander in the popover
in widget-factory.
There is no shape combining going on anymore, so
call this just gdk_surface_set_input_region, and
remove the offset arguments too. All callers pass
0 anyway.
Update all callers and implementations.
Sprinkle various g_assert() around the code where gcc cannot figure out
on its own that a variable is not NULL and too much refactoring would be
needed to make it do that.
Also fix usage of g_assert_nonnull(x) to use g_assert(x) because the
first is not marked as G_GNUC_NORETURN because of course GTester
supports not aborting on aborts.
Drop the input-mode, since it only makes sense for
floating devices, which we don't have anymore. And renamt
::input-source to ::source, to match the getter.
Update all users.
replace all uses with const char * (non-interned).
Also remove a lot fo juggling from atom to GdkAtom to string and back.
The X Atom hash table is now mapping to (again, non-interned) strings.
We were not properly converting the coordinates we
got to root coordinates. This was showing up as offsets
between the actual drop target and the area where drops
can happen, e.g. when dragging over a stack switcher
to switch pages.
We were forgetting to clean up the ::xevent signal
handler in some error cases. Move the signal connection
later, when we know the drag is going forward, and
use g_signal_connect_object to make sure the signal
handler is not forgotten.
Restructure the getters for event fields to
be more targeted at particular event types.
Update all callers, and replace all direct
event struct access with getters.
As a side-effect, this drops some unused getters.
Make the event translator return a new event, instead of
filling in a half-constructed one.
Update the two implementation in GdkX11Display and
GdkDeviceManagerXI2.
Instead of passing a half-constructed event and expect
it to be filled in, pass the surface as in argument, and
add an out argument for a newly constructed GdkEvent.
Replace the gdk_surface_move_to_rect() API with a new GdkSurface
method called gdk_surface_present_popup() taking a new GdkPopupLayout
object describing how they should be laid out on screen.
The layout properties provided are the same as the ones used with
gdk_surface_move_to_rect(), except they are now set up using
GdkPopupLayout.
Calling gdk_surface_present_popup() will either show the popup at the
position described using the popup layout object and a new unconstrained
size, or reposition it accordingly.
In some situations, such as when a popup is set to autohide, presenting
may immediately fail, in case the grab was not granted by the display
server.
After a successful present, the result of the layout can be queried
using the following methods:
* gdk_surface_get_position() - to get the position relative to its
parent
* gdk_surface_get_width() - to get the current width
* gdk_surface_get_height() - to get the current height
* gdk_surface_get_rect_anchor() - to get the anchor point on the anchor
rectangle the popup was effectively positioned against given
constraints defined by the environment and the layout rules provided
via GdkPopupLayout.
* gdk_surface_get_surface_anchor() - the same as the one above but for
the surface anchor.
A new signal replaces the old "moved-to-rect" one -
"popup-layout-changed". However, it is only intended to be emitted when
the layout changes implicitly by the windowing system, for example if
the monitor resolution changed, or the parent window moved.
The returned position should be relative to the parent surface, but
GdkSurface::x,y were only managed properly for O-R windows. This makes
it correct for regular windows too.
The marks are averaged based on the name, so this makes more sense.
Also rename the map/unmap marks to have the same capitalization as
everything else.
When we use if (GDK_PROFILER_IS_RUNNING) this means we get an
inlined if (FALSE) when the compiler support is not compiled in, which
gets rid of all the related code completely.
We also expand to G_UNLIKELY(gdk_profiler_is_running ()) in the supported
case which might cause somewhat better code generation.
All the code in e.g. init_randr15() divides the physical resolutions with
the screen scale, however if we get the screen scale from xsettings
rather than e.g. GDK_SCALE the initial setup is using the wrong value.
So, whenever the screen scale size is changed we need to trigger
a re-read of the randr data
This adds a GDK_DEBUG=default-settings flag which disables reads
from xsettings and Xft resources, and enables this for the testsuite.
This is one less way to get different testresults depending on the
environment. In particular, it was failing the css tests for me
due to getting the wrong font size because i have a different dpi.
We only have implementations of this on X11 and Win32,
so make it available as backend api there.
Update all callers to use either the backend api, or
just monitor 0.
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/1358
According to XDND "The XdndLeave message cancels the session.",
issue one when cancelling a drag, so the dest side has an opportunity
to forget about the GdkDrop.
The drag source might be cached and held alive, only disposed after
future drag begin operations. Ensure the drag surface gets hidden
properly or might might stay transparent but mapped till then.
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.
We use a compilation symbol in our build to allow the inclusion of
specific headers while building GTK, to avoid the need to include only
the global header.
Each namespace has its own compilation symbol because we used to have
different libraries, and strict symbol visibility between libraries;
now that we have a single library, and we can use private symbols across
namespaces while building GTK, we should have a single compilation
symbol, and simplify the build rules.
The "iconified" state is mostly an X11-ism; every other platform calls
this state "minimized" because it may not involve turning a window into
an icon at all.
Previously, the manufacturer property of the GdkMonitor was NULL,
and having at least PNP id at GdkMonitor.manufacturer makes it
possible to distinguish between different monitors programmatically.
Windows/surface's aren't supposed to be explicitly moved by any external
part, so don't provide API for doing so. Usage throughout Gdk is
replaced by the corresponding backend variants.
The generic layer still does the heavy lifting, leaving the backends
more or less just act as thin wrappers, dealing a bit with global
coordinate transformations. The end goal is to remove explicit surface
moving from the generic gdk layer.
To separate how toplevels and popups are configured, a first step is to
introduce a resize-only vfunc for backends to implement. It's meant to
only configure toplevel windows, i.e. popups. Currently it's used for
both types, but introducing the resize-only API is a first step.
When unreffing the stream from a different thread, the close function
will schedule its cleanup asynchornously in the main thread.
We need to make sure the stream object stays alive for as long as
that hasn't happened, so ref() it.
Fixes#2003
To make a frame clock tick as long as any of the associated surfaces
expect to receive ticks, make the surfaces inhibit freezing the clock,
instead of directly tell the frame clock to freeze itself.
This makes it so that as long as any surface using a certain frame clock
is not frozen (e.g. just received a frame event from the display
server), the frame clock will not be frozen.
With this, the frame clock is initiated as frozen, and won't be thawed
until any surface inhibits freeze. It will be frozen again, when every
surface has that previously inhibited freeze uninhibited freeze.