We cannot bubble up ::insert-text and ::delete-text signals from the
delegate to the wrapper editable without causing an infinite recursion,
due to how the signals are designed; ideally, we would have decoupled
signal emission from virtual functions *before* releasing GTK4, but now
that we have, we can't break the contract.
The GtkEntryBufferClass.deleted_text() behaviour changed between GTK3
and GTK4, which means any subclass of GtkEntryBuffer is now responsible
for emitting the "notify" signal for the "text" and "length" properties.
Without this, the GtkText delegate widget used by GtkPasswordEntry would
not be able to communicate changes in the contents of its buffer.
Fixes: #3484
- normally lighter (on bg_color)
- darker for headerbar
- undecorated checked buttons were never style properly (even gtk3)
see page2 volume buttons
Finetunes https://gitlab.gnome.org/GNOME/gtk/-/issues/3427
Float properties can not be read from keyfiles. This was causing changes
to this property in settings.ini to be ignored. Fix this by changing it
to a double.
Technically this change could be considered an API break, but there are
no users of this property as float yet and it is early enough to expect
there to never be any.
Also document this change in the 3 to 4 migration guide since in gtk 3
this setting will be kept a float.
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3441
When being fullscreen, and wanting to unfullscreen but not caring about
whether to go unmaximized or maximized (as this information is lost), if
the GdkToplevelLayout represents the full intended state, we won't be
able to do the right thing.
To avoid this issue, make the GdkToplevelLayout API intend based, where
if one e.g. doesn't call gdk_toplevel_set_maximized() with anything, the
backend will not attempt to change the maximized state.
This means we can also remove the old 'initially_maximized' and
'initially_fullscreen' fields from the private GtkWindow struct, as we
only deal with intents now.
When deciding whether to call gdk_toplevel_present(), check the
mappedness of GtkWidget instead of the mapped-ness of GdkSurface, as the
latter is mapped asynchronously, while the former is direct state of the
GtkWindow itself.
This fixes an issue where calling e.g. gtk_window_maximize() shortly
after showing it didn't take effect, as hadn't been mapped yet. While
maximizing after showing is racy, and will likely glitch from time to
time, the correct thing to do is still to maximize and handle whatever
state the compositor configured the window to be in.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3466
- Add borders around the main scrollable content, like most other
places.
- Set padding and spacing on .emoji-searchbar and .emoji-toolbar in a
more proper way.
- Remove unused button.emoji-section label styles.
These ended up square in the various refactors. Make them again L-shaped
by extending these along the edge being checked. This means we have to
check for corner positions in all edges, though.
In order to do this, leverage smooth scroll handling into the capture
phase scroll controller, controlled by ::scroll-begin in the propagation
phase controller.
There's 2 cases here:
- A child widget handles scroll. The scrolled window does not get
::scroll-begin, the child widget handles the full scroll sequence.
- No child handles scroll, the scrolled window gets ::scroll-begin,
and transfers control of scrolling to the capture phase controller.
As scrolling is performed, the pointer may fall into scrollable children,
but the scrolled window will be capturing the scroll events, so these
won't be seen by the child widgets.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/593
We let smooth scroll events that don't trigger a ::scroll signal through.
This is unintended, these are handled, even if just accumulated.
This fixes cases like GtkSpinButton inside GtkScrolledWindow, where both
would handle events, until the GtkSpinButton eventually shifts away from
underneath the pointer.
Brought up at https://gitlab.gnome.org/GNOME/gtk/-/issues/593
This code was here in gtk3 to cater for the completion window being
positioned. That was only to meant once as long as the completion window
was shown.
This doesn't work as well for gtk4, ::size-allocate gets propagated from
the toplevel, so happens much more often for the completion window, this
ends up with the completion position being reset to the first row
frequently.
Do this simply once when popping up the completion, instead.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3083
The coordinates are already widget-local here, not transformed by the
adjustment positions. Using the adjustment value here ends up pushing
the entry far from the left border.
The correct minimum value here is 0, which matches the treeview left
border.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3009
Let model buttons handle unpaired releases, these may happen indirectly
e.g. due to other child menus being opened at the time. Clicking would
dismiss the menu, but the menu item beneath the pointer would not get
activated.
We can handle that button release though via ::unpaired-release, so
there's no second click required.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3463
Tracking it through the GtkGestureClick becomes a bit cumbersome for
handling of simultaneously pressed buttons. We can track ::stopped,
but that also emits for a number of situations where we want drag to
continue.
However, the GtkGestureDrag is grouped with the click gesture, and
knows better when to finish the drag gesture (not just because of a
button release), so hook drag and zoom mode finalization there.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3426
Having a property with the same name of a method makes some languages
which put properties and method names in the same flat namespace not
really happy about our choices. To avoid collisions, let's put the the
"fullscreen" property into the past, alongside the "maximized" property.
Drop the "don't write code that crashes" folksy bit; don't start
sentences with conjunctions; remove copy-pasted references to
"iconified" states; point to the corresponding property notification in
a consistent manner.
Currently, the implicit grab is broken on the first button release,
in the case of pressing multiple buttons simultaneously. This means
that we emit crossing events early, and the next button releases
are sent to the pointer focus widget instead.
Consider the implicit grab effective until all buttons are released,
and only unset the pointer implicit grab (and emit crossing events)
after there are no further buttons pressed. We do this by checking
event modifiers, given button release events do contain the modifiers
in effect at the time the event was generated, we have to look for
exactly one active button modifier.
Fixes weird pointer states after pressing multiple buttons on a
widget.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3426
It was used by all surfaces to track 'is-mapped', but still part of the
GdkToplevelState, and is now replaced with a separate boolean in the
GdkSurface structure.
It also caused issues when a widget was unmapped, and due to that
unmapped a popover which hid its corresponding surface. When this
surface was hidden, it emitted a state change event, which would then go
back into GTK and queue a resize on popover widget, which would travel
back down to the widget that was originally unmapped, causing confusino
when doing future allocations.
To summarize, one should not hide widgets during allocation, and to
avoid this, make this new is-mapped boolean asynchronous when hiding a
surface, meaning the notification event for the changed mapped state
will be emitted in an idle callback. This avoids the above described
reentry issue.
This makes it possible to set 'maximized' to true in .ui files, and the
window will show up maximized.
gtk_window_is_maximized() will return the intended maximized state until
actually mapped, it will then show the actual maximized state. The same
applies to reading the property.
This commit changes the behavior of window size computation and the
default size properties to:
* The default-width and default-height properties are updated to the
current window size unless the size is fixed by e.g. being maxmized,
tiled etc.
* The compute-size semantics are to just pick the default size, or if
not adequate, use the measured size, and consequently update the
default size, unless unresizable.
* gtk_window_get_size() is removed, what's more likely relevant is the
gtk_window_get_default_size() which will now contain more sensible
values.
Various places that used gtk_window_get_size() were updated to use
gtk_window_get_default_size() to remember and restore previous sizes.
This also changes the default value of 'default-width' and
'default-height' from -1 to 0. The gtk builder simplify tool is taught
how to omit when the default size is set to both -1 and 0.
This fixes an issue where the focus of the window continuously received
fake motion events even when a popover was open, making input events end
up behind the popover.
It also adds a comment describing why motion events are requested. Note
that popovers won't work with this, and it's possible both in the past
and now that sporadic missplaced motion events will appear, e.g. when a
window changes allocation but a popover is open.
While the workaround hides majority of the issue there are still two big downsides:
- shadow does eat from the widget dimensions so alignment is broken
- situations like popover going upwards on screen edge break completely
The appropriate action is to revert these theme duct tape solutions to make room
for a proper fix.
This reverts commit b3dba1dca6.
Issue https://gitlab.gnome.org/GNOME/gtk/-/issues/1987
This removes the gdk_surface_set_shadow_width() function and related
vfuncs. The point here is that the shadow width and surface size can now
be communicated to GDK atomically, meaning it's possible to avoid
intermediate stages where the surface size includes the shadow, but
without the shadow width set, or the other way around.
This changes allocation of the widget trees to happen as a side effect
to the GdkSurface::layout signal, which first passes the GtkNative
instance where it is then forwarded to the implementations of the
GtkNative interface.
The implementations of GtkNative are the ones doing the actual
gtk_widget_allocate(), and they do so in their GtkNativeClass::layout
function.
The size should correspond what gtk_widget_measure() does, and it
measures what's within the window excluding the shadow; so make this
helper function correspond to this.
Showing before the child would result in bogus
gdk_drag_surface_present() with an "empty" (1x1) size. This can easily
be avoided by postponing showing until there is anything to show.
By moving popup layout emission to the layout phase, the current
GdkPopup::poup-layout-changed signal has no value on its own as it'd be
ignored by GtkPopover.
Make the Wayland backend communicate the popup layout changes via the
common signal; but leave the rest intact until other backends catch up.
Don't have GtkRoot listen directly to the layout signal on the frame
clock, but let it pass through GdkSurface. This will allow GdkSurface to
be more involved in the layout phase.
We need to tell people what signal will be emitted when calling
gtk_widget_activate(), and that the shortcuts API might be more
appropriate to what they are looking for.
Setting a field on a class structure is not always an easy task from
languages other than C. While bindings can provide access to the class
pointer, twiddling the fields in the class structure can be awkward.
Additionally, signal ids are not always readily available.
We can paper over the direct access to the class structure, as well as
the "signal name to id" mapping with a simple couple of setter
functions.
This broke when we started using GDK_PROFILER_CURRENT_TIME for
timekeeping - that gets defined to 0 when we're building without
sysprof, so we can use it to make such determinations. Go back
to using g_get_monotonic_time().
Fixes: #3438
This ensures that we don't leak window references inside the action muxer.
Otherwise, we risk not disposing the windows upon gtk_window_destroy()
and blocking the main loop from quitting.
Fixes#3419
This comes complete with animation support. For a good time, try:
@keyframes conic {
100% { background-image: conic-gradient(from 1turn, red, lime, blue, yellow, red); }
}
window {
background-image: conic-gradient(red, lime, blue, yellow, red);
animation: conic infinite linear 5s;
}
We only needed the widget to get its action muxer. And this way we don't
have to call gtk_widget_get_action_muxer() dozens of times, just once in
set_widget().
The get_size() vfuncs is deprecated in GTK3, and only used as a
fallback path for cell renderers that do not implement preferred
size virtual functions.
We have code in place to handle a NULL node in the state when dealing
with blend nodes, but we don't always check for NULL, which leads to
warnings in the CSS Blend modes demo.
Use the same initial check for the accessible object type that we use
when connecting the signal, in case we try to disconnect signals on
different widgets. Additionally, check before accessing data that might
have already been removed.
Fixes: #3403
The accessibility bus might not be available, and if it isn't the case,
it means something has failed at a level where the user can't do much
about it. There's no need to emit a critical warning.
We depend on GObject, which already depends on GLib; on older versions
of Meson, this ends up trying to depend on the system copy of GLib,
instead of the sub-project copy, in case the version of GLib we have
installed is too old.
To avoid bleeding edge deprecations we use GLIB_VERSION_MIN_REQUIRED and
GLIB_VERSION_MAX_ALLOWED. Since we depend on GLib 2.66, we cannot use
API introduced in 2.67, even when conditionally compiled.
- Reorder declaration blocks for code legibility.
- Don't lighten text color on :hover and :selected for better contrast.
- Add missing :focus-visible:focus-within styling to non-:selected row.
- Don't set the sidebar padding twice.
- Add padding to the assistant sidebar directly, as it doesn't have
.navigation-sidebar internally.
- Set missing margin to the sidebar separator.
See https://gitlab.gnome.org/GNOME/gtk/-/issues/3382
If an active grab gets undone on button press (e.g. closing a menu), we
will receive a button release on the new target even though it didn't handle
the button press, and disable ::active state.
This causes warnings when handling the button release, as it tries to undo
::active state that is not really there.
In order to fix this, check that the pointer focus actually had an implicit
grab at the time of receiving the button release, before trying to unset
the ::active state.
If the accessible object is hidden, we can skip the emission of the
AddAccessible and RemoveAccessible signals on the cache, as those
objects won't be visible in the accessibility tree.
Simplify getting the accessible role when checking if an accessible
implementation should present itself; this avoids going through
GtkAccessible twice to get the same data.
The GtkAtSpiContext is responsible for removing itself from the root,
which will remove itself from the cache. Any code path that leads to the
GtkAtSpiContext instance being collected passes through the
unrealization phase, which will also unregister the context from the
accessibility bus and from the cache.
- use the old Industrial style menuitems to make the design feel purposeful
- adjust corners to have compatible border-radii of child elements
- include sidebars and navigation sidebars to look consistent
(plus the assistant sidebar)
Implements https://gitlab.gnome.org/GNOME/gtk/-/issues/3366
The use of volatile was incorrect in GLib and has been that way for
a long time. Recently however that has changed, and this makes GTK
follow suit to avoid using volatile in the type registration.
See also: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1719
Combined with the above merge request for GLib, this fixes a large
number of compilation warnings when using Clang.
Since GTK4, the functions that used the GtkPackType enumeration,
`gtk_box_pack_{start,end}`, were replaced by `gtk_box_{append,prepend}`,
hence this enumeration isn't used anymore by any function within the
GtkBox type, and the child packing properties were also removed for GTK4.
So this commit adapts the documentation accordingly.
For readonly properties, we show the serialized value
in a label. If we don't take precautions, this can cause
our window to grow extremely wide, and break things.
So, ellipsize things at a reasonable size.
Fixes: #3278
GtkTreeView.get_tooltip_context() takes an inout X and Y coordinates,
but the "out" side is a side effect: the conversion from widget-relative
to bin window-relative coordinates is not documented, and can be done
using public API, if needed.
GtkIconView.get_tooltip_context() follows the same pattern, and takes
two inout arguments for the coordinates, but it does not change them any
more, after GtkIconView's bin window was dropped in commit 8dc5e13e.
There's really no point in having these `inout` arguments, and while
GtkTreeView and GtkIconView are certainly de-emphasised in GTK4, and we
nudge developers to move to the new list views, we should take advantage
of the API break to remove warts.
In commit 024d832d94, we introduced a
cascade-popdown property that makes closing a submenu
propagate up and close its parent menus. This is the
behavior we want when a menuitem in the submen is
activated.
What we overlooked is that we still need to be able to
close a submenu during navigation, before opening another
one. And in this case, propagating the closing is breaking
things. Fix this by adding a private close_submenu api
to GtkPopoverMenu that avoids the propagation.
Fixes: #3301
When falling back to using the program name to create a unique base path
for the objects on the accessibility bus we need to ensure that the name
is a valid DBus object path.
The AT-SPI cache interface is used to quickly populate the accessible
objects tree.
The tricky bit is ensuring that we emit change notifications on the
cache only when the cache is available, which means waiting until the
root is asynchronously registered.
The root path is shared by all AtSpiContext instances, so we should
compute it once, instead of every time we instantiate a new context.
This allows us to defer the path creation at realization time and ensure
that we have a registered application.
The expected behavior when activating check or radio
menuitems via keynav is that Space toggles the item
but keeps the menu open, while Return toggles the
item and closes the menu.
Ever since 5b5d2665d3, tooltips don't work properly,
since we get more motion events now, and those keep the
tooltips from appearing. This can be seen e.g. on the icon
in the password entry in widget-factory, or on the section
switcher buttons in the Emoji chooser.
Ignore synthetic motion events for the purposes of
determining whether the user moved the mouse.
Currently GTK can be built with G_ENABLE_DEBUG which enables various debug code and parsing
of those env vars, or without, which instead of parsing them prints a warning if they are set.
While building with G_ENABLE_DEBUG isn't strictly needed it's the only way to make GTK_DEBUG=interactive work,
which is a nice thing to have always.
This enables parsing of those env vars in any case and allows specific values being marked as also
available when not built with G_ENABLE_DEBUG (interactive for example). If not built with G_ENABLE_DEBUG
then all unavailable values will be marked as such in the help output and a note is added that
GTK needs to be built with G_ENABLE_DEBUG to use them, which should help discoverability.
An implicit grab means some button is down, reset the active state
only in that case when we get a grab broken event.
Avoids active state accounting warnings when we do get active grabs
broken (e.g. after selecting a menu option).
Since the $button_fill variables are no longer used outside of the
button() mixin (and it was for an ugly hack), there is no need to keep
that anymore.
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/3354
We may have the situation of multiple touchpoints in the same
widget, or combinations with other devices. Stack those ::active
states are preserved on widgets on all but the last pointer/touch
going away.
Use the GROUP role, and make sure to note that the child is always
revealed. Unlike GtkExpander, GtkRevealer can only be programmatically
toggled, so we cannot turn it into a "button" object.
Document the role of the GtkTreeExpander, and the behaviour of the
expander button.
Additionally, improve the label of the expander button, by adding a
fixed "Expand" label, and setting the "labelled-by" relation to the
child of the GtkTreeExpander.
The search bar widget has a "SEARCH" landmark role, which is described
as:
A landmark region that contains a collection of items and
objects that, as a whole, combine to create a search facility.
Commit fa3d1940bf added separate grab handling for GtkSearchEntry, but
didn't consider whether the bar was revealed or concealed. The expected
behavior for the latter is that the entry is cleared rather than focused,
fix the condition accordingly.
With the last commit, pressing the same button with multiple fingers
doesn't cause extra emissions, so we can remove exclusive and allow
pressing multiple buttons at once on touch.
Now that GtkATContext is explicitly realized and unrealized, we should
always create an instance at widget initialization time, and drop it
during the widget finalization. This should make it easier to set up the
initial accessible state of a widget during the instance initialization,
as well as reduce the chances of accidental creation of GtkATContext
instances during the destruction sequence.
Since GtkATContexts are now lazily realized, we need to go through the
GtkAccessible's implementation to access the :accessible-role property,
in case there are fallbacks.
There's no need to do a lot of work on construction, if we're delaying
all remote work after the GtkATContext is realized.
The GtkAtSpiContext should also keep a reference on the root, and drop
it at unrealize time.
By unrealizing the context we avoid additional work during the dispose
phase, in case widget code updates the accessible state. We use
GtkAccessible's API, to ensure we unrealize the right ATContext, instead
of the one we store inside GtkWidgetPrivate.
We drop the ATContext instance inside GtkWidget during finalization, to
mop up eventual vivifications there.
Making the list row child css depend on the position
is very expensive, and does not acutally work correctly
(since we don't have widgets for all children, so the
position of the child widget does not reflect the actual
model item position).
To make this more palatable, use the bottom border
instead of the top border, since most lists have a natural
border at the top (with headers), and may end up with
empty space at the bottom.
The overarching goal here is to not queue a resize
unless something has actually changed. In columnview
scenarios, we often deal with hundreds of labels.
Labels are cattle, not pets.
This is leftover code from when widgets were hidden
by default, and was setting them back to their initial
state.
This is getting in the way now, as hiding the widget
updates the HIDDEN accessible state, which ends up
re-creating the at context that we've already disposed
of, leading to memory leaks.
The hypothetical widget that needs to clone ATContext instances
because it needs to control the accessible role post-construction is
really GtkModelButton.
Fixes: #3342
Some widgets might want to override GtkAccessible and create their own
context in order to control the accessible role post-construction time.
To avoid explicitly copying the existing state over from the original
ATContext to the new one, we need a way to clone the context's state
from inside the ATContext itself.
Using GList is a bit lame, and makes the API more complicated to use
than necessary in the common case.
The only real use case for a GList is gtk_widget_add_mnemonic_label(),
and for that we can use the GValue-based API instead.
Fixes: #3343
The accessible-role property in GtkWidget has three possible targets:
- the :accessible-role of a GtkATContext, if realized
- the accessible_role field of GtkWidgetPrivate
- the accessible_role field of GtkWidgetClassPrivate
When we set the accessible role of a widget using the GObject property
mechanism, we want to either set the GtkWidgetPrivate.accessible_role
field, if there's no ATContext *or* if the ATContext is not realized.
Conversely, when we get the accessible-role property we want to have a
series of fallbacks in place:
- if GtkAccessible.get_at_context() returns an ATContext, and that
ATContext is realized, return the :accessible-role of the context
- if GtkWidgetPrivate.accessible_role is not WIDGET, return the
stored accessible role
- return GtkWidgetClassPrivate.accessible_role
This should help catch the case of getting the accessible role of
widgets that override GtkAccessible.get_at_context(), like
GtkModelButton.
See: #3342
Use a single environment variable for everything:
- select the ATContext implementation
- select the test ATContext
- disable ATContext entirely
We use the same pattern as GSK_RENDERER, GTK_DEBUG, etc.
The documentation needs to be updated to include the environment
variable.
The GtkPlacesOpenFlags enum is only used in private
API, so move it to private headers. Since we still need
a GType for it, add gtkplacessidebarprivate.h to the
headers we use for generating private enum types. In turn,
this registers the other private enums in that header, so
take the opportunity to fix their naming, and use the
generated types for the corresponding sidebarrow properties.
Fixes: #3337