Tk Source Code

View Ticket
Login
Ticket UUID: a9929f112af803c5dd65ef9c484100f8670bbc94
Title: Bugs in the implementation of TIP 577 ("Enhanced index values for Tk" )
Type: Bug Version: trunk
Submitter: nemethi Created on: 2021-11-04 11:24:32
Subsystem: 03. [*button] and [label] Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Important
Status: Closed Last Modified: 2023-07-11 07:21:38
Resolution: Fixed Closed By: jan.nijtmans
    Closed on: 2023-07-11 07:21:38
Description:
The following script demonstrates the issues I have experienced with Tk built from trunk, with Tcl 9 headers:

label .l1 -text "label"
ttk::label .l2 -text "ttk::label"
pack .l1 .l2

1. Both

  .l1 configure -underline -1

and

  .l1 configure -underline -2

will underline the last "l" character.  Why?  What is the exact definition of backwards indexing?  Shouldn't -1 be equivalent to "end" and -2 to "end-1"?  The above result doesn't confirm this rule.

2. The -underline option doesn't work at all for the ttk::label widget .l2.  Regardless of whether I set it to a positive or negative value, none of its characters will appear underlined.
User Comments: jan.nijtmans added on 2023-07-11 07:21:38:

Final part of fix committed here


jan.nijtmans added on 2023-07-11 07:18:17:

Final part of fix committed [0b05b5c750dff7d4|here]


jan.nijtmans added on 2023-07-11 07:17:58:

Final part of fix committed [0b05b5c750dff7d4|here]


jan.nijtmans added on 2023-06-27 06:49:12:

> Is this the final expected state?

With Tcl 8.7: Yes it is. With Tcl 9.0: Still working on this here


fvogel added on 2023-06-26 20:11:51:

With the very recent commits by Jan the status is now as follows. Is this the final expected state?

Tcl 8.7 (core-8-branch) + Tk 8.7 (main):

  • The underline is displayed (at the correct place) when the requested index is >= 0.
  • When the requested index is < 0 no underline is displayed.
  • When the requested index is end - $n the nth character starting from the end is underlined.
  • Requesting "" as an index removes the underline.
  • Output of Csaba's script:
    Index:  1
    Label:  -underline underline Underline -1 1
    TLabel: -underline underline Underline -1 1
    
    Index:  0
    Label:  -underline underline Underline -1 0
    TLabel: -underline underline Underline -1 0
    
    Index:  -1
    Label:  -underline underline Underline -1 -1
    TLabel: -underline underline Underline -1 -1
    
    Index:  -1-2
    Label:  -underline underline Underline -1 -1
    TLabel: -underline underline Underline -1 -1-2
    
    Index:  -2
    Label:  -underline underline Underline -1 -1
    TLabel: -underline underline Underline -1 -2
    
    Index:  -3
    Label:  -underline underline Underline -1 -1
    TLabel: -underline underline Underline -1 -3
    
    Index:  end
    Label:  -underline underline Underline -1 end
    TLabel: -underline underline Underline -1 end
    
    Index:  end-1
    Label:  -underline underline Underline -1 end-1
    TLabel: -underline underline Underline -1 end-1
    

Tcl 9 (main) + Tk 8.7 (main):

  • The underline is displayed (at the correct place) when the requested index is >= 0.
  • When the requested index is < 0 or end - $n the last character is underlined.
  • Requesting "" as an index removes the underline.
  • Output of Csaba's script:
    Index:  1
    Label:  -underline underline Underline {} 1
    TLabel: -underline underline Underline {} 1
    
    Index:  0
    Label:  -underline underline Underline {} 0
    TLabel: -underline underline Underline {} 0
    
    Index:  -1
    Label:  -underline underline Underline {} end
    TLabel: -underline underline Underline {} -1
    
    Index:  -1-2
    Label:  -underline underline Underline {} end
    TLabel: -underline underline Underline {} -1-2
    
    Index:  -2
    Label:  -underline underline Underline {} end
    TLabel: -underline underline Underline {} -2
    
    Index:  -3
    Label:  -underline underline Underline {} end
    TLabel: -underline underline Underline {} -3
    
    Index:  end
    Label:  -underline underline Underline {} end
    TLabel: -underline underline Underline {} end
    
    Index:  end-1
    Label:  -underline underline Underline {} end
    TLabel: -underline underline Underline {} end-1
    


jan.nijtmans added on 2023-06-23 11:39:34:

Since this change was made related to TIP #660, it broke the underline display for ttk:lablel. Still some more work to be done to fix this


jan.nijtmans added on 2023-06-23 09:37:11:

Changes are committed now for Tcl 8.7 and Tk 8.7, fixing this. Some changes still needed in Tcl 9.0, so it doesn't work yet when combining Tcl 9.0 with Tk8.7. Still some more work to do.


nemethi (claiming to be Csaba Nemethi) added on 2023-03-12 12:15:10:
The following script (also provided as attachment) might prove useful when testing the behavior of the -underline option:


label .l1 -text "label"
ttk::label .l2 -text "ttk::label"

ttk::frame .f
ttk::label .f.l -text "Index:"
ttk::entry .f.e -width 10 -textvariable index
bind .f.e <Return> {
    puts "\nIndex:\t$index"
    foreach l {.l1 .l2} {
        $l configure -underline $index
        puts "[winfo class $l]:\t[$l configure -underline]"
    }
}
pack .f.l .f.e -side left -padx 3p

pack .f -side bottom -padx 3p -pady 3p
pack .l1 .l2 -pady 3p


Here is the output for a few index values, before the last commit by Francois:

Index:	-2
Label:	-underline underline Underline {} end
TLabel:	-underline underline Underline {} end

Index:	-3
Label:	-underline underline Underline {} end-1
TLabel:	-underline underline Underline {} end-1


The last commit by Francois changes the ouput as follows:

Index:	-2
Label:	-underline underline Underline {} end
TLabel:	-underline underline Underline {} -2

Index:	-3
Label:	-underline underline Underline {} end-1
TLabel:	-underline underline Underline {} -3

jan.nijtmans added on 2022-01-21 08:46:28:

It turns out that Tcl_GetIntForIndex() doesn't always return the 'right' answer. Since TkGetIntForIndex() depends on it, that needs to be fixed first. Found a bug in the 8.7 implementation of Tcl_GetIntForIndex() (which was not crucial here), the changes in 9.0 need a further look.


jan.nijtmans added on 2021-11-04 20:44:20:

The -1 as 'end' and -2 as 'end-1' is meant to be used for the C-API (Tk_UnderlineTextLayout). There - indeed - negative numbers mean count backwards. But this is not supposed to be visible at script level.

You should use 'end' if you want to underline the last character and 'end-1' if you want to underline the character before that.

Yes, this is clearly an implementation bug. Will be fixed. The behavior with Tcl 8.7 and Tcl 9.0 should be the same at script level, at least that's the intention of the TIP


nemethi (claiming to be Csaba Nemethi) added on 2021-11-04 19:13:45:
Further references to the interpretation of negative underline indices as counting backwards from the end of the string can be found in the files doc/TextLayout.3 and  generic/tkFont.c.

nemethi (claiming to be Csaba Nemethi) added on 2021-11-04 12:26:39:
When Tk is compiled with Tcl 8.7 headers, both -1 and -2 result in no underlining, as expected.  But I thought that compiling Tk with Tcl 9 headers would activate the backwards indexing for negative values, as stated in the TIP.  According to this, in my understanding, -1 should underline the last character, -2 the last but one character, and so on.  I.e., -1 should be equivalent to "end" and -2 to "end-1".

jan.nijtmans added on 2021-11-04 12:00:56:
I quickly tested this: When Tk is compiled with Tcl 8.7 headers, your examples are behaving as expected.

Thanks for the report!

jan.nijtmans added on 2021-11-04 11:54:08:

This indeed sounds like a bug: both -1 and -2 should result in no underlining.

I'll have a look. Thanks!


Attachments: