Files
ladybird/Libraries/LibWeb/Painting/ResizeHandle.cpp
Zaggy1024 ee45cdfb09 LibWeb: Refactor pointer event handling/dispatch to work closer to spec
Pieces of the down, move, and up handlers are moved to separate
functions. Some part actually have specs, so the ones I've found thus
far have been brought in to make things more spec-aligned. A lot of
FIXMEs are added for things that the spec mentions or implies.

Pointer events are intended to be handled per pointer device, but this
still treats them the same as legacy mouse events. However, the PREVENT
MOUSE EVENT flag is implemented to block legacy mouse events for the
duration of a drag.

Behavior changes should be minimal.

One notable change is that auxclick is now fired for all non-primary
buttons, which matches the spec and other browsers.
2026-03-17 04:01:29 -05:00

81 lines
2.3 KiB
C++

/*
* Copyright (c) 2026, the Ladybird developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/DOM/Element.h>
#include <LibWeb/Page/ElementResizeAction.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/ResizeHandle.h>
#include <LibWeb/UIEvents/EventNames.h>
#include <LibWeb/UIEvents/MouseButton.h>
#include <LibWeb/UIEvents/PointerEvent.h>
namespace Web::Painting {
GC_DEFINE_ALLOCATOR(ResizeHandle);
GC::Ref<ResizeHandle> ResizeHandle::create(GC::Heap& heap, PaintableBox& paintable_box)
{
return heap.allocate<ResizeHandle>(paintable_box);
}
ResizeHandle::ResizeHandle(PaintableBox& paintable_box)
: m_paintable_box(paintable_box)
, m_element(as<DOM::Element>(*paintable_box.dom_node()))
{
}
void ResizeHandle::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_paintable_box);
visitor.visit(m_element);
if (m_resize_action)
m_resize_action->visit_edges(visitor);
}
bool ResizeHandle::contains(CSSPixelPoint position, ChromeMetrics const& metrics) const
{
return m_paintable_box->resizer_contains(position, metrics);
}
Optional<CSS::CursorPredefined> ResizeHandle::cursor() const
{
auto axes = m_paintable_box->physical_resize_axes();
if (axes.vertical) {
if (axes.horizontal) {
if (m_paintable_box->is_chrome_mirrored())
return CSS::CursorPredefined::SwResize;
return CSS::CursorPredefined::SeResize;
}
return CSS::CursorPredefined::NsResize;
}
return CSS::CursorPredefined::EwResize;
}
MouseAction ResizeHandle::handle_pointer_event(FlyString const& type, unsigned button, CSSPixelPoint visual_viewport_position)
{
if (type == UIEvents::EventNames::pointermove) {
if (!m_resize_action)
return MouseAction::None;
} else if (button != UIEvents::MouseButton::Primary) {
return MouseAction::None;
}
if (!m_resize_action)
m_resize_action = make<ElementResizeAction>(m_element, visual_viewport_position);
else
m_resize_action->handle_pointer_move(visual_viewport_position);
if (type == UIEvents::EventNames::pointerup) {
m_resize_action.clear();
return MouseAction::None;
}
return MouseAction::CaptureInput;
}
}