Attachment "cblink.tk.patch" to
ticket [3531366f]
added by
bll
2021-01-04 15:07:19.
--- generic/tkIntDecls.h 2020-12-11 09:48:53.000000000 -0800
+++ generic/tkIntDecls.h 2021-01-04 07:00:39.076603545 -0800
@@ -558,6 +558,9 @@
/* 186 */
EXTERN int TkpWillDrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
+/* 187 */
+EXTERN void TkpCursorBlinkFromSystem(Tcl_Interp *interp,
+ int *blinkon, int *blinkoff);
typedef struct TkIntStubs {
int magic;
@@ -793,6 +796,7 @@
#ifdef MAC_OSX_TCL /* MACOSX */
int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */
#endif /* MACOSX */
+ void (*tkpCursorBlinkFromSystem) (Tcl_Interp *interp, int *blinkon, int *blinkoff); /* 187 */
} TkIntStubs;
extern const TkIntStubs *tkIntStubsPtr;
@@ -1173,6 +1177,8 @@
#define TkpWillDrawWidget \
(tkIntStubsPtr->tkpWillDrawWidget) /* 186 */
#endif /* MACOSX */
+#define TkpCursorBlinkFromSystem \
+ (tkIntStubsPtr->tkpCursorBlinkFromSystem) /* 187 */
#endif /* defined(USE_TK_STUBS) */
--- generic/tkStubInit.c 2020-12-11 09:48:53.000000000 -0800
+++ generic/tkStubInit.c 2021-01-04 07:00:39.076603545 -0800
@@ -520,6 +520,7 @@
#ifdef MAC_OSX_TCL /* MACOSX */
TkpWillDrawWidget, /* 186 */
#endif /* MACOSX */
+ TkpCursorBlinkFromSystem, /* 187 */
};
static const TkIntPlatStubs tkIntPlatStubs = {
--- generic/ttk/ttkBlink.c 2020-12-11 09:48:53.000000000 -0800
+++ generic/ttk/ttkBlink.c 2021-01-04 07:00:39.076603545 -0800
@@ -52,12 +52,24 @@
CursorManager *cm = Tcl_GetAssocData(interp, cm_key,0);
if (!cm) {
- cm = ckalloc(sizeof(*cm));
- cm->timer = 0;
- cm->owner = 0;
- cm->onTime = DEF_CURSOR_ON_TIME;
- cm->offTime = DEF_CURSOR_OFF_TIME;
- Tcl_SetAssocData(interp, cm_key, CursorManagerDeleteProc, cm);
+ int ontime; /* temporary */
+ int offtime;
+
+ cm = ckalloc(sizeof(*cm));
+ cm->timer = 0;
+ cm->owner = 0;
+ cm->onTime = DEF_CURSOR_ON_TIME;
+ cm->offTime = DEF_CURSOR_OFF_TIME;
+
+ TkpCursorBlinkFromSystem(interp, &ontime, &offtime);
+ if (ontime != -1) {
+ cm->onTime = ontime;
+ }
+ if (offtime != -1) {
+ cm->offTime = offtime;
+ }
+
+ Tcl_SetAssocData(interp, cm_key, CursorManagerDeleteProc, cm);
}
return cm;
}
@@ -71,15 +83,17 @@
CursorManager *cm = (CursorManager*)clientData;
int blinkTime;
- if (cm->owner->flags & CURSOR_ON) {
- cm->owner->flags &= ~CURSOR_ON;
- blinkTime = cm->offTime;
- } else {
- cm->owner->flags |= CURSOR_ON;
- blinkTime = cm->onTime;
+ if (cm->offTime != 0) {
+ if (cm->owner->flags & CURSOR_ON) {
+ cm->owner->flags &= ~CURSOR_ON;
+ blinkTime = cm->offTime;
+ } else {
+ cm->owner->flags |= CURSOR_ON;
+ blinkTime = cm->onTime;
+ }
+ cm->timer = Tcl_CreateTimerHandler(blinkTime, CursorBlinkProc, clientData);
+ TtkRedisplayWidget(cm->owner);
}
- cm->timer = Tcl_CreateTimerHandler(blinkTime, CursorBlinkProc, clientData);
- TtkRedisplayWidget(cm->owner);
}
/* LoseCursor --
--- macosx/tkMacOSXCursor.c 2021-01-04 05:52:23.224915159 -0800
+++ macosx/tkMacOSXCursor.c 2021-01-04 07:01:08.001039537 -0800
@@ -596,6 +596,22 @@
gTkOwnsCursor = tkOwnsIt;
}
+void
+TkpCursorBlinkFromSystem (
+ Tcl_Interp *interp,
+ int *blinkon,
+ int *blinkoff)
+{
+ NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
+ NSString *nsblinkon = [preferences stringForKey:@"NSTextInsertionPointBlinkPeriodOn"];
+ if (nsblinkon != NULL) {
+ *blinkon = atoi ([nsblinkon UTF8String]);
+ }
+ NSString *nsblinkoff = [preferences stringForKey:@"NSTextInsertionPointBlinkPeriodOff"];
+ if (nsblinkoff != NULL) {
+ *blinkoff = atoi ([nsblinkoff UTF8String]);
+ }
+}
/*
* Local Variables:
* mode: objc
--- unix/tkUnixCursor.c 2020-12-11 09:48:53.000000000 -0800
+++ unix/tkUnixCursor.c 2021-01-04 07:00:39.076603545 -0800
@@ -641,6 +641,36 @@
XFreeCursor(unixCursorPtr->display, (Cursor) unixCursorPtr->info.cursor);
}
+
+void
+TkpCursorBlinkFromSystem (
+ Tcl_Interp *interp,
+ int *blinkon,
+ int *blinkoff)
+{
+ int result;
+ Tcl_Obj *listObj;
+ Tcl_Obj *conObj;
+ Tcl_Obj *coffObj;
+
+ result = Tcl_EvalEx (interp, "source $tk_library/ttk/cursorblink.tcl",
+ -1, TCL_EVAL_GLOBAL);
+ if (result == TCL_OK) {
+ result = Tcl_EvalEx (interp, "::ttk::cursorblink::getFromSystem",
+ -1, TCL_EVAL_GLOBAL);
+ if (result == TCL_OK) {
+ listObj = Tcl_GetObjResult (interp);
+ result = Tcl_ListObjIndex (interp, listObj, 0, &conObj);
+ if (result == TCL_OK) {
+ result = Tcl_ListObjIndex (interp, listObj, 1, &coffObj);
+ result = Tcl_GetIntFromObj (interp, conObj, blinkon);
+ result = Tcl_GetIntFromObj (interp, coffObj, blinkoff);
+ }
+ }
+ Tcl_ResetResult (interp);
+ }
+}
+
/*
* Local Variables:
* mode: c
--- win/tkWinCursor.c 2020-12-11 09:48:53.000000000 -0800
+++ win/tkWinCursor.c 2021-01-04 07:00:39.076603545 -0800
@@ -263,6 +263,37 @@
}
}
+
+void
+TkpCursorBlinkFromSystem (
+ Tcl_Interp *interp,
+ int *blinkon,
+ int *blinkoff)
+{
+ HKEY hKey;
+ LPCWSTR szSubKey = L"Control Panel\\Desktop";
+ LPCWSTR szCursorBlink = L"CursorBlinkRate";
+ DWORD dwSize = 40;
+ WCHAR lBuffer[40];
+ LSTATUS status;
+
+ status = RegOpenKeyExW (HKEY_CURRENT_USER, szSubKey, 0L, KEY_READ, &hKey);
+ if (status == ERROR_SUCCESS) {
+ memset (lBuffer, '\0', (size_t) (dwSize * sizeof (WCHAR)));
+ status = RegQueryValueExW (hKey, szCursorBlink,
+ NULL, NULL, (LPBYTE) lBuffer, &dwSize);
+ if (status == ERROR_SUCCESS) {
+ if (wcscmp (lBuffer, L"-1") == 0) {
+ *blinkoff = 0;
+ } else {
+ *blinkon = _wtoi (lBuffer);
+ *blinkoff = _wtoi (lBuffer);
+ }
+ }
+ RegCloseKey (hKey);
+ }
+}
+
/*
* Local Variables:
* mode: c
ADDED library/ttk/cursorblink.tcl
Index: library/ttk/cursorblink.tcl
==================================================================
--- library/ttk/cursorblink.tcl
+++ library/ttk/cursorblink.tcl
@@ -0,0 +1,153 @@
+#!/usr/bin/tclsh
+
+namespace eval ::ttk::cursorblink {
+
+ proc getFromSystem { } {
+
+ set ds $::env(DESKTOP_SESSION)
+
+ # default is unknown
+ set cursoron -1
+ set cursoroff -1
+
+ switch -exact $ds {
+ xfce {
+ set cursortm -1
+ try {
+ set cursorenabled [exec -ignorestderr \
+ xfconf-query -c xsettings -p /Net/CursorBlink \
+ 2>/dev/null ]
+ if { $cursorenabled } {
+ set cursortm [exec -ignorestderr \
+ xfconf-query -c xsettings -p /Net/CursorBlinkTime \
+ 2>/dev/null ]
+ } else {
+ set cursortm 0
+ }
+ } on error {err res} {
+ }
+ # GTK 3 divides the blink time by 3.
+ # Two parts on-time and one part off-time.
+ if { $cursortm != -1 } {
+ set cursoron [expr {round(double($cursortm)*2.0/3.0)}]
+ set cursoroff [expr {round(double($cursortm)/3.0)}]
+ }
+ }
+ gnome -
+ ubuntu -
+ mate -
+ cinnamon {
+ # gnome also has an inactivity timeout for the cursor, but Tk
+ # does not support that.
+
+ set schema org.gnome.desktop.interface
+ # they all use gsettings, but somehow have the need to create
+ # their own schema for the same settings...
+ switch -exact $ds {
+ mate {
+ set schema org.mate.interface
+ }
+ cinnamon {
+ set schema org.cinnamon.desktop.interface
+ }
+ default {
+ }
+ }
+
+ set cursortm -1
+ try {
+ set cursorenabled [exec -ignorestderr \
+ gsettings get $schema cursor-blink \
+ 2>/dev/null ]
+ if { $cursorenabled } {
+ set cursortm [exec -ignorestderr \
+ gsettings get $schema cursor-blink-time \
+ 2>/dev/null ]
+ } else {
+ set cursortm 0
+ }
+ } on error {err res} {
+ }
+ # GTK 3 divides the blink time by 3.
+ # Two parts on-time and one part off-time.
+ if { $cursortm != -1 } {
+ set cursoron [expr {round(double($cursortm)*2.0/3.0)}]
+ set cursoroff [expr {round(double($cursortm)/3.0)}]
+ }
+ }
+ plasma -
+ lxqt {
+ set cursortm -1
+
+ set confsearch [list]
+
+ switch -exact $ds {
+ plasma {
+ # in KDE 5 the QT setting no longer works.
+ # it is a manual setting in .config/kdeglobals
+ if { ! [info exists ::env(KDE_SESSION_VERSION)] ||
+ $::env(KDE_SESSION_VERSION) eq "5" } {
+ lappend confsearch \
+ [file join $::env(HOME) .config kdeglobals] \
+ CursorBlinkRate
+ }
+ # KDE 4
+ # kde's cursor blink is controlled by qt.
+ # it has the same cursorFlashTime setting as lxqt, but
+ # in a different configuration file.
+ # qt4-qtconfig does not allow a setting of 0. Presumably
+ # a manual update would be necessary.
+ if { ! [info exists ::env(KDE_SESSION_VERSION)] ||
+ $::env(KDE_SESSION_VERSION) eq "4" } {
+ lappend confsearch \
+ [file join $::env(HOME) .config Trolltech.conf] \
+ cursorFlashTime
+ }
+ }
+ lxqt {
+ lappend confsearch \
+ [file join $::env(HOME) .config lxqt lxqt.conf] \
+ cursorFlashTime
+ }
+ }
+
+ foreach {conffn conftag} $confsearch {
+ if { [file exists $conffn] } {
+ set found false
+ try {
+ # may not exist in the configuration file.
+ set cursortm [exec -ignorestderr \
+ egrep ^${conftag} $conffn | \
+ sed s,.*=,, \
+ 2>/dev/null ]
+ if { $cursortm ne {} } {
+ set found true
+ }
+ } on error { err res } {
+ }
+ if { $found } {
+ break
+ }
+ }
+ }
+ if { $cursortm != -1 } {
+ # The QT source code seems to split the blink time into two.
+ # The timing is highly suspect based on empirical testing.
+ # Try dividing by 4.
+ set cursoron [expr {$cursortm/4}]
+ set cursoroff $cursoron
+ }
+ }
+ default {
+ }
+ }
+
+ return [list $cursoron $cursoroff]
+ }
+}
+
+# for testing
+if { 0 } {
+ lassign [::ttk::cursorblink::getFromSystem] cursoron cursoroff
+ puts [list $cursoron $cursoroff]
+}