Even though button 1 (or touch down) presses do most often have
an effect in one way or another (starting drag, moving focus,
starting selection, ...), there is one situation that they do
immediately nothing: When clicking on the entry does not move
the text caret around. Dragging might start a selection, but
the entry did not do anything just yet, and an immediate
button/touch release should remain at "did nothing".
And that is precisely the hint that the Wayland IM context's click
gesture takes, clicks that do not scroll nor move the caret around,
having the GtkText not claim the gesture in that situation makes
the IM gesture able to do its thing without in-fighting.
This is typically not a problem when the GtkText is embedded in
another GtkEditable implementation (e.g. GtkEntry), since the
IM gesture is inactive and capturing from the parent widget, so
gets a pass that it otherwise doesn't get when both gestures are
in the same widget. This makes it work regardless of GtkText not
being a child of a composite widget, like NautilusQueryEditor
and AdwRowEntry.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5351
In overwrite mode, every typed character gets
handled as a delete+insert, but we should not
record these as two individually undoable
steps.
This matches how we handle overwrite mode in
GtkTextView.
Fixes: #4411
Move the implementations from gtksnapshot.c to
gtk/deprecated/gtkrender.c and deprecated these
functions. We want to get rid of them.
These functions are still used in some of our widgetry,
so use G_GNUC_BEGIN/END_IGNORE_DEPRECATIONS around
them.
Doing reset() on the text widgets after commit and delete_surrounding
is still too eager for some IMs (e.g. those that expect being able
to commit text while keeping a preedit buffer shown).
However, reset() is more of a "synchronize state" action on Wayland,
and it is still desirable to do that after changes that do come from
the IM (e.g. requesting the new surrounding text and cursor/anchor
positions). Notably here, the text_input protocol may still come up
with a preedit string after this state synchronization happens.
Shuffle the code so that the text widgets do not reset() the IM
context after text is deleted or committed, but the Wayland IM does
apply its practical effects after these actions happen. This keeps
the Wayland IM fully up-to-date wrt text widget state, while not
altering the ::commit and ::delete-surrounding-text behavior for
other IM context implementations.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5200
Fixes: 5b78fe2721 (gtktextview: Also reset IM context after IM...)
Fixes: 7c0a395ff9 (gtktext: Also reset IM context after IM...)
Fixes: 52ac71b972 (gtktextview: Shuffle the places doing IM reset)
Fixes: 9e29739e66 (gtktext: Shuffle the places doing IM reset)
When the IM commands the GtkText to delete text, the cursor position
would change, and so would the surrounding text. Reset the IM context
so that these updates are properly picked up by the IM.
Fixes backspace key behavior in the GNOME Shell OSK, since that relies
on the surrounding text being properly updated for the next iteration.
Resetting the IM on IM updates is too eager and indeed the simple
IM context doesn't like that this happens in the middle of dead
key handling.
We however want to reset the IM after actual text buffer changes
(say, a committed string) moved the cursor position, altered the
surrounding text, etc. So that the IM implementation does know to
update its state.
Since there is going to be an actual IM reset anyways, it does
no longer make sense to try to preserve the old priv->need_im_reset
status during commit handling.
Fixes: 52ac71b972 ("gtktextview: Shuffle the places doing IM reset")
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5133
Resetting the IM on IM updates is too eager and indeed the simple
IM context doesn't like that this happens in the middle of dead
key handling.
We however want to reset the IM after actual text buffer changes
(say, a committed string) moved the cursor position, altered the
surrounding text, etc. So that the IM implementation does know to
update its state.
Fixes: 9e29739e66 ("gtktext: Shuffle the places doing IM reset")
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5133
We were disabling the insert-emoji action when the
no-emoji input hint is set, but the Ctrl-. shortcut
was bypassing the action and kept working. Make
the shortcut activate the action instead.
Fixes: #5123
During text widget manipulation (inserting or deleting text via keyboard)
the IM context is reset somewhat early, before the actual change took place.
This makes IM lag behind in terms of surrounding text and cursor position.
Shuffle these IM reset calls so that they happen after the changes, and
ensure that the IM is actually reset, since that is currently toggled on
a pretty narrow set of circumstances.
It appears that we mess up accounting for blinking
cursors sometimes, and can hit blink_cb when there
is a nonempty selection.
Instead of asserting, warn and stop blinking.
Related: #4767
Those property features don't seem to be in use anywhere.
They are redundant since the docs cover the same information
and more. They also created unnecessary translation work.
Closes#4904
We were looking at GtkWidget:has-focus from
event controller signal handlers here, but
the widget property is only changed after
the event controllers.
Currently when the widget is realized after the focus in event the input
method isn't activated as enable is never sent. The call trace is
gtk_text_focus_changed ->
gtk_im_context_focus_in ->
gtk_im_context_wayland_focus_in
which returns early as self->widget is NULL since it's set up in
gtk_text_realize() via gtk_im_context_set_client_widget(). Handle that
case by invoking gtk_im_context_focus_in() from gtk_text_realize() too.
A case where the above happens is a GtkSearchEntry in a GtkSearchBar.
E.g. in gtk4-demo when starting the demo and then hitting the search
button right away.
If we set the placeholder text before setting a buffer, we end up with
both the placeholder *and* the buffer's contents visible at the same
time.
Fixes: #4376
All possible ramifications after button1 press (move cursor,
begin drag, begin dnd, select word/line, ...) result in user
actions. The right thing after that is consuming the events,
set the gesture state for that.
Currently we use layout coordinates and widget height when determining
where a click or drag has happened. If the widget has top padding (which it
does inside a GtkEntry, for example), the area where it's possible to select
text is shifted down, so the part of GtkText above the layout is not counted
as the draggable area and instead the equal area below the widget is counted.
Since GtkText is always single-line, there's no need to do any of that and
we can use widget coordinates. Then the draggable area matches the widget
and the problems goes away.
In many cases, we have an "extra-menu" property that is used to allow
applications to join menus into the native menu for the widget. Previously,
this was done by nesting that menu in a section.
Doing so increases the complexity of the rules for GtkMenuTracker as you
may want different handling from inside of the section vs toplevel
sections.
If instead we synthetically glue the menus together, we have a much more
natural joining of menus as the application developer would expect for
their menu.
This also ports GtkLabel, GtkText, GtkPasswordEntry, and GtkTextView to
use the joined menu helper.
The joined menu helper comes originally from GNOME Builder and has had
extensive use there.
Fixes#4094
We need to update the visibility of the placeholder
label when we create it, otherwise we can end up
with placeholder text on top of entry content.
Fixes: #4066
Remove a boatload of "or %NULL" from nullable parameters
and return values. gi-docgen generates suitable text from
the annotation that we don't need to duplicate.
This adds a few missing nullable annotations too.
Stash away the device timestamp when obscuring
the pointer, and compare it when we decice whether
to unobscure it. This fixes a problem where synthetic
motion events would make the cursor reappear
prematurely.
In some cases, we were inadvertedly merging the
preedit attributes into priv->attrs, instead of
keeping them separate. This was causing the underlines
to grow beyond the preedit and never go away. One
place where this was showing up is the fontchooser
preview.
Fixes: #3679
If multiple nested widgets have drag sources on them, both using bubble
phase, we need to reliably pick the inner one. Both of them will try to
start dragging, and we need to make sure there are no situations where the
outer widget starts drag earlier and cancels the inner one.
Currently, this can easily happen via integer rounding: start and current
coordinates passed into gtk_drag_check_threshold() are initially doubles
(other than in GtkNotebook and GtkIconView), and are casted to ints. Then
those rounded values are used to calculate deltas to compare to the drag
threshold, losing quite a lot of precision along the way, and often
resulting in the outer widget getting larger deltas.
To avoid it, just don't round it. Introduce a variant of the function that
operates on doubles: gtk_drag_check_threshold_double() and use it instead
of the original everywhere.