Beispiel #1
0
WebMouseEventBuilder::WebMouseEventBuilder(const Widget* widget, const MouseEvent& event)
{
    if (event.type() == eventNames().mousemoveEvent)
        type = WebInputEvent::MouseMove;
    else if (event.type() == eventNames().mouseoutEvent)
        type = WebInputEvent::MouseLeave;
    else if (event.type() == eventNames().mouseoverEvent)
        type = WebInputEvent::MouseEnter;
    else if (event.type() == eventNames().mousedownEvent)
        type = WebInputEvent::MouseDown;
    else if (event.type() == eventNames().mouseupEvent)
        type = WebInputEvent::MouseUp;
    else if (event.type() == eventNames().contextmenuEvent)
        type = WebInputEvent::ContextMenu;
    else
        return; // Skip all other mouse events.
    timeStampSeconds = event.timeStamp() / millisPerSecond;
    switch (event.button()) {
    case LeftButton:
        button = WebMouseEvent::ButtonLeft;
        break;
    case MiddleButton:
        button = WebMouseEvent::ButtonMiddle;
        break;
    case RightButton:
        button = WebMouseEvent::ButtonRight;
        break;
    }
    modifiers = getWebInputModifiers(event);
    if (event.buttonDown()) {
        switch (event.button()) {
        case LeftButton:
            modifiers |= WebInputEvent::LeftButtonDown;
            break;
        case MiddleButton:
            modifiers |= WebInputEvent::MiddleButtonDown;
            break;
        case RightButton:
            modifiers |= WebInputEvent::RightButtonDown;
            break;
        }
    }
    ScrollView* view = widget->parent();
    IntPoint p = view->contentsToWindow(
        IntPoint(event.absoluteLocation().x(), event.absoluteLocation().y()));
    globalX = event.screenX();
    globalY = event.screenY();
    windowX = p.x();
    windowY = p.y();

#if OS(ANDROID)
    // absoluteLocation is actually scaled if the widget is inside an Iframe.
    // Switch to return scaled offsets so that the behaviors are consistent.
    // TODO (qinmin): maybe we should return adsolute offset in DOM space?
    IntPoint origin = view->contentsToWindow(widget->location());
    x = p.x() - origin.x();
    y = p.y() - origin.y();
#else
    x = event.absoluteLocation().x() - widget->location().x();
    y = event.absoluteLocation().y() - widget->location().y();
#endif
    clickCount = event.detail();
}
void SpinButtonElement::defaultEventHandler(Event* event)
{
    if (!event->isMouseEvent()) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;
    }

    LayoutBox* box = layoutBox();
    if (!box) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;
    }

    if (!shouldRespondToMouseEvents()) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;
    }

    MouseEvent* mouseEvent = toMouseEvent(event);
    IntPoint local = roundedIntPoint(box->absoluteToLocal(FloatPoint(mouseEvent->absoluteLocation()), UseTransforms));
    if (mouseEvent->type() == EventTypeNames::mousedown && mouseEvent->button() == LeftButton) {
        if (box->pixelSnappedBorderBoxRect().contains(local)) {
            // The following functions of HTMLInputElement may run JavaScript
            // code which detaches this shadow node. We need to take a reference
            // and check layoutObject() after such function calls.
            RefPtrWillBeRawPtr<Node> protector(this);
            if (m_spinButtonOwner)
                m_spinButtonOwner->focusAndSelectSpinButtonOwner();
            if (layoutObject()) {
                if (m_upDownState != Indeterminate) {
                    // A JavaScript event handler called in doStepAction() below
                    // might change the element state and we might need to
                    // cancel the repeating timer by the state change. If we
                    // started the timer after doStepAction(), we would have no
                    // chance to cancel the timer.
                    startRepeatingTimer();
                    doStepAction(m_upDownState == Up ? 1 : -1);
                }
            }
            event->setDefaultHandled();
        }
    } else if (mouseEvent->type() == EventTypeNames::mouseup && mouseEvent->button() == LeftButton) {
        releaseCapture();
    } else if (event->type() == EventTypeNames::mousemove) {
        if (box->pixelSnappedBorderBoxRect().contains(local)) {
            if (!m_capturing) {
                if (LocalFrame* frame = document().frame()) {
                    frame->eventHandler().setCapturingMouseEventsNode(this);
                    m_capturing = true;
                    if (Page* page = document().page())
                        page->chromeClient().registerPopupOpeningObserver(this);
                }
            }
            UpDownState oldUpDownState = m_upDownState;
            m_upDownState = (local.y() < box->size().height() / 2) ? Up : Down;
            if (m_upDownState != oldUpDownState)
                layoutObject()->setShouldDoFullPaintInvalidation();
        } else {
            releaseCapture();
            m_upDownState = Indeterminate;
        }
    }

    if (!event->defaultHandled())
        HTMLDivElement::defaultEventHandler(event);
}
void SpinButtonElement::defaultEventHandler(Event* event)
{
    if (!event->isMouseEvent()) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;
    }

    RenderBox* box = renderBox();
    if (!box) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;
    }

    RefPtr<HTMLInputElement> input(static_cast<HTMLInputElement*>(shadowAncestorNode()));
    if (input->disabled() || input->isReadOnlyFormControl()) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;
    }

    MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
    IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
    if (mouseEvent->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
        if (box->borderBoxRect().contains(local)) {
            // The following functions of HTMLInputElement may run JavaScript
            // code which detaches this shadow node. We need to take a reference
            // and check renderer() after such function calls.
            RefPtr<Node> protector(this);
            input->focus();
            input->select();
            if (renderer()) {
                ASSERT(m_upDownState != Indeterminate);
                input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
                if (renderer())
                    startRepeatingTimer();
            }
            event->setDefaultHandled();
        }
    } else if (mouseEvent->type() == eventNames().mouseupEvent && mouseEvent->button() == LeftButton)
        stopRepeatingTimer();
    else if (event->type() == eventNames().mousemoveEvent) {
        if (box->borderBoxRect().contains(local)) {
            if (!m_capturing) {
                if (Frame* frame = document()->frame()) {
                    frame->eventHandler()->setCapturingMouseEventsNode(this);
                    m_capturing = true;
                }
            }
            UpDownState oldUpDownState = m_upDownState;
            m_upDownState = local.y() < box->height() / 2 ? Up : Down;
            if (m_upDownState != oldUpDownState)
                renderer()->repaint();
        } else {
            releaseCapture();
            m_upDownState = Indeterminate;
        }
    }

    if (!event->defaultHandled())
        HTMLDivElement::defaultEventHandler(event);
}
void HTMLAnchorElement::defaultEventHandler(Event* evt)
{
    // React on clicks and on keypresses.
    // Don't make this KEYUP_EVENT again, it makes khtml follow links it shouldn't,
    // when pressing Enter in the combo.
    if (m_isLink && (evt->type() == eventNames().clickEvent || (evt->type() == eventNames().keydownEvent && m_focused))) {
        MouseEvent* e = 0;
        if (evt->type() == eventNames().clickEvent && evt->isMouseEvent())
            e = static_cast<MouseEvent*>(evt);

        KeyboardEvent* k = 0;
        if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent())
            k = static_cast<KeyboardEvent*>(evt);

        if (e && e->button() == RightButton) {
            HTMLElement::defaultEventHandler(evt);
            return;
        }

        // If the link is editable, then we need to check the settings to see whether or not to follow the link
        if (isContentEditable()) {
            EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior;
            if (Settings* settings = document()->settings())
                editableLinkBehavior = settings->editableLinkBehavior();
                
            switch (editableLinkBehavior) {
                // Always follow the link (Safari 2.0 behavior)
                default:
                case EditableLinkDefaultBehavior:
                case EditableLinkAlwaysLive:
                    break;

                case EditableLinkNeverLive:
                    HTMLElement::defaultEventHandler(evt);
                    return;

                // If the selection prior to clicking on this link resided in the same editable block as this link,
                // and the shift key isn't pressed, we don't want to follow the link
                case EditableLinkLiveWhenNotFocused:
                    if (e && !e->shiftKey() && m_rootEditableElementForSelectionOnMouseDown == rootEditableElement()) {
                        HTMLElement::defaultEventHandler(evt);
                        return;
                    }
                    break;

                // Only follow the link if the shift key is down (WinIE/Firefox behavior)
                case EditableLinkOnlyLiveWithShiftKey:
                    if (e && !e->shiftKey()) {
                        HTMLElement::defaultEventHandler(evt);
                        return;
                    }
                    break;
            }
        }

        if (k) {
            if (k->keyIdentifier() != "Enter") {
                HTMLElement::defaultEventHandler(evt);
                return;
            }
            evt->setDefaultHandled();
            dispatchSimulatedClick(evt);
            return;
        }

        String url = parseURL(getAttribute(hrefAttr));

        ASSERT(evt->target());
        ASSERT(evt->target()->toNode());
        if (evt->target()->toNode()->hasTagName(imgTag)) {
            HTMLImageElement* img = static_cast<HTMLImageElement*>(evt->target()->toNode());
            if (img && img->isServerMap()) {
                RenderImage* r = static_cast<RenderImage*>(img->renderer());
                if (r && e) {
                    int absx, absy;
                    r->absolutePosition(absx, absy);
                    int x = e->pageX() - absx;
                    int y = e->pageY() - absy;
                    url += "?";
                    url += String::number(x);
                    url += ",";
                    url += String::number(y);
                } else {
                    evt->setDefaultHandled();
                    HTMLElement::defaultEventHandler(evt);
                    return;
                }
            }
        }

        if (!evt->defaultPrevented() && document()->frame())
            document()->frame()->loader()->urlSelected(document()->completeURL(url), getAttribute(targetAttr), evt, false, true);

        evt->setDefaultHandled();
    } else if (m_isLink && isContentEditable()) {
    // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
    // for the LiveWhenNotFocused editable link behavior
        if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() != RightButton && document()->frame() && document()->frame()->selection()) {
            MouseEvent* e = static_cast<MouseEvent*>(evt);

            m_rootEditableElementForSelectionOnMouseDown = document()->frame()->selection()->rootEditableElement();
            m_wasShiftKeyDownOnMouseDown = e && e->shiftKey();
        } else if (evt->type() == eventNames().mouseoverEvent) {
        // These are cleared on mouseover and not mouseout because their values are needed for drag events, but these happen
        // after mouse out events.
            m_rootEditableElementForSelectionOnMouseDown = 0;
            m_wasShiftKeyDownOnMouseDown = false;
        }
    }

    HTMLElement::defaultEventHandler(evt);
}
Beispiel #5
0
static v8::Handle<v8::Value> buttonAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.MouseEvent.button._get");
    MouseEvent* imp = V8MouseEvent::toNative(info.Holder());
    return v8::Integer::New(imp->button());
}
void PrimitivesExample::mousePressEvent(MouseEvent& event) {
    if(event.button() != MouseEvent::Button::Left) return;

    _previousMousePosition = event.position();
    event.setAccepted();
}
void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
{
    // If the element is visible, on mouseup, clear the value, and set selection
    HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
    if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
        if (renderer() && renderer()->visibleToHitTesting()) {
            if (Frame* frame = document()->frame()) {
                frame->eventHandler()->setCapturingMouseEventsNode(this);
                m_capturing = true;
            }
        }
        input->focus();
        input->select();
        event->setDefaultHandled();
    }
    if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
        if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
            if (Frame* frame = document()->frame()) {
                frame->eventHandler()->setCapturingMouseEventsNode(0);
                m_capturing = false;
            }
#if !PLATFORM(OLYMPIA)
            // FIXME: It's always false on OLYMPIA platform. This problem depends on RIM bug #1067.
            if (hovered()) {
#else
            if (event->target() == this) {
#endif
                RefPtr<HTMLInputElement> protector(input);
                String oldValue = input->value();
                input->setValue("");
                if (!oldValue.isEmpty()) {
                    toRenderTextControl(input->renderer())->setChangedSinceLastChangeEvent(true);
                    input->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
                }
                input->onSearch();
                event->setDefaultHandled();
            }
        }
    }

    if (!event->defaultHandled())
        HTMLDivElement::defaultEventHandler(event);
}

// ----------------------------

inline SpinButtonElement::SpinButtonElement(HTMLElement* shadowParent)
    : TextControlInnerElement(shadowParent->document(), shadowParent)
    , m_capturing(false)
    , m_upDownState(Indeterminate)
    , m_pressStartingState(Indeterminate)
    , m_repeatingTimer(this, &SpinButtonElement::repeatingTimerFired)
{
}

PassRefPtr<SpinButtonElement> SpinButtonElement::create(HTMLElement* shadowParent)
{
    return adoptRef(new SpinButtonElement(shadowParent));
}

void SpinButtonElement::defaultEventHandler(Event* event)
{
    if (!event->isMouseEvent()) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;
    }

    RenderBox* box = renderBox();
    if (!box) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;        
    }
    
    HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode());
    if (input->disabled() || input->isReadOnlyFormControl()) {
        if (!event->defaultHandled())
            HTMLDivElement::defaultEventHandler(event);
        return;
    }

    MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
    IntPoint local = roundedIntPoint(box->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
    if (mouseEvent->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
        if (box->borderBoxRect().contains(local)) {
            RefPtr<Node> protector(input);
            input->focus();
            input->select();
            input->stepUpFromRenderer(m_upDownState == Up ? 1 : -1);
            event->setDefaultHandled();
            startRepeatingTimer();
        }
    } else if (mouseEvent->type() == eventNames().mouseupEvent && mouseEvent->button() == LeftButton)
        stopRepeatingTimer();
    else if (event->type() == eventNames().mousemoveEvent) {
        if (box->borderBoxRect().contains(local)) {
            if (!m_capturing) {
                if (Frame* frame = document()->frame()) {
                    frame->eventHandler()->setCapturingMouseEventsNode(this);
                    m_capturing = true;
                }
            }
            UpDownState oldUpDownState = m_upDownState;
            m_upDownState = local.y() < box->height() / 2 ? Up : Down;
            if (m_upDownState != oldUpDownState)
                renderer()->repaint();
        } else {
            if (m_capturing) {
                stopRepeatingTimer();
                if (Frame* frame = document()->frame()) {
                    frame->eventHandler()->setCapturingMouseEventsNode(0);
                    m_capturing = false;
                }
            }
        }
    }

    if (!event->defaultHandled())
        HTMLDivElement::defaultEventHandler(event);
}

void SpinButtonElement::startRepeatingTimer()
{
    m_pressStartingState = m_upDownState;
    ScrollbarTheme* theme = ScrollbarTheme::nativeTheme();
    m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay());
}
Beispiel #8
0
void Widget::processEvent(Event* event, PassKey<Widget, WindowSystemPrivate>)
{
	switch(event->type()) {
	case Event::kFocusIn: {
		if(isAcceptsFocus_) {
			Widget* widget = first_;
			Widget* next = widget;

			while(next) {
				widget = next;

				if(widget->isAcceptsFocus_ && widget->first_ && widget->isVisible()
				   && widget->isEnabled()) {
					next = widget->first_;
				}
				else {
					next = next->next_;
				}
			}

			if(focus_)
				focus_->hasFocus_ = false;

			focus_ = widget;

			if(focus_) {
				focus_->hasFocus_ = true;
				focus_->dispatchEvent(event);
			}
		}

		return; }

	case Event::kFocusOut:
		if(focus_) {
			focus_->hasFocus_ = false;
			focus_->dispatchEvent(event);
		}

		return;

	case Event::kMouseEnter: {
		if(!hasGrab_) {
			MouseEvent* e = static_cast<MouseEvent*>(event);
			dispatchEvent(e);

			updateHoverPoint(e->pos());
		}

		return; }

	case Event::kMouseLeave: {
		if(!hasGrab_)
			sendMouseLeave();

		return; }

	case Event::kMouseMove: {
		MouseEvent* e = static_cast<MouseEvent*>(event);
		Widget* widget;
		Point<int> pos;

		if(hasGrab_) {
			std::tie(widget, pos) = hoveredWidget();

			e->setPos(e->windowPos() - pos, {});
			widget->processMouseEvent(e);
		}
		else {
			std::tie(widget, pos) = updateHoverPoint(e->pos());

			e->setPos(pos, {});
			widget->dispatchEvent(e);
		}

		return; }

	case Event::kMousePress: {
		MouseEvent* e = static_cast<MouseEvent*>(event);
		hasGrab_ = true;

		Widget* widget;
		Point<int> pos;
		std::tie(widget, pos) = hoveredWidget();

		widget->updateFocus(this);

		e->setPos(e->windowPos() - pos, {});
		widget->processMouseEvent(e);
		return; }

	case Event::kMouseRelease: {
		MouseEvent* e = static_cast<MouseEvent*>(event);

		Widget* widget;
		Point<int> pos;
		std::tie(widget, pos) = hoveredWidget();

		Point<int> eventPos = e->pos();
		e->setPos(e->windowPos() - pos, {});
		widget->processMouseEvent(e);

		if(e->buttons() == MouseButton::kNone) {
			hasGrab_ = false;
			updateHoverPoint(eventPos);
		}

		Duration duration = widget->timeCounter_.restart();
		if(duration <= 300_ms && e->button() != MouseButton::kNone
		   && e->button() == widget->lastButton_) {
			MouseEvent ev(Event::kMouseDoubleClick);
			ev.setTimestamp(e->timestamp(), {});
			ev.setModifiers(e->modifiers(), {});
			ev.setPos(e->pos(), {});
			ev.setWindowPos(e->windowPos(), {});
			ev.setGlobalPos(e->globalPos(), {});
			ev.setButton(e->button(), {});
			ev.setButtons(e->buttons(), {});
			widget->processEvent(&ev, {});

			widget->lastButton_ = MouseButton::kNone;
		}
		else {
			widget->lastButton_ = e->button();
		}

		return; }

	case Event::kMouseWheel: {
		MouseWheelEvent* e = static_cast<MouseWheelEvent*>(event);

		Widget* widget;
		Point<int> pos;
		std::tie(widget, pos) = hoveredWidget();

		e->setPos(e->windowPos() - pos, {});
		widget->processMouseEvent(e);
		return; }

	case Event::kKeyPress: {
		Widget* widget = focus_;
		while(focus_) {
			if(focus_->dispatchEvent(event)) {
				if(event->isAccepted())
					return;
			}

			widget = widget->parent_;
		}

		return; }

	case Event::kKeyRelease: {
		Widget* widget = focus_;
		while(focus_) {
			if(focus_->dispatchEvent(event)) {
				if(event->isAccepted())
					return;
			}

			widget = widget->parent_;
		}

		return; }

	case Event::kShow: {
		show();
		break; }

	case Event::kHide: {
		hide();
		break; }

	case Event::kEnable: {
		enable();
		break; }

	case Event::kDisable: {
		disable();
		break; }

	case Event::kClose : {
		if(dispatchEvent(event) && event->isAccepted()) {
			hide();
		}

		return; }

	case Event::kPaint: {
		repaint(static_cast<PaintEvent*>(event));

		// repaint() calls the dispatchEvent() by itself so we don't need to call it one
		// more time
		return; }

	case Event::kMove: {
		MoveEvent* e = static_cast<MoveEvent*>(event);
		pos_ = e->pos();
		break; }

	case Event::kResize: {
		ResizeEvent* e = static_cast<ResizeEvent*>(event);
		size_ = e->size();
		break; }

	default:
		break;
	}

	dispatchEvent(event);

	if(event->type() == Event::kResize && layout_) {
		layout_->setGeometry(rect());
	}
}
	void KrienGraphiXToolbox::mouseReleased( const MouseEvent &evt )
	{
		if ( evt.button() == MouseEvent::Button::LeftButton )
			m_leftMouseBtnDown = false;
	}