summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2011-10-25 20:47:00 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2011-10-25 20:47:00 (GMT)
commitaa3245a4b2c8f920670b73acc1e7c4c879f9025a (patch)
treec01887f3f3d5c59291130568d33a6ea36f7fb1bf
parentc06f0fc17c7c109a25877cdbd0d274620bae5aa9 (diff)
parent7386abe11a73dd013ce6fb5674493ec2ddbdc59b (diff)
downloadtk-aa3245a4b2c8f920670b73acc1e7c4c879f9025a.zip
tk-aa3245a4b2c8f920670b73acc1e7c4c879f9025a.tar.gz
tk-aa3245a4b2c8f920670b73acc1e7c4c879f9025a.tar.bz2
Fix for bug 3410609; confirmed to work on UK keyboard.
-rw-r--r--ChangeLog10
-rw-r--r--generic/tkInt.h2
-rw-r--r--unix/tkUnixEvent.c1
-rw-r--r--unix/tkUnixKey.c35
4 files changed, 42 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index e11a372..d7fb2e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2011-10-27 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tkInt.h: [Bug 3410609]: Change the event mechanism
+ * unix/tkUnixEvent.c: for <KeyPress> events to use the keysym
+ * unix/tkUnixKey.c: returned by XLookupString in preference to
+ the one that appears in the raw X event at any level. This change
+ allows binding to ISO_Level3_Shift-ed characters, composed characters,
+ and similar beasts. KeyRelease events still work as they did before,
+ as does Tk with input methods disabled.
+
2011-10-13 Jan Nijtmans <nijtmans@users.sf.net>
* win/tkWinDialog.c: Internationalization of all Windows font
diff --git a/generic/tkInt.h b/generic/tkInt.h
index 587cdac..51bc896 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -824,6 +824,8 @@ typedef struct {
* allocated with ckalloc(). */
int charValueLen; /* Length of string in charValuePtr when that
* is non-NULL. */
+ KeySym keysym; /* Key symbol computed after input methods
+ * have been invoked */
} TkKeyEvent;
/*
diff --git a/unix/tkUnixEvent.c b/unix/tkUnixEvent.c
index c7f126f..0987129 100644
--- a/unix/tkUnixEvent.c
+++ b/unix/tkUnixEvent.c
@@ -323,6 +323,7 @@ TransferXEventsToTcl(
if (event.type == KeyPress || event.type == KeyRelease) {
event.k.charValuePtr = NULL;
event.k.charValueLen = 0;
+ event.k.keysym = NoSymbol;
/*
* Force the calling of the input method engine now. The results
diff --git a/unix/tkUnixKey.c b/unix/tkUnixKey.c
index 35f54c7..7461d75 100644
--- a/unix/tkUnixKey.c
+++ b/unix/tkUnixKey.c
@@ -120,7 +120,7 @@ TkpGetString(
Tcl_DStringSetLength(dsPtr, TCL_DSTRING_STATIC_SIZE-1);
len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
- NULL, &status);
+ &kePtr->keysym, &status);
if (status == XBufferOverflow) {
/*
@@ -130,7 +130,7 @@ TkpGetString(
Tcl_DStringSetLength(dsPtr, len);
len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
- NULL, &status);
+ &kePtr->keysym, &status);
}
if ((status != XLookupChars) && (status != XLookupBoth)) {
len = 0;
@@ -144,8 +144,8 @@ TkpGetString(
Tcl_DStringInit(&buf);
Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
- Tcl_DStringValue(&buf), Tcl_DStringLength(&buf), NULL,
- &status);
+ Tcl_DStringValue(&buf), Tcl_DStringLength(&buf),
+ &kePtr->keysym, &status);
/*
* If the buffer wasn't big enough, grow the buffer and try again.
@@ -154,7 +154,7 @@ TkpGetString(
if (status == XBufferOverflow) {
Tcl_DStringSetLength(&buf, len);
len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
- Tcl_DStringValue(&buf), len, NULL, &status);
+ Tcl_DStringValue(&buf), len, &kePtr->keysym, &status);
}
if ((status != XLookupChars) && (status != XLookupBoth)) {
len = 0;
@@ -178,7 +178,7 @@ TkpGetString(
Tcl_DStringInit(&buf);
Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
- TCL_DSTRING_STATIC_SIZE, 0, 0);
+ TCL_DSTRING_STATIC_SIZE, &kePtr->keysym, 0);
Tcl_DStringValue(&buf)[len] = '\0';
if (len == 1) {
@@ -273,6 +273,29 @@ TkpGetKeySym(
{
KeySym sym;
int index;
+ TkKeyEvent* kePtr = (TkKeyEvent*) eventPtr;
+
+#ifdef TK_USE_INPUT_METHODS
+ /*
+ * If input methods are active, we may already have determined a keysym.
+ * Return it.
+ */
+
+ if (eventPtr->type == KeyPress && dispPtr
+ && (dispPtr->flags & TK_DISPLAY_USE_IM)) {
+ if (kePtr->charValuePtr == NULL) {
+ Tcl_DString ds;
+ TkWindow *winPtr = (TkWindow *)
+ Tk_IdToWindow(eventPtr->xany.display, eventPtr->xany.window);
+ Tcl_DStringInit(&ds);
+ (void) TkpGetString(winPtr, eventPtr, &ds);
+ Tcl_DStringFree(&ds);
+ }
+ if (kePtr->charValuePtr != NULL) {
+ return kePtr->keysym;
+ }
+ }
+#endif
/*
* Refresh the mapping information if it's stale