Search code examples
webviewwxpythonwx.html2

Detect link mouseover events in wxPython's html2-webview


Background:

Since updating to the 2.9.4 I've begun switching a (nastily hacked in) pygtk version of webkit to the new html2 webview that comes with wxPython.

Question:

From what I can see from the docs (http://wxpython.org/Phoenix/docs/html/html2.WebView.html#html2-webview) there is no way (using python) to detect when a link is being hovered over (such as the "hovering-over-link" event http://webkitgtk.org/reference/webkitgtk/stable/webkitgtk-webkitwebview.html#WebKitWebView-hovering-over-link).

Am I going to have to resort to some javascript hackery to do this or is there another, better, solution?


Solution

  • So until this gets added I've just gone with the javascript solution. To do this we use javascript to create a page change event which is vetoed in the python code.

    First, each time a page is loaded we run the following javascript (using RunScript)

        function hoverLink(link) { 
            window.location.href = "PROXY/HOVER_EVENT_START/" + link;
        }
        function hoverLinkEnd(link) { 
            window.location.href = "PROXY/HOVER_EVENT_END/" + link;
        }
    
        function setupHoverLinks(elem) { 
            elem.onmouseover = function() {
                hoverLink(elem.href);
            }
            elem.onmouseout = function() {
                hoverLinkEnd(elem.href);
            }
        }
    
        // Loop through all links in the document and
        // setup some event listeners.
        links = document.getElementsByTagName("a");
    
        for (var i = 0; i < links.length; i++) {
                link = links[i].href;
                setupHoverLinks(links[i]);
        }
    

    This will cause a page change event each time a mouse in/out event occurs on any of the pages links. The final part of the url contains the relevant link.

    We then hook into the EVT_WEB_VIEW_NAVIGATING event, catch any of our custom page changes and veto the page change event, e.g.

    def OnPageNavigation(self, evt):
        ...
        uri = evt.GetURL() # you may need to deal with unicode here
    
        if "PROXY/HOVER_EVENT_START/" in uri:
            # Simple way to get the link
            link = uri.split("PROXY/HOVER_EVENT_START/")[1]
            ...
            # Run your mouseover code
            ...
            evt.Veto()
            return
        elif "PROXY/HOVER_EVENT_END/" in uri:
            ...
            # Run your mouseout code
            ...
            evt.Veto()
            return
        ...