Changeset 82831 in webkit


Ignore:
Timestamp:
Apr 4, 2011 7:23:25 AM (13 years ago)
Author:
Martin Robinson
Message:

2011-04-04 Martin Robinson <mrobinson@igalia.com>

Reviewed by Xan Lopez.

[Gtk] webkit_web_view_popup_menu_handler should call SelectionController::localCaretRect
https://bugs.webkit.org/show_bug.cgi?id=54633

Remove use of legacy editing positions when positioning keyboard-driven context
menus. Simplify the code greatly.

  • webkit/webkitwebview.cpp: (getLocationForKeyboardGeneratedContextMenu): Added this helper which calculates the context menu position. (webkit_web_view_popup_menu_handler): Simplify code preventing the menu from bumping into the edges of the view. Remove (0,-1) hack as it no longer seems to be important.
Location:
trunk/Source/WebKit/gtk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/gtk/ChangeLog

    r82774 r82831  
     12011-04-04  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Xan Lopez.
     4
     5        [Gtk] webkit_web_view_popup_menu_handler should call SelectionController::localCaretRect
     6        https://bugs.webkit.org/show_bug.cgi?id=54633
     7
     8        Remove use of legacy editing positions when positioning keyboard-driven context
     9        menus. Simplify the code greatly.
     10
     11        * webkit/webkitwebview.cpp:
     12        (getLocationForKeyboardGeneratedContextMenu): Added this helper which calculates
     13        the context menu position.
     14        (webkit_web_view_popup_menu_handler): Simplify code preventing the menu from bumping
     15        into the edges of the view. Remove (0,-1) hack as it no longer seems to be important.
     16
    1172011-04-02  Dominic Cooney  <dominicc@google.com>
    218
  • trunk/Source/WebKit/gtk/webkit/webkitwebview.cpp

    r82553 r82831  
    382382}
    383383
     384static const int gContextMenuMargin = 1;
     385static IntPoint getLocationForKeyboardGeneratedContextMenu(Frame* frame)
     386{
     387    SelectionController* selection = frame->selection();
     388    if (!selection->selection().isNonOrphanedCaretOrRange()
     389         || (selection->selection().isCaret() && !selection->selection().isContentEditable())) {
     390        if (Node* focusedNode = getFocusedNode(frame))
     391            return focusedNode->getRect().location();
     392
     393        // There was no selection and no focused node, so just put the context
     394        // menu into the corner of the view, offset slightly.
     395        return IntPoint(gContextMenuMargin, gContextMenuMargin);
     396    }
     397
     398    // selection->selection().firstRange can return 0 here, but if that was the case
     399    // selection->selection().isNonOrphanedCaretOrRange() would have returned false
     400    // above, so we do not have to check it.
     401    IntRect firstRect = frame->editor()->firstRectForRange(selection->selection().firstRange().get());
     402    return IntPoint(firstRect.x(), firstRect.maxY());
     403}
     404
    384405static gboolean webkit_web_view_popup_menu_handler(GtkWidget* widget)
    385406{
    386     static const int contextMenuMargin = 1;
    387 
    388     // The context menu event was generated from the keyboard, so show the context menu by the current selection.
    389     Page* page = core(WEBKIT_WEB_VIEW(widget));
    390     Frame* frame = page->focusController()->focusedOrMainFrame();
     407    Frame* frame = core(WEBKIT_WEB_VIEW(widget))->focusController()->focusedOrMainFrame();
     408    IntPoint location = getLocationForKeyboardGeneratedContextMenu(frame);
     409
    391410    FrameView* view = frame->view();
    392411    if (!view)
    393         return FALSE;   
    394 
    395     Position start = frame->selection()->selection().start();
    396     Position end = frame->selection()->selection().end();
    397 
    398     int rightAligned = FALSE;
    399     IntPoint location;
    400 
    401     if (!start.deprecatedNode() || !end.deprecatedNode()
    402         || (frame->selection()->selection().isCaret() && !frame->selection()->selection().isContentEditable())) {
    403         // If there's a focused elment, use its location.
    404         if (Node* focusedNode = getFocusedNode(frame)) {
    405             IntRect focusedNodeRect = focusedNode->getRect();
    406             location = IntPoint(rightAligned ? focusedNodeRect.maxX() : focusedNodeRect.x(), focusedNodeRect.maxY());
    407         } else
    408             location = IntPoint(rightAligned ? view->contentsWidth() - contextMenuMargin : contextMenuMargin, contextMenuMargin);
    409     } else {
    410         RenderObject* renderer = start.deprecatedNode()->renderer();
    411         if (!renderer)
    412             return FALSE;
    413 
    414         // Calculate the rect of the first line of the selection (cribbed from -[WebCoreFrameBridge firstRectForDOMRange:],
    415         // now Frame::firstRectForRange(), which perhaps this should call).
    416         int extraWidthToEndOfLine = 0;
    417 
    418         InlineBox* startInlineBox;
    419         int startCaretOffset;
    420         start.getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);
    421         IntRect startCaretRect = renderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
    422         if (startCaretRect != IntRect())
    423             startCaretRect = renderer->localToAbsoluteQuad(FloatRect(startCaretRect)).enclosingBoundingBox();
    424 
    425         InlineBox* endInlineBox;
    426         int endCaretOffset;
    427         end.getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);
    428         IntRect endCaretRect = renderer->localCaretRect(endInlineBox, endCaretOffset);
    429         if (endCaretRect != IntRect())
    430             endCaretRect = renderer->localToAbsoluteQuad(FloatRect(endCaretRect)).enclosingBoundingBox();
    431 
    432         IntRect firstRect;
    433         if (startCaretRect.y() == endCaretRect.y())
    434             firstRect = IntRect(MIN(startCaretRect.x(), endCaretRect.x()),
    435                                 startCaretRect.y(),
    436                                 abs(endCaretRect.x() - startCaretRect.x()),
    437                                 MAX(startCaretRect.height(), endCaretRect.height()));
    438         else
    439             firstRect = IntRect(startCaretRect.x(),
    440                                 startCaretRect.y(),
    441                                 startCaretRect.width() + extraWidthToEndOfLine,
    442                                 startCaretRect.height());
    443 
    444         location = IntPoint(rightAligned ? firstRect.maxX() : firstRect.x(), firstRect.maxY());
    445     }
    446 
    447     // FIXME: The IntSize(0, -1) is a hack to get the hit-testing to result in the selected element.
    448     // Ideally we'd have the position of a context menu event be separate from its target node.
    449     location = view->contentsToWindow(location) + IntSize(0, -1);
    450     if (location.y() < 0)
    451         location.setY(contextMenuMargin);
    452     else if (location.y() > view->height())
    453         location.setY(view->height() - contextMenuMargin);
    454     if (location.x() < 0)
    455         location.setX(contextMenuMargin);
    456     else if (location.x() > view->width())
    457         location.setX(view->width() - contextMenuMargin);
    458     IntPoint global(globalPointForClientPoint(gtk_widget_get_window(widget), location));
    459 
    460     PlatformMouseEvent event(location, global, RightButton, MouseEventPressed, 0, false, false, false, false, gtk_get_current_event_time());
    461 
     412        return FALSE;
     413
     414    // Never let the context menu touch the very edge of the view.
     415    location = view->contentsToWindow(location);
     416    location.expandedTo(IntPoint(gContextMenuMargin, gContextMenuMargin));
     417    location.shrunkTo(IntPoint(view->width() - gContextMenuMargin, view->height() - gContextMenuMargin));
     418
     419    IntPoint globalPoint(globalPointForClientPoint(gtk_widget_get_window(widget), location));
     420    PlatformMouseEvent event(location, globalPoint, RightButton, MouseEventPressed, 0, false, false, false, false, gtk_get_current_event_time());
    462421    return webkit_web_view_forward_context_menu_event(WEBKIT_WEB_VIEW(widget), event);
    463422}
Note: See TracChangeset for help on using the changeset viewer.