@@ -65,6 +65,10 @@ Time KeymapWrapper::sLastRepeatableKeyTime = 0;
65
65
KeymapWrapper::RepeatState KeymapWrapper::sRepeatState =
66
66
KeymapWrapper::NOT_PRESSED;
67
67
68
+ #ifdef MOZ_WAYLAND
69
+ uint32_t KeymapWrapper::sLastRepeatableSerial = 0 ;
70
+ #endif
71
+
68
72
static const char * GetBoolName (bool aBool) { return aBool ? " TRUE" : " FALSE" ; }
69
73
70
74
static const char * GetStatusName (nsEventStatus aStatus) {
@@ -665,6 +669,8 @@ void KeymapWrapper::SetModifierMasks(xkb_keymap* aKeymap) {
665
669
keymapWrapper->SetModifierMask (aKeymap, INDEX_LEVEL3, " Level3" );
666
670
keymapWrapper->SetModifierMask (aKeymap, INDEX_LEVEL5, " Level5" );
667
671
672
+ keymapWrapper->SetKeymap (aKeymap);
673
+
668
674
MOZ_LOG (gKeyLog , LogLevel::Info,
669
675
(" %p KeymapWrapper::SetModifierMasks, CapsLock=0x%X, NumLock=0x%X, "
670
676
" ScrollLock=0x%X, Level3=0x%X, Level5=0x%X, "
@@ -707,6 +713,13 @@ void KeymapWrapper::HandleKeymap(uint32_t format, int fd, uint32_t size) {
707
713
}
708
714
709
715
struct xkb_context * xkb_context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
716
+ if (!xkb_context) {
717
+ MOZ_LOG (gKeyLog , LogLevel::Info,
718
+ (" KeymapWrapper::HandleKeymap(): failed to get xkb_context!" ));
719
+ close (fd);
720
+ return ;
721
+ }
722
+
710
723
struct xkb_keymap * keymap = xkb_keymap_new_from_string (
711
724
xkb_context, mapString, XKB_KEYMAP_FORMAT_TEXT_V1,
712
725
XKB_KEYMAP_COMPILE_NO_FLAGS);
@@ -717,6 +730,7 @@ void KeymapWrapper::HandleKeymap(uint32_t format, int fd, uint32_t size) {
717
730
if (!keymap) {
718
731
MOZ_LOG (gKeyLog , LogLevel::Info,
719
732
(" KeymapWrapper::HandleKeymap(): Failed to compile keymap!" ));
733
+ xkb_context_unref (xkb_context);
720
734
return ;
721
735
}
722
736
@@ -731,6 +745,11 @@ void KeymapWrapper::HandleKeymap(uint32_t format, int fd, uint32_t size) {
731
745
KeymapWrapper::~KeymapWrapper () {
732
746
#ifdef MOZ_X11
733
747
gdk_window_remove_filter (nullptr , FilterEvents, this );
748
+ #endif
749
+ #ifdef MOZ_WAYLAND
750
+ if (mXkbKeymap ) {
751
+ xkb_keymap_unref (mXkbKeymap );
752
+ }
734
753
#endif
735
754
if (mOnKeysChangedSignalHandle ) {
736
755
g_signal_handler_disconnect (mGdkKeymap , mOnKeysChangedSignalHandle );
@@ -858,6 +877,87 @@ GdkFilterReturn KeymapWrapper::FilterEvents(GdkXEvent* aXEvent,
858
877
}
859
878
#endif
860
879
880
+ #ifdef MOZ_WAYLAND
881
+ // static
882
+ void KeymapWrapper::KeyboardHandlerForWayland (uint32_t aSerial,
883
+ uint32_t aHardwareKeycode,
884
+ uint32_t aState) {
885
+ KeymapWrapper* keymapWrapper = GetInstance ();
886
+ if (!keymapWrapper->IsAutoRepeatableKey (aHardwareKeycode)) {
887
+ MOZ_LOG (gKeyLog , LogLevel::Info,
888
+ (" KeyboardHandlerForWayland(aSerial=%u, aHardwareKeycode=0x%08X, "
889
+ " aState=%s), no repeat key" ,
890
+ aSerial, aHardwareKeycode,
891
+ aState == WL_KEYBOARD_KEY_STATE_PRESSED
892
+ ? " WL_KEYBOARD_KEY_STATE_PRESSED"
893
+ : " WL_KEYBOARD_KEY_STATE_RELEASED" ));
894
+ return ;
895
+ }
896
+
897
+ if (aState == WL_KEYBOARD_KEY_STATE_PRESSED) {
898
+ MOZ_LOG (gKeyLog , LogLevel::Info,
899
+ (" KeyboardHandlerForWayland(aSerial=%u, aHardwareKeycode=0x%08X, "
900
+ " aState=WL_KEYBOARD_KEY_STATE_PRESSED), first key pressed" ,
901
+ aSerial, aHardwareKeycode));
902
+
903
+ sLastRepeatableSerial = aSerial;
904
+ sLastRepeatableHardwareKeyCode = aHardwareKeycode;
905
+ sRepeatState = FIRST_PRESS;
906
+
907
+ // This runnable will be run after GDK's key event.
908
+ //
909
+ // Next key press of GDK will be after repeat's delay ms.
910
+ // But event time in next key press wonn't updated.
911
+ //
912
+ // The delay's default is 400ms in GTK/wayland. Even if we can get this
913
+ // information from repeat_info, if we wait for this time, it is too late.
914
+ // We guess that 10ms will be enough durration to set repeat state.
915
+
916
+ NS_DelayedDispatchToCurrentThread (
917
+ NS_NewRunnableFunction (
918
+ __func__,
919
+ [aSerial] {
920
+ if (sLastRepeatableSerial != aSerial) {
921
+ // We already receive newer key event. Don't set repeat state.
922
+ return ;
923
+ }
924
+
925
+ MOZ_LOG (gKeyLog , LogLevel::Info,
926
+ (" KeyboardHandlerForWayland(aSerial=%u, "
927
+ " aState=WL_KEYBOARD_KEY_STATE_PRESSED), repeating" ,
928
+ aSerial));
929
+ sRepeatState = REPEATING;
930
+ }),
931
+ 10);
932
+ return ;
933
+ }
934
+
935
+ if (sLastRepeatableHardwareKeyCode != aHardwareKeycode) {
936
+ MOZ_LOG (gKeyLog , LogLevel::Info,
937
+ (" KeyboardHandlerForWayland(aSerial=%u, aHardwareKeycode=0x%08X "
938
+ " aState=WL_KEYBOARD_KEY_STATE_RELEASED), released key isn't "
939
+ " matched" ,
940
+ aSerial, aHardwareKeycode));
941
+ return ;
942
+ }
943
+
944
+ MOZ_LOG (gKeyLog , LogLevel::Info,
945
+ (" KeyboardHandlerForWayland(aSerial=%u, aHardwareKeycode=0x%08X"
946
+ " aState=WL_KEYBOARD_KEY_STATE_RELEASED), not pressed" ,
947
+ aSerial, aHardwareKeycode));
948
+
949
+ sLastRepeatableSerial = aSerial;
950
+ sRepeatState = NOT_PRESSED;
951
+ }
952
+
953
+ void KeymapWrapper::SetKeymap (xkb_keymap* aKeymap) {
954
+ if (mXkbKeymap ) {
955
+ xkb_keymap_unref (mXkbKeymap );
956
+ }
957
+ mXkbKeymap = xkb_keymap_ref (aKeymap);
958
+ }
959
+ #endif
960
+
861
961
static void ResetBidiKeyboard () {
862
962
// Reset the bidi keyboard settings for the new GdkKeymap
863
963
nsCOMPtr<nsIBidiKeyboard> bidiKeyboard = nsContentUtils::GetBidiKeyboard ();
@@ -2033,15 +2133,28 @@ bool KeymapWrapper::IsLatinGroup(guint8 aGroup) {
2033
2133
}
2034
2134
2035
2135
bool KeymapWrapper::IsAutoRepeatableKey (guint aHardwareKeyCode) {
2136
+ GdkDisplay* gdkDisplay = gdk_display_get_default ();
2036
2137
#ifdef MOZ_X11
2037
- uint8_t indexOfArray = aHardwareKeyCode / 8 ;
2038
- MOZ_ASSERT (indexOfArray < std::size (mKeyboardState .auto_repeats ),
2039
- " invalid index" );
2040
- char bitMask = 1 << (aHardwareKeyCode % 8 );
2041
- return (mKeyboardState .auto_repeats [indexOfArray] & bitMask) != 0 ;
2042
- #else
2043
- return false ;
2138
+ if (GdkIsX11Display (gdkDisplay)) {
2139
+ uint8_t indexOfArray = aHardwareKeyCode / 8 ;
2140
+ MOZ_ASSERT (indexOfArray < std::size (mKeyboardState .auto_repeats ),
2141
+ " invalid index" );
2142
+ char bitMask = 1 << (aHardwareKeyCode % 8 );
2143
+ return (mKeyboardState .auto_repeats [indexOfArray] & bitMask) != 0 ;
2144
+ }
2145
+ #endif
2146
+ #ifdef MOZ_WAYLAND
2147
+ if (GdkIsWaylandDisplay (gdkDisplay)) {
2148
+ if (MOZ_UNLIKELY (!mXkbKeymap )) {
2149
+ static bool sWarned = false ;
2150
+ NS_WARNING_ASSERTION (sWarned , " no keymap!" );
2151
+ sWarned = true ;
2152
+ return false ;
2153
+ }
2154
+ return !!xkb_keymap_key_repeats (mXkbKeymap , aHardwareKeyCode);
2155
+ }
2044
2156
#endif
2157
+ return false ;
2045
2158
}
2046
2159
2047
2160
/* static */
@@ -2646,6 +2759,8 @@ void KeymapWrapper::SetFocusOut(wl_surface* aFocusSurface) {
2646
2759
2647
2760
keymapWrapper->mFocusSurface = nullptr ;
2648
2761
keymapWrapper->mFocusSerial = 0 ;
2762
+
2763
+ sRepeatState = NOT_PRESSED;
2649
2764
}
2650
2765
2651
2766
void KeymapWrapper::GetFocusInfo (wl_surface** aFocusSurface,
@@ -2654,6 +2769,14 @@ void KeymapWrapper::GetFocusInfo(wl_surface** aFocusSurface,
2654
2769
*aFocusSurface = keymapWrapper->mFocusSurface ;
2655
2770
*aFocusSerial = keymapWrapper->mFocusSerial ;
2656
2771
}
2772
+
2773
+ void KeymapWrapper::ClearKeymap () {
2774
+ KeymapWrapper* keymapWrapper = KeymapWrapper::GetInstance ();
2775
+ if (keymapWrapper->mXkbKeymap ) {
2776
+ xkb_keymap_unref (keymapWrapper->mXkbKeymap );
2777
+ keymapWrapper->mXkbKeymap = nullptr ;
2778
+ }
2779
+ }
2657
2780
#endif
2658
2781
2659
2782
} // namespace widget
0 commit comments