Qt와 GTK에서 마우스 클릭 시 입력기 모듈에 보내는 요청 시퀀스가 좀 달랐음.
GTK에서는 일부 위젯 한정으로 텍스트 편집 중 마우스를 클릭했을 때 입력기에 reset 신호를 보내고 나서 preedit text(한국어에서는 입력 중인 글자)를 그대로 커밋해 버리는데 Qt는 마우스가 클릭되었다는 신호만 보내고 말아서 입력기가 저걸 어떻게 처리하느냐에 따라 behavior 자체가 완전히 달라짐.
참고로 내가 찾아본 몇 가지 입력기는 마우스 이벤트를 받았을 때 이렇게 처리한다고 함.
- fcitx: preedit text 바깥 영역을 클릭한 경우에만 commit, 나머지 케이스는 무시. 이마저도 Qt 모듈 쪽에서 처리해서 입력기 내부 버퍼는 그대로 남아 있음
- uim: 아예 무시
- ibus: 어디를 클릭하든 commit(Qt 버전이 충분히 높은 경우 한정)
- nimf: 입력기 모듈로 Qt가 직접 보내주는 이벤트를 무시하는 대신 global event filter를 통해 애플리케이션 내 모든 마우스 이벤트를 모니터링해서 reset 신호를 보냄
Nimf의 경우 "GDK 키 이벤트 후킹하기" 옵션을 켜면 입력기 관련 처리가 제대로 구현되지 않은 GTK 위젯을 쓰는 프로그램에서도 마우스 이벤트를 알아서 처리해 줘서 Qt나 GTK를 쓰는 어지간한 프로그램에서는 버그가 잘 안 나는 편이라던데 난 아직 안 써봐서 모르겠음.
요약: - GTK에서는 위젯 단위에서 마우스 이벤트가 들어왔을 때 입력기에 리셋 신호를 보내도록 되어 있는 경우가 많아서 그게 구현되지 않은 위젯을 쓸 때에 버그가 일어남(Nimf에서는 그것도 일부는 해결 가능) - Qt는 마우스 이벤트만 입력 모듈에 보내주고 끝내기 때문에 입력기 쪽 모듈에서 그걸 처리하는 방식에 따라 버그가 나기도 하고 안 나기도 함
열심이시네요 - dc App
원래 버그 고치는 게 늘 하는 일이자 취미이자 특기라 그럼
주작아님 내가 개추함 - dc App
나두 개추
이것도 이슈에 자료태그로 올릴까 아님 걍 마크다운 파일로 커밋?
자료를 repository 내 파일로 관리하느냐 이슈로 관리하느냐의 차이 같은데 개인적으로는 버그랑 섞이는 건 별로임.
그럼 자료파일 pr 올려줘요
아 근데 자료는 따로 리포파는게 어떰
그게 좋겠다
resources 팠음
확인함. 시간 날 때 올리도록 하겠음.
방금 nimf 써 봤는데 GTK 옵션 두 개 켜니까 어지간한 프로그램은 잘 돌아감. 물론 얘도 해결 못하는 프로그램 버그가 제법 있긴 함.
깃합 한글입력 그룹에 이슈로 올려줘
ibus가 다른거보다 무난하게 잘 동작하는 이유가 이거였구나
대신 낡은 거 쓰면 좀 문제가 많긴 함.
nimf 에서는 입력기 모듈로 Qt가 직접 보내주는 이벤트를 무시하지는 않음. Qt4 는 현재 안 쓰니까 패스하고 Qt5 를 보면,
https://gitlab.com/nimf-i18n/nimf/-/blob/master/modules/clients/qt5/im-nimf-qt5.cpp#L377
https://gitlab.com/nimf-i18n/nimf/-/blob/master/modules/clients/qt5/im-nimf-qt5.cpp#L125
사용자가
옵션으로 껐다 켰다할 수 있게 해놓았고, 옵션을 켜면 아마 모든 Qt 어플에서 끝글자 버그 안 날거임.
그리고 Qt5 에서는 마우스 이벤트를 Qt 입력 API 를 통하여 입력기가 받을 수 있는 방법이 없음.
그래서 qApp->installEventFilter(context->m_handler), qApp->removeEventFilter(context->m_handler) 요 함수를 쓰는거고. 아마 그게 글로벌 이벤트 맞을 거임. Qt4 의 경우는
https://gitlab.com/nimf-i18n/nimf/-/blob/master/modules/clients/qt4/im-nimf-qt4.cpp#L334
이렇게 입력 API (filterEvent) 를 통하여 마우스 이벤트를 받을 수 있고. 근데 현시점에서 qt4 사장되고 qt5 로 아마 다 교체되었을 듯.
본문에 약간 부정확하게 쓰긴 했는데 invokeAction 함수로 click을 받을 수 있긴 함. 다만 이게 언제나 들어오는 건 아니어서 문제지.
invokeAction 은 Called by the input item when the word currently being composed is tapped by the user, as indicated by the action a and the given cursorPosition. Input methods often use this information to offer more word suggestions to the user. 우리가 안드로이드 쓸 때 터치하면 키보드가 위로 올라오잖아. 아마 그런거 구현할 때 invokeAction 이거 쓰는거 같은디
님 댓글 보고 Qt 관련해서 좀 더 찾아 보니까 invokeAction은 한국어 입력에서 딱히 중요한 것 같진 않고 위젯에서 commit이든 reset이든 정상적으로 날려 주고 이걸 입력기에서 잘 처리하는 게 관건인 것 같음.
그리고 타 입력기의 경우 GTK 입력 모듈에 gtk_key_snooper_install() 이게 내장되어 있을 거임. grep 으로 검색함 해보셈. 그 함수를 사용하지 않아도 끝글자 버그가 없어야 정상임. 그것 때문에 어플 개발자 입장에서 어플에서 입력 루틴이 제대로 되었다고 간주하고 있을 수 있고.. 아무튼 그런게 땜에 버그 리포팅도 어렵고 어플 개발자 입장에서는 각 입력기 마다 동작이 약간씩 다르니 그걸 해결하기도 어렵겠지. 그래서 nimf 에서는 workaround(땜빵) 기능을 옵션으로 껐다 켰다 할 수 있게 해놓았음. 땜방 기능을 껐을 때 입력 버그가 있다면 그건 거의 어플 버그일 것으로 추측
글구 sublime 같은 경우는 전에 테스트해보니.. 일부 키(화살표, 에 대해서 KeyPress(누를 때) 이벤트를 입력기로 보내는 것이 아니라 KeyRelease(키에서 손가락 땔 때) 이벤트를 보내는 것 같음. 어플 버그인데, gtk_key_snooper_install() 이 함수 쓰면 해결되는 거 같음.
딴지는 아니구, 내가 알고 있는 노하우 참고하라는 의미이고, 한글 버그 신경써줘서 고마워! 내가 맨날 오픈소스 욕 5G게한 보람을.. 느낀다 ㅋㅋㅋ 앞으로 욕 안하께~~ 발작도 안하구~~
정보 감사함.
깃헙그룹에 이 내용 정리해서 올려줘
언제 저거 정리할 여유가 생길지는 모르겠는데 아마 이번 주 안에는 올릴 듯.