Skip to content

Commit b76875b

Browse files
committed
use netsurf's mousevent
1 parent 0253de8 commit b76875b

File tree

4 files changed

+113
-21
lines changed

4 files changed

+113
-21
lines changed

src/browser/browser.zig

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -431,14 +431,34 @@ pub const Page = struct {
431431
navigate: std.Uri,
432432
};
433433

434-
pub fn click(self: *Page, allocator: Allocator, x: u32, y: u32) !?ClickResult {
435-
const element = self.renderer.getElementAtPosition(x, y) orelse return null;
434+
pub const MouseEvent = struct {
435+
x: i32,
436+
y: i32,
437+
type: Type,
438+
439+
const Type = enum {
440+
pressed,
441+
released,
442+
};
443+
};
436444

437-
const event = try parser.eventCreate();
438-
defer parser.eventDestroy(event);
445+
pub fn mouseEvent(self: *Page, allocator: Allocator, me: MouseEvent) !?ClickResult {
446+
if (me.type != .pressed) {
447+
return null;
448+
}
439449

440-
try parser.eventInit(event, "click", .{ .bubbles = true, .cancelable = true });
441-
if ((try parser.eventDefaultPrevented(event)) == true) {
450+
const element = self.renderer.getElementAtPosition(me.x, me.y) orelse return null;
451+
452+
const event = try parser.mouseEventCreate();
453+
defer parser.mouseEventDestroy(event);
454+
455+
try parser.mouseEventInit(event, "click", .{
456+
.bubbles = true,
457+
.cancelable = true,
458+
.x = me.x,
459+
.y = me.y,
460+
});
461+
if ((try parser.mouseEventDefaultPrevented(event)) == true) {
442462
return null;
443463
}
444464

@@ -838,13 +858,13 @@ const FlatRenderer = struct {
838858
return 1;
839859
}
840860

841-
pub fn getElementAtPosition(self: *const FlatRenderer, x: u32, y: u32) ?*parser.Element {
842-
if (y > 1) {
861+
pub fn getElementAtPosition(self: *const FlatRenderer, x: i32, y: i32) ?*parser.Element {
862+
if (y != 1 or x < 0) {
843863
return null;
844864
}
845865

846866
const elements = self.elements.items;
847-
return if (x < elements.len) @ptrFromInt(elements[x]) else null;
867+
return if (x < elements.len) @ptrFromInt(elements[@intCast(x)]) else null;
848868
}
849869
};
850870

src/cdp/domains/input.zig

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818

1919
const std = @import("std");
20+
const Page = @import("../../browser/browser.zig").Page;
2021

2122
pub fn processMessage(cmd: anytype) !void {
2223
const action = std.meta.stringToEnum(enum {
@@ -31,20 +32,39 @@ pub fn processMessage(cmd: anytype) !void {
3132
// https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchMouseEvent
3233
fn dispatchMouseEvent(cmd: anytype) !void {
3334
const params = (try cmd.params(struct {
34-
type: []const u8,
35-
x: u32,
36-
y: u32,
35+
x: i32,
36+
y: i32,
37+
type: Type,
38+
39+
const Type = enum {
40+
mousePressed,
41+
mouseReleased,
42+
mouseMoved,
43+
mouseWheel,
44+
};
3745
})) orelse return error.InvalidParams;
3846

3947
try cmd.sendResult(null, .{});
4048

41-
if (std.ascii.eqlIgnoreCase(params.type, "mousePressed") == false) {
42-
return;
49+
// quickly ignore types we know we don't handle
50+
switch (params.type) {
51+
.mouseMoved, .mouseWheel => return,
52+
else => {},
4353
}
4454

4555
const bc = cmd.browser_context orelse return;
4656
const page = bc.session.currentPage() orelse return;
47-
const click_result = (try page.click(cmd.arena, params.x, params.y)) orelse return;
57+
58+
const mouse_event = Page.MouseEvent{
59+
.x = params.x,
60+
.y = params.y,
61+
.type = switch (params.type) {
62+
.mousePressed => .pressed,
63+
.mouseReleased => .released,
64+
else => unreachable,
65+
},
66+
};
67+
const click_result = (try page.mouseEvent(cmd.arena, mouse_event)) orelse return;
4868

4969
switch (click_result) {
5070
.navigate => |uri| try clickNavigate(cmd, uri),

src/netsurf/netsurf.zig

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const c = @cImport({
2424
@cInclude("dom/bindings/hubbub/parser.h");
2525
@cInclude("events/event_target.h");
2626
@cInclude("events/event.h");
27+
@cInclude("events/mouse_event.h");
2728
});
2829

2930
const mimalloc = @import("mimalloc");
@@ -809,14 +810,10 @@ const DispatchOpts = struct {
809810
pub fn elementDispatchEvent(element: *Element, opts: DispatchOpts) !bool {
810811
const event = try eventCreate();
811812
defer eventDestroy(event);
812-
813813
try eventInit(event, opts.type, .{ .bubbles = opts.bubbles, .cancelable = opts.cancelable });
814814

815-
var res: bool = undefined;
816815
const et: *EventTarget = @ptrCast(element);
817-
const err = eventTargetVtable(et).dispatch_event.?(et, event, &res);
818-
try DOMErr(err);
819-
return res;
816+
return eventTargetDispatchEvent(et, event);
820817
}
821818

822819
pub fn eventTargetTBaseFieldName(comptime T: type) ?[]const u8 {
@@ -878,6 +875,61 @@ pub const EventTargetTBase = extern struct {
878875
}
879876
};
880877

878+
// MouseEvent
879+
880+
pub const MouseEvent = c.dom_mouse_event;
881+
882+
pub fn mouseEventCreate() !*MouseEvent {
883+
var evt: ?*MouseEvent = undefined;
884+
const err = c._dom_mouse_event_create(&evt);
885+
try DOMErr(err);
886+
return evt.?;
887+
}
888+
889+
pub fn mouseEventDestroy(evt: *MouseEvent) void {
890+
c._dom_mouse_event_destroy(evt);
891+
}
892+
893+
const MouseEventOpts = struct {
894+
x: i32,
895+
y: i32,
896+
bubbles: bool = false,
897+
cancelable: bool = false,
898+
ctrl: bool = false,
899+
alt: bool = false,
900+
shift: bool = false,
901+
meta: bool = false,
902+
button: u16 = 0,
903+
click_count: u16 = 1,
904+
};
905+
906+
pub fn mouseEventInit(evt: *MouseEvent, typ: []const u8, opts: MouseEventOpts) !void {
907+
const s = try strFromData(typ);
908+
const err = c._dom_mouse_event_init(
909+
evt,
910+
s,
911+
opts.bubbles,
912+
opts.cancelable,
913+
null, // dom_abstract_view* ?
914+
opts.click_count, // details
915+
opts.x, // screen_x
916+
opts.y, // screen_y
917+
opts.x, // client_x
918+
opts.y, // client_y
919+
opts.ctrl,
920+
opts.alt,
921+
opts.shift,
922+
opts.meta,
923+
opts.button,
924+
null, // related target
925+
);
926+
try DOMErr(err);
927+
}
928+
929+
pub fn mouseEventDefaultPrevented(evt: *MouseEvent) !bool {
930+
return eventDefaultPrevented(@ptrCast(evt));
931+
}
932+
881933
// NodeType
882934

883935
pub const NodeType = enum(u4) {

0 commit comments

Comments
 (0)