The gesture should claim the sequence after triggering uncancellable
actions, like pasting, showing a menu or selecting words/lines. A
single first button press initiating a drag does not trigger
anything yet, so it should avoid claiming the sequence.
The gesture should be accepted whenever it triggers uncancellable
actions in the widget. This means it should be accepted if the
click does result in toggling the switch.
This leaves the pan gesture room to handle dragging the handle.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2895
... and do the right things:
nothing: selection = rubberband
ctrl: selection = selection OR rubberband
shift: selection = selection AND (NOT rubberband)
ctrl+shift: selection = selection XOR rubberband
(not sure this one makes sense, but toggling is fun)
Instead of storing the active items as we go, compute the affected items
whenever the rubberband changes and in particular when the rubberband
ends.
That way, the rubberband is guaranteed to select a rectangle even
after scrolling very far.
This is achieved by having a get_items_in_rect() vfunc that selects all
the items in the rubberbanded rectangle and returns them as a bitset.
The rubberband is now handled on the list coordinate system.
When starting the rubberband, we track the item under the pointer and
follow it when it is moving.
This may lead to the rubberband start position changing position and
while this may be confusing, it alerts users to the fact that something
crazy is going on.
In particular, track which items remain in ::items-changed
signal emissions.
But the main use case is sorting, which causes items-changed(0, n, n)
to be emitted.
We only want to send grab-notify to widgets that might have been
interacting with devices via events. Instead of going through all
widgets in all toplevels, we have the window/pointer focus information,
so we can just traverse the widget stacks for every involved foci.
Move away from grab_notify, and use the set_child_focus() vfunc to track
child widgets being set the keyboard focus. This is not 1:1, but seems
good enough at the moment.
Fix various issues that prevented inline completion
and inline selection from working reliably. We were
passing byte counts to gtk_editable_select_region in
one place, but that function expects char counts.
We were listening for GtkEditable::insert-text on
the GtkText widget, but that does not emit those signals,
so listen for GtkEntryBuffer::inserted-text instead.
Finally, we were not clearing the stored completion_prefix
enough, leading to situations where the stored prefix
does not match the text in the entry anymore.
In 99.9% of all cases, these are just NULL, NULL.
So just do away with these arguments, people can
use the setters for the rare cases where they want
the scrolled window to use a different adjustment.
While it's worth thinking about bringing the "windows can be dragged
with open popovers" behavior back, this does not kick in anymore, nor
should be the way to handle this given all the autoclose surface
semantic changes.
This got stuck in ancient times when widgets were windowed, so the devices
in a window to know the devices in that widget would pan out. We do only
want here the devices that are inside the widget, not spread over the
surface, so rewrite this helper function to poke the toplevel foci, and
look they are contained inside the widget.
Crossing events are now detached from widget state, all tricky consequences
from getting multiple crossing events are now somewhat moot. Resort to sending
all generated crossing events, and drop this barely (ever?) used API.
When a gesture (group) claims a sequence, all other gesture groups
in the same widget should get cancelled. Not just previously claimed
ones, that shouldn't happen actually.
This is a list model holding strings, initialized
from a char **. String lists are buildable as well,
and that replaces the buildable support in GktDropDowns.
These sources are using GtkListStore apis,
but were replying on indirect includes to
get the header. Make this explicit, to prepare
for GtkEntryCompletion losing its tree view
dependencies.
This api has not really been kept up with current
user experiences in popups, and we're better off
just dropping it and letting people do their own
popups if they need custom UI.
Use gtk_widget_prepend_controller to supersede entry keynav
while the popup is open. This fixes selecting completions
with the keyboard - the Enter keypress was ending up
triggering GtkText::activate instead of inserting the
selected completion into the entry.
Add a variant of gtk_widget_add_controller that
inserts the controller at the beginning, instead
of the end. This will be used in entry completion
to make sure the entry completion key event handling
supersedes the entry one while the popup is open.
Keep this private for now, until we determine if
it needs to be public api.
We were adding event controllers at the end, but
announcing a change at the beginning, in
gtk_widget_add_controller. Fix that by emitting
::items-changed for the position where we actually
inserted the controller.
Due to an oversight, when multi filters were split into
any and every, any ended up with the listmodel and buildable
implementations, and every didn't get any.
Move the implementations up.
This showed up as a test failure when we get NULL as
selected item and then try to unref it. Luckily
get_selected_item is transfer none, so we don't have
to worry about it.
We are currently not robust against model changes or
widget invalidations, so we can actually end up in
situations where we run out of items here. Handle
the failure a bit more gracefully, by returning NULL.
This is good enough to make scrolling work okish most
of the time. We still need a proper fix to handle
other situations.
Use a drop motion controller to autoscroll horizontally
while a drag operation is hovering over the list. The
vertical scrolling is handled by the listview.
Break out an update_autoscroll() function that can
be used for other things than rubberbanding. It will
be used for autoscroll during DND in the future.
All widgets cache their render node already. Just allocate the
last_visible_child always at 0/0 and then move its rendernode around
during snapshot.
Fixes#2678
We already know that a widget will have literally 1 node, not more.
Avoid doing the GtkSnapshot state stack dance and just append a new
transform node instead.
Seems to give me around 400 more icons in the fishbowl
The GtkIMMultiContext uses a delegate pattern to proxy an existing input
method context. Let's not use loaded terms like "slave" when we have
perfectly fungible terms like "delegate".
Libcloudproviders has a single header entry point, so we shouldn't
include a sub-header.
Additionally, the include path provided by the pkg-config file is:
-I${includedir}/cloudproviders
So the include directive should be:
#include <cloudproviders.h>
The fact that it worked until now was an accident caused by the blanket:
-I${includedir}
we get for free; it broke the build when using libcloudproviders as a
subproject.
This patch implements the openFiles delegate which is required
to open files which are associated with an application via the
Finder or via open on the command line. The patch has been
proposed by jessevdk@gmail.com.
See: https://gitlab.gnome.org/GNOME/gtk/-/issues/463
I tested the patch with the GNU pspp application on MacOS with
the quartz backend.
Shift-Tabbing was getting stuck in GtkSearchEntry and
GtkPasswordEntry, since they grab the focus to a child
of theirs. Copy the same fix that we are already using
in GtkEntry.
Fixes: #2842
If we leave the valign to be the default fill, then
the images pick up baseline alignment from the environment,
which can occasionally lead to misplaced -/+ icons in
spinbuttons, for example in the "Page Setup" tab of
the print dialog.
Use better matching format modifiers/specifiers, initialise some things
which in theory wont be written to because of getters using g_return_if_fail(),
a cast, and gsize as input for malloc because gsize!=glong on 64bit Windows.
We lost this when GtkSpinButton was first ported
to the new editable regime, and then the GtkBoxLayout.
Bring it back, but without text measurement, by overriding
width-chars for the GtkText inside, and only do it if
GtkSpinButton::width-chars is unset (ie -1).
Also adjust the documentation slightly to point out
how auto-sizing can be turned off.
GTK 4.0 was currently using GL_EXT_framebuffer_object, which is
deprecated as the ARB version has been merged into OpenGL 3.0 as well as
OpenGL ES 2.0, and provides laxer requirements.
This is a port of !2076 for 4.x.
This gesture handles both individual touch events and touchpad gesture
events, and was checking the touchpad phase in generic code paths. This
is dubious since event methods error out on the wrong GdkEventTypes.
Check the touchpad gesture phase within the branch handling touchpad
events, and make it clear which is the gesture phase of all that we are
ignoring.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2825
This makes 'gtk_file_chooser_get_filter' work for the
portal native file chooser by handling the corresponding
'current_filter' argument in the response retrieved via
D-Bus.
In order to try to map the retrieved 'current_filter' to one
of the existing list of filters, use the retrieved filter's name,
similar to how xdg-desktop-portal-gtk does it when evaluating the
'current_filter' input parameter in 'options'.)
Note: This depends on the following merge/pull requests
which fix the filter handling in gtk for native file choosers
and introduce the 'current_filter' handling for FileChooser portal.
* https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/1959
* https://github.com/flatpak/xdg-desktop-portal/pull/493
* https://github.com/flatpak/xdg-desktop-portal-gtk/pull/311
This fixes#1820 for desktop portal case.
Fixes: #1820
'gtk_file_chooser_get_filter' did not work for GtkFileChooserNative,
since the previous way did not properly handle the delegate dialog,
s.a. commit a136cbae8f
("filechoosernative: forward current_filter to delegate dialog",
2018-11-29) for details, wich basiscally fixed the same thing for
the 'gtk_file_chooser_set_filter' case.
This fixes#1820 for the fallback dialog. A solution for the portal
one (which also requires changes to xdg-desktop-portal and
xdg-desktop-portal-gtk as well) will be suggested in a subsequent step.
Bug: #1820
Scroll events can have history too, so make a
getter that works for both. This drops the
gdk_scroll_event_get_history getter that was
added a few commits earlier, since we now
store scroll history in the same way as
motion history.
Update the docs, and all callers.
This is not just about consistency with other functions.
It is about avoiding reentrancy problems.
GtkListBase first doing an unselect_all() will then force the
SelectionModel to consider a state where all items are unselected
(and potentially deciding to autoselect one) and then cause a
"selection-changed" emission that unselects all items and potentially
updates all the list item widgets in the GtkListBase to the unselected
state.
After this, GtkListBase selects new items, but to the SelectionModel and
the list item widgets this looks like an enitrely new operation and
there is no way to associate it with the previous state, so the
SelectionModel cannot undo any previous actions it took when
unselecting.
And all listitem widgets will now think they were just selected and
start running animations about selecting.
Replace a previous fix with a more correct one: Update the
selected state from the model instead of reusing the old state, the
model might have updated the selected state.
When translating coordinates from an event, we need to
take the surface transform into account. This makes
double-clicking on editable cells in treeviews work
again.
Fixes: #2831
This is a selection model that stores the selection
state in a boolean property of the items, and thus
persists across reordering and similar changes.
Fixes: #2826
The selection model will only emit one of items-changed
or selection-changed, so when we handle an items-changed,
we must assume that selection state may have changed for
any of the newly added items.
This fixes lingering selection state in the visible range
if you change the sorting of the colors demo.
Fixes: #2827
Move the selection changes to button release, to
avoid conflict with the drag gesture for rubberbanding.
This avoids peeking at the parent, and is generally
nicer.
Among other things, you can now shift-click to select
a range in the colors demo in gtk4-demo.
When I changed things to only collect the set
in the stop() function, I overlooked that this
has the side-effect of only handling items which
are backed by a widget at the time stop() is called.
If we make a big rubberband and autoscroll down too
far, we loose the items that go out the visible range
at the top. Fix that by maintaining the set as we go.
It's finally unused.
Accessible types should either watch properties they are interested in
directly, or should have (private) API to allow widgets to update the
accessible state directly.
Now that we don't have any additional subclasses of GtkEntryAccessible
in GTK, we can drop all the conditional fluff in the base class.
We still need to subscribe to the global notify signal, because of the
sheer amount of properties watched by GtkEntryAccessible.
GtkPasswordEntryAccessible is not a GtkEntryAccessible any more, so it
will need a proper implementation of various interfaces and
functionality in order to work like any other entry.
We're already listening to the adjustment property on the spin button,
there's no need to reset the adjustment on widget set/unset, since the
accessible instance is always tied to the same widget.
Drop the GtkWidgetAccessibleClass.notify_gtk and the
AtkObjectClass.initialize overrides: they don't do anything relevant.
Instead, have GtkProgressBar update the accessible state when the
fraction changes.
Do not use a generic "notify" signal handler.
Additionally, clean up the GtkIconViewAccessible implementation to bring
it up with modern idiomatic GObject.
It feels slightly wrong to have GtkOrientable operate on widgets, but at
least what happens when an orientable widget changes orientation should
be part of GtkWidget.
This will allow to add more state changes without accessing widget state
from the outside of gtkwidget.c.
We expect widgets to use their own derived GtkWidgetAccessible type,
these days, and given that we hard code the default accessible type of a
GtkWidget to GtkWidgetAccessible, and that we enforce the dependency of
the type passed to gtk_widget_class_set_accessible_type(), the registry
code path is clearly unused.
The tooltip handling in GtkWidget is "special":
- the string is stored inside the qdata instead of the private
instance data
- the accessors call g_object_set() and g_object_get(), and the
logic is all inside the property implementation, instead of
being the other way around
- the getters return a copy of the string
- the setters don't really notify all the involved properties
The GtkWidgetAccessible uses the (escaped) tooltip text as a source for
the accessible object description, which means it has to store the
tooltip inside the object qdata, and update its copy at construction and
property notification time.
We can simplify this whole circus by making the tooltip properties (text
and markup) more idiomatic:
- notify all side-effect properties
- return a constant string from the getter
- if tooltip-text is set:
- store the text as is
- escape the markup and store it separately for the markup getter
- if tooltip-markup is set:
- store the markup as is
- parse the markup and store it separately for the text getter
The part of the testtooltips interactive test that checks that the
getters are doing the right thing is now part of the gtk testsuite, so
we ensure we don't regress in behaviour.
When exclusive is TRUE, we would not always emit a
::selection-changed signal that covers all the items
that were unselected.
This commit includes a test.
Tell reordered columns to reorder their cells to
the new position. This is necessary to get things
like separators right. The visible symptom of this
problem was the lack of the right border when the
last column is reorder to another position, since
the title widget was still the last in its container,
so :last-child applied.
When we are given a for_size as width for the whole
column view, we need to distribute it over the columns
as gtk_column_view_allocate_columns would, in order
to find out which for_size to give to each cell.
This is a bit recursive, but works. Since we are
doing this recursion for every row, we should consider
adding a cache for those distributed widths.
If you add a widget to a parent, this will invalidate the css nodes
for parent/siblings. Afterwards, if the parent is mapped, we will
realize the new child. This calls gtk_widget_update_alpha() which
needs the css opacity, so it revalidates the css.
Thus, for each widget_add (while visible) will trigger a full
revalidation of each sibling. If you add N children to a parent that
leads to O(N^2) revalidations.
To demo this I changed gtk-demo to always double the count
(independent of the fps) and print the time it took. Here is the
results (after a bit):
Setting fishbowl count=256 took 3,4 msec
Setting fishbowl count=512 took 10,1 msec
Setting fishbowl count=1024 took 34,1 msec
Setting fishbowl count=2048 took 126,3 msec
Setting fishbowl count=4096 took 480,3 msec
Setting fishbowl count=8192 took 1892,7 msec
Setting fishbowl count=16384 took 7751,0 msec
Setting fishbowl count=32768 took 38097,7 msec
Setting fishbowl count=65536 took 191987,7 msec
To fix this we drop gtk_widget_update_alpha() and just
calculate it when needed (which is only in a single place).
It was really only necessary because we previously set
the alpha on the surface.
With this fix the above becomes:
Setting fishbowl count=256 took 1,0 msec
Setting fishbowl count=512 took 1,9 msec
Setting fishbowl count=1024 took 3,7 msec
Setting fishbowl count=2048 took 7,4 msec
Setting fishbowl count=4096 took 18,1 msec
Setting fishbowl count=8192 took 31,0 msec
Setting fishbowl count=16384 took 66,3 msec
Setting fishbowl count=32768 took 126,7 msec
Setting fishbowl count=65536 took 244,6 msec
Setting fishbowl count=131072 took 492,2 msec
Setting fishbowl count=262144 took 984,3 msec
The new names are
GtkListView - listview row
GtkGridView - gridview child
GtkColumView - columnview header
columnview listview row
Adwaita css has been updated to preserve
existing styles.
Fixes: #2818
gtk_css_node_ensure_style() recurses over previous siblings to ensure
these have a style before its following sibling. As seen in
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2027 this can
cause us to stack overflow and crash if we have a lot of children.
And even if we don't have *that* many children its still somewhat
bad to have stack depths of the same magnitude as the number of
children, both for performance reasons and debuggability.
Rename the show-separators property to show-row-separators,
and add a matching show-column-separators property. It is
implemented by setting the .column-separators style class
on the column view.
This is an expected feature with rubberband selection:
as you get close to the edge while doing rubberband
selection, the list scrolls to extend your selection.
Implement the typical rubberband selection, including
autoscroll. This is only useful with multiselection,
and not very compatible with single-click-activate.
Therefore, it is not enabled by default, and needs
to be turned on explicitly.
Autoscroll when the pointer gets close to the
edge during column resizing or reordering. This
is similar to what the treeview does, but it is
implemented using a tick callback, and has
variable speed.
Allow rearranging columns by dragging, in the same
way the treeview does.
We add the "dnd" style class to the header while
it is dragged, and we move the header of the dragged
column to the end of its parents children, so that
it gets drawn on top.
Add helper functions that let us temporarily give
a different allocation to headers. These will be
used to implement interactive column reordering
in GtkColumnView.
The listview inside always thinks it gets its full size,
and updates its horizontal adjustment accordingly.
So keep our own adjustment, and update it when allocating.
Tweak the behavior slightly. We don't show
a scrollbar as long as we have at least
min-size available, but we still give the
entire size to the child, up to nat-size.
This matches how viewports handle scroll-minimum.
stat/fstat aren't compatible with GStatBuf on Windows in all cases.
Since we don't really need the file descriptor anyway here replace it with
a g_stat call.
This fixes a compiler warning with 64bit mingw.
And lets us remove this scary ifdeffery.
Since it's a type with sub-classes, we need to use GTypeInstance (at the
very least), otherwise we won't be able to address each sub-class as
such.
This is similar to how GskRenderNode and GdkEvent are handled, with the
added difficulty that GtkExpression is meant to be used in properties,
in order to be deserialised by GtkBuilder. This requires adding a
GParamSpec sub-class that we can match on from within GtkBuilder,
alongside some convenience API for storing a GtkExpression inside a
GValue.
The print backends do some complicated dispose handling
where the implementations call gtk_print_backend_destroy().
Our tests (in particular, the templates test) trigger
situations where we use print backends after dispose,
and they can't handle the printers listmodel being
NULL at that time. So just remove the printers in
dispose, keep the empty liststore until finalize.
There is no agreement that a coverflow widget is
appropriate for GTK 4.
It would be ok as a demo if it could live in gtk-demo,
but that requires us to make GtkListBase public first.
The demo is also somewhat rough and needs more work
to look plausible.
Drop GtkCoverFlow and the related demo for now.
We require a C compiler supporting C99 now. The main purpose of
these fallbacks was for MSVC. From what I can see this is now all supported
by MSVC 2015+ anyway.
The only other change this includes is to replace isnanf() with the
(type infering) C99 isnan() macro, because MSVC doesn't provide isnanf().
This is a somewhat large commit that:
- Adds GtkColumnViewSorter
This is a special-purpose, private sorter implementation which sorts
according to multiple sorters, allowing each individual sorter to be
inverted. This will be used with clickable column view headers.
- Adds a read-only GtkColumnView::sorter property
The GtkColumnView creates a GtkColumnViewSorter at startup that it uses
for this property.
- Adds a writable GtkColumnViewColumn::sorter property
This allows defining per-column sorters. Whenever an application sets a
sorter for a column, the header becomes clickable and whenever
a header is clicked, that column's sorter is prepended to the list of
sorters, unless it is already the first sorter, in which case we invert
its order. No column can be in the list more than once.
Add a mode to GtkListItemWidget that activates on
single click and selects on hover. Make
GtkListItemManager set this on its items
when its own 'property' of the same name is set.
The port is kind of evil, in that it stores either a PangoFontFamily or a
PangoFontFace in the list, depending on if the fontchooser is configured
to select fonts or faces.
It also does not cache the font description anymore, so more calls to
pango_font_describe() may happen.
If both of these issues turn out problematic, the fontchooser would need
to resurrect GtkDelayedFontDescription again and put objects of that
type through the model.
These changes depend on Pango 1.46's introduction of listmodels and
various new getters, so the dependency has been upgraded.
This uses a custom GtkColumnViewTitle widget. So far that widget is
pretty boring, but that will change once we added
resizing, reordering, dnd, sorting, hiding/showing of columns or
whatever UIs we want.
The ColumnView now allocates column widths first and then the individual
rows use the new layout manager which looks at the column allocations to
allocate their children.
It's a GtkListItemWidget subclass that tracks the column it belongs to
and allows the column to track it.
We also use this subclass to implement sizing support so columns share
the same size and get resized in sync.
It's private, no APIs, we don't talk about it. But we will start using
it very soon, so we can do size request caching in columns and avoid
sizegroups...
We only create them in root/unroot (they should be created in
appear/disappear, but that vfunc doesn't exist yet), that way we can
avoid expensive work while the widget isn't used for anything.
This way, we can ensure it's always there when we need it (before the
item gets created) and gone when we don't (if some GC language holds on
to the item after we've destroyed the widget).
Instead of 6 vfuncs, we now have 3 and rely on the factory keeping track
of what it needs to do.
We're doing lots of dancing from one object to another here, but this
will hopefully get simpler with further commits.
This splits GtkListItem into 2 parts:
1. GtkListItem
This is purely a GObject with public API for developers who want to
populate lists. There is no chance to cause conflict with GtkWidget
properties that the list implementation assumed control over and
defines a clear boundary.
2. GtkListItemWidget
The widget part of the listitem. This is not only fully in control of
the list machinery, the machinery can also use different widget
implementations for different list widgets like I inted to for
GtkColumnView.
The widget mostly works out of the box, but some tweaking may be
necessary (in particular in the theme) and the gtk-demo changes might
require removing before this is production-ready.