From adae05cf045e35cbe073673d77cc380b1241f89d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 23 Feb 2023 17:08:09 -0800 Subject: [PATCH] gtk: mouse input --- include/ghostty.h | 3 +- src/apprt/gtk.zig | 80 +++++++++++++++++++++++++++++++++++++++++++++ src/input/mouse.zig | 1 + 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/include/ghostty.h b/include/ghostty.h index 1764ef445..6da1db805 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -51,7 +51,8 @@ typedef enum { } ghostty_input_mouse_state_e; typedef enum { - GHOSTTY_MOUSE_LEFT = 1, + GHOSTTY_MOUSE_UNKNOWN, + GHOSTTY_MOUSE_LEFT, GHOSTTY_MOUSE_RIGHT, GHOSTTY_MOUSE_MIDDLE, } ghostty_input_mouse_button_e; diff --git a/src/apprt/gtk.zig b/src/apprt/gtk.zig index e1fa9e0f2..c18635667 100644 --- a/src/apprt/gtk.zig +++ b/src/apprt/gtk.zig @@ -221,6 +221,18 @@ pub const Surface = struct { im_context, ); + // Clicks + const gesture_click = c.gtk_gesture_click_new(); + errdefer c.g_object_unref(gesture_click); + c.gtk_gesture_single_set_button(@ptrCast( + *c.GtkGestureSingle, + gesture_click, + ), 0); + c.gtk_widget_add_controller(widget, @ptrCast( + *c.GtkEventController, + gesture_click, + )); + // The GL area has to be focusable so that it can receive events c.gtk_widget_set_focusable(widget, 1); c.gtk_widget_set_focus_on_click(widget, 1); @@ -245,6 +257,8 @@ pub const Surface = struct { _ = c.g_signal_connect_data(ec_focus, "enter", c.G_CALLBACK(>kFocusEnter), self, null, c.G_CONNECT_DEFAULT); _ = c.g_signal_connect_data(ec_focus, "leave", c.G_CALLBACK(>kFocusLeave), self, null, c.G_CONNECT_DEFAULT); _ = c.g_signal_connect_data(im_context, "commit", c.G_CALLBACK(>kInputCommit), self, null, c.G_CONNECT_DEFAULT); + _ = c.g_signal_connect_data(gesture_click, "pressed", c.G_CALLBACK(>kMouseDown), self, null, c.G_CONNECT_DEFAULT); + _ = c.g_signal_connect_data(gesture_click, "released", c.G_CALLBACK(>kMouseUp), self, null, c.G_CONNECT_DEFAULT); } fn realize(self: *Surface) !void { @@ -327,6 +341,17 @@ pub const Surface = struct { _ = val; } + pub fn getCursorPos(self: *const Surface) !apprt.CursorPos { + _ = self; + return .{}; + // const unscaled_pos = self.window.getCursorPos(); + // const pos = try self.cursorPosToPixels(unscaled_pos); + // return apprt.CursorPos{ + // .x = @floatCast(f32, pos.xpos), + // .y = @floatCast(f32, pos.ypos), + // }; + } + fn gtkRealize(area: *c.GtkGLArea, ud: ?*anyopaque) callconv(.C) void { log.debug("gl surface realized", .{}); @@ -392,6 +417,44 @@ pub const Surface = struct { alloc.destroy(self); } + fn gtkMouseDown( + gesture: *c.GtkGestureClick, + _: c.gint, + _: c.gdouble, + _: c.gdouble, + ud: ?*anyopaque, + ) callconv(.C) void { + const button = translateMouseButton(c.gtk_gesture_single_get_current_button(@ptrCast( + *c.GtkGestureSingle, + gesture, + ))); + + const self = userdataSelf(ud.?); + self.core_surface.mouseButtonCallback(.press, button, .{}) catch |err| { + log.err("error in key callback err={}", .{err}); + return 0; + }; + } + + fn gtkMouseUp( + gesture: *c.GtkGestureClick, + _: c.gint, + _: c.gdouble, + _: c.gdouble, + ud: ?*anyopaque, + ) callconv(.C) void { + const button = translateMouseButton(c.gtk_gesture_single_get_current_button(@ptrCast( + *c.GtkGestureSingle, + gesture, + ))); + + const self = userdataSelf(ud.?); + self.core_surface.mouseButtonCallback(.release, button, .{}) catch |err| { + log.err("error in key callback err={}", .{err}); + return 0; + }; + } + fn gtkKeyPressed( _: *c.GtkEventControllerKey, keyval: c.guint, @@ -474,6 +537,23 @@ pub const Surface = struct { } }; +fn translateMouseButton(button: c.guint) input.MouseButton { + return switch (button) { + 1 => .left, + 2 => .middle, + 3 => .right, + 4 => .four, + 5 => .five, + 6 => .six, + 7 => .seven, + 8 => .eight, + 9 => .nine, + 10 => .ten, + 11 => .eleven, + else => .unknown, + }; +} + fn translateMods(state: c.GdkModifierType) input.Mods { var mods: input.Mods = .{}; if (state & c.GDK_SHIFT_MASK != 0) mods.shift = true; diff --git a/src/input/mouse.zig b/src/input/mouse.zig index e1059e4c0..224abef35 100644 --- a/src/input/mouse.zig +++ b/src/input/mouse.zig @@ -32,6 +32,7 @@ pub const MouseButton = enum(c_int) { break :max cur; }; + unknown = 0, left = 1, right = 2, middle = 3,