GNU bug report logs - #69941
30.0.50; Faulty fontification of radio button widgets

Previous Next

Package: emacs;

Reported by: Stephen Berman <stephen.berman <at> gmx.net>

Date: Fri, 22 Mar 2024 15:01:01 UTC

Severity: normal

Found in version 30.0.50

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


Message #139 received at 69941-done <at> debbugs.gnu.org (full text, mbox):

From: Stephen Berman <stephen.berman <at> gmx.net>
To: Mauro Aranda <maurooaranda <at> gmail.com>
Cc: 69941-done <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#69941: 30.0.50; Faulty fontification of radio button widgets
Date: Sun, 09 Feb 2025 11:31:10 +0100
On Sat, 8 Feb 2025 20:50:20 -0300 Mauro Aranda <maurooaranda <at> gmail.com> wrote:

> Stephen Berman <stephen.berman <at> gmx.net> writes:
>
>> With the attached file I can reproduce the problem.  Save the file and
>> then invoke Emacs from master (i.e., with your patch) as follows:
>>
>> emacs -Q -l srb-widget-test.el -f srb-widget-test
>>
>> In the displayed buffer "*Widget Test*" the three radio buttons "One",
>> "Two" and "Confirm" are active, which the default face visually
>> confirms.  (Their labels are fontified with face `widget-unselected'.)
>> Now do the following steps:
>>
>> 1. Hit TAB to move point to radio button "One".
>> 2. Type RET to activate the "Reset" button and move point to it.  Also,
>>    the radio buttons are now deactivated, which is indicated by their
>>    now being fontified with face `widget-inactive' (as are their
>>    labels).
>> 3. Type RET on the "Reset" button to reactivate the radio buttons.
>> 4. Hit TAB twice to move point to radio button "Two". Hitting RET
>>    results in the same state as in step 2.
>> 5. Repeat step 3 and then hit TAB three times (or S-TAB once) to move
>>    point to radio button "Confirm".  This pops up two indented radio
>>    buttons "Right" and "Wrong" under "Confirm", and point is now on
>>    "Right".  Note that the radio buttons "One", "Two" and "Confirm" are
>>    deactivated, while "Right" and "Wrong" are active.
>> 6. Type RET on radio button "Right".  This deletes radio buttons "Right"
>>    and "Wrong" and moves point to "Reset".  Radio buttons "One", "Two"
>>    and "Confirm" remain deactivated (confirmed by tabbing to each and
>>    typing RET, which dings and displays the message "Attempt to perform
>>    action on inactive widget"); however:
>> => Now radio button "One" is misfontified with the default face instead
>>    of face `widget-inactive'.
>>
>> If you repeat step 5 and then tab to radio button "Wrong" and hit RET,
>> the resulting state is the same as in step 6, i.e., radio button "One"
>> (and only it) is again misfontified.
>
> OK, it's a similar problem, but this time with the :inactive overlay,
> which has FRONT-ADVANCE t.
>
>> ;;; -*- lexical-binding: t; -*-
>>
>> (defvar srb--radio-widget)
>> (defvar srb--confirm-widget)
>> (defvar srb--reset-button)
>>
>> (defun srb--result (widget)
>>   (pcase (widget-value widget)
>>       ("One" (ignore))
>>       ("Two" (ignore))
>>       ("Confirm"
>>        (goto-char (widget-get srb--radio-widget :to))
>>        (setq srb--confirm-widget
>>          (widget-create
>>           'radio-button-choice
>>           :indent 4
>>           :notify (lambda (child &rest _)
>>             (srb--confirm child))
>>           '(item "Right")
>>           '(item "Wrong")))))
>>   (when srb--reset-button
>>     (widget-apply srb--reset-button :activate))
>>   (if (equal (widget-value srb--radio-widget) "Confirm")
>>       (widget-backward 2)
>>     (goto-char (widget-get srb--reset-button :from)))
>>   (widget-value-set srb--radio-widget "")
>>   (widget-apply srb--radio-widget :deactivate))
>
> Here, before the :deactivate call the widget is already inactive, and
> because of that the :deactivate call (which calls
> widget-specify-inactive) does nothing at all, since it detects there's
> already an :inactive overlay.  That :inactive overlay doesn't include
> the 1st button anymore, since that one gets inserted right at the
> overlay start.
>
> So, modifying an inactive widget right at the start or at the end of the
> overlay can produce this effect.
>
> I don't think we can solve it easily like my patch did with the :from
> and :to markers, though.  But here's an idea:
>
> When a widget is already inactive (i.e., it has an :inactive property),
> instead of doing nothing we make sure to move the overlay so that it
> includes again all the widget, from the :from marker to the :to marker.
>
> If we do that, we should document that if some code modifies an
> :inactive widget, it has to call again :deactivate.
>
> I attach a patch with that idea, together with documentation changes and
> a new test.

Thanks, I confirm this fixes the remaining misfontification.  However,
if I switch the order of the last two lines above -- i.e, first
deactivate the radio widget and then set its value to the empty
string -- then I see the same misfontification of radio button "One"
that still occurs in emacs-30 (i.e. without both this patch and your
previous one).  Is this expected, and if so, can you explain why?

Steve Berman




This bug report was last modified 82 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.