summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkText.c2
-rw-r--r--tests/listbox.test1
-rw-r--r--win/tkWinKey.c47
-rw-r--r--win/tkWinX.c64
4 files changed, 75 insertions, 39 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index ab77d99..0e41ac8 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -3042,7 +3042,7 @@ CountIndices(
* If 'viewUpdate' is true, we may adjust the window contents'
* y-position, and scrollbar setting.
*
- * If 'viewUpdate' is false, true we can guarantee that textPtr->topIndex
+ * If 'viewUpdate' is true we can guarantee that textPtr->topIndex
* points to a valid TkTextLine after this function returns. However, if
* 'viewUpdate' is false, then there is no such guarantee (since
* topIndex.linePtr can be garbage). The caller is expected to take
diff --git a/tests/listbox.test b/tests/listbox.test
index be8d582..99c84a7 100644
--- a/tests/listbox.test
+++ b/tests/listbox.test
@@ -1222,6 +1222,7 @@ test listbox-4.1 {ConfigureListbox procedure} -constraints {
pack .l
update
} -body {
+ update
set x [getsize .]
.l configure -setgrid 0
update
diff --git a/win/tkWinKey.c b/win/tkWinKey.c
index 5591133..2698c4d 100644
--- a/win/tkWinKey.c
+++ b/win/tkWinKey.c
@@ -113,12 +113,23 @@ TkpGetString(
Tcl_DStringAppend(dsPtr, buf, len);
} else if (keyEv->send_event == -3) {
+
+ char buf[XMaxTransChars];
+ int len;
+
/*
- * Special case for WM_UNICHAR. xkey.trans_chars[] already contains a
- * UTF-8 char.
+ * Special case for WM_UNICHAR.
*/
- Tcl_DStringAppend(dsPtr, keyEv->trans_chars, keyEv->nbytes);
+ len = Tcl_UniCharToUtf(keyEv->keycode, buf);
+ if ((keyEv->keycode <= 0xffff) || (len == XMaxTransChars)) {
+ Tcl_DStringAppend(dsPtr, buf, len);
+ } else {
+ Tcl_UniCharToUtf(((keyEv->keycode - 0x10000) >> 10) | 0xd800, buf);
+ Tcl_DStringAppend(dsPtr, buf, 3);
+ Tcl_UniCharToUtf(((keyEv->keycode - 0x10000) & 0x3ff) | 0xdc00, buf);
+ Tcl_DStringAppend(dsPtr, buf, 3);
+ }
} else {
/*
* This is an event generated from generic code. It has no nchars or
@@ -335,18 +346,24 @@ KeycodeToKeysym(
/*
* Windows only gives us an undifferentiated VK_CONTROL code (for
* example) when either Control key is pressed. To distinguish between
- * left and right, we have to query the state of one of the two to
- * determine which was actually pressed. So if the keycode indicates
- * Control, Shift, or Menu (the key that everybody else calls Alt), do
- * this extra test. If the right-side key was pressed, return the
- * appropriate keycode. Otherwise, we fall through and rely on the
- * keymap table to hold the correct keysym value.
+ * left and right, we use the Extended flag. Indeed, the right Control
+ * and Alt (aka Menu) keys are such extended keys (which their left
+ * counterparts are not).
+ * Regarding the shift case, Windows does not set the Extended flag for
+ * the neither the left nor the right shift key. As a consequence another
+ * way to distinguish between the two keys is to query the state of one
+ * of the two to determine which was actually pressed. So if the keycode
+ * indicates Shift, do this extra test. If the right-side key was
+ * pressed, return the appropriate keycode. Otherwise, we fall through
+ * and rely on the keymap table to hold the correct keysym value.
+ * Note: this little trick only works for KeyPress, not for KeyRelease,
+ * for reasons stated in bug [2945130]
*/
case VK_CONTROL:
- if (GetKeyState(VK_RCONTROL) & 0x80) {
- return XK_Control_R;
- }
+ if (state & EXTENDED_MASK) {
+ return XK_Control_R;
+ }
break;
case VK_SHIFT:
if (GetKeyState(VK_RSHIFT) & 0x80) {
@@ -354,9 +371,9 @@ KeycodeToKeysym(
}
break;
case VK_MENU:
- if (GetKeyState(VK_RMENU) & 0x80) {
- return XK_Alt_R;
- }
+ if (state & EXTENDED_MASK) {
+ return XK_Alt_R;
+ }
break;
}
return keymap[keycode];
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 99102cb..bb60a2d 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -81,6 +81,7 @@ typedef struct ThreadSpecificData {
TkDisplay *winDisplay; /* TkDisplay structure that represents Windows
* screen. */
int updatingClipboard; /* If 1, we are updating the clipboard. */
+ int surrogateBuffer; /* Buffer for first of surrogate pair. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -911,15 +912,24 @@ Tk_TranslateWinEvent(
Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam));
return 1;
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN:
+ if (wParam == VK_PACKET) {
+ /*
+ * This will trigger WM_CHAR event(s) with unicode data.
+ */
+ *resultPtr =
+ PostMessageW(hwnd, message, HIWORD(lParam), LOWORD(lParam));
+ return 1;
+ }
+ /* else fall through */
case WM_CLOSE:
case WM_SETFOCUS:
case WM_KILLFOCUS:
case WM_DESTROYCLIPBOARD:
case WM_UNICHAR:
case WM_CHAR:
- case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
- case WM_KEYDOWN:
case WM_KEYUP:
case WM_MOUSEWHEEL:
GenerateXEvent(hwnd, message, wParam, lParam);
@@ -1197,17 +1207,34 @@ GenerateXEvent(
event.type = KeyPress;
event.xany.send_event = -1;
event.xkey.keycode = 0;
- event.xkey.nbytes = 1;
- event.xkey.trans_chars[0] = (char) wParam;
-
- if (IsDBCSLeadByte((BYTE) wParam)) {
- MSG msg;
+ if ((int)wParam & 0xff00) {
+ int ch1 = wParam & 0xffff;
- if ((PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0)
- && (msg.message == WM_CHAR)) {
- GetMessage(&msg, NULL, 0, 0);
- event.xkey.nbytes = 2;
- event.xkey.trans_chars[1] = (char) msg.wParam;
+ if ((ch1 & 0xfc00) == 0xd800) {
+ tsdPtr->surrogateBuffer = ch1;
+ return;
+ }
+ if ((ch1 & 0xfc00) == 0xdc00) {
+ ch1 = ((tsdPtr->surrogateBuffer & 0x3ff) << 10) |
+ (ch1 & 0x3ff) | 0x10000;
+ tsdPtr->surrogateBuffer = 0;
+ }
+ event.xany.send_event = -3;
+ event.xkey.nbytes = 0;
+ event.xkey.keycode = ch1;
+ } else {
+ event.xkey.nbytes = 1;
+ event.xkey.trans_chars[0] = (char) wParam;
+
+ if (IsDBCSLeadByte((BYTE) wParam)) {
+ MSG msg;
+
+ if ((PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0)
+ && (msg.message == WM_CHAR)) {
+ GetMessage(&msg, NULL, 0, 0);
+ event.xkey.nbytes = 2;
+ event.xkey.trans_chars[1] = (char) msg.wParam;
+ }
}
}
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
@@ -1215,15 +1242,10 @@ GenerateXEvent(
break;
case WM_UNICHAR: {
- char buffer[XMaxTransChars];
- int i;
event.type = KeyPress;
event.xany.send_event = -3;
event.xkey.keycode = wParam;
- event.xkey.nbytes = Tcl_UniCharToUtf((int)wParam, buffer);
- for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) {
- event.xkey.trans_chars[i] = buffer[i];
- }
+ event.xkey.nbytes = 0;
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
event.type = KeyRelease;
break;
@@ -1321,11 +1343,7 @@ GetState(
state &= ~mask;
}
if (HIWORD(lParam) & KF_EXTENDED) {
- if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) {
- state |= EXTENDED_MASK;
- } else {
- state &= ~EXTENDED_MASK;
- }
+ state |= EXTENDED_MASK;
}
}
return state;