mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Implement pinch-to-zoom support
Adds pinch event handling that adjusts the VisualViewport scale and offset. VisualViewport's (offset, scale) is then used to construct a transformation matrix which is applied before display list execution.
This commit is contained in:
parent
b477c6bfc4
commit
9862d8b4a6
Notes:
github-actions[bot]
2025-10-10 13:39:26 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 9862d8b4a6
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6430
Reviewed-by: https://github.com/gmta
Reviewed-by: https://github.com/konradekk
14 changed files with 149 additions and 40 deletions
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <LibUnicode/CharacterTypes.h>
|
||||
#include <LibUnicode/Segmenter.h>
|
||||
#include <LibWeb/CSS/VisualViewport.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/Editing/Internal/Algorithms.h>
|
||||
#include <LibWeb/HTML/CloseWatcherManager.h>
|
||||
|
|
@ -383,17 +384,20 @@ GC::Ptr<Painting::PaintableBox const> EventHandler::paint_root() const
|
|||
return m_navigable->active_document()->paintable_box();
|
||||
}
|
||||
|
||||
EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, int wheel_delta_x, int wheel_delta_y)
|
||||
EventResult EventHandler::handle_mousewheel(CSSPixelPoint visual_viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, int wheel_delta_x, int wheel_delta_y)
|
||||
{
|
||||
if (should_ignore_device_input_event())
|
||||
return EventResult::Dropped;
|
||||
|
||||
if (!m_navigable->active_document())
|
||||
auto document = m_navigable->active_document();
|
||||
if (!document)
|
||||
return EventResult::Dropped;
|
||||
if (!m_navigable->active_document()->is_fully_active())
|
||||
if (!document->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseWheel);
|
||||
auto viewport_position = document->visual_viewport()->map_to_layout_viewport(visual_viewport_position);
|
||||
|
||||
document->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseWheel);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
|
@ -448,16 +452,19 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
|
|||
return handled_event;
|
||||
}
|
||||
|
||||
EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
EventResult EventHandler::handle_mouseup(CSSPixelPoint visual_viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
{
|
||||
if (should_ignore_device_input_event())
|
||||
return EventResult::Dropped;
|
||||
|
||||
if (!m_navigable->active_document())
|
||||
auto document = m_navigable->active_document();
|
||||
if (!document)
|
||||
return EventResult::Dropped;
|
||||
if (!m_navigable->active_document()->is_fully_active())
|
||||
if (!document->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto viewport_position = document->visual_viewport()->map_to_layout_viewport(visual_viewport_position);
|
||||
|
||||
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseUp);
|
||||
|
||||
if (!paint_root())
|
||||
|
|
@ -594,22 +601,24 @@ after_node_use:
|
|||
return handled_event;
|
||||
}
|
||||
|
||||
EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
EventResult EventHandler::handle_mousedown(CSSPixelPoint visual_viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
{
|
||||
if (should_ignore_device_input_event())
|
||||
return EventResult::Dropped;
|
||||
|
||||
if (!m_navigable->active_document())
|
||||
auto document = m_navigable->active_document();
|
||||
if (!document)
|
||||
return EventResult::Dropped;
|
||||
if (!m_navigable->active_document()->is_fully_active())
|
||||
if (!document->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto viewport_position = document->visual_viewport()->map_to_layout_viewport(visual_viewport_position);
|
||||
|
||||
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseDown);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
||||
GC::Ref<DOM::Document> document = *m_navigable->active_document();
|
||||
GC::Ptr<DOM::Node> node;
|
||||
|
||||
ScopeGuard update_hovered_node_guard = [&node, &document] {
|
||||
|
|
@ -723,7 +732,7 @@ EventResult EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSP
|
|||
return EventResult::Handled;
|
||||
}
|
||||
|
||||
EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 buttons, u32 modifiers)
|
||||
EventResult EventHandler::handle_mousemove(CSSPixelPoint visual_viewport_position, CSSPixelPoint screen_position, u32 buttons, u32 modifiers)
|
||||
{
|
||||
if (should_ignore_device_input_event())
|
||||
return EventResult::Dropped;
|
||||
|
|
@ -733,13 +742,14 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
if (!m_navigable->active_document()->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto& document = *m_navigable->active_document();
|
||||
auto viewport_position = document.visual_viewport()->map_to_layout_viewport(visual_viewport_position);
|
||||
|
||||
m_navigable->active_document()->update_layout(DOM::UpdateLayoutReason::EventHandlerHandleMouseMove);
|
||||
|
||||
if (!paint_root())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto& document = *m_navigable->active_document();
|
||||
|
||||
bool hovered_node_changed = false;
|
||||
bool is_hovering_link = false;
|
||||
Gfx::Cursor hovered_node_cursor = Gfx::StandardCursor::None;
|
||||
|
|
@ -912,7 +922,7 @@ EventResult EventHandler::handle_mouseleave()
|
|||
return EventResult::Handled;
|
||||
}
|
||||
|
||||
EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
EventResult EventHandler::handle_doubleclick(CSSPixelPoint visual_viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
{
|
||||
if (should_ignore_device_input_event())
|
||||
return EventResult::Dropped;
|
||||
|
|
@ -923,6 +933,7 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
|
|||
return EventResult::Dropped;
|
||||
|
||||
auto& document = *m_navigable->active_document();
|
||||
auto viewport_position = document.visual_viewport()->map_to_layout_viewport(visual_viewport_position);
|
||||
|
||||
document.update_layout(DOM::UpdateLayoutReason::EventHandlerHandleDoubleClick);
|
||||
|
||||
|
|
@ -1004,7 +1015,7 @@ EventResult EventHandler::handle_doubleclick(CSSPixelPoint viewport_position, CS
|
|||
return EventResult::Handled;
|
||||
}
|
||||
|
||||
EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPixelPoint viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, Vector<HTML::SelectedFile> files)
|
||||
EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPixelPoint visual_viewport_position, CSSPixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, Vector<HTML::SelectedFile> files)
|
||||
{
|
||||
if (!m_navigable->active_document())
|
||||
return EventResult::Dropped;
|
||||
|
|
@ -1012,6 +1023,8 @@ EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPi
|
|||
return EventResult::Dropped;
|
||||
|
||||
auto& document = *m_navigable->active_document();
|
||||
auto viewport_position = document.visual_viewport()->map_to_layout_viewport(visual_viewport_position);
|
||||
|
||||
document.update_layout(DOM::UpdateLayoutReason::EventHandlerHandleDragAndDrop);
|
||||
|
||||
if (!paint_root())
|
||||
|
|
@ -1050,6 +1063,19 @@ EventResult EventHandler::handle_drag_and_drop_event(DragEvent::Type type, CSSPi
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
EventResult EventHandler::handle_pinch_event(CSSPixelPoint point, double scale_delta)
|
||||
{
|
||||
auto document = m_navigable->active_document();
|
||||
if (!document)
|
||||
return EventResult::Dropped;
|
||||
if (!document->is_fully_active())
|
||||
return EventResult::Dropped;
|
||||
|
||||
auto visual_viewport = document->visual_viewport();
|
||||
visual_viewport->zoom(point, scale_delta);
|
||||
return EventResult::Handled;
|
||||
}
|
||||
|
||||
EventResult EventHandler::focus_next_element()
|
||||
{
|
||||
if (!m_navigable->active_document())
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ public:
|
|||
|
||||
EventResult handle_drag_and_drop_event(DragEvent::Type, CSSPixelPoint, CSSPixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
||||
|
||||
EventResult handle_pinch_event(CSSPixelPoint, double scale_delta);
|
||||
|
||||
EventResult handle_keydown(UIEvents::KeyCode, unsigned modifiers, u32 code_point, bool repeat);
|
||||
EventResult handle_keyup(UIEvents::KeyCode, unsigned modifiers, u32 code_point, bool repeat);
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,11 @@ EventResult Page::handle_drag_and_drop_event(DragEvent::Type type, DevicePixelPo
|
|||
return top_level_traversable()->event_handler().handle_drag_and_drop_event(type, device_to_css_point(position), device_to_css_point(screen_position), button, buttons, modifiers, move(files));
|
||||
}
|
||||
|
||||
EventResult Page::handle_pinch_event(DevicePixelPoint position, double scale)
|
||||
{
|
||||
return top_level_traversable()->event_handler().handle_pinch_event(device_to_css_point(position), scale);
|
||||
}
|
||||
|
||||
EventResult Page::handle_keydown(UIEvents::KeyCode key, unsigned modifiers, u32 code_point, bool repeat)
|
||||
{
|
||||
return focused_navigable().event_handler().handle_keydown(key, modifiers, code_point, repeat);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ public:
|
|||
EventResult handle_doubleclick(DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers);
|
||||
|
||||
EventResult handle_drag_and_drop_event(DragEvent::Type, DevicePixelPoint, DevicePixelPoint screen_position, unsigned button, unsigned buttons, unsigned modifiers, Vector<HTML::SelectedFile> files);
|
||||
EventResult handle_pinch_event(DevicePixelPoint point, double scale);
|
||||
|
||||
EventResult handle_keydown(UIEvents::KeyCode, unsigned modifiers, u32 code_point, bool repeat);
|
||||
EventResult handle_keyup(UIEvents::KeyCode, unsigned modifiers, u32 code_point, bool repeat);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue