mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-19 15:43:20 +00:00
LibWeb+UI+WebContent: Pipe pinch events from AppKit UI to WebContent
This commit is contained in:
parent
e6831003c6
commit
c630de17ab
Notes:
github-actions[bot]
2025-10-10 13:39:44 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: c630de17ab
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6430
Reviewed-by: https://github.com/gmta
Reviewed-by: https://github.com/konradekk
10 changed files with 86 additions and 1 deletions
|
@ -290,6 +290,9 @@ void EventLoop::process_input_events() const
|
|||
},
|
||||
[&](Web::DragEvent& drag_event) {
|
||||
return page.handle_drag_and_drop_event(drag_event.type, drag_event.position, drag_event.screen_position, drag_event.button, drag_event.buttons, drag_event.modifiers, move(drag_event.files));
|
||||
},
|
||||
[&](Web::PinchEvent&) {
|
||||
return EventResult::Dropped;
|
||||
});
|
||||
|
||||
for (size_t i = 0; i < event.coalesced_event_count; ++i)
|
||||
|
|
|
@ -105,3 +105,19 @@ ErrorOr<Web::DragEvent> IPC::decode(Decoder& decoder)
|
|||
|
||||
return Web::DragEvent { type, position, screen_position, button, buttons, modifiers, move(files), nullptr };
|
||||
}
|
||||
|
||||
template<>
|
||||
WEB_API ErrorOr<void> IPC::encode(Encoder& encoder, Web::PinchEvent const& event)
|
||||
{
|
||||
TRY(encoder.encode(event.position));
|
||||
TRY(encoder.encode(event.scale_delta));
|
||||
return {};
|
||||
}
|
||||
|
||||
template<>
|
||||
WEB_API ErrorOr<Web::PinchEvent> IPC::decode(Decoder& decoder)
|
||||
{
|
||||
auto position = TRY(decoder.decode<Web::DevicePixelPoint>());
|
||||
auto scale_delta = TRY(decoder.decode<double>());
|
||||
return Web::PinchEvent { position, scale_delta };
|
||||
}
|
||||
|
|
|
@ -85,7 +85,12 @@ struct WEB_API DragEvent {
|
|||
OwnPtr<BrowserInputData> browser_data;
|
||||
};
|
||||
|
||||
using InputEvent = Variant<KeyEvent, MouseEvent, DragEvent>;
|
||||
struct WEB_API PinchEvent {
|
||||
Web::DevicePixelPoint position;
|
||||
double scale_delta;
|
||||
};
|
||||
|
||||
using InputEvent = Variant<KeyEvent, MouseEvent, DragEvent, PinchEvent>;
|
||||
|
||||
struct QueuedInputEvent {
|
||||
u64 page_id { 0 };
|
||||
|
@ -115,4 +120,10 @@ WEB_API ErrorOr<void> encode(Encoder&, Web::DragEvent const&);
|
|||
template<>
|
||||
WEB_API ErrorOr<Web::DragEvent> decode(Decoder&);
|
||||
|
||||
template<>
|
||||
WEB_API ErrorOr<void> encode(Encoder&, Web::PinchEvent const&);
|
||||
|
||||
template<>
|
||||
WEB_API ErrorOr<Web::PinchEvent> decode(Decoder&);
|
||||
|
||||
}
|
||||
|
|
|
@ -214,6 +214,9 @@ void ViewImplementation::enqueue_input_event(Web::InputEvent event)
|
|||
cloned_event.files = move(event.files);
|
||||
|
||||
client().async_drag_event(m_client_state.page_index, cloned_event);
|
||||
},
|
||||
[this](Web::PinchEvent const& event) {
|
||||
client().async_pinch_event(m_client_state.page_index, event);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,11 @@ void ConnectionFromClient::drag_event(u64 page_id, Web::DragEvent event)
|
|||
enqueue_input_event({ page_id, move(event), 0 });
|
||||
}
|
||||
|
||||
void ConnectionFromClient::pinch_event(u64 page_id, Web::PinchEvent event)
|
||||
{
|
||||
enqueue_input_event({ page_id, move(event), 0 });
|
||||
}
|
||||
|
||||
void ConnectionFromClient::enqueue_input_event(Web::QueuedInputEvent event)
|
||||
{
|
||||
m_input_event_queue.enqueue(move(event));
|
||||
|
|
|
@ -75,6 +75,7 @@ private:
|
|||
virtual void key_event(u64 page_id, Web::KeyEvent) override;
|
||||
virtual void mouse_event(u64 page_id, Web::MouseEvent) override;
|
||||
virtual void drag_event(u64 page_id, Web::DragEvent) override;
|
||||
virtual void pinch_event(u64 page_id, Web::PinchEvent) override;
|
||||
virtual void ready_to_paint(u64 page_id) override;
|
||||
virtual void debug_request(u64 page_id, ByteString, ByteString) override;
|
||||
virtual void get_source(u64 page_id) override;
|
||||
|
|
|
@ -44,6 +44,7 @@ endpoint WebContentServer
|
|||
key_event(u64 page_id, Web::KeyEvent event) =|
|
||||
mouse_event(u64 page_id, Web::MouseEvent event) =|
|
||||
drag_event(u64 page_id, Web::DragEvent event) =|
|
||||
pinch_event(u64 page_id, Web::PinchEvent event) =|
|
||||
|
||||
debug_request(u64 page_id, ByteString request, ByteString argument) =|
|
||||
get_source(u64 page_id) =|
|
||||
|
|
|
@ -55,6 +55,7 @@ struct HideCursor {
|
|||
@property (nonatomic, strong) NSMenu* select_dropdown;
|
||||
@property (nonatomic, strong) NSTextField* status_label;
|
||||
@property (nonatomic, strong) NSAlert* dialog;
|
||||
@property (nonatomic, strong) NSMagnificationGestureRecognizer* pinch_recognizer;
|
||||
|
||||
// NSEvent does not provide a way to mark whether it has been handled, nor can we attach user data to the event. So
|
||||
// when we dispatch the event for a second time after WebContent has had a chance to handle it, we must track that
|
||||
|
@ -122,6 +123,10 @@ struct HideCursor {
|
|||
|
||||
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSPasteboardTypeFileURL, nil]];
|
||||
|
||||
self.pinch_recognizer = [[NSMagnificationGestureRecognizer alloc] initWithTarget:self
|
||||
action:@selector(onPinch:)];
|
||||
[self addGestureRecognizer:self.pinch_recognizer];
|
||||
|
||||
m_modifier_flags = 0;
|
||||
}
|
||||
|
||||
|
@ -1155,4 +1160,31 @@ struct HideCursor {
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (void)onPinch:(NSMagnificationGestureRecognizer*)recognizer
|
||||
{
|
||||
double scale_delta = 0;
|
||||
switch (recognizer.state) {
|
||||
case NSGestureRecognizerStateBegan:
|
||||
m_web_view_bridge->pinch_state() = { .previous_scale = recognizer.magnification };
|
||||
break;
|
||||
case NSGestureRecognizerStateChanged:
|
||||
scale_delta = recognizer.magnification - m_web_view_bridge->pinch_state()->previous_scale;
|
||||
m_web_view_bridge->pinch_state()->previous_scale = recognizer.magnification;
|
||||
break;
|
||||
case NSGestureRecognizerStateEnded:
|
||||
case NSGestureRecognizerStateCancelled:
|
||||
scale_delta = recognizer.magnification - m_web_view_bridge->pinch_state()->previous_scale;
|
||||
m_web_view_bridge->pinch_state() = {};
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
NSPoint point = [recognizer locationInView:self];
|
||||
Web::PinchEvent pinch_event;
|
||||
pinch_event.position = Ladybird::ns_point_to_gfx_point(point).to_type<Web::DevicePixels>() * m_web_view_bridge->device_pixel_ratio();
|
||||
pinch_event.scale_delta = scale_delta;
|
||||
m_web_view_bridge->enqueue_input_event(move(pinch_event));
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -79,6 +79,11 @@ void WebViewBridge::enqueue_input_event(Web::KeyEvent event)
|
|||
ViewImplementation::enqueue_input_event(move(event));
|
||||
}
|
||||
|
||||
void WebViewBridge::enqueue_input_event(Web::PinchEvent event)
|
||||
{
|
||||
ViewImplementation::enqueue_input_event(move(event));
|
||||
}
|
||||
|
||||
Optional<WebViewBridge::Paintable> WebViewBridge::paintable()
|
||||
{
|
||||
Gfx::Bitmap const* bitmap = nullptr;
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
void enqueue_input_event(Web::MouseEvent);
|
||||
void enqueue_input_event(Web::DragEvent);
|
||||
void enqueue_input_event(Web::KeyEvent);
|
||||
void enqueue_input_event(Web::PinchEvent);
|
||||
|
||||
struct Paintable {
|
||||
Gfx::Bitmap const& bitmap;
|
||||
|
@ -45,6 +46,8 @@ public:
|
|||
|
||||
Function<void()> on_zoom_level_changed;
|
||||
|
||||
auto& pinch_state() { return m_pinch_state; }
|
||||
|
||||
private:
|
||||
WebViewBridge(Vector<Web::DevicePixelRect> screen_rects, float device_pixel_ratio, u64 maximum_frames_per_second);
|
||||
|
||||
|
@ -55,6 +58,11 @@ private:
|
|||
|
||||
Vector<Web::DevicePixelRect> m_screen_rects;
|
||||
Gfx::IntSize m_viewport_size;
|
||||
|
||||
struct PinchState {
|
||||
double previous_scale { 1.0 };
|
||||
};
|
||||
Optional<PinchState> m_pinch_state;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue