apprt/gtk: Move Xkb state to App, remove un-needed fields, style changes

This commit is contained in:
Chris Marchesi
2023-12-31 12:10:25 -08:00
parent a3ce446fee
commit d235554606
3 changed files with 29 additions and 26 deletions

View File

@ -56,6 +56,9 @@ clipboard_confirmation_window: ?*ClipboardConfirmationWindow = null,
/// This is set to false when the main loop should exit. /// This is set to false when the main loop should exit.
running: bool = true, running: bool = true,
/// Xkb state (X11 only). Will be null on Wayland.
x11_xkb: ?x11.X11Xkb = null,
pub fn init(core_app: *CoreApp, opts: Options) !App { pub fn init(core_app: *CoreApp, opts: Options) !App {
_ = opts; _ = opts;
@ -170,8 +173,9 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
return error.GtkApplicationRegisterFailed; return error.GtkApplicationRegisterFailed;
} }
var x11_xkb: ?x11.X11Xkb = null;
const display = c.gdk_display_get_default(); const display = c.gdk_display_get_default();
if (x11.x11_is_display(display)) { if (x11.is_display(display)) {
// Set the X11 window class property (WM_CLASS) if are are on an X11 // Set the X11 window class property (WM_CLASS) if are are on an X11
// display. // display.
// //
@ -197,6 +201,9 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
"ghostty"; "ghostty";
c.g_set_prgname(prgname); c.g_set_prgname(prgname);
c.gdk_x11_display_set_program_class(display, app_id); c.gdk_x11_display_set_program_class(display, app_id);
// Set up Xkb
x11_xkb = try x11.X11Xkb.init(c.gdk_display_get_default());
} }
// This just calls the "activate" signal but its part of the normal // This just calls the "activate" signal but its part of the normal
@ -210,6 +217,7 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
.config = config, .config = config,
.ctx = ctx, .ctx = ctx,
.cursor_none = cursor_none, .cursor_none = cursor_none,
.x11_xkb = x11_xkb,
// If we are NOT the primary instance, then we never want to run. // If we are NOT the primary instance, then we never want to run.
// This means that another instance of the GTK app is running and // This means that another instance of the GTK app is running and
// our "activate" call above will open a window. // our "activate" call above will open a window.
@ -574,3 +582,9 @@ test "isValidAppId" {
try testing.expect(!isValidAppId("")); try testing.expect(!isValidAppId(""));
try testing.expect(!isValidAppId("foo" ** 86)); try testing.expect(!isValidAppId("foo" ** 86));
} }
/// Loads keyboard state from Xkb if there is an event pending and Xkb is
/// loaded (X11 only). Returns null otherwise.
pub fn modifier_state_from_xkb(self: *App, display_: ?*c.GdkDisplay) ?input.Mods {
return (self.x11_xkb orelse return null).modifier_state_from_notify(display_);
}

View File

@ -19,7 +19,6 @@ const Window = @import("Window.zig");
const ClipboardConfirmationWindow = @import("ClipboardConfirmationWindow.zig"); const ClipboardConfirmationWindow = @import("ClipboardConfirmationWindow.zig");
const inspector = @import("inspector.zig"); const inspector = @import("inspector.zig");
const gtk_key = @import("key.zig"); const gtk_key = @import("key.zig");
const x11 = @import("x11.zig");
const c = @import("c.zig"); const c = @import("c.zig");
const log = std.log.scoped(.gtk_surface); const log = std.log.scoped(.gtk_surface);
@ -254,9 +253,6 @@ im_composing: bool = false,
im_buf: [128]u8 = undefined, im_buf: [128]u8 = undefined,
im_len: u7 = 0, im_len: u7 = 0,
/// Xkb state (X11 only). Will be null on Wayland.
x11_xkb: ?x11.X11Xkb = null,
pub fn create(alloc: Allocator, app: *App, opts: Options) !*Surface { pub fn create(alloc: Allocator, app: *App, opts: Options) !*Surface {
var surface = try alloc.create(Surface); var surface = try alloc.create(Surface);
errdefer alloc.destroy(surface); errdefer alloc.destroy(surface);
@ -359,9 +355,6 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
}; };
errdefer self.* = undefined; errdefer self.* = undefined;
// Set up Xkb if we are running under X11.
self.x11_xkb = try x11.X11Xkb.init(c.gdk_display_get_default());
// Set our default mouse shape // Set our default mouse shape
try self.setMouseShape(.text); try self.setMouseShape(.text);
@ -1343,18 +1336,16 @@ fn keyEvent(
const device = c.gdk_event_get_device(event); const device = c.gdk_event_get_device(event);
var mods = init_mods: { var mods = init_mods: {
if (self.x11_xkb) |x11_xkb| { // Add any modifier state events from Xkb if we have them (X11 only).
// Add any modifier state events from Xkb if we have them (X11 only). if (self.app.modifier_state_from_xkb(display)) |xkb_mods| {
if (x11_xkb.modifier_state_from_notify(display)) |xkb_mods| { break :init_mods xkb_mods;
break :init_mods xkb_mods;
}
// Null back from the Xkb call means there was no modifier
// event to read. This likely means that the key event did not
// result in a modifier change and we can safely rely on the
// GDK state.
} }
// Null back from the Xkb call means there was no modifier
// event to read. This likely means that the key event did not
// result in a modifier change and we can safely rely on the
// GDK state.
break :init_mods translateMods(c.gdk_device_get_modifier_state(device)); break :init_mods translateMods(c.gdk_device_get_modifier_state(device));
}; };

View File

@ -6,7 +6,7 @@ const input = @import("../../input.zig");
const log = std.log.scoped(.gtk_x11); const log = std.log.scoped(.gtk_x11);
/// Returns true if the passed in display is an X11 display. /// Returns true if the passed in display is an X11 display.
pub fn x11_is_display(display: ?*c.GdkDisplay) bool { pub fn is_display(display: ?*c.GdkDisplay) bool {
return c.g_type_check_instance_is_a( return c.g_type_check_instance_is_a(
@ptrCast(@alignCast(display orelse return false)), @ptrCast(@alignCast(display orelse return false)),
c.gdk_x11_display_get_type(), c.gdk_x11_display_get_type(),
@ -14,9 +14,7 @@ pub fn x11_is_display(display: ?*c.GdkDisplay) bool {
} }
pub const X11Xkb = struct { pub const X11Xkb = struct {
opcode: c_int,
base_event_code: c_int, base_event_code: c_int,
base_error_code: c_int,
funcs: Funcs, funcs: Funcs,
/// Initialize an X11Xkb struct, for the given GDK display. If the display /// Initialize an X11Xkb struct, for the given GDK display. If the display
@ -27,25 +25,25 @@ pub const X11Xkb = struct {
const display = display_ orelse return null; const display = display_ orelse return null;
// If the display isn't X11, then we don't need to do anything. // If the display isn't X11, then we don't need to do anything.
if (!x11_is_display(display)) return null; if (!is_display(display)) return null;
log.debug("X11Xkb.init: initializing Xkb", .{}); log.debug("X11Xkb.init: initializing Xkb", .{});
const xdisplay = c.gdk_x11_display_get_xdisplay(display); const xdisplay = c.gdk_x11_display_get_xdisplay(display);
var result: X11Xkb = .{ var result: X11Xkb = .{
.opcode = 0,
.base_event_code = 0, .base_event_code = 0,
.base_error_code = 0,
.funcs = try Funcs.init(), .funcs = try Funcs.init(),
}; };
log.debug("X11Xkb.init: running XkbQueryExtension", .{}); log.debug("X11Xkb.init: running XkbQueryExtension", .{});
var opcode: c_int = 0;
var base_error_code: c_int = 0;
var major = c.XkbMajorVersion; var major = c.XkbMajorVersion;
var minor = c.XkbMinorVersion; var minor = c.XkbMinorVersion;
if (result.funcs.XkbQueryExtension( if (result.funcs.XkbQueryExtension(
xdisplay, xdisplay,
&result.opcode, &opcode,
&result.base_event_code, &result.base_event_code,
&result.base_error_code, &base_error_code,
&major, &major,
&minor, &minor,
) == 0) { ) == 0) {