Search code examples
htmlinputembeddedqtwebkit

QtWebkit: How to hook a virtual keyboard on <input> fields


I'm working on an embedded Webkit browser (with Qt 4.8.0 on linux) that runs with a remote control on a TV set. I have pretty much everything working so far, and I'm now trying to handle the <input> tag in webpages.

What I'd like to happen is: whenever an input field is selected, I'd like to pop my virtual keyboard and let the user enter text with his remote, then push back the result into the .

I tried several methods already to do that:

  • installing a QInputContext using this tutorial: I see no event go through the InputContext I installed.
  • re-implementing various eventFilter() at different stages of my browser (in the QApp, in the QGraphicsWebPage, in the QGraphicsWebView ): I see LOADS of events, but never the ones I'm interested in ( QEvent::RequestSoftwareInputPanel / QEvent::CloseSoftwareInputPanel / FocusIn/ FocusOut/ Enter/ Leave).
  • using installSceneEventFilter() gives me the same result as the previous point.

Since I'm not using a mouse, I can't handle the events like "mouse hover" or "mouse clicked" to determine if the <input> element was focused.

So I'm wondering how I can hook up to any <input> in the web page to detect when the focus arrived on it. Note that I guess this has to work even if the <input> field is dynamically inserted through a Javascript script in the page.

Is there a Qt signal I can connect to?
How to handle new input forms inserted dynamically?

Possible solutions I havent explored yet: using the QT_KEYPAD_NAVIGATION in mkspecs for my arch, and then filter the QEvent::EnterEditFocus that should pass. I'd rather stick to the vanilla Qt that I have now, so that's an extreme (which I'm not sure will work).


Solution

  • For those interested in the solution, here it is:

    • use addToJavascriptWindowObject() to insert a C++ object of your own, that has at least 1 method: showMultitap(cont QWebElement&). Let's say you insert it with the name "multitap".

    • inject a javascript code that looks like the following:

      document.addEventListener("focus", function(e){
          window.multitap.showMultitap(e); // will land in your C++ object
      }, true);
      

    And check in your C++ handler that the element is a text element before actually showing the VK.

    • one issue you'll have is that you can't exit a text field with only the keyboard (or remote) arrows, so you'll have to add DEFINES += QT_KEYPAD_NAVIGATON to your Qt compilation process (best is to put them in the qmakespecs of your arch).