@@ -554,11 +554,14 @@ void MCPlatformHandleDragDrop(MCPlatformWindowRef p_window, bool& r_accepted)
554554// //////////////////////////////////////////////////////////////////////////////
555555
556556// SN-2014-09-15: [[ Bug 13423 ]] Added new static variable to keep the last keys pressed
557+ // SN-2015-06-23: [[ Bug 3537 ]] Sometimes a keyUp key message can be already
558+ // mapped (when nativised).
557559struct MCKeyMessage
558560{
559561 MCPlatformKeyCode key_code;
560562 codepoint_t mapped_codepoint;
561563 codepoint_t unmapped_codepoint;
564+ bool needs_mapping;
562565 struct MCKeyMessage * next;
563566};
564567
@@ -583,14 +586,17 @@ void MCKeyMessageClear(MCKeyMessage *&p_message_queue)
583586}
584587
585588// SN-2014-11-03: [[ Bug 13832 ]] Added a message queue parameter
586- void MCKeyMessageAppend (MCKeyMessage *&p_message_queue, MCPlatformKeyCode p_key_code, codepoint_t p_mapped_codepoint, codepoint_t p_unmapped_codepoint)
589+ // SN-2015-06-23: [[ Bug 3537 ]] If the input has already been nativised, then
590+ // we don't want to map it with map_key_to_engine.
591+ void MCKeyMessageAppend (MCKeyMessage *&p_message_queue, MCPlatformKeyCode p_key_code, codepoint_t p_mapped_codepoint, codepoint_t p_unmapped_codepoint, bool p_needs_mapping = true )
587592{
588593 MCKeyMessage *t_new;
589594 t_new = new MCKeyMessage;
590595
591596 t_new -> key_code = p_key_code;
592597 t_new -> mapped_codepoint = p_mapped_codepoint;
593598 t_new -> unmapped_codepoint = p_unmapped_codepoint;
599+ t_new -> needs_mapping = p_needs_mapping;
594600 t_new -> next = nil;
595601
596602 if (p_message_queue != nil)
@@ -713,9 +719,20 @@ void MCPlatformHandleKeyUp(MCPlatformWindowRef p_window, MCPlatformKeyCode p_key
713719 {
714720 MCPlatformKeyCode t_mapped_key_code;
715721 MCAutoStringRef t_mapped_char;
716- map_key_to_engine (s_pending_key_up -> key_code, s_pending_key_up -> mapped_codepoint, s_pending_key_up -> unmapped_codepoint, t_mapped_key_code, &t_mapped_char);
717-
718- MCdispatcher -> wkup (p_window, *t_mapped_char, t_mapped_key_code);
722+
723+ // SN-2015-06-23: [[ Bug 3537 ]] We don't want to map a nativised char -
724+ // but we want to map key strokes like F1 and such
725+ // This is intended to mimic the behaviour of the key down process,
726+ // in which MCDispatcher::wkdown is called with the nativised char
727+ if (s_pending_key_up -> needs_mapping)
728+ map_key_to_engine (s_pending_key_up -> key_code, s_pending_key_up -> mapped_codepoint, s_pending_key_up -> unmapped_codepoint, t_mapped_key_code, &t_mapped_char);
729+ else
730+ {
731+ /* UNCHECKED */ MCStringCreateWithNativeChars ((const char_t *)&(s_pending_key_up -> mapped_codepoint), 1 , &t_mapped_char);
732+ t_mapped_key_code = s_pending_key_up -> key_code;
733+ }
734+
735+ MCdispatcher -> wkup (p_window, *t_mapped_char, t_mapped_key_code);
719736 MCKeyMessageNext (s_pending_key_up);
720737 }
721738}
@@ -918,15 +935,24 @@ void MCPlatformHandleTextInputInsertText(MCPlatformWindowRef p_window, unichar_t
918935 // this wrong key is replaced by the dead-key char
919936 // SN-2015-04-10: [[ Bug 14205 ]] When using the dictation, there is no
920937 // pending key down, but the composition was still on though.
921- if (t_was_compositing && s_pending_key_down)
938+ // SN-2015-06-23: [[ Bug 3537 ]] We should not cast p_char as a uint1 if it
939+ // is not a native char.
940+ uint1 t_char[2 ];
941+ bool t_is_native_char;
942+ t_is_native_char = MCUnicodeMapToNative (p_chars, 1 , t_char[0 ]);
943+ t_char[1 ] = 0 ;
944+
945+ if (t_was_compositing && s_pending_key_down && t_is_native_char)
922946 {
923- s_pending_key_down -> key_code = (uint1)*p_chars ;
924- s_pending_key_down -> mapped_codepoint = (uint1)*p_chars ;
925- s_pending_key_down -> unmapped_codepoint = (uint1)*p_chars ;
947+ s_pending_key_down -> key_code = (uint1)*t_char ;
948+ s_pending_key_down -> mapped_codepoint = (uint1)*t_char ;
949+ s_pending_key_down -> unmapped_codepoint = (uint1)*t_char ;
926950
927951 // SN-2015-05-18: [[ Bug 15385 ]] Enqueue the first char in the sequence
928952 // here - that will be the same as keyDown.
929- MCKeyMessageAppend (s_pending_key_up, (uint1)*p_chars, (uint1)*p_chars, (uint1)*p_chars);
953+ // SN-2015-06-23: [[ Bug 3537 ]] In this only case, we don't want this
954+ // nativised char to be mapped again in MCPlatformHandleKeyUp.
955+ MCKeyMessageAppend (s_pending_key_up, (uint1)*t_char, (uint1)*t_char, (uint1)*t_char, false );
930956 }
931957
932958 // Set the text.
@@ -939,16 +965,14 @@ void MCPlatformHandleTextInputInsertText(MCPlatformWindowRef p_window, unichar_t
939965 // [Raw]KeyDown/Up and remove the first character from the sequence of keys typed.
940966 // If the character successfully combined with the dead char before it in a native char, we don't use finsert
941967 // Otherwise, we have the dead char in p_chars, we need to remove the one stored first in the sequence
942- uint1 t_char[2 ];
943- t_char[1 ] = 0 ;
944-
945968 MCAutoStringRef t_string;
969+
946970 // SN-2015-01-20: [[ Bug 14406 ]] If we have a series of pending keys, we have two possibilities:
947971 // - typing IME characters: the characters are native, so we use the finsertnew
948972 // - typing dead characters: the character, if we arrive here, is > 127
949973 // SN-2015-04-13: [[ Bug 14205 ]] Ensure that s_pending_key_down is not nil
950974 if (*p_chars > 127 && s_pending_key_down && s_pending_key_down -> next
951- && MCUnicodeMapToNative (p_chars, 1 , t_char[ 0 ]) )
975+ && t_is_native_char )
952976 {
953977 MCStringCreateWithNativeChars ((const char_t *)t_char, 1 , &t_string);
954978 MCdispatcher -> wkdown (p_window, *t_string, *t_char);
0 commit comments