[webkit-help] EditorClient*::handleKeyboardEvent()

Stephan Assmus superstippi at gmx.de
Mon Feb 8 08:25:24 PST 2010


On 2010-02-07 at 23:24:29 [+0100], Alexey Proskuryakov <ap at webkit.org> 
wrote:
> 
> 07.02.2010, в 13:09, Stephan Assmus написал(а):
> 
> >> What is the kind of the start node here? Inputs themselves are indeed 
> >> not contentEditable, nodes in shadow tree below them are. So, my first 
> >> guess would the that the focus ends up being on a wrong node.
> > 
> > Doesn't this suggest I am doing something wrong with handling focus and 
> > selection?
> 
> 
> Yes, that's what I'd be looking for first.
> 
> But before investigating any further, I'd be sure to verify this 
> hypothesis by actually checking what the start node is. And then, you 
> could see what code sets the selection in your port, and in other ports.

Ok, I've gone over the code again which sets up Page, Frame and FrameView 
while comparing it with the Qt port. I found some spots to improve and 
simplify, but it hasn't helped the problem. I've added debugging output to 
the EditorClientHaiku and also SelectionController. This is what I get:

/Code/WebKit> HaikuLauncher www.haiku-os.org/?q=user
0x180526c0->SelectionController::SelectionController((nil), 1)
  (The SelectionController instance that Page creates as
   "m_dragCaretController".)
0x18058278->SelectionController::SelectionController(0x18057fa0, 0)
  (The SelectionController instance created by the first Frame, which
   (the Frame) appends itself to the Page via setMainFrame())

When I load a web page that has user/password text controls, and click into 
a text control, this output is generated:

0x18058278->SelectionController::paintCaret()
  not visible
[...]

The visibility of the caret is decided upon creation of 
SelectionController, when isDragCaretController is true. WebCore::Frame 
always passes "false" for this parameter. It is true only for 
m_dragCaretController in the Page.

In EditorClientHaiku, I've added some output for the node that is the 
selection start:

    Node* start = frame->selection()->start().node();
    if (!start)
        return;
    printf("selection start is shadow node/tree: %d/%d\n",
        start->isShadowNode(), start->isInShadowTree());

The output when I begin to type:

selection start is shadow node/tree: 0/1
0x18058278->SelectionController::paintCaret()
  not visible
[...]


So a shadow tree seems to be created, even though the selected node itself 
doesn't consider itself to be a shadow node. The burning question is 
whether there are two SelectionControllers supposed to exist, or if the 
main frame is somehow supposed to take over the dragCarentController from 
the page. Here is some code that is used for setup:


"WebProcess" is the equivalent to QWebPage, like the toplevel object to 
hold everything else:

WebProcess::WebProcess(WebView* webView)
    : BHandler("WebView process")
    , m_webView(webView)
    , m_mainFrame(0)
    , m_page(0)
{
    WebCore::EditorClientHaiku* editorClient
        = new WebCore::EditorClientHaiku();

    m_page = new WebCore::Page(
        new WebCore::ChromeClientHaiku(this, webView),
        new WebCore::ContextMenuClientHaiku(),
        editorClient,
        new WebCore::DragClientHaiku(webView),
        new WebCore::InspectorClientHaiku(),
        0,
        0);

    editorClient->setPage(m_page);

    // Default settings - We should have WebViewSettings class for this.
    WebCore::Settings* settings = m_page->settings();
    settings->setLoadsImagesAutomatically(true);
    settings->setMinimumFontSize(5);
    settings->setMinimumLogicalFontSize(5);
    settings->setShouldPrintBackgrounds(true);
    settings->setJavaScriptEnabled(true);

    [snipped font settings init]
}

void WebProcess::init()
{
    m_mainFrame = new WebFrame(this, m_page);
}


My "WebFrame" is the equivalent of QWebFrame, QFrameData and 
QWebFramePrivate combined, this is the constructor:

WebFrame::WebFrame(WebProcess* webProcess, WebCore::Page* parentPage,
        WebCore::Frame* parentFrame,
        WebCore::HTMLFrameOwnerElement* ownerElement,
        const WebCore::String& frameName)
    : m_textMagnifier(1.0)
    , m_isEditable(true)
    , m_beingDestroyed(false)
    , m_title(0)
    , m_impl(new WebFramePrivate())
{
    m_impl->name = frameName;
    m_impl->ownerElement = ownerElement;
    m_impl->page = parentPage;
    m_impl->loaderClient = new WebCore::FrameLoaderClientHaiku(
        webProcess, this);
    m_impl->frame = WebCore::Frame::create(parentPage, ownerElement,
        m_impl->loaderClient);

    m_impl->frame->tree()->setName(frameName);
    if (parentFrame)
        parentFrame->tree()->appendChild(m_impl->frame);

    m_impl->frame->init();
}


This is how a FrameView is created in the FrameLoaderClient implementation:

void FrameLoaderClientHaiku::transitionToCommittedForNewPage()
{
    ASSERT(m_webFrame);

    Frame* frame = m_webFrame->frame();

    BRect bounds = m_webProcess->viewBounds();
    IntSize size = IntSize(bounds.IntegerWidth() + 1,
        bounds.IntegerHeight() + 1);

    bool transparent = m_webFrame->isTransparent();
    Color backgroundColor = transparent ? WebCore::Color::transparent
        : WebCore::Color::white;

    frame->createView(size, backgroundColor, transparent, IntSize(), false);
}

Any help greatly appreciated!

Best regards,
-Stephan


More information about the webkit-help mailing list