eL.
eL.

Reputation: 311

Dead keys don't arrive at keyPressedEvent()

I'm using Qt 4.3.1 (I'm not able to uptade at the moment) for a program, anyway in Windows dead keys (^, ´, `, ...) don't arrive at the keyPressedEvent(), i always have to press them twice.

So why don't those dead keys arrive? How can I fix it?

In MacOS everything works fine though.

Thx, eL.

Upvotes: 3

Views: 1322

Answers (2)

Noah Callaway
Noah Callaway

Reputation: 636

After looking at the Qt documentation I'm not sure if keyPressEvent is supposed to deliver dead keys or not. I'm actually kind of surprised that you see them on a Mac.

I'm guessing that Qt is choosing to wait for WM_CHAR events, or something, before sending the keyPressEvent for your widget. As you can see from this page: http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx#_win32_Dead_Character_Messages the order of key events when a user pressed a dead-key followed by a real-key is:

WM_KEYDOWN
WM_DEADCHAR
WM_KEYUP
WM_KEYDOWN
WM_CHAR
WM_KEYUP

If you really want to capture the deadchar key-presses, look at subclassing QApplication and overriding the winEventFilter (http://doc.qt.io/qt-4.8/qcoreapplication.html#winEventFilter) method. This will let you capture the WM_DEADCHAR events as they come in. You can then create a KeyEvent and dispatch it to the widget that currently has focus.

Upvotes: 2

Logunov
Logunov

Reputation: 1

The guess that Qt waits for WM_CHAR events is wrong. While processing WM_KEYDOWN event the Qt looks for WM_DEADCHAR message in the message queue. If there is such message, Qt bypasses normal WM_KEYDOWN processing. If You want to receive QKeyEvent for dead keys, You should clean up the message queue from WM_DEADCHAR messages. Write a bit of code like this:

bool TEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
 if(eventType=="windows_generic_MSG")
 { 
  MSG *msg=static_cast<MSG*>(message);
  MSG peekedMsg;
  switch(msg->message)
  {
   case WM_KEYDOWN:
   case WM_SYSKEYDOWN:
   PeekMessage(&peekedMsg, msg->hwnd, WM_DEADCHAR, WM_DEADCHAR, PM_REMOVE); 
   case WM_CHAR:
   case WM_DEADCHAR:
   if(msg->lParam&0x40000000) //message is repeated via the key holding down
   return 1;
  }
 }
 return 0;
}

Upvotes: 0

Related Questions