diff --git a/src/apprt/gtk/ClipboardConfirmationWindow.zig b/src/apprt/gtk/ClipboardConfirmationWindow.zig index ce67c7a7b..a28b7ddd4 100644 --- a/src/apprt/gtk/ClipboardConfirmationWindow.zig +++ b/src/apprt/gtk/ClipboardConfirmationWindow.zig @@ -131,49 +131,27 @@ fn init( ); } + _ = DialogType.signals.response.connect( + dialog, + *ClipboardConfirmation, + gtkResponse, + self, + .{}, + ); + switch (DialogType) { adw.AlertDialog => { const parent: ?*gtk.Widget = widget: { const window = core_surface.rt_surface.container.window() orelse break :widget null; - break :widget @ptrCast(@alignCast(window.window)); + break :widget window.window.as(gtk.Widget); }; - - dialog.choose(parent, null, gtkChoose, self); - }, - adw.MessageDialog => { - if (adw_version.atLeast(1, 3, 0)) { - dialog.choose(null, gtkChoose, self); - } else { - _ = adw.MessageDialog.signals.response.connect( - dialog, - *ClipboardConfirmation, - gtkResponse, - self, - .{}, - ); - dialog.as(gtk.Widget).show(); - } + dialog.as(adw.Dialog).present(parent); }, + adw.MessageDialog => dialog.as(gtk.Window).present(), else => unreachable, } } -fn gtkChoose(dialog_: ?*gobject.Object, result: *gio.AsyncResult, ud: ?*anyopaque) callconv(.C) void { - const dialog = gobject.ext.cast(DialogType, dialog_.?).?; - const self: *ClipboardConfirmation = @ptrCast(@alignCast(ud.?)); - const response = dialog.chooseFinish(result); - if (std.mem.orderZ(u8, response, "ok") == .eq) { - self.core_surface.completeClipboardRequest( - self.pending_req, - self.data, - true, - ) catch |err| { - log.err("Failed to requeue clipboard request: {}", .{err}); - }; - } - self.destroy(); -} - fn gtkResponse(_: *DialogType, response: [*:0]u8, self: *ClipboardConfirmation) callconv(.C) void { if (std.mem.orderZ(u8, response, "ok") == .eq) { self.core_surface.completeClipboardRequest( diff --git a/src/apprt/gtk/CloseDialog.zig b/src/apprt/gtk/CloseDialog.zig index 47ea5f27b..ea683c477 100644 --- a/src/apprt/gtk/CloseDialog.zig +++ b/src/apprt/gtk/CloseDialog.zig @@ -113,11 +113,11 @@ pub const Target = union(enum) { const focused = list.findCustom(null, findActiveWindow); return @ptrCast(@alignCast(focused.f_data)); }, - .window => |v| @ptrCast(v.window), - .tab => |v| @ptrCast(v.window.window), - .surface => |v| surface: { + .window => |v| v.window.as(gtk.Window), + .tab => |v| v.window.window.as(gtk.Window), + .surface => |v| { const window_ = v.container.window() orelse return null; - break :surface @ptrCast(window_.window); + return window_.window.as(gtk.Window); }, }; } @@ -134,7 +134,7 @@ pub const Target = union(enum) { fn close(self: Target) void { switch (self) { .app => |v| v.quitNow(), - .window => |v| gtk.Window.destroy(@ptrCast(v.window)), + .window => |v| v.window.as(gtk.Window).destroy(), .tab => |v| v.remove(), .surface => |v| v.container.remove(), } diff --git a/src/apprt/gtk/ConfigErrorsDialog.zig b/src/apprt/gtk/ConfigErrorsDialog.zig index c10c5771d..c10f8e679 100644 --- a/src/apprt/gtk/ConfigErrorsDialog.zig +++ b/src/apprt/gtk/ConfigErrorsDialog.zig @@ -58,7 +58,7 @@ pub fn maybePresent(app: *App, window: ?*Window) void { _ = DialogType.signals.response.connect(dialog, *App, onResponse, app, .{}); - const parent: ?*gtk.Widget = if (window) |w| @ptrCast(w.window) else null; + const parent = if (window) |w| w.window.as(gtk.Widget) else null; switch (DialogType) { adw.AlertDialog => dialog.as(adw.Dialog).present(parent), diff --git a/src/apprt/gtk/ImguiWidget.zig b/src/apprt/gtk/ImguiWidget.zig index 71b1c7f1d..f1f0c8f6b 100644 --- a/src/apprt/gtk/ImguiWidget.zig +++ b/src/apprt/gtk/ImguiWidget.zig @@ -179,8 +179,8 @@ pub fn init(self: *ImguiWidget) !void { ); self.* = .{ - .gl_area = @ptrCast(gl_area), - .im_context = @ptrCast(im_context), + .gl_area = gl_area, + .im_context = im_context.as(gtk.IMContext), .ig_ctx = ig_ctx, }; } diff --git a/src/apprt/gtk/Split.zig b/src/apprt/gtk/Split.zig index 8f19974e6..9caa9ab56 100644 --- a/src/apprt/gtk/Split.zig +++ b/src/apprt/gtk/Split.zig @@ -287,8 +287,8 @@ pub fn updateChildren(self: *const Split) void { self.removeChildren(); // Set our current children - self.paned.setStartChild(@ptrCast(@alignCast(self.top_left.widget()))); - self.paned.setEndChild(@ptrCast(@alignCast(self.bottom_right.widget()))); + self.paned.setStartChild(self.top_left.widget()); + self.paned.setEndChild(self.bottom_right.widget()); } /// A mapping of direction to the element (if any) in that direction. diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index b48655610..cf5976fe6 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -523,7 +523,7 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void { // initialize the context menu self.context_menu.init(self); - self.context_menu.setParent(@ptrCast(@alignCast(overlay))); + self.context_menu.setParent(overlay.as(gtk.Widget)); // initialize the resize overlay self.resize_overlay.init(self, &app.config); @@ -1068,7 +1068,7 @@ pub fn promptTitle(self: *Surface) !void { entry.getBuffer().setText(self.getTitle() orelse "", -1); const dialog = builder.getObject(adw.AlertDialog, "prompt_title_dialog").?; - dialog.choose(@ptrCast(window.window), null, gtkPromptTitleResponse, self); + dialog.choose(window.window.as(gtk.Widget), null, gtkPromptTitleResponse, self); } /// Set the current working directory of the surface. @@ -1220,7 +1220,7 @@ pub fn clipboardRequest( ud_ptr.* = .{ .self = self, .state = state }; // Start our async request - const clipboard = getClipboard(@ptrCast(self.gl_area), clipboard_type) orelse return; + const clipboard = getClipboard(self.gl_area.as(gtk.Widget), clipboard_type) orelse return; clipboard.readTextAsync(null, gtkClipboardRead, ud_ptr); } @@ -1232,7 +1232,7 @@ pub fn setClipboardString( confirm: bool, ) !void { if (!confirm) { - const clipboard = getClipboard(@ptrCast(self.gl_area), clipboard_type) orelse return; + const clipboard = getClipboard(self.gl_area.as(gtk.Widget), clipboard_type) orelse return; clipboard.setText(val); // We only toast if we are copying to the standard clipboard. @@ -2150,10 +2150,6 @@ pub fn dimSurface(self: *Surface) void { }; } -fn userdataSelf(ud: *anyopaque) *Surface { - return @ptrCast(@alignCast(ud)); -} - fn translateMouseButton(button: c_uint) input.MouseButton { return switch (button) { 1 => .left, @@ -2383,7 +2379,7 @@ fn g_value_holds(value_: ?*gobject.Value, g_type: gobject.Type) bool { fn gtkPromptTitleResponse(source_object: ?*gobject.Object, result: *gio.AsyncResult, ud: ?*anyopaque) callconv(.C) void { if (!adw_version.supportsDialogs()) return; const dialog = gobject.ext.cast(adw.AlertDialog, source_object.?).?; - const self = userdataSelf(ud orelse return); + const self: *Surface = @ptrCast(@alignCast(ud)); const response = dialog.chooseFinish(result); if (std.mem.orderZ(u8, "ok", response) == .eq) { diff --git a/src/apprt/gtk/TabView.zig b/src/apprt/gtk/TabView.zig index 0078e4d3d..85a9bbcb2 100644 --- a/src/apprt/gtk/TabView.zig +++ b/src/apprt/gtk/TabView.zig @@ -115,7 +115,7 @@ pub fn gotoNthTab(self: *TabView, position: c_int) bool { } pub fn getTabPosition(self: *TabView, tab: *Tab) ?c_int { - const page = self.tab_view.getPage(@ptrCast(tab.box)); + const page = self.tab_view.getPage(tab.box.as(gtk.Widget)); return self.tab_view.getPagePosition(page); } @@ -161,17 +161,17 @@ pub fn moveTab(self: *TabView, tab: *Tab, position: c_int) void { } pub fn reorderPage(self: *TabView, tab: *Tab, position: c_int) void { - const page = self.tab_view.getPage(@ptrCast(tab.box)); + const page = self.tab_view.getPage(tab.box.as(gtk.Widget)); _ = self.tab_view.reorderPage(page, position); } pub fn setTabTitle(self: *TabView, tab: *Tab, title: [:0]const u8) void { - const page = self.tab_view.getPage(@ptrCast(tab.box)); + const page = self.tab_view.getPage(tab.box.as(gtk.Widget)); page.setTitle(title.ptr); } pub fn setTabTooltip(self: *TabView, tab: *Tab, tooltip: [:0]const u8) void { - const page = self.tab_view.getPage(@ptrCast(tab.box)); + const page = self.tab_view.getPage(tab.box.as(gtk.Widget)); page.setTooltip(tooltip.ptr); } @@ -186,8 +186,7 @@ fn newTabInsertPosition(self: *TabView, tab: *Tab) c_int { /// Adds a new tab with the given title to the notebook. pub fn addTab(self: *TabView, tab: *Tab, title: [:0]const u8) void { const position = self.newTabInsertPosition(tab); - const box_widget: *gtk.Widget = @ptrCast(tab.box); - const page = self.tab_view.insert(box_widget, position); + const page = self.tab_view.insert(tab.box.as(gtk.Widget), position); self.setTabTitle(tab, title); self.tab_view.setSelectedPage(page); } @@ -204,7 +203,7 @@ pub fn closeTab(self: *TabView, tab: *Tab) void { if (n > 1) self.forcing_close = false; } - const page = self.tab_view.getPage(@ptrCast(tab.box)); + const page = self.tab_view.getPage(tab.box.as(gtk.Widget)); self.tab_view.closePage(page); // If we have no more tabs we close the window @@ -214,22 +213,17 @@ pub fn closeTab(self: *TabView, tab: *Tab) void { // unref to force the cleanup. This will trigger a critical // warning from GTK, but I don't know any other workaround. if (!adw_version.atLeast(1, 5, 1)) { - const box: *gtk.Box = @ptrCast(@alignCast(tab.box)); - box.as(gobject.Object).unref(); + tab.box.unref(); } self.window.close(); } } -pub fn createWindow(currentWindow: *Window) !*Window { - const alloc = currentWindow.app.core_app.alloc; - const app = currentWindow.app; - - // Create a new window - const window = try Window.create(alloc, app); - window.present(); - return window; +pub fn createWindow(window: *Window) !*Window { + const new_window = try Window.create(window.app.core_app.alloc, window.app); + new_window.present(); + return new_window; } fn adwPageAttached(_: *adw.TabView, page: *adw.TabPage, _: c_int, self: *TabView) callconv(.C) void { diff --git a/src/apprt/gtk/ghostty_gtk_compat.h b/src/apprt/gtk/ghostty_gtk_compat.h deleted file mode 100644 index c0dc819c2..000000000 --- a/src/apprt/gtk/ghostty_gtk_compat.h +++ /dev/null @@ -1,14 +0,0 @@ -// This file is used to provide compatibility if necessary with -// older versions of GTK and GLib. - -#include - -// Compatibility with gobject < 2.74 -#ifndef G_CONNECT_DEFAULT -#define G_CONNECT_DEFAULT 0 -#endif - -// Compatibility with gobject < 2.74 -#ifndef G_APPLICATION_DEFAULT_FLAGS -#define G_APPLICATION_DEFAULT_FLAGS G_APPLICATION_FLAGS_NONE -#endif diff --git a/src/apprt/gtk/menu.zig b/src/apprt/gtk/menu.zig index 4118097c0..d0a93b80d 100644 --- a/src/apprt/gtk/menu.zig +++ b/src/apprt/gtk/menu.zig @@ -92,17 +92,17 @@ pub fn Menu( pub fn refresh(self: *const Self) void { const window: *gtk.Window, const has_selection: bool = switch (T) { Window => window: { - const core_surface = self.parent.actionSurface() orelse break :window .{ - @ptrCast(@alignCast(self.parent.window)), - false, - }; - const has_selection = core_surface.hasSelection(); - break :window .{ @ptrCast(@alignCast(self.parent.window)), has_selection }; + const has_selection = if (self.parent.actionSurface()) |core_surface| + core_surface.hasSelection() + else + false; + + break :window .{ self.parent.window.as(gtk.Window), has_selection }; }, Surface => surface: { const window = self.parent.container.window() orelse return; const has_selection = self.parent.core_surface.hasSelection(); - break :surface .{ @ptrCast(@alignCast(window.window)), has_selection }; + break :surface .{ window.window.as(gtk.Window), has_selection }; }, else => unreachable, }; diff --git a/src/apprt/gtk/winproto/wayland.zig b/src/apprt/gtk/winproto/wayland.zig index d1f3835e5..6737e98e2 100644 --- a/src/apprt/gtk/winproto/wayland.zig +++ b/src/apprt/gtk/winproto/wayland.zig @@ -106,7 +106,7 @@ pub const App = struct { } pub fn initQuickTerminal(_: *App, apprt_window: *ApprtWindow) !void { - const window: *gtk.Window = @ptrCast(apprt_window.window); + const window = apprt_window.window.as(gtk.Window); gtk4_layer_shell.initForWindow(window); gtk4_layer_shell.setLayer(window, .top); @@ -229,16 +229,11 @@ pub const Window = struct { // This should never fail, because if we're being called at this point // then we've already asserted that our app state is Wayland. - if (gobject.typeCheckInstanceIsA( - gdk_surface.as(gobject.TypeInstance), - gdk_wayland.WaylandSurface.getGObjectType(), - ) == 0) - return error.NoWaylandSurface; - const gdk_wl_surface = gobject.ext.cast( gdk_wayland.WaylandSurface, gdk_surface, ) orelse return error.NoWaylandSurface; + const wl_surface: *wl.Surface = @ptrCast(@alignCast( gdk_wl_surface.getWlSurface() orelse return error.NoWaylandSurface, )); @@ -260,9 +255,8 @@ pub const Window = struct { }; if (apprt_window.isQuickTerminal()) { - const surface: *gdk.Surface = @ptrCast(gdk_surface); _ = gdk.Surface.signals.enter_monitor.connect( - surface, + gdk_surface, *ApprtWindow, enteredMonitor, apprt_window, @@ -361,7 +355,7 @@ pub const Window = struct { } fn syncQuickTerminal(self: *Window) !void { - const window: *gtk.Window = @ptrCast(self.apprt_window.window); + const window = self.apprt_window.window.as(gtk.Window); const position = self.apprt_window.config.quick_terminal_position; const anchored_edge: ?gtk4_layer_shell.ShellEdge = switch (position) { @@ -417,7 +411,7 @@ pub const Window = struct { monitor: *gdk.Monitor, apprt_window: *ApprtWindow, ) callconv(.C) void { - const window: *gtk.Window = @ptrCast(apprt_window.window); + const window = apprt_window.window.as(gtk.Window); const size = apprt_window.config.quick_terminal_size; const position = apprt_window.config.quick_terminal_position;