mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
gtk(wayland,x11): refactors (#7485)
This commit is contained in:
@ -48,16 +48,11 @@ pub const App = struct {
|
|||||||
_ = config;
|
_ = config;
|
||||||
_ = app_id;
|
_ = app_id;
|
||||||
|
|
||||||
// Check if we're actually on Wayland
|
|
||||||
if (gobject.typeCheckInstanceIsA(
|
|
||||||
gdk_display.as(gobject.TypeInstance),
|
|
||||||
gdk_wayland.WaylandDisplay.getGObjectType(),
|
|
||||||
) == 0) return null;
|
|
||||||
|
|
||||||
const gdk_wayland_display = gobject.ext.cast(
|
const gdk_wayland_display = gobject.ext.cast(
|
||||||
gdk_wayland.WaylandDisplay,
|
gdk_wayland.WaylandDisplay,
|
||||||
gdk_display,
|
gdk_display,
|
||||||
) orelse return error.NoWaylandDisplay;
|
) orelse return null;
|
||||||
|
|
||||||
const display: *wl.Display = @ptrCast(@alignCast(
|
const display: *wl.Display = @ptrCast(@alignCast(
|
||||||
gdk_wayland_display.getWlDisplay() orelse return error.NoWaylandDisplay,
|
gdk_wayland_display.getWlDisplay() orelse return error.NoWaylandDisplay,
|
||||||
));
|
));
|
||||||
@ -76,9 +71,9 @@ pub const App = struct {
|
|||||||
registry.setListener(*Context, registryListener, context);
|
registry.setListener(*Context, registryListener, context);
|
||||||
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
|
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
|
||||||
|
|
||||||
if (context.kde_decoration_manager != null) {
|
// Do another round-trip to get the default decoration mode
|
||||||
// FIXME: Roundtrip again because we have to wait for the decoration
|
if (context.kde_decoration_manager) |deco_manager| {
|
||||||
// manager to respond with the preferred default mode. Ew.
|
deco_manager.setListener(*Context, decoManagerListener, context);
|
||||||
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
|
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,80 +116,54 @@ pub const App = struct {
|
|||||||
event: wl.Registry.Event,
|
event: wl.Registry.Event,
|
||||||
context: *Context,
|
context: *Context,
|
||||||
) void {
|
) void {
|
||||||
switch (event) {
|
inline for (@typeInfo(Context).@"struct".fields) |field| {
|
||||||
// https://wayland.app/protocols/wayland#wl_registry:event:global
|
// Globals should be optional pointers
|
||||||
.global => |global| {
|
const T = switch (@typeInfo(field.type)) {
|
||||||
log.debug("wl_registry.global: interface={s}", .{global.interface});
|
.optional => |o| switch (@typeInfo(o.child)) {
|
||||||
|
.pointer => |v| v.child,
|
||||||
|
else => continue,
|
||||||
|
},
|
||||||
|
else => continue,
|
||||||
|
};
|
||||||
|
|
||||||
if (registryBind(
|
// Only process Wayland interfaces
|
||||||
org.KdeKwinBlurManager,
|
if (!@hasDecl(T, "interface")) continue;
|
||||||
registry,
|
|
||||||
global,
|
|
||||||
)) |blur_manager| {
|
|
||||||
context.kde_blur_manager = blur_manager;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (registryBind(
|
switch (event) {
|
||||||
org.KdeKwinServerDecorationManager,
|
.global => |v| global: {
|
||||||
registry,
|
if (std.mem.orderZ(
|
||||||
global,
|
u8,
|
||||||
)) |deco_manager| {
|
v.interface,
|
||||||
context.kde_decoration_manager = deco_manager;
|
T.interface.name,
|
||||||
deco_manager.setListener(*Context, decoManagerListener, context);
|
) != .eq) break :global;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (registryBind(
|
@field(context, field.name) = registry.bind(
|
||||||
org.KdeKwinSlideManager,
|
v.name,
|
||||||
registry,
|
T,
|
||||||
global,
|
T.generated_version,
|
||||||
)) |slide_manager| {
|
) catch |err| {
|
||||||
context.kde_slide_manager = slide_manager;
|
log.warn(
|
||||||
return;
|
"error binding interface {s} error={}",
|
||||||
}
|
.{ v.interface, err },
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
if (registryBind(
|
// This should be a rare occurrence, but in case a global
|
||||||
xdg.ActivationV1,
|
// is suddenly no longer available, we destroy and unset it
|
||||||
registry,
|
// as the protocol mandates.
|
||||||
global,
|
.global_remove => |v| remove: {
|
||||||
)) |activation| {
|
const global = @field(context, field.name) orelse break :remove;
|
||||||
context.xdg_activation = activation;
|
if (global.getId() == v.name) {
|
||||||
return;
|
global.destroy();
|
||||||
}
|
@field(context, field.name) = null;
|
||||||
},
|
}
|
||||||
|
},
|
||||||
// We don't handle removal events
|
}
|
||||||
.global_remove => {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind a Wayland interface to a global object. Returns non-null
|
|
||||||
/// if the binding was successful, otherwise null.
|
|
||||||
///
|
|
||||||
/// The type T is the Wayland interface type that we're requesting.
|
|
||||||
/// This function will verify that the global object is the correct
|
|
||||||
/// interface and version before binding.
|
|
||||||
fn registryBind(
|
|
||||||
comptime T: type,
|
|
||||||
registry: *wl.Registry,
|
|
||||||
global: anytype,
|
|
||||||
) ?*T {
|
|
||||||
if (std.mem.orderZ(
|
|
||||||
u8,
|
|
||||||
global.interface,
|
|
||||||
T.interface.name,
|
|
||||||
) != .eq) return null;
|
|
||||||
|
|
||||||
return registry.bind(global.name, T, T.generated_version) catch |err| {
|
|
||||||
log.warn("error binding interface {s} error={}", .{
|
|
||||||
global.interface,
|
|
||||||
err,
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decoManagerListener(
|
fn decoManagerListener(
|
||||||
_: *org.KdeKwinServerDecorationManager,
|
_: *org.KdeKwinServerDecorationManager,
|
||||||
event: org.KdeKwinServerDecorationManager.Event,
|
event: org.KdeKwinServerDecorationManager.Event,
|
||||||
|
@ -36,16 +36,11 @@ pub const App = struct {
|
|||||||
config: *const Config,
|
config: *const Config,
|
||||||
) !?App {
|
) !?App {
|
||||||
// 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 (gobject.typeCheckInstanceIsA(
|
|
||||||
gdk_display.as(gobject.TypeInstance),
|
|
||||||
gdk_x11.X11Display.getGObjectType(),
|
|
||||||
) == 0) return null;
|
|
||||||
|
|
||||||
// Get our X11 display
|
|
||||||
const gdk_x11_display = gobject.ext.cast(
|
const gdk_x11_display = gobject.ext.cast(
|
||||||
gdk_x11.X11Display,
|
gdk_x11.X11Display,
|
||||||
gdk_display,
|
gdk_display,
|
||||||
) orelse return null;
|
) orelse return null;
|
||||||
|
|
||||||
const xlib_display = gdk_x11_display.getXdisplay();
|
const xlib_display = gdk_x11_display.getXdisplay();
|
||||||
|
|
||||||
const x11_program_name: [:0]const u8 = if (config.@"x11-instance-name") |pn|
|
const x11_program_name: [:0]const u8 = if (config.@"x11-instance-name") |pn|
|
||||||
|
Reference in New Issue
Block a user