Tk Source Code

View Ticket
Ticket UUID: 1dc430ad598bd5bedc8d8c82478ff5c8c8991e8c
Title: Cursor blink rate in [text] widgets doesn't match Windows settings
Type: Bug Version: 8.6
Submitter: MG Created on: 2016-11-13 01:23:34
Subsystem: 18. [text] Assigned To: nobody
Priority: 5 Medium Severity: Cosmetic
Status: Open Last Modified: 2023-06-13 19:11:59
Resolution: None Closed By: nobody
    Closed on:

The cursor blink rate for the Text widget doesn't seem to attempt to match the Windows settings by default; very minor, but it would be nice if it did, even if it was only checked on program startup to set an appropriate default for the rest of the program's lifetime. TWAPI provides access to it via [twapi::get_caret_blink_time], and I think the matching Windows API function is GetCaretBlinkTime().

User Comments: fvogel added on 2023-06-13 19:11:59:

Some work towards getting the system settings has been done and posted as patches in [3531366fff].

MG added on 2016-12-06 22:12:13:

Happy to defer to your perception there, probably more reliable than mine. And agreed, best to have Tk check the system setting on startup and use the value at that time as its own default; checking for changes to the system setting later is probably overkill.

WRT other widgets.. label et al don't support the option(s) like the text widget does; I have no idea how they currently get their on/off flash times, whether it's fixed or does check the option internally but can't be configured per widget, etc. But having them all mirror the initial setting for the text widget would be nice.

My experience poking around in Linux WMs is very limited, but doesn't leave me with much hope of finding a useful API call for anything across them all, especially something relatively minor like this. As for MacOS, the most relevant thing I can find is the NSTextInsertionPointBlinkPeriod option (for versions < 10.8; for 10.9 and higher it's apparantly NSTextInsertionPointBlinkPeriodOn and NSTextInsertionPointBlinkPeriodOff, all in milliseconds). eclipse has an example of getting the value.

fvogel added on 2016-12-03 09:20:59:

After experimenting a bit like you did, my perception is that the on and off times on windows is the same (when GetCaretBlinkTime() is not INFINITE). I could go for this change on Windows, i.e. replace the defaults values of -insertofftime and -insertontime by what GetCaretBlinkTime() returns. Then the Tk app still has the possibility of changing the cursor flash rate using the existing widget options. However, letting Tk honor user changes of this system setting while the Tk app is running seems however going a bit too far, and does anyway not sound as a good idea to me.

So this has to be done for the text widget, but also for the entry widget, the spinbox and the canvas. That is, all widgets featuring a possibly blinking cursor. Well, OK that's possible.

Question: is there a similar system call on Linux and OS X providing on and off times of the cursor? How to implement the feature on those two platforms?

MG added on 2016-11-14 05:03:47:

That is a good question, and after some searching of documentation and playing around in the Windows settings, I can't figure out how Windows actually does it. It doesn't seem to be fixed; it looks like the ratio of on/off is different for different settings (for very high settings, it seems to be about 50/50, but for very low settings, it seems to be about 70/30 on/off; numbers based on my perception of watching it flash in the settings window, nothing mathematical).

My initial reason for opening the ticket was a user reporting that he had cursor flashing turned off entirely in Windows, but my Tcl/Tk app still flashed. So, unless anyone else has more luck than me figuring out how Windows actually calculates on/off time from the setting, maybe this ticket should just be "default -insertofftime to 0 on Windows when GetCaretBlinkTime() returns INFINITE", and otherwise stick with the existing defaults.

fvogel added on 2016-11-13 10:16:32:

Indeed the text widget does not attempt to match the default value of the cursor blink time with the OS settings.

The cursor blink time in the text widget is set, at the Tcl/Tk level, by two options -insertofftime and -insertontime, which have hardcoded default values (the same on all platforms):

#define DEF_TEXT_INSERT_ON_TIME		"600"

You are suggesting to use GetCaretBlinkTime() on Windows, but this only provides one value ("the time required to invert the caret's pixels" according to MSDN), not the ON and OFF values. Or would you suggest to use identical ON and OFF times, both being equal to the value returned by GetCaretBlinkTime()?