├── .clang-format ├── .editorconfig ├── .envrc ├── .gitattributes ├── .github ├── DISCUSSION_TEMPLATE │ └── issue-triage.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ └── preapproved.md ├── dependabot.yml ├── pinact.yml ├── scripts │ └── check-translations.sh └── workflows │ ├── clean-artifacts.yml │ ├── milestone.yml │ ├── nix.yml │ ├── publish-tag.yml │ ├── release-pr.yml │ ├── release-tag.yml │ ├── release-tip.yml │ ├── test.yml │ └── update-colorschemes.yml ├── .gitignore ├── .gitmodules ├── .mailmap ├── .prettierignore ├── CODEOWNERS ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── PACKAGING.md ├── README.md ├── build.zig ├── build.zig.zon ├── build.zig.zon.json ├── build.zig.zon.nix ├── build.zig.zon.txt ├── default.nix ├── dist ├── linux │ ├── app.desktop.in │ ├── com.mitchellh.ghostty.metainfo.xml.in │ ├── dbus.service.flatpak.in │ ├── dbus.service.in │ ├── ghostty_dolphin.desktop │ ├── ghostty_nautilus.py │ └── systemd.service.in ├── macos │ ├── update_appcast_tag.py │ └── update_appcast_tip.py └── windows │ ├── ghostty.ico │ ├── ghostty.manifest │ └── ghostty.rc ├── example ├── .gitignore ├── app.ts ├── index.html ├── package-lock.json └── package.json ├── flake.lock ├── flake.nix ├── flatpak ├── build-support │ └── check-zig-cache.sh ├── com.mitchellh.ghostty-debug.yml ├── com.mitchellh.ghostty.yml ├── dependencies.yml ├── exceptions.json └── zig-packages.json ├── images ├── Ghostty.icon │ ├── Assets │ │ ├── Ghostty.png │ │ ├── Inner Bevel 6px.png │ │ ├── Screen Effects.png │ │ ├── Screen.png │ │ └── gloss.png │ └── icon.json └── icons │ ├── icon_1024.png │ ├── icon_1024@2x.png │ ├── icon_128.png │ ├── icon_128@2x.png │ ├── icon_16.png │ ├── icon_16@2x.png │ ├── icon_256.png │ ├── icon_256@2x.png │ ├── icon_32.png │ ├── icon_32@2x.png │ ├── icon_512.png │ └── icon_512@2x.png ├── include ├── ghostty.h └── module.modulemap ├── macos ├── .gitignore ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── Alternate Icons │ │ ├── BlueprintImage.imageset │ │ │ ├── Contents.json │ │ │ └── macOS-AppIcon-1024px.png │ │ ├── ChalkboardImage.imageset │ │ │ ├── Contents.json │ │ │ └── macOS-AppIcon-1024px.png │ │ ├── Contents.json │ │ ├── GlassImage.imageset │ │ │ ├── Contents.json │ │ │ └── macOS-AppIcon-1024px.png │ │ ├── HolographicImage.imageset │ │ │ ├── Contents.json │ │ │ └── macOS-AppIcon-1024px.png │ │ ├── MicrochipImage.imageset │ │ │ ├── Contents.json │ │ │ └── macOS-AppIcon-1024px.png │ │ ├── PaperImage.imageset │ │ │ ├── Contents.json │ │ │ └── macOS-AppIcon-1024px.png │ │ ├── RetroImage.imageset │ │ │ ├── Contents.json │ │ │ └── macOS-AppIcon-1024px.png │ │ └── XrayImage.imageset │ │ │ ├── Contents.json │ │ │ └── macOS-AppIcon-1024px.png │ ├── AppIconImage.imageset │ │ ├── Contents.json │ │ ├── macOS-AppIcon-1024px.png │ │ ├── macOS-AppIcon-256px-128pt@2x.png │ │ └── macOS-AppIcon-512px.png │ ├── Contents.json │ ├── Custom Icon │ │ ├── Contents.json │ │ ├── CustomIconBaseAluminum.imageset │ │ │ ├── Contents.json │ │ │ └── base.png │ │ ├── CustomIconBaseBeige.imageset │ │ │ ├── Contents.json │ │ │ └── beige.png │ │ ├── CustomIconBaseChrome.imageset │ │ │ ├── Contents.json │ │ │ └── chrome.png │ │ ├── CustomIconBasePlastic.imageset │ │ │ ├── Contents.json │ │ │ └── plastic.png │ │ ├── CustomIconCRT.imageset │ │ │ ├── Contents.json │ │ │ └── crt-effect.png │ │ ├── CustomIconGhost.imageset │ │ │ ├── Contents.json │ │ │ └── ghosty.png │ │ ├── CustomIconGloss.imageset │ │ │ ├── Contents.json │ │ │ └── gloss.png │ │ ├── CustomIconScreen.imageset │ │ │ ├── Contents.json │ │ │ └── screen-dark.png │ │ └── CustomIconScreenMask.imageset │ │ │ ├── Contents.json │ │ │ └── screen-mask.png │ └── ResetZoom.imageset │ │ ├── Contents.json │ │ └── ResetZoom.pdf ├── Ghostty-Info.plist ├── Ghostty.entitlements ├── Ghostty.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── swiftpm │ │ │ └── Package.resolved │ └── xcshareddata │ │ └── xcschemes │ │ └── Ghostty.xcscheme ├── GhosttyDebug.entitlements ├── GhosttyReleaseLocal.entitlements ├── GhosttyTests │ └── BenchmarkTests.swift └── Sources │ ├── App │ ├── iOS │ │ └── iOSApp.swift │ └── macOS │ │ ├── AppDelegate.swift │ │ ├── MainMenu.xib │ │ ├── ghostty-bridging-header.h │ │ └── main.swift │ ├── Features │ ├── About │ │ ├── About.xib │ │ ├── AboutController.swift │ │ └── AboutView.swift │ ├── App Intents │ │ ├── CloseTerminalIntent.swift │ │ ├── CommandPaletteIntent.swift │ │ ├── Entities │ │ │ ├── CommandEntity.swift │ │ │ └── TerminalEntity.swift │ │ ├── GetTerminalDetailsIntent.swift │ │ ├── GhosttyIntentError.swift │ │ ├── InputIntent.swift │ │ ├── IntentPermission.swift │ │ ├── KeybindIntent.swift │ │ ├── NewTerminalIntent.swift │ │ └── QuickTerminalIntent.swift │ ├── ClipboardConfirmation │ │ ├── ClipboardConfirmation.xib │ │ ├── ClipboardConfirmationController.swift │ │ └── ClipboardConfirmationView.swift │ ├── Colorized Ghostty Icon │ │ ├── ColorizedGhosttyIcon.swift │ │ ├── ColorizedGhosttyIconImage.swift │ │ └── ColorizedGhosttyIconView.swift │ ├── Command Palette │ │ ├── CommandPalette.swift │ │ └── TerminalCommandPalette.swift │ ├── Global Keybinds │ │ └── GlobalEventTap.swift │ ├── QuickTerminal │ │ ├── QuickTerminal.xib │ │ ├── QuickTerminalController.swift │ │ ├── QuickTerminalPosition.swift │ │ ├── QuickTerminalScreen.swift │ │ ├── QuickTerminalSpaceBehavior.swift │ │ └── QuickTerminalWindow.swift │ ├── Secure Input │ │ ├── SecureInput.swift │ │ └── SecureInputOverlay.swift │ ├── Services │ │ └── ServiceProvider.swift │ ├── Settings │ │ ├── ConfigurationErrors.xib │ │ ├── ConfigurationErrorsController.swift │ │ ├── ConfigurationErrorsView.swift │ │ └── SettingsView.swift │ ├── Splits │ │ ├── SplitTree.swift │ │ ├── SplitView.Divider.swift │ │ ├── SplitView.swift │ │ └── TerminalSplitTreeView.swift │ ├── Terminal │ │ ├── BaseTerminalController.swift │ │ ├── ErrorView.swift │ │ ├── TerminalController.swift │ │ ├── TerminalRestorable.swift │ │ ├── TerminalView.swift │ │ └── Window Styles │ │ │ ├── HiddenTitlebarTerminalWindow.swift │ │ │ ├── Terminal.xib │ │ │ ├── TerminalHiddenTitlebar.xib │ │ │ ├── TerminalTabsTitlebarTahoe.xib │ │ │ ├── TerminalTabsTitlebarVentura.xib │ │ │ ├── TerminalTransparentTitlebar.xib │ │ │ ├── TerminalWindow.swift │ │ │ ├── TitlebarTabsTahoeTerminalWindow.swift │ │ │ ├── TitlebarTabsVenturaTerminalWindow.swift │ │ │ └── TransparentTitlebarTerminalWindow.swift │ └── Update │ │ └── UpdateDelegate.swift │ ├── Ghostty │ ├── FullscreenMode+Extension.swift │ ├── Ghostty.Action.swift │ ├── Ghostty.App.swift │ ├── Ghostty.Command.swift │ ├── Ghostty.Config.swift │ ├── Ghostty.Error.swift │ ├── Ghostty.Event.swift │ ├── Ghostty.Input.swift │ ├── Ghostty.Shell.swift │ ├── Ghostty.Surface.swift │ ├── InspectorView.swift │ ├── NSEvent+Extension.swift │ ├── Package.swift │ ├── SurfaceView.swift │ ├── SurfaceView_AppKit.swift │ └── SurfaceView_UIKit.swift │ └── Helpers │ ├── AppInfo.swift │ ├── Backport.swift │ ├── CodableBridge.swift │ ├── CrossKit.swift │ ├── Cursor.swift │ ├── DraggableWindowView.swift │ ├── ExpiringUndoManager.swift │ ├── Extensions │ ├── Array+Extension.swift │ ├── Double+Extension.swift │ ├── Duration+Extension.swift │ ├── EventModifiers+Extension.swift │ ├── FileHandle+Extension.swift │ ├── KeyboardShortcut+Extension.swift │ ├── NSAppearance+Extension.swift │ ├── NSApplication+Extension.swift │ ├── NSImage+Extension.swift │ ├── NSMenuItem+Extension.swift │ ├── NSPasteboard+Extension.swift │ ├── NSScreen+Extension.swift │ ├── NSView+Extension.swift │ ├── NSWindow+Extension.swift │ ├── NSWorkspace+Extension.swift │ ├── OSColor+Extension.swift │ ├── Optional+Extension.swift │ ├── String+Extension.swift │ ├── UndoManager+Extension.swift │ └── View+Extension.swift │ ├── Fullscreen.swift │ ├── HostingWindow.swift │ ├── KeyboardLayout.swift │ ├── LastWindowPosition.swift │ ├── MetalView.swift │ ├── PermissionRequest.swift │ ├── Private │ ├── CGS.swift │ └── Dock.swift │ ├── TabGroupCloseCoordinator.swift │ ├── VibrantLayer.h │ ├── VibrantLayer.m │ └── Weak.swift ├── nix ├── build-support │ ├── build-inputs.nix │ ├── check-blueprints.sh │ ├── check-zig-cache.sh │ ├── fetch-zig-cache.sh │ ├── gi-typelib-path.nix │ ├── ld-library-path.nix │ └── update-mirror.sh ├── devShell.nix ├── package.nix ├── vm │ ├── common-cinnamon.nix │ ├── common-gnome.nix │ ├── common-plasma6.nix │ ├── common-xfce.nix │ ├── common.nix │ ├── create-cinnamon.nix │ ├── create-gnome.nix │ ├── create-plasma6.nix │ ├── create-xfce.nix │ ├── create.nix │ ├── wayland-cinnamon.nix │ ├── wayland-gnome.nix │ ├── wayland-plasma6.nix │ ├── x11-cinnamon.nix │ ├── x11-gnome.nix │ ├── x11-plasma6.nix │ └── x11-xfce.nix ├── wraptest.nix └── zigCacheHash.nix ├── pkg ├── README.md ├── apple-sdk │ ├── build.zig │ └── build.zig.zon ├── breakpad │ ├── build.zig │ ├── build.zig.zon │ └── vendor │ │ └── third_party │ │ └── lss │ │ └── linux_syscall_support.h ├── cimgui │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ ├── main.zig │ └── vendor │ │ ├── cimgui.cpp │ │ └── cimgui.h ├── fontconfig │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ ├── char_set.zig │ ├── common.zig │ ├── config.zig │ ├── error.zig │ ├── font_set.zig │ ├── init.zig │ ├── lang_set.zig │ ├── main.zig │ ├── matrix.zig │ ├── object_set.zig │ ├── override │ │ └── include │ │ │ ├── fcalias.h │ │ │ ├── fcaliastail.h │ │ │ ├── fcftalias.h │ │ │ ├── fcftaliastail.h │ │ │ └── fcobjshash.h │ ├── pattern.zig │ ├── range.zig │ ├── test.zig │ └── value.zig ├── freetype │ ├── Library.zig │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ ├── computations.zig │ ├── errors.zig │ ├── face.zig │ ├── freetype-zig.h │ ├── main.zig │ ├── tag.zig │ └── test.zig ├── glslang │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ ├── init.zig │ ├── main.zig │ ├── override │ │ └── glslang │ │ │ └── build_info.h │ ├── program.zig │ ├── shader.zig │ ├── test.zig │ └── test │ │ └── simple.frag ├── gtk4-layer-shell │ ├── build.zig │ ├── build.zig.zon │ └── src │ │ └── main.zig ├── harfbuzz │ ├── blob.zig │ ├── buffer.zig │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ ├── common.zig │ ├── coretext.zig │ ├── errors.zig │ ├── face.zig │ ├── font.zig │ ├── freetype.zig │ ├── main.zig │ ├── shape.zig │ └── version.zig ├── highway │ ├── bridge.cpp │ ├── build.zig │ ├── build.zig.zon │ └── main.zig ├── libintl │ ├── build.zig │ ├── build.zig.zon │ ├── config.h │ ├── libgnuintl.h │ └── libintl.h ├── libpng │ ├── build.zig │ ├── build.zig.zon │ └── pnglibconf.h ├── libxml2 │ ├── build.zig │ ├── build.zig.zon │ └── override │ │ ├── config │ │ ├── posix │ │ │ └── config.h │ │ └── win32 │ │ │ └── config.h │ │ └── include │ │ └── libxml │ │ └── xmlversion.h ├── macos │ ├── animation.zig │ ├── animation │ │ └── c.zig │ ├── build.zig │ ├── build.zig.zon │ ├── carbon.zig │ ├── carbon │ │ └── c.zig │ ├── dispatch.zig │ ├── dispatch │ │ ├── c.zig │ │ ├── data.zig │ │ └── queue.zig │ ├── foundation.zig │ ├── foundation │ │ ├── array.zig │ │ ├── attributed_string.zig │ │ ├── base.zig │ │ ├── c.zig │ │ ├── character_set.zig │ │ ├── data.zig │ │ ├── dictionary.zig │ │ ├── number.zig │ │ ├── string.zig │ │ ├── type.zig │ │ └── url.zig │ ├── graphics.zig │ ├── graphics │ │ ├── affine_transform.zig │ │ ├── bitmap_context.zig │ │ ├── c.zig │ │ ├── color_space.zig │ │ ├── context.zig │ │ ├── font.zig │ │ ├── geometry.zig │ │ ├── image.zig │ │ └── path.zig │ ├── iosurface.zig │ ├── iosurface │ │ ├── c.zig │ │ └── iosurface.zig │ ├── main.zig │ ├── os.zig │ ├── os │ │ ├── c.zig │ │ ├── log.zig │ │ ├── signpost.zig │ │ └── zig_macos.c │ ├── text.zig │ ├── text │ │ ├── c.zig │ │ ├── ext.c │ │ ├── font.zig │ │ ├── font_collection.zig │ │ ├── font_descriptor.zig │ │ ├── font_manager.zig │ │ ├── frame.zig │ │ ├── framesetter.zig │ │ ├── line.zig │ │ ├── paragraph_style.zig │ │ ├── run.zig │ │ └── stylized_strings.zig │ ├── video.zig │ └── video │ │ ├── c.zig │ │ ├── display_link.zig │ │ └── pixel_format.zig ├── oniguruma │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ ├── errors.zig │ ├── init.zig │ ├── main.zig │ ├── regex.zig │ ├── region.zig │ ├── testing.zig │ └── types.zig ├── opengl │ ├── Buffer.zig │ ├── Framebuffer.zig │ ├── Program.zig │ ├── Renderbuffer.zig │ ├── Shader.zig │ ├── Texture.zig │ ├── VertexArray.zig │ ├── build.zig │ ├── c.zig │ ├── draw.zig │ ├── errors.zig │ ├── extensions.zig │ ├── glad.zig │ ├── main.zig │ └── primitives.zig ├── sentry │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ ├── envelope.zig │ ├── level.zig │ ├── main.zig │ ├── transport.zig │ ├── uuid.zig │ └── value.zig ├── simdutf │ ├── build.zig │ ├── build.zig.zon │ └── vendor │ │ ├── simdutf.cpp │ │ └── simdutf.h ├── spirv-cross │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ └── main.zig ├── utf8proc │ ├── build.zig │ ├── build.zig.zon │ ├── c.zig │ └── main.zig ├── utfcpp │ ├── build.zig │ ├── build.zig.zon │ └── empty.cc ├── wuffs │ ├── build.zig │ ├── build.zig.zon │ └── src │ │ ├── c.zig │ │ ├── error.zig │ │ ├── jpeg.zig │ │ ├── main.zig │ │ ├── png.zig │ │ └── swizzle.zig └── zlib │ ├── build.zig │ └── build.zig.zon ├── po ├── README_CONTRIBUTORS.md ├── README_TRANSLATORS.md ├── bg_BG.UTF-8.po ├── ca_ES.UTF-8.po ├── com.mitchellh.ghostty.pot ├── de_DE.UTF-8.po ├── es_AR.UTF-8.po ├── es_BO.UTF-8.po ├── fr_FR.UTF-8.po ├── ga_IE.UTF-8.po ├── he_IL.UTF-8.po ├── id_ID.UTF-8.po ├── ja_JP.UTF-8.po ├── ko_KR.UTF-8.po ├── mk_MK.UTF-8.po ├── nb_NO.UTF-8.po ├── nl_NL.UTF-8.po ├── pl_PL.UTF-8.po ├── pt_BR.UTF-8.po ├── ru_RU.UTF-8.po ├── tr_TR.UTF-8.po ├── uk_UA.UTF-8.po └── zh_CN.UTF-8.po ├── shell.nix ├── snap ├── local │ └── launcher └── snapcraft.yaml ├── src ├── App.zig ├── Command.zig ├── Surface.zig ├── apprt.zig ├── apprt │ ├── action.zig │ ├── browser.zig │ ├── embedded.zig │ ├── gtk.zig │ ├── gtk │ │ ├── App.zig │ │ ├── Builder.zig │ │ ├── ClipboardConfirmationWindow.zig │ │ ├── CloseDialog.zig │ │ ├── CommandPalette.zig │ │ ├── ConfigErrorsDialog.zig │ │ ├── GlobalShortcuts.zig │ │ ├── ImguiWidget.zig │ │ ├── ResizeOverlay.zig │ │ ├── Split.zig │ │ ├── Surface.zig │ │ ├── Tab.zig │ │ ├── TabView.zig │ │ ├── URLWidget.zig │ │ ├── Window.zig │ │ ├── adw_version.zig │ │ ├── blueprint_compiler.zig │ │ ├── cgroup.zig │ │ ├── flatpak.zig │ │ ├── gresource.zig │ │ ├── gtk_version.zig │ │ ├── headerbar.zig │ │ ├── inspector.zig │ │ ├── key.zig │ │ ├── menu.zig │ │ ├── style-dark.css │ │ ├── style-hc-dark.css │ │ ├── style-hc.css │ │ ├── style.css │ │ ├── ui │ │ │ ├── 1.0 │ │ │ │ ├── menu-headerbar-split_menu.blp │ │ │ │ ├── menu-surface-context_menu.blp │ │ │ │ └── menu-window-titlebar_menu.blp │ │ │ ├── 1.2 │ │ │ │ ├── ccw-osc-52-read.blp │ │ │ │ ├── ccw-osc-52-write.blp │ │ │ │ ├── ccw-paste.blp │ │ │ │ └── config-errors-dialog.blp │ │ │ ├── 1.5 │ │ │ │ ├── ccw-osc-52-read.blp │ │ │ │ ├── ccw-osc-52-write.blp │ │ │ │ ├── ccw-paste.blp │ │ │ │ ├── command-palette.blp │ │ │ │ ├── config-errors-dialog.blp │ │ │ │ └── prompt-title-dialog.blp │ │ │ └── README.md │ │ ├── winproto.zig │ │ └── winproto │ │ │ ├── noop.zig │ │ │ ├── wayland.zig │ │ │ └── x11.zig │ ├── none.zig │ ├── structs.zig │ └── surface.zig ├── benchmark │ ├── Benchmark.zig │ ├── CApi.zig │ ├── CodepointWidth.zig │ ├── GraphemeBreak.zig │ ├── TerminalParser.zig │ ├── TerminalStream.zig │ ├── cli.zig │ ├── main.zig │ └── options.zig ├── build │ ├── Config.zig │ ├── GhosttyBench.zig │ ├── GhosttyDist.zig │ ├── GhosttyDocs.zig │ ├── GhosttyExe.zig │ ├── GhosttyFrameData.zig │ ├── GhosttyI18n.zig │ ├── GhosttyLib.zig │ ├── GhosttyResources.zig │ ├── GhosttyWebdata.zig │ ├── GhosttyXCFramework.zig │ ├── GhosttyXcodebuild.zig │ ├── GitVersion.zig │ ├── HelpStrings.zig │ ├── LibtoolStep.zig │ ├── LipoStep.zig │ ├── MetallibStep.zig │ ├── SharedDeps.zig │ ├── UnicodeTables.zig │ ├── XCFrameworkStep.zig │ ├── bash_completions.zig │ ├── docker │ │ └── debian │ │ │ └── Dockerfile │ ├── fish_completions.zig │ ├── framegen │ │ ├── frames │ │ │ ├── frame_001.txt │ │ │ ├── frame_002.txt │ │ │ ├── frame_003.txt │ │ │ ├── frame_004.txt │ │ │ ├── frame_005.txt │ │ │ ├── frame_006.txt │ │ │ ├── frame_007.txt │ │ │ ├── frame_008.txt │ │ │ ├── frame_009.txt │ │ │ ├── frame_010.txt │ │ │ ├── frame_011.txt │ │ │ ├── frame_012.txt │ │ │ ├── frame_013.txt │ │ │ ├── frame_014.txt │ │ │ ├── frame_015.txt │ │ │ ├── frame_016.txt │ │ │ ├── frame_017.txt │ │ │ ├── frame_018.txt │ │ │ ├── frame_019.txt │ │ │ ├── frame_020.txt │ │ │ ├── frame_021.txt │ │ │ ├── frame_022.txt │ │ │ ├── frame_023.txt │ │ │ ├── frame_024.txt │ │ │ ├── frame_025.txt │ │ │ ├── frame_026.txt │ │ │ ├── frame_027.txt │ │ │ ├── frame_028.txt │ │ │ ├── frame_029.txt │ │ │ ├── frame_030.txt │ │ │ ├── frame_031.txt │ │ │ ├── frame_032.txt │ │ │ ├── frame_033.txt │ │ │ ├── frame_034.txt │ │ │ ├── frame_035.txt │ │ │ ├── frame_036.txt │ │ │ ├── frame_037.txt │ │ │ ├── frame_038.txt │ │ │ ├── frame_039.txt │ │ │ ├── frame_040.txt │ │ │ ├── frame_041.txt │ │ │ ├── frame_042.txt │ │ │ ├── frame_043.txt │ │ │ ├── frame_044.txt │ │ │ ├── frame_045.txt │ │ │ ├── frame_046.txt │ │ │ ├── frame_047.txt │ │ │ ├── frame_048.txt │ │ │ ├── frame_049.txt │ │ │ ├── frame_050.txt │ │ │ ├── frame_051.txt │ │ │ ├── frame_052.txt │ │ │ ├── frame_053.txt │ │ │ ├── frame_054.txt │ │ │ ├── frame_055.txt │ │ │ ├── frame_056.txt │ │ │ ├── frame_057.txt │ │ │ ├── frame_058.txt │ │ │ ├── frame_059.txt │ │ │ ├── frame_060.txt │ │ │ ├── frame_061.txt │ │ │ ├── frame_062.txt │ │ │ ├── frame_063.txt │ │ │ ├── frame_064.txt │ │ │ ├── frame_065.txt │ │ │ ├── frame_066.txt │ │ │ ├── frame_067.txt │ │ │ ├── frame_068.txt │ │ │ ├── frame_069.txt │ │ │ ├── frame_070.txt │ │ │ ├── frame_071.txt │ │ │ ├── frame_072.txt │ │ │ ├── frame_073.txt │ │ │ ├── frame_074.txt │ │ │ ├── frame_075.txt │ │ │ ├── frame_076.txt │ │ │ ├── frame_077.txt │ │ │ ├── frame_078.txt │ │ │ ├── frame_079.txt │ │ │ ├── frame_080.txt │ │ │ ├── frame_081.txt │ │ │ ├── frame_082.txt │ │ │ ├── frame_083.txt │ │ │ ├── frame_084.txt │ │ │ ├── frame_085.txt │ │ │ ├── frame_086.txt │ │ │ ├── frame_087.txt │ │ │ ├── frame_088.txt │ │ │ ├── frame_089.txt │ │ │ ├── frame_090.txt │ │ │ ├── frame_091.txt │ │ │ ├── frame_092.txt │ │ │ ├── frame_093.txt │ │ │ ├── frame_094.txt │ │ │ ├── frame_095.txt │ │ │ ├── frame_096.txt │ │ │ ├── frame_097.txt │ │ │ ├── frame_098.txt │ │ │ ├── frame_099.txt │ │ │ ├── frame_100.txt │ │ │ ├── frame_101.txt │ │ │ ├── frame_102.txt │ │ │ ├── frame_103.txt │ │ │ ├── frame_104.txt │ │ │ ├── frame_105.txt │ │ │ ├── frame_106.txt │ │ │ ├── frame_107.txt │ │ │ ├── frame_108.txt │ │ │ ├── frame_109.txt │ │ │ ├── frame_110.txt │ │ │ ├── frame_111.txt │ │ │ ├── frame_112.txt │ │ │ ├── frame_113.txt │ │ │ ├── frame_114.txt │ │ │ ├── frame_115.txt │ │ │ ├── frame_116.txt │ │ │ ├── frame_117.txt │ │ │ ├── frame_118.txt │ │ │ ├── frame_119.txt │ │ │ ├── frame_120.txt │ │ │ ├── frame_121.txt │ │ │ ├── frame_122.txt │ │ │ ├── frame_123.txt │ │ │ ├── frame_124.txt │ │ │ ├── frame_125.txt │ │ │ ├── frame_126.txt │ │ │ ├── frame_127.txt │ │ │ ├── frame_128.txt │ │ │ ├── frame_129.txt │ │ │ ├── frame_130.txt │ │ │ ├── frame_131.txt │ │ │ ├── frame_132.txt │ │ │ ├── frame_133.txt │ │ │ ├── frame_134.txt │ │ │ ├── frame_135.txt │ │ │ ├── frame_136.txt │ │ │ ├── frame_137.txt │ │ │ ├── frame_138.txt │ │ │ ├── frame_139.txt │ │ │ ├── frame_140.txt │ │ │ ├── frame_141.txt │ │ │ ├── frame_142.txt │ │ │ ├── frame_143.txt │ │ │ ├── frame_144.txt │ │ │ ├── frame_145.txt │ │ │ ├── frame_146.txt │ │ │ ├── frame_147.txt │ │ │ ├── frame_148.txt │ │ │ ├── frame_149.txt │ │ │ ├── frame_150.txt │ │ │ ├── frame_151.txt │ │ │ ├── frame_152.txt │ │ │ ├── frame_153.txt │ │ │ ├── frame_154.txt │ │ │ ├── frame_155.txt │ │ │ ├── frame_156.txt │ │ │ ├── frame_157.txt │ │ │ ├── frame_158.txt │ │ │ ├── frame_159.txt │ │ │ ├── frame_160.txt │ │ │ ├── frame_161.txt │ │ │ ├── frame_162.txt │ │ │ ├── frame_163.txt │ │ │ ├── frame_164.txt │ │ │ ├── frame_165.txt │ │ │ ├── frame_166.txt │ │ │ ├── frame_167.txt │ │ │ ├── frame_168.txt │ │ │ ├── frame_169.txt │ │ │ ├── frame_170.txt │ │ │ ├── frame_171.txt │ │ │ ├── frame_172.txt │ │ │ ├── frame_173.txt │ │ │ ├── frame_174.txt │ │ │ ├── frame_175.txt │ │ │ ├── frame_176.txt │ │ │ ├── frame_177.txt │ │ │ ├── frame_178.txt │ │ │ ├── frame_179.txt │ │ │ ├── frame_180.txt │ │ │ ├── frame_181.txt │ │ │ ├── frame_182.txt │ │ │ ├── frame_183.txt │ │ │ ├── frame_184.txt │ │ │ ├── frame_185.txt │ │ │ ├── frame_186.txt │ │ │ ├── frame_187.txt │ │ │ ├── frame_188.txt │ │ │ ├── frame_189.txt │ │ │ ├── frame_190.txt │ │ │ ├── frame_191.txt │ │ │ ├── frame_192.txt │ │ │ ├── frame_193.txt │ │ │ ├── frame_194.txt │ │ │ ├── frame_195.txt │ │ │ ├── frame_196.txt │ │ │ ├── frame_197.txt │ │ │ ├── frame_198.txt │ │ │ ├── frame_199.txt │ │ │ ├── frame_200.txt │ │ │ ├── frame_201.txt │ │ │ ├── frame_202.txt │ │ │ ├── frame_203.txt │ │ │ ├── frame_204.txt │ │ │ ├── frame_205.txt │ │ │ ├── frame_206.txt │ │ │ ├── frame_207.txt │ │ │ ├── frame_208.txt │ │ │ ├── frame_209.txt │ │ │ ├── frame_210.txt │ │ │ ├── frame_211.txt │ │ │ ├── frame_212.txt │ │ │ ├── frame_213.txt │ │ │ ├── frame_214.txt │ │ │ ├── frame_215.txt │ │ │ ├── frame_216.txt │ │ │ ├── frame_217.txt │ │ │ ├── frame_218.txt │ │ │ ├── frame_219.txt │ │ │ ├── frame_220.txt │ │ │ ├── frame_221.txt │ │ │ ├── frame_222.txt │ │ │ ├── frame_223.txt │ │ │ ├── frame_224.txt │ │ │ ├── frame_225.txt │ │ │ ├── frame_226.txt │ │ │ ├── frame_227.txt │ │ │ ├── frame_228.txt │ │ │ ├── frame_229.txt │ │ │ ├── frame_230.txt │ │ │ ├── frame_231.txt │ │ │ ├── frame_232.txt │ │ │ ├── frame_233.txt │ │ │ ├── frame_234.txt │ │ │ └── frame_235.txt │ │ └── main.zig │ ├── gtk.zig │ ├── main.zig │ ├── mdgen │ │ ├── ghostty_1_footer.md │ │ ├── ghostty_1_header.md │ │ ├── ghostty_5_footer.md │ │ ├── ghostty_5_header.md │ │ ├── main_ghostty_1.zig │ │ ├── main_ghostty_5.zig │ │ └── mdgen.zig │ ├── webgen │ │ ├── main_actions.zig │ │ ├── main_commands.zig │ │ └── main_config.zig │ ├── zig.zig │ └── zsh_completions.zig ├── build_config.zig ├── cli.zig ├── cli │ ├── README.md │ ├── action.zig │ ├── args.zig │ ├── boo.zig │ ├── crash_report.zig │ ├── diagnostics.zig │ ├── edit_config.zig │ ├── ghostty.zig │ ├── help.zig │ ├── list_actions.zig │ ├── list_colors.zig │ ├── list_fonts.zig │ ├── list_keybinds.zig │ ├── list_themes.zig │ ├── lorem_ipsum.txt │ ├── show_config.zig │ ├── show_face.zig │ ├── ssh-cache │ │ ├── DiskCache.zig │ │ └── Entry.zig │ ├── ssh_cache.zig │ ├── tui.zig │ ├── validate_config.zig │ └── version.zig ├── config.zig ├── config │ ├── CApi.zig │ ├── Config.zig │ ├── ErrorList.zig │ ├── RepeatableStringMap.zig │ ├── Wasm.zig │ ├── c_get.zig │ ├── command.zig │ ├── conditional.zig │ ├── config-template │ ├── edit.zig │ ├── formatter.zig │ ├── io.zig │ ├── key.zig │ ├── path.zig │ ├── string.zig │ ├── sublime_syntax.zig │ ├── testdata │ │ ├── theme_dark │ │ ├── theme_light │ │ └── theme_simple │ ├── theme.zig │ ├── url.zig │ └── vim.zig ├── crash │ ├── dir.zig │ ├── main.zig │ ├── minidump.zig │ ├── minidump │ │ ├── external.zig │ │ ├── reader.zig │ │ ├── stream.zig │ │ └── stream_threadlist.zig │ ├── sentry.zig │ ├── sentry_envelope.zig │ └── testdata │ │ └── macos.dmp ├── datastruct │ ├── array_list_collection.zig │ ├── blocking_queue.zig │ ├── cache_table.zig │ ├── circ_buf.zig │ ├── intrusive_linked_list.zig │ ├── lru.zig │ ├── main.zig │ └── segmented_pool.zig ├── fastmem.zig ├── file_type.zig ├── font │ ├── Atlas.zig │ ├── CodepointMap.zig │ ├── CodepointResolver.zig │ ├── Collection.zig │ ├── DeferredFace.zig │ ├── Glyph.zig │ ├── Metrics.zig │ ├── SharedGrid.zig │ ├── SharedGridSet.zig │ ├── discovery.zig │ ├── embedded.zig │ ├── face.zig │ ├── face │ │ ├── coretext.zig │ │ ├── freetype.zig │ │ └── web_canvas.zig │ ├── library.zig │ ├── main.zig │ ├── nerd_font_attributes.zig │ ├── nerd_font_codegen.py │ ├── opentype.zig │ ├── opentype │ │ ├── head.zig │ │ ├── hhea.zig │ │ ├── os2.zig │ │ ├── post.zig │ │ ├── sfnt.zig │ │ └── svg.zig │ ├── res │ │ ├── CodeNewRoman-Regular.otf │ │ ├── CozetteVector.ttf │ │ ├── GeistMono-Regular.ttf │ │ ├── Inconsolata-Regular.ttf │ │ ├── JetBrainsMonoNerdFont-Bold.ttf │ │ ├── JetBrainsMonoNerdFont-BoldItalic.ttf │ │ ├── JetBrainsMonoNerdFont-Italic.ttf │ │ ├── JetBrainsMonoNerdFont-Regular.ttf │ │ ├── JetBrainsMonoNoNF-Regular.ttf │ │ ├── JuliaMono-Regular.ttf │ │ ├── KawkabMono-Regular.ttf │ │ ├── Lilex-VF.ttf │ │ ├── MIT.txt │ │ ├── MonaspaceNeon-Regular.otf │ │ ├── NotoColorEmoji.ttf │ │ ├── NotoEmoji-Regular.ttf │ │ ├── OFL.txt │ │ ├── README.md │ │ └── TerminusTTF-Regular.ttf │ ├── shape.zig │ ├── shaper │ │ ├── Cache.zig │ │ ├── coretext.zig │ │ ├── feature.zig │ │ ├── harfbuzz.zig │ │ ├── noop.zig │ │ ├── run.zig │ │ ├── testdata │ │ │ └── arabic.txt │ │ └── web_canvas.zig │ ├── sprite.zig │ └── sprite │ │ ├── Face.zig │ │ ├── canvas.zig │ │ ├── draw │ │ ├── README.md │ │ ├── block.zig │ │ ├── box.zig │ │ ├── braille.zig │ │ ├── branch.zig │ │ ├── common.zig │ │ ├── geometric_shapes.zig │ │ ├── octants.txt │ │ ├── powerline.zig │ │ ├── special.zig │ │ ├── symbols_for_legacy_computing.zig │ │ └── symbols_for_legacy_computing_supplement.zig │ │ └── testdata │ │ ├── U+1CC00...U+1CCFF-11x21+2.png │ │ ├── U+1CC00...U+1CCFF-12x24+3.png │ │ ├── U+1CC00...U+1CCFF-18x36+4.png │ │ ├── U+1CC00...U+1CCFF-9x17+1.png │ │ ├── U+1CD00...U+1CDFF-11x21+2.png │ │ ├── U+1CD00...U+1CDFF-12x24+3.png │ │ ├── U+1CD00...U+1CDFF-18x36+4.png │ │ ├── U+1CD00...U+1CDFF-9x17+1.png │ │ ├── U+1CE00...U+1CEFF-11x21+2.png │ │ ├── U+1CE00...U+1CEFF-12x24+3.png │ │ ├── U+1CE00...U+1CEFF-18x36+4.png │ │ ├── U+1CE00...U+1CEFF-9x17+1.png │ │ ├── U+1FB00...U+1FBFF-11x21+2.png │ │ ├── U+1FB00...U+1FBFF-12x24+3.png │ │ ├── U+1FB00...U+1FBFF-18x36+4.png │ │ ├── U+1FB00...U+1FBFF-9x17+1.png │ │ ├── U+2500...U+25FF-11x21+2.png │ │ ├── U+2500...U+25FF-12x24+3.png │ │ ├── U+2500...U+25FF-18x36+4.png │ │ ├── U+2500...U+25FF-9x17+1.png │ │ ├── U+2800...U+28FF-11x21+2.png │ │ ├── U+2800...U+28FF-12x24+3.png │ │ ├── U+2800...U+28FF-18x36+4.png │ │ ├── U+2800...U+28FF-9x17+1.png │ │ ├── U+E000...U+E0FF-11x21+2.png │ │ ├── U+E000...U+E0FF-12x24+3.png │ │ ├── U+E000...U+E0FF-18x36+4.png │ │ ├── U+E000...U+E0FF-9x17+1.png │ │ ├── U+F500...U+F5FF-11x21+2.png │ │ ├── U+F500...U+F5FF-12x24+3.png │ │ ├── U+F500...U+F5FF-18x36+4.png │ │ ├── U+F500...U+F5FF-9x17+1.png │ │ ├── U+F600...U+F6FF-11x21+2.png │ │ ├── U+F600...U+F6FF-12x24+3.png │ │ ├── U+F600...U+F6FF-18x36+4.png │ │ └── U+F600...U+F6FF-9x17+1.png ├── global.zig ├── helpgen.zig ├── input.zig ├── input │ ├── Binding.zig │ ├── KeyEncoder.zig │ ├── KeymapDarwin.zig │ ├── KeymapNoop.zig │ ├── Link.zig │ ├── command.zig │ ├── function_keys.zig │ ├── helpgen_actions.zig │ ├── key.zig │ ├── keyboard.zig │ ├── keycodes.zig │ ├── kitty.zig │ └── mouse.zig ├── inspector │ ├── Inspector.zig │ ├── cell.zig │ ├── cursor.zig │ ├── key.zig │ ├── main.zig │ ├── page.zig │ ├── termio.zig │ └── units.zig ├── main.zig ├── main_bench.zig ├── main_c.zig ├── main_gen.zig ├── main_ghostty.zig ├── main_wasm.zig ├── math.zig ├── os │ ├── TempDir.zig │ ├── args.zig │ ├── cf_release_thread.zig │ ├── cgroup.zig │ ├── dbus.zig │ ├── desktop.zig │ ├── env.zig │ ├── file.zig │ ├── flatpak.zig │ ├── homedir.zig │ ├── hostname.zig │ ├── i18n.zig │ ├── kernel_info.zig │ ├── locale.zig │ ├── macos.zig │ ├── main.zig │ ├── mouse.zig │ ├── open.zig │ ├── passwd.zig │ ├── pipe.zig │ ├── resourcesdir.zig │ ├── shell.zig │ ├── systemd.zig │ ├── wasm.zig │ ├── wasm │ │ ├── log.zig │ │ └── target.zig │ ├── windows.zig │ └── xdg.zig ├── pty.zig ├── quirks.zig ├── renderer.zig ├── renderer │ ├── Metal.zig │ ├── OpenGL.zig │ ├── Options.zig │ ├── State.zig │ ├── Thread.zig │ ├── WebGL.zig │ ├── cell.zig │ ├── cursor.zig │ ├── generic.zig │ ├── image.zig │ ├── link.zig │ ├── message.zig │ ├── metal │ │ ├── Frame.zig │ │ ├── IOSurfaceLayer.zig │ │ ├── Pipeline.zig │ │ ├── RenderPass.zig │ │ ├── Target.zig │ │ ├── Texture.zig │ │ ├── api.zig │ │ ├── buffer.zig │ │ └── shaders.zig │ ├── opengl │ │ ├── Frame.zig │ │ ├── Pipeline.zig │ │ ├── RenderPass.zig │ │ ├── Target.zig │ │ ├── Texture.zig │ │ ├── buffer.zig │ │ └── shaders.zig │ ├── shaders │ │ ├── glsl │ │ │ ├── bg_color.f.glsl │ │ │ ├── bg_image.f.glsl │ │ │ ├── bg_image.v.glsl │ │ │ ├── cell_bg.f.glsl │ │ │ ├── cell_text.f.glsl │ │ │ ├── cell_text.v.glsl │ │ │ ├── common.glsl │ │ │ ├── full_screen.v.glsl │ │ │ ├── image.f.glsl │ │ │ └── image.v.glsl │ │ ├── shaders.metal │ │ ├── shadertoy_prefix.glsl │ │ ├── test_shadertoy_crt.glsl │ │ └── test_shadertoy_invalid.glsl │ ├── shadertoy.zig │ └── size.zig ├── shell-integration │ ├── README.md │ ├── bash │ │ ├── bash-preexec.sh │ │ └── ghostty.bash │ ├── elvish │ │ └── lib │ │ │ └── ghostty-integration.elv │ ├── fish │ │ └── vendor_conf.d │ │ │ └── ghostty-shell-integration.fish │ └── zsh │ │ ├── .zshenv │ │ └── ghostty-integration ├── simd │ ├── base64.cpp │ ├── base64.zig │ ├── codepoint_width.cpp │ ├── codepoint_width.zig │ ├── index_of.cpp │ ├── index_of.h │ ├── index_of.zig │ ├── main.zig │ ├── vt.cpp │ ├── vt.h │ └── vt.zig ├── stb │ ├── main.zig │ ├── stb.c │ ├── stb_image.h │ └── stb_image_resize.h ├── surface_mouse.zig ├── synthetic │ ├── Bytes.zig │ ├── Generator.zig │ ├── Osc.zig │ ├── Utf8.zig │ ├── cli.zig │ ├── cli │ │ ├── Ascii.zig │ │ ├── Osc.zig │ │ └── Utf8.zig │ └── main.zig ├── terminal │ ├── PageList.zig │ ├── Parser.zig │ ├── Screen.zig │ ├── Selection.zig │ ├── StringMap.zig │ ├── Tabstops.zig │ ├── Terminal.zig │ ├── UTF8Decoder.zig │ ├── ansi.zig │ ├── apc.zig │ ├── bitmap_allocator.zig │ ├── charsets.zig │ ├── color.zig │ ├── csi.zig │ ├── dcs.zig │ ├── device_status.zig │ ├── hash_map.zig │ ├── hyperlink.zig │ ├── kitty.zig │ ├── kitty │ │ ├── color.zig │ │ ├── graphics.zig │ │ ├── graphics_command.zig │ │ ├── graphics_exec.zig │ │ ├── graphics_image.zig │ │ ├── graphics_render.zig │ │ ├── graphics_storage.zig │ │ ├── graphics_unicode.zig │ │ ├── key.zig │ │ └── testdata │ │ │ ├── dog.png │ │ │ ├── image-png-none-50x76-2147483647-raw.data │ │ │ ├── image-rgb-none-20x15-2147483647-raw.data │ │ │ └── image-rgb-zlib_deflate-128x96-2147483647-raw.data │ ├── main.zig │ ├── modes.zig │ ├── mouse_shape.zig │ ├── osc.zig │ ├── page.zig │ ├── parse_table.zig │ ├── point.zig │ ├── ref_counted_set.zig │ ├── res │ │ ├── glitch.txt │ │ └── rgb.txt │ ├── sanitize.zig │ ├── search.zig │ ├── sgr.zig │ ├── size.zig │ ├── stream.zig │ ├── style.zig │ ├── tmux.zig │ └── x11_color.zig ├── terminfo │ ├── Source.zig │ ├── ghostty.zig │ └── main.zig ├── termio.zig ├── termio │ ├── Exec.zig │ ├── Options.zig │ ├── Termio.zig │ ├── Thread.zig │ ├── backend.zig │ ├── mailbox.zig │ ├── message.zig │ ├── shell_integration.zig │ └── stream_handler.zig └── unicode │ ├── grapheme.zig │ ├── lut.zig │ ├── main.zig │ └── props.zig ├── test ├── Dockerfile ├── README.md ├── cases │ ├── vttest │ │ ├── 1_1.sh │ │ ├── 1_1.sh.alacritty.png │ │ ├── 1_1.sh.ghostty.png │ │ ├── 1_1.sh.xterm.png │ │ ├── 1_2.sh │ │ ├── 1_2.sh.alacritty.png │ │ ├── 1_2.sh.ghostty.png │ │ ├── 1_2.sh.xterm.png │ │ ├── 1_3.sh │ │ ├── 1_3.sh.alacritty.png │ │ ├── 1_3.sh.ghostty.png │ │ ├── 1_3.sh.xterm.png │ │ ├── 1_4.sh │ │ ├── 1_4.sh.alacritty.png │ │ ├── 1_4.sh.ghostty.png │ │ ├── 1_4.sh.xterm.png │ │ ├── 1_5.sh │ │ ├── 1_5.sh.alacritty.png │ │ ├── 1_5.sh.ghostty.png │ │ ├── 1_5.sh.xterm.png │ │ ├── 1_6.sh │ │ ├── 1_6.sh.alacritty.png │ │ ├── 1_6.sh.ghostty.png │ │ ├── 1_6.sh.xterm.png │ │ ├── launch.sh │ │ ├── launch.sh.alacritty.png │ │ ├── launch.sh.ghostty.png │ │ └── launch.sh.xterm.png │ ├── wraptest.sh │ ├── wraptest.sh.alacritty.png │ ├── wraptest.sh.ghostty.png │ └── wraptest.sh.xterm.png ├── run-all.sh ├── run-host.sh └── run.sh ├── typos.toml └── vendor ├── glad ├── include │ ├── KHR │ │ └── khrplatform.h │ └── glad │ │ └── gl.h └── src │ └── gl.c └── nerd-fonts ├── LICENSE ├── README.md └── font-patcher.py /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{sh,bash}] 4 | indent_size = 2 5 | indent_style = space 6 | 7 | [bash-preexec.sh] 8 | indent_size = 4 9 | indent_style = space 10 | 11 | [*.swift] 12 | indent_size = 4 13 | indent_style = space 14 | trim_trailing_whitespace = true 15 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | # If we are a computer with nix-shell available, then use that to setup 2 | # the build environment with exactly what we need. 3 | if has nix; then 4 | watch_file nix/{devShell,package,wraptest}.nix 5 | use flake 6 | fi 7 | 8 | source_env_if_exists .envrc.local 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | build.zig.zon.nix linguist-generated=true 2 | build.zig.zon.txt linguist-generated=true 3 | build.zig.zon.json linguist-generated=true 4 | vendor/** linguist-vendored 5 | website/** linguist-documentation 6 | pkg/breakpad/vendor/** linguist-vendored 7 | pkg/cimgui/vendor/** linguist-vendored 8 | pkg/glfw/wayland-headers/** linguist-vendored 9 | pkg/libintl/config.h linguist-generated=true 10 | pkg/libintl/libintl.h linguist-generated=true 11 | pkg/simdutf/vendor/** linguist-vendored 12 | src/terminal/res/** linguist-vendored 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Features, Bug Reports, Questions 4 | url: https://github.com/ghostty-org/ghostty/discussions/new/choose 5 | about: Our preferred starting point if you have any questions or suggestions about configuration, features or behavior. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/preapproved.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Pre-Discussed and Approved Topics 3 | about: |- 4 | Only for topics already discussed and approved in the GitHub Discussions section. 5 | --- 6 | 7 | **DO NOT OPEN A NEW ISSUE. PLEASE USE THE DISCUSSIONS SECTION.** 8 | 9 | **I DIDN'T READ THE ABOVE LINE. PLEASE CLOSE THIS ISSUE.** 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | # Check for updates to GitHub Actions every weekday 8 | interval: "daily" 9 | -------------------------------------------------------------------------------- /.github/pinact.yml: -------------------------------------------------------------------------------- 1 | version: 3 2 | ignore_actions: 3 | - name: "DeterminateSystems/nix-installer-action" 4 | ref: "main" 5 | -------------------------------------------------------------------------------- /.github/scripts/check-translations.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | old_pot=$(mktemp) 4 | cp po/com.mitchellh.ghostty.pot "$old_pot" 5 | zig build update-translations 6 | 7 | # Compare previous POT to current POT 8 | msgcmp "$old_pot" po/com.mitchellh.ghostty.pot --use-untranslated 9 | 10 | # Compare all other POs to current POT 11 | for f in po/*.po; do 12 | # Ignore untranslated entries 13 | msgcmp --use-untranslated "$f" po/com.mitchellh.ghostty.pot; 14 | done 15 | -------------------------------------------------------------------------------- /.github/workflows/clean-artifacts.yml: -------------------------------------------------------------------------------- 1 | name: Clean Artifacts 2 | on: 3 | schedule: 4 | # Once a day 5 | - cron: "0 0 * * *" 6 | workflow_dispatch: 7 | jobs: 8 | remove-old-artifacts: 9 | runs-on: ubuntu-latest 10 | timeout-minutes: 10 11 | steps: 12 | - name: Remove old artifacts 13 | uses: c-hive/gha-remove-artifacts@44fc7acaf1b3d0987da0e8d4707a989d80e9554b # v1.4.0 14 | with: 15 | age: "1 week" 16 | skip-tags: true 17 | skip-recent: 5 18 | -------------------------------------------------------------------------------- /.github/workflows/milestone.yml: -------------------------------------------------------------------------------- 1 | # Description: 2 | # - Add milestone to a merged PR automatically 3 | # - Add milestone to a closed issue that has a merged PR fix (if any) 4 | 5 | name: Milestone Action 6 | on: 7 | issues: 8 | types: [closed] 9 | pull_request_target: 10 | types: [closed] 11 | 12 | jobs: 13 | update-milestone: 14 | runs-on: namespace-profile-ghostty-sm 15 | name: Milestone Update 16 | steps: 17 | - name: Set Milestone for PR 18 | uses: hustcer/milestone-action@09bdc6fda0f43a4df28cda5815cc47df74cfdba7 # v2.8 19 | if: github.event.pull_request.merged == true 20 | with: 21 | action: bind-pr # `bind-pr` is the default action 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | 25 | # Bind milestone to closed issue that has a merged PR fix 26 | - name: Set Milestone for Issue 27 | uses: hustcer/milestone-action@09bdc6fda0f43a4df28cda5815cc47df74cfdba7 # v2.8 28 | if: github.event.issue.state == 'closed' 29 | with: 30 | action: bind-issue 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .*.swp 3 | .swp 4 | *.log 5 | .DS_Store 6 | .vscode/ 7 | .direnv/ 8 | .envrc.local 9 | .flatpak-builder/ 10 | zig-cache/ 11 | .zig-cache/ 12 | zig-out/ 13 | /result* 14 | example/*.wasm 15 | test/ghostty 16 | test/cases/**/*.actual.png 17 | flatpak/builddir/ 18 | flatpak/repo/ 19 | 20 | glad.zip 21 | /Box_test.ppm 22 | /Box_test_diff.ppm 23 | /ghostty.qcow2 24 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/.gitmodules -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Mitchell Hashimoto <m@mitchellh.com> <mitchell.hashimoto@gmail.com> 2 | Gregory Anders <greg@gpanders.com> <8965202+gpanders@users.noreply.github.com> 3 | Jeffrey C. Ollie <jeff@ocjtech.us> <jcollie@dmacc.edu> 4 | Kevin Hovsäter <kevin@hovsater.com> <kevin@hovsater.com> 5 | Nathan Fisher <nfisher.sr@gmail.com> <jeang3nie@hitchhiker-linux.org> 6 | Paul Berg <naydex.mc@gmail.com> <9824244+Pangoraw@users.noreply.github.com> 7 | RGBCube <git@rgbcu.be> <RGBCube@users.noreply.github.com> 8 | RGBCube <git@rgbcu.be> <78925721+RGBCube@users.noreply.github.com> 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Docs: https://prettier.io/docs/en/ignore.html 2 | flake.lock 3 | vendor/ 4 | **/*.html 5 | zig-cache/ 6 | zig-out/ 7 | 8 | # jujutsu 9 | .jj/ 10 | 11 | # macos is managed by XCode GUI 12 | macos/ 13 | 14 | # produced by Icon Composer on macOS 15 | images/Ghostty.icon/icon.json 16 | 17 | # website dev run 18 | website/.next 19 | 20 | # shaders 21 | *.frag 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Mitchell Hashimoto, Ghostty contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | init: 2 | @echo You probably want to run "zig build" instead. 3 | .PHONY: init 4 | 5 | # glad updates the GLAD loader. To use this, place the generated glad.zip 6 | # in this directory next to the Makefile, remove vendor/glad and run this target. 7 | # 8 | # Generator: https://gen.glad.sh/ 9 | glad: vendor/glad 10 | .PHONY: glad 11 | 12 | vendor/glad: vendor/glad/include/glad/gl.h vendor/glad/include/glad/glad.h 13 | 14 | vendor/glad/include/glad/gl.h: glad.zip 15 | rm -rf vendor/glad 16 | mkdir -p vendor/glad 17 | unzip glad.zip -dvendor/glad 18 | find vendor/glad -type f -exec touch '{}' + 19 | 20 | vendor/glad/include/glad/glad.h: vendor/glad/include/glad/gl.h 21 | @echo "#include <glad/gl.h>" > $@ 22 | 23 | clean: 24 | rm -rf \ 25 | zig-out zig-cache \ 26 | macos/build \ 27 | macos/GhosttyKit.xcframework 28 | .PHONY: clean 29 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | (import ( 2 | let 3 | lock = builtins.fromJSON (builtins.readFile ./flake.lock); 4 | nodeName = lock.nodes.root.inputs.flake-compat; 5 | in 6 | fetchTarball { 7 | url = 8 | lock.nodes.${nodeName}.locked.url 9 | or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.${nodeName}.locked.rev}.tar.gz"; 10 | sha256 = lock.nodes.${nodeName}.locked.narHash; 11 | } 12 | ) {src = ./.;}) 13 | .defaultNix 14 | -------------------------------------------------------------------------------- /dist/linux/app.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Name=@NAME@ 4 | Type=Application 5 | Comment=A terminal emulator 6 | TryExec=@GHOSTTY@ 7 | Exec=@GHOSTTY@ --launched-from=desktop 8 | Icon=com.mitchellh.ghostty 9 | Categories=System;TerminalEmulator; 10 | Keywords=terminal;tty;pty; 11 | StartupNotify=true 12 | StartupWMClass=@APPID@ 13 | Terminal=false 14 | Actions=new-window; 15 | X-GNOME-UsesNotifications=true 16 | X-TerminalArgExec=-e 17 | X-TerminalArgTitle=--title= 18 | X-TerminalArgAppId=--class= 19 | X-TerminalArgDir=--working-directory= 20 | X-TerminalArgHold=--wait-after-command 21 | DBusActivatable=true 22 | X-KDE-Shortcuts=Ctrl+Alt+T 23 | 24 | [Desktop Action new-window] 25 | Name=New Window 26 | Exec=@GHOSTTY@ --launched-from=desktop 27 | -------------------------------------------------------------------------------- /dist/linux/dbus.service.flatpak.in: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=@APPID@ 3 | Exec=@GHOSTTY@ --launched-from=dbus 4 | -------------------------------------------------------------------------------- /dist/linux/dbus.service.in: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=@APPID@ 3 | SystemdService=@APPID@.service 4 | Exec=@GHOSTTY@ --launched-from=dbus 5 | -------------------------------------------------------------------------------- /dist/linux/ghostty_dolphin.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Service 3 | ServiceTypes=KonqPopupMenu/Plugin 4 | MimeType=inode/directory 5 | Actions=RunGhosttyDir 6 | 7 | [Desktop Action RunGhosttyDir] 8 | Name=Open Ghostty Here 9 | Icon=com.mitchellh.ghostty 10 | Exec=ghostty --working-directory=%F --gtk-single-instance=false 11 | 12 | -------------------------------------------------------------------------------- /dist/linux/systemd.service.in: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=@NAME@ 3 | After=graphical-session.target 4 | After=dbus.socket 5 | Requires=dbus.socket 6 | 7 | [Service] 8 | Type=notify-reload 9 | ReloadSignal=SIGUSR2 10 | BusName=@APPID@ 11 | ExecStart=@GHOSTTY@ --launched-from=systemd 12 | 13 | [Install] 14 | WantedBy=graphical-session.target 15 | -------------------------------------------------------------------------------- /dist/windows/ghostty.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/dist/windows/ghostty.ico -------------------------------------------------------------------------------- /dist/windows/ghostty.manifest: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 2 | <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> 3 | <asmv3:application> 4 | <asmv3:windowsSettings> 5 | <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware> 6 | <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness> 7 | </asmv3:windowsSettings> 8 | </asmv3:application> 9 | <dependency> 10 | <dependentAssembly> 11 | <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> 12 | </dependentAssembly> 13 | </dependency> 14 | </assembly> 15 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | .parcel-cache/ 2 | dist/ 3 | node_modules/ 4 | example.wasm* 5 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | <!doctype html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="utf-8"/> 5 | <title>Ghostty Example</title> 6 | <script type="module" src="app.ts"></script> 7 | </head> 8 | <body> 9 | <p>Open your console, we are just debugging here.</p> 10 | <p>The current <b>grayscale</b> font atlas is rendered below.</p> 11 | <div><div id="atlas-canvas" style="display: inline-block; border: 1px solid green;"></div></div> 12 | <p>The current <b>color</b> font atlas is rendered below.</p> 13 | <div><div id="atlas-color-canvas" style="display: inline-block; border: 1px solid blue;"></div></div> 14 | </body> 15 | </html> 16 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ghostty example", 3 | "version": "0.1.0", 4 | "description": "Example showing ghostty and wasm.", 5 | "source": "index.html", 6 | "browserslist": "> 0.5%, last 2 versions, not dead", 7 | "scripts": { 8 | "start": "parcel", 9 | "build": "parcel build", 10 | "check": "tsc --noEmit" 11 | }, 12 | "author": "Mitchell Hashimoto", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@parcel/transformer-inline-string": "^2.8.0", 16 | "parcel": "^2.8.0", 17 | "typescript": "^4.9.3" 18 | }, 19 | "dependencies": { 20 | "zig-js": "file:../vendor/zig-js/js" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /flatpak/exceptions.json: -------------------------------------------------------------------------------- 1 | { 2 | "com.mitchellh.ghostty": ["finish-args-flatpak-spawn-access"] 3 | } 4 | -------------------------------------------------------------------------------- /images/Ghostty.icon/Assets/Ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/Ghostty.icon/Assets/Ghostty.png -------------------------------------------------------------------------------- /images/Ghostty.icon/Assets/Inner Bevel 6px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/Ghostty.icon/Assets/Inner Bevel 6px.png -------------------------------------------------------------------------------- /images/Ghostty.icon/Assets/Screen Effects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/Ghostty.icon/Assets/Screen Effects.png -------------------------------------------------------------------------------- /images/Ghostty.icon/Assets/Screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/Ghostty.icon/Assets/Screen.png -------------------------------------------------------------------------------- /images/Ghostty.icon/Assets/gloss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/Ghostty.icon/Assets/gloss.png -------------------------------------------------------------------------------- /images/icons/icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_1024.png -------------------------------------------------------------------------------- /images/icons/icon_1024@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_1024@2x.png -------------------------------------------------------------------------------- /images/icons/icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_128.png -------------------------------------------------------------------------------- /images/icons/icon_128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_128@2x.png -------------------------------------------------------------------------------- /images/icons/icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_16.png -------------------------------------------------------------------------------- /images/icons/icon_16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_16@2x.png -------------------------------------------------------------------------------- /images/icons/icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_256.png -------------------------------------------------------------------------------- /images/icons/icon_256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_256@2x.png -------------------------------------------------------------------------------- /images/icons/icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_32.png -------------------------------------------------------------------------------- /images/icons/icon_32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_32@2x.png -------------------------------------------------------------------------------- /images/icons/icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_512.png -------------------------------------------------------------------------------- /images/icons/icon_512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/images/icons/icon_512@2x.png -------------------------------------------------------------------------------- /include/module.modulemap: -------------------------------------------------------------------------------- 1 | // This makes Ghostty available to the XCode build for the macOS app. 2 | // We append "Kit" to it not to be cute, but because targets have to have 3 | // unique names and we use Ghostty for other things. 4 | module GhosttyKit { 5 | umbrella header "ghostty.h" 6 | export * 7 | } 8 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /*.xcframework 3 | build/ 4 | xcuserdata/ 5 | DerivedData/ 6 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/BlueprintImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-1024px.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/BlueprintImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Alternate Icons/BlueprintImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/ChalkboardImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-1024px.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/ChalkboardImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Alternate Icons/ChalkboardImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/GlassImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-1024px.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/GlassImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Alternate Icons/GlassImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/HolographicImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-1024px.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/HolographicImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Alternate Icons/HolographicImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/MicrochipImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-1024px.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/MicrochipImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Alternate Icons/MicrochipImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/PaperImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-1024px.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/PaperImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Alternate Icons/PaperImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/RetroImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-1024px.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/RetroImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Alternate Icons/RetroImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/XrayImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-1024px.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Alternate Icons/XrayImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Alternate Icons/XrayImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/AppIconImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "macOS-AppIcon-256px-128pt@2x.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "macOS-AppIcon-512px.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "macOS-AppIcon-1024px.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/AppIconImage.imageset/macOS-AppIcon-1024px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/AppIconImage.imageset/macOS-AppIcon-1024px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/AppIconImage.imageset/macOS-AppIcon-256px-128pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/AppIconImage.imageset/macOS-AppIcon-256px-128pt@2x.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/AppIconImage.imageset/macOS-AppIcon-512px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/AppIconImage.imageset/macOS-AppIcon-512px.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconBaseAluminum.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "base.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconBaseAluminum.imageset/base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconBaseAluminum.imageset/base.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "beige.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/beige.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/beige.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "chrome.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/chrome.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "plastic.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/plastic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/plastic.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconCRT.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "crt-effect.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconCRT.imageset/crt-effect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconCRT.imageset/crt-effect.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconGhost.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ghosty.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconGhost.imageset/ghosty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconGhost.imageset/ghosty.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconGloss.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "gloss.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconGloss.imageset/gloss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconGloss.imageset/gloss.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconScreen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "screen-dark.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconScreen.imageset/screen-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconScreen.imageset/screen-dark.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconScreenMask.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "screen-mask.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/Custom Icon/CustomIconScreenMask.imageset/screen-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/Custom Icon/CustomIconScreenMask.imageset/screen-mask.png -------------------------------------------------------------------------------- /macos/Assets.xcassets/ResetZoom.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ResetZoom.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Assets.xcassets/ResetZoom.imageset/ResetZoom.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/macos/Assets.xcassets/ResetZoom.imageset/ResetZoom.pdf -------------------------------------------------------------------------------- /macos/Ghostty.entitlements: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>com.apple.security.automation.apple-events</key> 6 | <true/> 7 | <key>com.apple.security.device.audio-input</key> 8 | <true/> 9 | <key>com.apple.security.device.camera</key> 10 | <true/> 11 | <key>com.apple.security.personal-information.addressbook</key> 12 | <true/> 13 | <key>com.apple.security.personal-information.calendars</key> 14 | <true/> 15 | <key>com.apple.security.personal-information.location</key> 16 | <true/> 17 | <key>com.apple.security.personal-information.photos-library</key> 18 | <true/> 19 | </dict> 20 | </plist> 21 | -------------------------------------------------------------------------------- /macos/Ghostty.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <Workspace 3 | version = "1.0"> 4 | <FileRef 5 | location = "self:"> 6 | </FileRef> 7 | </Workspace> 8 | -------------------------------------------------------------------------------- /macos/Ghostty.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>IDEDidComputeMac32BitWarning</key> 6 | <true/> 7 | </dict> 8 | </plist> 9 | -------------------------------------------------------------------------------- /macos/Ghostty.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "originHash" : "e721da7f9826abdffcb6185e886155efa2514bd6234475f1afa893e29eb258d6", 3 | "pins" : [ 4 | { 5 | "identity" : "sparkle", 6 | "kind" : "remoteSourceControl", 7 | "location" : "https://github.com/sparkle-project/Sparkle", 8 | "state" : { 9 | "revision" : "0ef1ee0220239b3776f433314515fd849025673f", 10 | "version" : "2.6.4" 11 | } 12 | } 13 | ], 14 | "version" : 3 15 | } 16 | -------------------------------------------------------------------------------- /macos/GhosttyDebug.entitlements: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>com.apple.security.automation.apple-events</key> 6 | <true/> 7 | <key>com.apple.security.cs.disable-library-validation</key> 8 | <true/> 9 | <key>com.apple.security.device.audio-input</key> 10 | <true/> 11 | <key>com.apple.security.device.camera</key> 12 | <true/> 13 | <key>com.apple.security.personal-information.addressbook</key> 14 | <true/> 15 | <key>com.apple.security.personal-information.calendars</key> 16 | <true/> 17 | <key>com.apple.security.personal-information.location</key> 18 | <true/> 19 | <key>com.apple.security.personal-information.photos-library</key> 20 | <true/> 21 | </dict> 22 | </plist> 23 | -------------------------------------------------------------------------------- /macos/GhosttyReleaseLocal.entitlements: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>com.apple.security.automation.apple-events</key> 6 | <true/> 7 | <key>com.apple.security.cs.disable-library-validation</key> 8 | <true/> 9 | <key>com.apple.security.device.audio-input</key> 10 | <true/> 11 | <key>com.apple.security.device.camera</key> 12 | <true/> 13 | <key>com.apple.security.personal-information.addressbook</key> 14 | <true/> 15 | <key>com.apple.security.personal-information.calendars</key> 16 | <true/> 17 | <key>com.apple.security.personal-information.location</key> 18 | <true/> 19 | <key>com.apple.security.personal-information.photos-library</key> 20 | <true/> 21 | </dict> 22 | </plist> 23 | -------------------------------------------------------------------------------- /macos/GhosttyTests/BenchmarkTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GhosttyTests.swift 3 | // GhosttyTests 4 | // 5 | // Created by Mitchell Hashimoto on 7/9/25. 6 | // 7 | 8 | import Testing 9 | import GhosttyKit 10 | 11 | extension Tag { 12 | @Tag static var benchmark: Self 13 | } 14 | 15 | /// The whole idea behind these benchmarks is that they're run by right-clicking 16 | /// in Xcode and using "Profile" to open them in instruments. They aren't meant to 17 | /// be run in general. 18 | /// 19 | /// When running them, set the `if:` to `true`. There's probably a better 20 | /// programmatic way to do this but I don't know it yet! 21 | @Suite( 22 | "Benchmarks", 23 | .enabled(if: false), 24 | .tags(.benchmark) 25 | ) 26 | struct BenchmarkTests { 27 | @Test func example() async throws { 28 | ghostty_benchmark_cli( 29 | "terminal-stream", 30 | "--data=/Users/mitchellh/Documents/ghostty/bug.osc.txt") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /macos/Sources/App/macOS/ghostty-bridging-header.h: -------------------------------------------------------------------------------- 1 | // C imports here are exposed to Swift. 2 | 3 | #import "VibrantLayer.h" 4 | -------------------------------------------------------------------------------- /macos/Sources/Features/About/AboutController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Cocoa 3 | import SwiftUI 4 | 5 | class AboutController: NSWindowController, NSWindowDelegate { 6 | static let shared: AboutController = AboutController() 7 | 8 | override var windowNibName: NSNib.Name? { "About" } 9 | 10 | override func windowDidLoad() { 11 | guard let window = window else { return } 12 | window.center() 13 | window.isMovableByWindowBackground = true 14 | window.contentView = NSHostingView(rootView: AboutView()) 15 | } 16 | 17 | // MARK: - Functions 18 | 19 | func show() { 20 | window?.makeKeyAndOrderFront(nil) 21 | } 22 | 23 | func hide() { 24 | window?.close() 25 | } 26 | 27 | //MARK: - First Responder 28 | 29 | @IBAction func close(_ sender: Any) { 30 | self.window?.performClose(sender) 31 | } 32 | 33 | @IBAction func closeWindow(_ sender: Any) { 34 | self.window?.performClose(sender) 35 | } 36 | 37 | // This is called when "escape" is pressed. 38 | @objc func cancel(_ sender: Any?) { 39 | close() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /macos/Sources/Features/App Intents/GhosttyIntentError.swift: -------------------------------------------------------------------------------- 1 | enum GhosttyIntentError: Error, CustomLocalizedStringResourceConvertible { 2 | case appUnavailable 3 | case surfaceNotFound 4 | case permissionDenied 5 | 6 | var localizedStringResource: LocalizedStringResource { 7 | switch self { 8 | case .appUnavailable: "The Ghostty app isn't properly initialized." 9 | case .surfaceNotFound: "The terminal no longer exists." 10 | case .permissionDenied: "Ghostty doesn't allow Shortcuts." 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconImage.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension View { 4 | /// Returns the ghostty icon to use for views. 5 | func ghosttyIconImage() -> Image { 6 | #if os(macOS) 7 | // If we have a specific icon set, then use that 8 | if let delegate = NSApplication.shared.delegate as? AppDelegate, 9 | let nsImage = delegate.appIcon { 10 | return Image(nsImage: nsImage) 11 | } 12 | 13 | // Grab the icon from the running application. This is the best way 14 | // I've found so far to get the proper icon for our current icon 15 | // tinting and so on with macOS Tahoe 16 | if let icon = NSRunningApplication.current.icon { 17 | return Image(nsImage: icon) 18 | } 19 | 20 | // Get our defined application icon image. 21 | if let nsImage = NSApp.applicationIconImage { 22 | return Image(nsImage: nsImage) 23 | } 24 | #endif 25 | 26 | // Fall back to a static representation 27 | return Image("AppIconImage") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import Cocoa 3 | 4 | // For testing. 5 | struct ColorizedGhosttyIconView: View { 6 | var body: some View { 7 | Image(nsImage: ColorizedGhosttyIcon( 8 | screenColors: [.purple, .blue], 9 | ghostColor: .yellow, 10 | frame: .aluminum 11 | ).makeImage()!) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /macos/Sources/Features/QuickTerminal/QuickTerminalScreen.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | enum QuickTerminalScreen { 4 | case main 5 | case mouse 6 | case menuBar 7 | 8 | init?(fromGhosttyConfig string: String) { 9 | switch (string) { 10 | case "main": 11 | self = .main 12 | 13 | case "mouse": 14 | self = .mouse 15 | 16 | case "macos-menu-bar": 17 | self = .menuBar 18 | 19 | default: 20 | return nil 21 | } 22 | } 23 | 24 | var screen: NSScreen? { 25 | switch (self) { 26 | case .main: 27 | return NSScreen.main 28 | 29 | case .mouse: 30 | let mouseLoc = NSEvent.mouseLocation 31 | return NSScreen.screens.first(where: { $0.frame.contains(mouseLoc) }) 32 | 33 | case .menuBar: 34 | return NSScreen.screens.first 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /macos/Sources/Features/QuickTerminal/QuickTerminalSpaceBehavior.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Cocoa 3 | 4 | enum QuickTerminalSpaceBehavior { 5 | case remain 6 | case move 7 | 8 | init?(fromGhosttyConfig string: String) { 9 | switch (string) { 10 | case "move": 11 | self = .move 12 | 13 | case "remain": 14 | self = .remain 15 | 16 | default: 17 | return nil 18 | } 19 | } 20 | 21 | var collectionBehavior: NSWindow.CollectionBehavior { 22 | let commonBehavior: [NSWindow.CollectionBehavior] = [ 23 | .ignoresCycle, 24 | .fullScreenAuxiliary 25 | ] 26 | 27 | switch (self) { 28 | case .move: 29 | // We want this to move the window to the active space. 30 | return NSWindow.CollectionBehavior([.canJoinAllSpaces] + commonBehavior) 31 | case .remain: 32 | // We want this to remain the window in the current space. 33 | return NSWindow.CollectionBehavior([.moveToActiveSpace] + commonBehavior) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /macos/Sources/Features/Settings/ConfigurationErrorsController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Cocoa 3 | import SwiftUI 4 | import Combine 5 | 6 | class ConfigurationErrorsController: NSWindowController, NSWindowDelegate, ConfigurationErrorsViewModel { 7 | /// Singleton for the errors view. 8 | static let sharedInstance = ConfigurationErrorsController() 9 | 10 | override var windowNibName: NSNib.Name? { "ConfigurationErrors" } 11 | 12 | /// The data model for this view. Update this directly and the associated view will be updated, too. 13 | @Published var errors: [String] = [] { 14 | didSet { 15 | if (errors.count == 0) { 16 | self.window?.performClose(nil) 17 | } 18 | } 19 | } 20 | 21 | //MARK: - NSWindowController 22 | 23 | override func windowWillLoad() { 24 | shouldCascadeWindows = false 25 | } 26 | 27 | override func windowDidLoad() { 28 | guard let window = window else { return } 29 | window.center() 30 | window.level = .popUpMenu 31 | window.contentView = NSHostingView(rootView: ConfigurationErrorsView(model: self)) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /macos/Sources/Features/Settings/SettingsView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct SettingsView: View { 4 | // We need access to our app delegate to know if we're quitting or not. 5 | @EnvironmentObject private var appDelegate: AppDelegate 6 | 7 | var body: some View { 8 | HStack { 9 | Image("AppIconImage") 10 | .resizable() 11 | .scaledToFit() 12 | .frame(width: 128, height: 128) 13 | 14 | VStack(alignment: .leading) { 15 | Text("Coming Soon. 🚧").font(.title) 16 | Text("You can't configure settings in the GUI yet. To modify settings, " + 17 | "edit the file at $HOME/.config/ghostty/config and restart Ghostty.") 18 | .multilineTextAlignment(.leading) 19 | .lineLimit(nil) 20 | } 21 | } 22 | .padding() 23 | .frame(minWidth: 500, maxWidth: 500, minHeight: 156, maxHeight: 156) 24 | } 25 | } 26 | 27 | struct SettingsView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | SettingsView() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /macos/Sources/Features/Terminal/ErrorView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct ErrorView: View { 4 | var body: some View { 5 | HStack { 6 | Image("AppIconImage") 7 | .resizable() 8 | .scaledToFit() 9 | .frame(width: 128, height: 128) 10 | 11 | VStack(alignment: .leading) { 12 | Text("Oh, no. 😭").font(.title) 13 | Text("Something went fatally wrong.\nCheck the logs and restart Ghostty.") 14 | } 15 | } 16 | .padding() 17 | } 18 | } 19 | 20 | struct ErrorView_Previews: PreviewProvider { 21 | static var previews: some View { 22 | ErrorView() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /macos/Sources/Ghostty/FullscreenMode+Extension.swift: -------------------------------------------------------------------------------- 1 | import GhosttyKit 2 | 3 | extension FullscreenMode { 4 | /// Initialize from a Ghostty fullscreen action. 5 | static func from(ghostty: ghostty_action_fullscreen_e) -> Self? { 6 | return switch ghostty { 7 | case GHOSTTY_FULLSCREEN_NATIVE: 8 | .native 9 | 10 | case GHOSTTY_FULLSCREEN_NON_NATIVE: 11 | .nonNative 12 | 13 | case GHOSTTY_FULLSCREEN_NON_NATIVE_VISIBLE_MENU: 14 | .nonNativeVisibleMenu 15 | 16 | case GHOSTTY_FULLSCREEN_NON_NATIVE_PADDED_NOTCH: 17 | .nonNativePaddedNotch 18 | 19 | default: 20 | nil 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /macos/Sources/Ghostty/Ghostty.Error.swift: -------------------------------------------------------------------------------- 1 | extension Ghostty { 2 | /// Possible errors from internal Ghostty calls. 3 | enum Error: Swift.Error, CustomLocalizedStringResourceConvertible { 4 | case apiFailed 5 | 6 | var localizedStringResource: LocalizedStringResource { 7 | switch self { 8 | case .apiFailed: return "libghostty API call failed" 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Sources/Ghostty/Ghostty.Event.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import GhosttyKit 3 | 4 | extension Ghostty { 5 | /// A comparable event. 6 | struct ComparableKeyEvent: Equatable { 7 | let keyCode: UInt16 8 | let flags: NSEvent.ModifierFlags 9 | 10 | init(event: NSEvent) { 11 | self.keyCode = event.keyCode 12 | self.flags = event.modifierFlags 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Sources/Ghostty/Ghostty.Shell.swift: -------------------------------------------------------------------------------- 1 | extension Ghostty { 2 | struct Shell { 3 | // Characters to escape in the shell. 4 | static let escapeCharacters = "\\ ()[]{}<>\"'`!#amp;;|*?\t" 5 | 6 | /// Escape shell-sensitive characters in string. 7 | static func escape(_ str: String) -> String { 8 | var result = str 9 | for char in escapeCharacters { 10 | result = result.replacingOccurrences( 11 | of: String(char), 12 | with: "\\\(char)" 13 | ) 14 | } 15 | 16 | return result 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/AppInfo.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// True if we appear to be running in Xcode. 4 | func isRunningInXcode() -> Bool { 5 | if let _ = ProcessInfo.processInfo.environment["__XCODE_BUILT_PRODUCTS_DIR_PATHS"] { 6 | return true 7 | } 8 | 9 | return false 10 | } 11 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/CodableBridge.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | /// A wrapper that allows a Swift Codable to implement NSSecureCoding. 4 | class CodableBridge<Wrapped: Codable>: NSObject, NSSecureCoding { 5 | let value: Wrapped 6 | init(_ value: Wrapped) { self.value = value } 7 | 8 | static var supportsSecureCoding: Bool { return true } 9 | 10 | required init?(coder aDecoder: NSCoder) { 11 | guard let data = aDecoder.decodeObject(of: NSData.self, forKey: "data") as? Data else { return nil } 12 | guard let archiver = try? NSKeyedUnarchiver(forReadingFrom: data) else { return nil } 13 | guard let value = archiver.decodeDecodable(Wrapped.self, forKey: "value") else { return nil } 14 | self.value = value 15 | } 16 | 17 | func encode(with aCoder: NSCoder) { 18 | let archiver = NSKeyedArchiver(requiringSecureCoding: true) 19 | try? archiver.encodeEncodable(value, forKey: "value") 20 | aCoder.encode(archiver.encodedData, forKey: "data") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Cursor.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | /// This helps manage the stateful nature of NSCursor hiding and unhiding. 4 | class Cursor { 5 | private static var counter: UInt = 0 6 | 7 | static var isVisible: Bool { 8 | counter == 0 9 | } 10 | 11 | static func hide() { 12 | counter += 1 13 | NSCursor.hide() 14 | } 15 | 16 | /// Unhide the cursor. Returns true if the cursor was previously hidden. 17 | static func unhide() -> Bool { 18 | // Its always safe to call unhide when the counter is zero because it 19 | // won't go negative. 20 | NSCursor.unhide() 21 | 22 | if (counter > 0) { 23 | counter -= 1 24 | return true 25 | } 26 | 27 | return false 28 | } 29 | 30 | static func unhideCompletely() -> UInt { 31 | let counter = self.counter 32 | for _ in 0..<counter { 33 | assert(unhide()) 34 | } 35 | assert(self.counter == 0) 36 | return counter 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/DraggableWindowView.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import SwiftUI 3 | 4 | struct DraggableWindowView: NSViewRepresentable { 5 | func makeNSView(context: Context) -> DraggableWindowNSView { 6 | return DraggableWindowNSView() 7 | } 8 | 9 | func updateNSView(_ nsView: DraggableWindowNSView, context: Context) { 10 | // No need to update anything here 11 | } 12 | } 13 | 14 | class DraggableWindowNSView: NSView { 15 | override func mouseDown(with event: NSEvent) { 16 | guard let window = self.window else { return } 17 | window.performDrag(with: event) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/Double+Extension.swift: -------------------------------------------------------------------------------- 1 | extension Double { 2 | func clamped(to range: ClosedRange<Double>) -> Double { 3 | return Swift.min(Swift.max(self, range.lowerBound), range.upperBound) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/Duration+Extension.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Duration { 4 | var timeInterval: TimeInterval { 5 | return TimeInterval(self.components.seconds) + 6 | TimeInterval(self.components.attoseconds) / 1_000_000_000_000_000_000 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/FileHandle+Extension.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension FileHandle: @retroactive TextOutputStream { 4 | /// Write a string to a filehandle. 5 | public func write(_ string: String) { 6 | let data = Data(string.utf8) 7 | self.write(data) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/NSAppearance+Extension.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | extension NSAppearance { 4 | /// Returns true if the appearance is some kind of dark. 5 | var isDark: Bool { 6 | return name.rawValue.lowercased().contains("dark") 7 | } 8 | 9 | /// Initialize a desired NSAppearance for the Ghostty configuration. 10 | convenience init?(ghosttyConfig config: Ghostty.Config) { 11 | guard let theme = config.windowTheme else { return nil } 12 | switch (theme) { 13 | case "dark": 14 | self.init(named: .darkAqua) 15 | 16 | case "light": 17 | self.init(named: .aqua) 18 | 19 | case "auto": 20 | let color = OSColor(config.backgroundColor) 21 | if color.isLightColor { 22 | self.init(named: .aqua) 23 | } else { 24 | self.init(named: .darkAqua) 25 | } 26 | 27 | default: 28 | return nil 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/NSMenuItem+Extension.swift: -------------------------------------------------------------------------------- 1 | import AppKit 2 | 3 | extension NSMenuItem { 4 | /// Sets the image property from a symbol if we want images on our menu items. 5 | func setImageIfDesired(systemSymbolName symbol: String) { 6 | // We only set on macOS 26 when icons on menu items became the norm. 7 | if #available(macOS 26, *) { 8 | image = NSImage(systemSymbolName: symbol, accessibilityDescription: title) 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/NSWindow+Extension.swift: -------------------------------------------------------------------------------- 1 | import AppKit 2 | 3 | extension NSWindow { 4 | /// Get the CGWindowID type for the window (used for low level CoreGraphics APIs). 5 | var cgWindowId: CGWindowID? { 6 | // "If the window doesn’t have a window device, the value of this 7 | // property is equal to or less than 0." - Docs. In practice I've 8 | // found this is true if a window is not visible. 9 | guard windowNumber > 0 else { return nil } 10 | return CGWindowID(windowNumber) 11 | } 12 | 13 | /// True if this is the first window in the tab group. 14 | var isFirstWindowInTabGroup: Bool { 15 | guard let firstWindow = tabGroup?.windows.first else { return true } 16 | return firstWindow === self 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/Optional+Extension.swift: -------------------------------------------------------------------------------- 1 | extension Optional where Wrapped == String { 2 | /// Executes a closure with a C string pointer, handling nil gracefully. 3 | func withCString<T>(_ body: (UnsafePointer<Int8>?) throws -> T) rethrows -> T { 4 | if let string = self { 5 | return try string.withCString(body) 6 | } else { 7 | return try body(nil) 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/String+Extension.swift: -------------------------------------------------------------------------------- 1 | extension String { 2 | func truncate(length: Int, trailing: String = "…") -> String { 3 | let maxLength = length - trailing.count 4 | guard maxLength > 0, !self.isEmpty, self.count > length else { 5 | return self 6 | } 7 | return self.prefix(maxLength) + trailing 8 | } 9 | 10 | #if canImport(AppKit) 11 | func temporaryFile(_ filename: String = "temp") -> URL { 12 | let url = FileManager.default.temporaryDirectory 13 | .appendingPathComponent(filename) 14 | .appendingPathExtension("txt") 15 | let string = self 16 | try? string.write(to: url, atomically: true, encoding: .utf8) 17 | return url 18 | } 19 | #endif 20 | } 21 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/UndoManager+Extension.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension UndoManager { 4 | /// A Boolean value that indicates whether the undo manager is currently performing 5 | /// either an undo or redo operation. 6 | var isUndoingOrRedoing: Bool { 7 | isUndoing || isRedoing 8 | } 9 | 10 | /// Temporarily disables undo registration while executing the provided handler. 11 | /// 12 | /// This method provides a convenient way to perform operations without recording them 13 | /// in the undo stack. It ensures that undo registration is properly re-enabled even 14 | /// if the handler throws an error. 15 | func disableUndoRegistration(handler: () -> Void) { 16 | disableUndoRegistration() 17 | handler() 18 | enableUndoRegistration() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Extensions/View+Extension.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | extension View { 4 | func innerShadow<S: Shape, ST: ShapeStyle>( 5 | using shape: S = Rectangle(), 6 | stroke: ST = Color.black, 7 | width: CGFloat = 6, 8 | blur: CGFloat = 6 9 | ) -> some View { 10 | return self 11 | .overlay( 12 | shape 13 | .stroke(stroke, lineWidth: width) 14 | .blur(radius: blur) 15 | .mask(shape) 16 | ) 17 | } 18 | } 19 | 20 | extension View { 21 | func pointerStyleFromCursor(_ cursor: NSCursor) -> some View { 22 | if #available(macOS 15.0, *) { 23 | return self.pointerStyle(.image( 24 | Image(nsImage: cursor.image), 25 | hotSpot: .init(x: cursor.hotSpot.x, y: cursor.hotSpot.y) 26 | )) 27 | } else { 28 | return self 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/HostingWindow.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct HostingWindowKey: EnvironmentKey { 4 | typealias Value = () -> NSWindow? // needed for weak link 5 | static let defaultValue: Self.Value = { nil } 6 | } 7 | 8 | extension EnvironmentValues { 9 | /// This can be used to set the hosting NSWindow to a NSHostingView 10 | var hostingWindow: HostingWindowKey.Value { 11 | get { return self[HostingWindowKey.self] } 12 | set { self[HostingWindowKey.self] = newValue } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/KeyboardLayout.swift: -------------------------------------------------------------------------------- 1 | import Carbon 2 | 3 | class KeyboardLayout { 4 | /// Return a string ID of the current keyboard input source. 5 | static var id: String? { 6 | if let source = TISCopyCurrentKeyboardInputSource()?.takeRetainedValue(), 7 | let sourceIdPointer = TISGetInputSourceProperty(source, kTISPropertyInputSourceID) { 8 | let sourceId = unsafeBitCast(sourceIdPointer, to: CFString.self) 9 | return sourceId as String 10 | } 11 | 12 | return nil 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/MetalView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import MetalKit 3 | 4 | /// Renders an MTKView with the given renderer class. 5 | struct MetalView<V: MTKView>: View { 6 | @State private var metalView = V() 7 | 8 | var body: some View { 9 | MetalViewRepresentable(metalView: $metalView) 10 | } 11 | } 12 | 13 | fileprivate struct MetalViewRepresentable<V: MTKView>: NSViewRepresentable { 14 | @Binding var metalView: V 15 | 16 | func makeNSView(context: Context) -> some NSView { 17 | metalView 18 | } 19 | 20 | func updateNSView(_ view: NSViewType, context: Context) { 21 | updateMetalView() 22 | } 23 | 24 | func updateMetalView() { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/VibrantLayer.h: -------------------------------------------------------------------------------- 1 | #import <QuartzCore/QuartzCore.h> 2 | 3 | typedef NS_ENUM(NSUInteger, VibrantLayerType) { 4 | VibrantLayerTypeLight, 5 | VibrantLayerTypeDark 6 | }; 7 | 8 | // This layer can be used to recreate the "vibrant" appearance you see of 9 | // views placed inside `NSVisualEffectView`s. When a light NSAppearance is 10 | // active, we will use the private "plus darker" blend mode. For dark 11 | // appearances we use "plus lighter". 12 | @interface VibrantLayer : CALayer 13 | 14 | - (id)initForAppearance:(VibrantLayerType)type; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/VibrantLayer.m: -------------------------------------------------------------------------------- 1 | #import "VibrantLayer.h" 2 | 3 | @interface VibrantLayer() 4 | 5 | @property (nonatomic) VibrantLayerType type; 6 | 7 | @end 8 | 9 | @implementation VibrantLayer 10 | 11 | - (id)initForAppearance:(VibrantLayerType)type { 12 | self = [super init]; 13 | if (self) { 14 | _type = type; 15 | } 16 | return self; 17 | } 18 | 19 | - (id)compositingFilter { 20 | if (self.type == VibrantLayerTypeLight) { 21 | return @"plusD"; 22 | } else { 23 | return @"plusL"; 24 | } 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /macos/Sources/Helpers/Weak.swift: -------------------------------------------------------------------------------- 1 | /// A wrapper that holds a weak reference to an object. This lets us create native containers 2 | /// of weak references. 3 | class Weak<T: AnyObject> { 4 | weak var value: T? 5 | 6 | init(_ value: T? = nil) { 7 | self.value = value 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nix/build-support/build-inputs.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | stdenv, 5 | enableX11 ? true, 6 | enableWayland ? true, 7 | }: 8 | [ 9 | pkgs.libGL 10 | ] 11 | ++ lib.optionals stdenv.hostPlatform.isLinux [ 12 | pkgs.bzip2 13 | pkgs.expat 14 | pkgs.fontconfig 15 | pkgs.freetype 16 | pkgs.harfbuzz 17 | pkgs.libpng 18 | pkgs.libxml2 19 | pkgs.oniguruma 20 | pkgs.simdutf 21 | pkgs.zlib 22 | 23 | pkgs.glslang 24 | pkgs.spirv-cross 25 | 26 | pkgs.libxkbcommon 27 | 28 | pkgs.glib 29 | pkgs.gobject-introspection 30 | pkgs.gsettings-desktop-schemas 31 | pkgs.gst_all_1.gst-plugins-base 32 | pkgs.gst_all_1.gst-plugins-good 33 | pkgs.gst_all_1.gstreamer 34 | pkgs.gtk4 35 | pkgs.libadwaita 36 | ] 37 | ++ lib.optionals (stdenv.hostPlatform.isLinux && enableX11) [ 38 | pkgs.xorg.libX11 39 | pkgs.xorg.libXcursor 40 | pkgs.xorg.libXi 41 | pkgs.xorg.libXrandr 42 | ] 43 | ++ lib.optionals (stdenv.hostPlatform.isLinux && enableWayland) [ 44 | pkgs.gtk4-layer-shell 45 | pkgs.wayland 46 | ] 47 | -------------------------------------------------------------------------------- /nix/build-support/check-blueprints.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o nounset -o pipefail -o errexit 4 | 5 | find src -name \*.blp -exec blueprint-compiler format {} \+ 6 | find src -name \*.blp -exec blueprint-compiler compile --output=/dev/null {} \; 7 | -------------------------------------------------------------------------------- /nix/build-support/fetch-zig-cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # NOTE THIS IS A TEMPORARY SCRIPT TO SUPPORT PACKAGE MAINTAINERS. 4 | # 5 | # A future Zig version will hopefully fix the issue where 6 | # `zig build --fetch` doesn't fetch transitive dependencies[1]. When that 7 | # is resolved, we won't need any special machinery for the general use case 8 | # at all and packagers can just use `zig build --fetch`. 9 | # 10 | # [1]: https://github.com/ziglang/zig/issues/20976 11 | 12 | if [ -z ${ZIG_GLOBAL_CACHE_DIR+x} ] 13 | then 14 | echo "must set ZIG_GLOBAL_CACHE_DIR!" 15 | exit 1 16 | fi 17 | 18 | # Go through each line of our build.zig.zon.txt and fetch it. 19 | SCRIPT_PATH="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)" 20 | ZON_TXT_FILE="$SCRIPT_PATH/../../build.zig.zon.txt" 21 | while IFS= read -r url; do 22 | echo "Fetching: $url" 23 | zig fetch "$url" >/dev/null 2>&1 || { 24 | echo "Failed to fetch: $url" >&2 25 | exit 1 26 | } 27 | done < "$ZON_TXT_FILE" 28 | -------------------------------------------------------------------------------- /nix/build-support/gi-typelib-path.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | stdenv, 5 | }: 6 | lib.makeSearchPath "lib/girepository-1.0" (map (lib.getOutput "lib") (lib.optionals stdenv.hostPlatform.isLinux [ 7 | pkgs.cairo 8 | pkgs.gdk-pixbuf 9 | pkgs.glib 10 | pkgs.gobject-introspection 11 | pkgs.graphene 12 | pkgs.gtk4 13 | pkgs.gtk4-layer-shell 14 | pkgs.harfbuzz 15 | pkgs.libadwaita 16 | pkgs.pango 17 | ])) 18 | -------------------------------------------------------------------------------- /nix/build-support/ld-library-path.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | stdenv, 5 | enableX11 ? true, 6 | enableWayland ? true, 7 | }: 8 | lib.makeLibraryPath (import ./build-inputs.nix { 9 | inherit pkgs lib stdenv enableX11 enableWayland; 10 | }) 11 | -------------------------------------------------------------------------------- /nix/build-support/update-mirror.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This script generates a directory that can be uploaded to blob 4 | # storage to mirror our dependencies. The dependencies are unmodified 5 | # so their checksum and content hashes will match. 6 | 7 | set -e # Exit immediately if a command exits with a non-zero status 8 | 9 | SCRIPT_PATH="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" 10 | INPUT_FILE="$SCRIPT_PATH/../../build.zig.zon2json-lock" 11 | OUTPUT_DIR="blob" 12 | 13 | # Ensure the output directory exists 14 | mkdir -p "$OUTPUT_DIR" 15 | 16 | # Use jq to iterate over the JSON and download files 17 | jq -r 'to_entries[] | "\(.key) \(.value.name) \(.value.url)"' "$INPUT_FILE" | while read -r key name url; do 18 | # Skip URLs that don't start with http(s). They aren't necessary for 19 | # our mirror. 20 | if ! echo "$url" | grep -Eq "^https?://"; then 21 | continue 22 | fi 23 | 24 | # Extract the file extension from the URL 25 | extension=$(echo "$url" | grep -oE '\.[a-z0-9]+(\.[a-z0-9]+)?#39;) 26 | 27 | filename="${name}-${key}${extension}" 28 | echo "$url -> $filename" 29 | curl -L -o "$OUTPUT_DIR/$filename" "$url" 30 | done 31 | -------------------------------------------------------------------------------- /nix/vm/common-cinnamon.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common.nix 4 | ]; 5 | 6 | services.xserver = { 7 | displayManager = { 8 | lightdm = { 9 | enable = true; 10 | }; 11 | }; 12 | desktopManager = { 13 | cinnamon = { 14 | enable = true; 15 | }; 16 | }; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /nix/vm/common-plasma6.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common.nix 4 | ]; 5 | 6 | services = { 7 | displayManager = { 8 | sddm = { 9 | enable = true; 10 | wayland = { 11 | enable = true; 12 | }; 13 | }; 14 | }; 15 | desktopManager = { 16 | plasma6 = { 17 | enable = true; 18 | }; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /nix/vm/common-xfce.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common.nix 4 | ]; 5 | 6 | services.xserver = { 7 | displayManager = { 8 | lightdm = { 9 | enable = true; 10 | }; 11 | }; 12 | desktopManager = { 13 | xfce = { 14 | enable = true; 15 | }; 16 | }; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /nix/vm/create-cinnamon.nix: -------------------------------------------------------------------------------- 1 | { 2 | system, 3 | nixpkgs, 4 | overlay, 5 | module, 6 | uid ? 1000, 7 | gid ? 1000, 8 | }: 9 | import ./create.nix { 10 | inherit system nixpkgs overlay module uid gid; 11 | common = ./common-cinnamon.nix; 12 | } 13 | -------------------------------------------------------------------------------- /nix/vm/create-gnome.nix: -------------------------------------------------------------------------------- 1 | { 2 | system, 3 | nixpkgs, 4 | overlay, 5 | module, 6 | uid ? 1000, 7 | gid ? 1000, 8 | }: 9 | import ./create.nix { 10 | inherit system nixpkgs overlay module uid gid; 11 | common = ./common-gnome.nix; 12 | } 13 | -------------------------------------------------------------------------------- /nix/vm/create-plasma6.nix: -------------------------------------------------------------------------------- 1 | { 2 | system, 3 | nixpkgs, 4 | overlay, 5 | module, 6 | uid ? 1000, 7 | gid ? 1000, 8 | }: 9 | import ./create.nix { 10 | inherit system nixpkgs overlay module uid gid; 11 | common = ./common-plasma6.nix; 12 | } 13 | -------------------------------------------------------------------------------- /nix/vm/create-xfce.nix: -------------------------------------------------------------------------------- 1 | { 2 | system, 3 | nixpkgs, 4 | overlay, 5 | module, 6 | uid ? 1000, 7 | gid ? 1000, 8 | }: 9 | import ./create.nix { 10 | inherit system nixpkgs overlay module uid gid; 11 | common = ./common-xfce.nix; 12 | } 13 | -------------------------------------------------------------------------------- /nix/vm/create.nix: -------------------------------------------------------------------------------- 1 | { 2 | system, 3 | nixpkgs, 4 | overlay, 5 | module, 6 | common ? ./common.nix, 7 | uid ? 1000, 8 | gid ? 1000, 9 | }: let 10 | pkgs = import nixpkgs { 11 | inherit system; 12 | overlays = [ 13 | overlay 14 | ]; 15 | }; 16 | in 17 | nixpkgs.lib.nixosSystem { 18 | system = builtins.replaceStrings ["darwin"] ["linux"] system; 19 | modules = [ 20 | { 21 | virtualisation.vmVariant = { 22 | virtualisation.host.pkgs = pkgs; 23 | }; 24 | 25 | nixpkgs.overlays = [ 26 | overlay 27 | ]; 28 | 29 | users.groups.ghostty = { 30 | gid = gid; 31 | }; 32 | 33 | users.users.ghostty = { 34 | uid = uid; 35 | }; 36 | 37 | system.stateVersion = nixpkgs.lib.trivial.release; 38 | } 39 | common 40 | module 41 | ]; 42 | } 43 | -------------------------------------------------------------------------------- /nix/vm/wayland-cinnamon.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common-cinnamon.nix 4 | ]; 5 | 6 | services.displayManager.defaultSession = "cinnamon-wayland"; 7 | } 8 | -------------------------------------------------------------------------------- /nix/vm/wayland-gnome.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common-gnome.nix 4 | ]; 5 | 6 | services.displayManager = { 7 | defaultSession = "gnome"; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /nix/vm/wayland-plasma6.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common-plasma6.nix 4 | ]; 5 | services.displayManager.defaultSession = "plasma"; 6 | } 7 | -------------------------------------------------------------------------------- /nix/vm/x11-cinnamon.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common-cinnamon.nix 4 | ]; 5 | 6 | services.displayManager.defaultSession = "cinnamon"; 7 | } 8 | -------------------------------------------------------------------------------- /nix/vm/x11-gnome.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common-gnome.nix 4 | ]; 5 | 6 | services.displayManager = { 7 | defaultSession = "gnome-xorg"; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /nix/vm/x11-plasma6.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common-plasma6.nix 4 | ]; 5 | services.displayManager.defaultSession = "plasmax11"; 6 | } 7 | -------------------------------------------------------------------------------- /nix/vm/x11-xfce.nix: -------------------------------------------------------------------------------- 1 | {...}: { 2 | imports = [ 3 | ./common-xfce.nix 4 | ]; 5 | 6 | services.displayManager.defaultSession = "xfce"; 7 | } 8 | -------------------------------------------------------------------------------- /nix/wraptest.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, 3 | fetchFromGitHub, 4 | autoPatchelfHook, 5 | }: 6 | stdenv.mkDerivation rec { 7 | version = "0.1.0-e7a96089"; 8 | pname = "wraptest"; 9 | 10 | src = fetchFromGitHub { 11 | owner = "mattiase"; 12 | repo = pname; 13 | rev = "e7a960892873035d2ef56b9770c32b43635821fb"; 14 | sha256 = "sha256-+v6xpPCmvKfsDkPmBSv6+6yAg2Kzame5Zwx2WKjQreI="; 15 | }; 16 | 17 | nativeBuildInputs = [ 18 | autoPatchelfHook 19 | ]; 20 | 21 | buildPhase = '' 22 | runHook preBuild 23 | 24 | cc -O3 -o wraptest wraptest.c 25 | 26 | runHook postBuild 27 | ''; 28 | 29 | installPhase = '' 30 | runHook preInstall 31 | 32 | mkdir -p $out/bin 33 | cp wraptest $out/bin/ 34 | 35 | runHook postInstall 36 | ''; 37 | 38 | meta = { 39 | description = "Test of DEC VT terminal line-wrapping semantics"; 40 | homepage = "https://github.com/mattiase/wraptest"; 41 | platforms = ["aarch64-linux" "i686-linux" "x86_64-linux"]; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /nix/zigCacheHash.nix: -------------------------------------------------------------------------------- 1 | # This file is auto-generated! check build-support/check-zig-cache-hash.sh for 2 | # more details. 3 | "sha256-S8kS+gO17dl9LJGKL1+kgDUre+vPTmdTvXzgc585Fl8=" 4 | -------------------------------------------------------------------------------- /pkg/apple-sdk/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .apple_sdk, 3 | .version = "0.1.0", 4 | .dependencies = .{}, 5 | .fingerprint = 0xdde52860f7c464d2, 6 | .paths = .{""}, 7 | } 8 | -------------------------------------------------------------------------------- /pkg/breakpad/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .breakpad, 3 | .version = "0.1.0", 4 | .fingerprint = 0xfe9f9e4c76d5f962, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | .breakpad = .{ 8 | .url = "https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz", 9 | .hash = "N-V-__8AALw2uwF_03u4JRkZwRLc3Y9hakkYV7NKRR9-RIZJ", 10 | .lazy = true, 11 | }, 12 | 13 | .apple_sdk = .{ .path = "../apple-sdk" }, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /pkg/cimgui/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .cimgui, 3 | .version = "1.90.6", // -docking branch 4 | .fingerprint = 0x49726f5f8acbc90d, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // This should be kept in sync with the submodule in the cimgui source 8 | // code in ./vendor/ to be safe that they're compatible. 9 | .imgui = .{ 10 | // ocornut/imgui 11 | .url = "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz", 12 | .hash = "N-V-__8AAH0GaQC8a52s6vfIxg88OZgFgEW6DFxfSK4lX_l3", 13 | }, 14 | 15 | .apple_sdk = .{ .path = "../apple-sdk" }, 16 | .freetype = .{ .path = "../freetype" }, 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /pkg/cimgui/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cDefine("CIMGUI_DEFINE_ENUMS_AND_STRUCTS", "1"); 3 | @cInclude("cimgui.h"); 4 | }); 5 | -------------------------------------------------------------------------------- /pkg/cimgui/main.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("c.zig").c; 2 | 3 | // OpenGL 4 | pub extern fn ImGui_ImplOpenGL3_Init(?[*:0]const u8) callconv(.c) bool; 5 | pub extern fn ImGui_ImplOpenGL3_Shutdown() callconv(.c) void; 6 | pub extern fn ImGui_ImplOpenGL3_NewFrame() callconv(.c) void; 7 | pub extern fn ImGui_ImplOpenGL3_RenderDrawData(*c.ImDrawData) callconv(.c) void; 8 | 9 | // Metal 10 | pub extern fn ImGui_ImplMetal_Init(*anyopaque) callconv(.c) bool; 11 | pub extern fn ImGui_ImplMetal_Shutdown() callconv(.c) void; 12 | pub extern fn ImGui_ImplMetal_NewFrame(*anyopaque) callconv(.c) void; 13 | pub extern fn ImGui_ImplMetal_RenderDrawData(*c.ImDrawData, *anyopaque, *anyopaque) callconv(.c) void; 14 | 15 | // OSX 16 | pub extern fn ImGui_ImplOSX_Init(*anyopaque) callconv(.c) bool; 17 | pub extern fn ImGui_ImplOSX_Shutdown() callconv(.c) void; 18 | pub extern fn ImGui_ImplOSX_NewFrame(*anyopaque) callconv(.c) void; 19 | 20 | test {} 21 | -------------------------------------------------------------------------------- /pkg/fontconfig/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .fontconfig, 3 | .version = "2.14.2", 4 | .fingerprint = 0x4a79a5a40c6d6d8, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | .fontconfig = .{ 8 | .url = "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz", 9 | .hash = "N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v", 10 | .lazy = true, 11 | }, 12 | 13 | .freetype = .{ .path = "../freetype", .lazy = true }, 14 | .libxml2 = .{ .path = "../libxml2", .lazy = true }, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /pkg/fontconfig/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cInclude("fontconfig/fontconfig.h"); 3 | }); 4 | -------------------------------------------------------------------------------- /pkg/fontconfig/error.zig: -------------------------------------------------------------------------------- 1 | pub const Error = error{ 2 | OutOfMemory, 3 | FontconfigFailed, 4 | FontconfigNoMatch, 5 | FontconfigTypeMismatch, 6 | FontconfigNoId, 7 | }; 8 | -------------------------------------------------------------------------------- /pkg/fontconfig/init.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | const Config = @import("config.zig").Config; 4 | 5 | pub fn init() bool { 6 | return c.FcInit() == c.FcTrue; 7 | } 8 | 9 | pub fn fini() void { 10 | c.FcFini(); 11 | } 12 | 13 | pub fn initLoadConfig() *Config { 14 | return @ptrCast(c.FcInitLoadConfig()); 15 | } 16 | 17 | pub fn initLoadConfigAndFonts() *Config { 18 | return @ptrCast(c.FcInitLoadConfigAndFonts()); 19 | } 20 | 21 | pub fn version() u32 { 22 | return @intCast(c.FcGetVersion()); 23 | } 24 | 25 | test "version" { 26 | const testing = std.testing; 27 | try testing.expect(version() > 0); 28 | } 29 | 30 | test "init" { 31 | try std.testing.expect(init()); 32 | defer fini(); 33 | } 34 | 35 | test "initLoadConfig" { 36 | var config = initLoadConfig(); 37 | defer config.destroy(); 38 | } 39 | 40 | test "initLoadConfigAndFonts" { 41 | var config = initLoadConfigAndFonts(); 42 | defer config.destroy(); 43 | } 44 | -------------------------------------------------------------------------------- /pkg/fontconfig/lang_set.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | 5 | pub const LangSet = opaque { 6 | pub fn create() *LangSet { 7 | return @ptrCast(c.FcLangSetCreate()); 8 | } 9 | 10 | pub fn destroy(self: *LangSet) void { 11 | c.FcLangSetDestroy(self.cval()); 12 | } 13 | 14 | pub fn hasLang(self: *const LangSet, lang: [:0]const u8) bool { 15 | return c.FcLangSetHasLang(self.cvalConst(), lang.ptr) == c.FcTrue; 16 | } 17 | 18 | pub inline fn cval(self: *LangSet) *c.struct__FcLangSet { 19 | return @ptrCast(self); 20 | } 21 | 22 | pub inline fn cvalConst(self: *const LangSet) *const c.struct__FcLangSet { 23 | return @ptrCast(self); 24 | } 25 | }; 26 | 27 | test "create" { 28 | const testing = std.testing; 29 | 30 | var fs = LangSet.create(); 31 | defer fs.destroy(); 32 | 33 | try testing.expect(!fs.hasLang("und-zsye")); 34 | } 35 | -------------------------------------------------------------------------------- /pkg/fontconfig/matrix.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | 5 | pub const Matrix = extern struct { 6 | xx: f64, 7 | xy: f64, 8 | yx: f64, 9 | yy: f64, 10 | }; 11 | -------------------------------------------------------------------------------- /pkg/fontconfig/object_set.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | const Property = @import("main.zig").Property; 4 | 5 | pub const ObjectSet = opaque { 6 | pub fn create() *ObjectSet { 7 | return @ptrCast(c.FcObjectSetCreate()); 8 | } 9 | 10 | pub fn destroy(self: *ObjectSet) void { 11 | c.FcObjectSetDestroy(self.cval()); 12 | } 13 | 14 | pub fn add(self: *ObjectSet, p: Property) bool { 15 | return c.FcObjectSetAdd(self.cval(), p.cval().ptr) == c.FcTrue; 16 | } 17 | 18 | pub inline fn cval(self: *ObjectSet) *c.struct__FcObjectSet { 19 | return @ptrCast(@alignCast(self)); 20 | } 21 | }; 22 | 23 | test "create" { 24 | const testing = std.testing; 25 | 26 | var os = ObjectSet.create(); 27 | defer os.destroy(); 28 | 29 | try testing.expect(os.add(.family)); 30 | } 31 | -------------------------------------------------------------------------------- /pkg/fontconfig/override/include/fcalias.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/pkg/fontconfig/override/include/fcalias.h -------------------------------------------------------------------------------- /pkg/fontconfig/override/include/fcaliastail.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/pkg/fontconfig/override/include/fcaliastail.h -------------------------------------------------------------------------------- /pkg/fontconfig/override/include/fcftalias.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/pkg/fontconfig/override/include/fcftalias.h -------------------------------------------------------------------------------- /pkg/fontconfig/override/include/fcftaliastail.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/pkg/fontconfig/override/include/fcftaliastail.h -------------------------------------------------------------------------------- /pkg/fontconfig/range.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | 5 | pub const Range = opaque { 6 | pub fn destroy(self: *Range) void { 7 | c.FcRangeDestroy(self.cval()); 8 | } 9 | 10 | pub inline fn cval(self: *Range) *c.struct__FcRange { 11 | return @ptrCast(self); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /pkg/freetype/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .freetype, 3 | .version = "2.13.2", 4 | .fingerprint = 0xac2059b6f7bbfe0a, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // freetype/freetype 8 | .freetype = .{ 9 | .url = "https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz", 10 | .hash = "N-V-__8AAKLKpwC4H27Ps_0iL3bPkQb-z6ZVSrB-x_3EEkub", 11 | .lazy = true, 12 | }, 13 | 14 | .apple_sdk = .{ .path = "../apple-sdk" }, 15 | .libpng = .{ .path = "../libpng" }, 16 | .zlib = .{ .path = "../zlib" }, 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /pkg/freetype/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cInclude("freetype-zig.h"); 3 | }); 4 | -------------------------------------------------------------------------------- /pkg/freetype/computations.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | 4 | /// Compute (a*b)/0x10000 with maximum accuracy. Its main use is to multiply 5 | /// a given value by a 16.16 fixed-point factor. 6 | pub fn mulFix(a: i32, b: i32) i32 { 7 | return @intCast(c.FT_MulFix(a, b)); 8 | } 9 | -------------------------------------------------------------------------------- /pkg/freetype/freetype-zig.h: -------------------------------------------------------------------------------- 1 | #include <ft2build.h> 2 | #include FT_FREETYPE_H 3 | #include FT_TRUETYPE_TABLES_H 4 | #include <freetype/ftmm.h> 5 | #include <freetype/ftoutln.h> 6 | #include <freetype/ftsnames.h> 7 | #include <freetype/ttnameid.h> 8 | #include <freetype/ftbitmap.h> 9 | #include <freetype/ftbbox.h> 10 | -------------------------------------------------------------------------------- /pkg/freetype/main.zig: -------------------------------------------------------------------------------- 1 | const computations = @import("computations.zig"); 2 | const errors = @import("errors.zig"); 3 | const face = @import("face.zig"); 4 | const tag = @import("tag.zig"); 5 | 6 | pub const c = @import("c.zig").c; 7 | pub const testing = @import("test.zig"); 8 | pub const Library = @import("Library.zig"); 9 | 10 | pub const Error = errors.Error; 11 | pub const Face = face.Face; 12 | pub const Tag = tag.Tag; 13 | pub const mulFix = computations.mulFix; 14 | 15 | test { 16 | @import("std").testing.refAllDecls(@This()); 17 | } 18 | -------------------------------------------------------------------------------- /pkg/freetype/tag.zig: -------------------------------------------------------------------------------- 1 | /// FT_Tag 2 | pub const Tag = packed struct(u32) { 3 | d: u8, 4 | c: u8, 5 | b: u8, 6 | a: u8, 7 | 8 | pub fn init(v: *const [4]u8) Tag { 9 | return .{ .a = v[0], .b = v[1], .c = v[2], .d = v[3] }; 10 | } 11 | 12 | /// Converts the ID to a string. The return value is only valid 13 | /// for the lifetime of the self pointer. 14 | pub fn str(self: Tag) [4]u8 { 15 | return .{ self.a, self.b, self.c, self.d }; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /pkg/freetype/test.zig: -------------------------------------------------------------------------------- 1 | pub const font_regular = @embedFile("res/JetBrainsMono-Regular.ttf"); 2 | -------------------------------------------------------------------------------- /pkg/glslang/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .glslang, 3 | .version = "14.2.0", 4 | .fingerprint = 0x274a35558e2e504, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // KhronosGroup/glslang 8 | .glslang = .{ 9 | .url = "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz", 10 | .hash = "N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy", 11 | }, 12 | 13 | .apple_sdk = .{ .path = "../apple-sdk" }, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /pkg/glslang/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cInclude("glslang/Include/glslang_c_interface.h"); 3 | @cInclude("glslang/Public/resource_limits_c.h"); 4 | }); 5 | -------------------------------------------------------------------------------- /pkg/glslang/init.zig: -------------------------------------------------------------------------------- 1 | const c = @import("c.zig").c; 2 | 3 | pub fn init() !void { 4 | if (c.glslang_initialize_process() == 0) return error.GlslangInitFailed; 5 | } 6 | 7 | pub fn finalize() void { 8 | c.glslang_finalize_process(); 9 | } 10 | -------------------------------------------------------------------------------- /pkg/glslang/main.zig: -------------------------------------------------------------------------------- 1 | const initpkg = @import("init.zig"); 2 | const program = @import("program.zig"); 3 | const shader = @import("shader.zig"); 4 | 5 | pub const c = @import("c.zig").c; 6 | pub const testing = @import("test.zig"); 7 | 8 | pub const init = initpkg.init; 9 | pub const finalize = initpkg.finalize; 10 | pub const Program = program.Program; 11 | pub const Shader = shader.Shader; 12 | 13 | test { 14 | @import("std").testing.refAllDecls(@This()); 15 | } 16 | -------------------------------------------------------------------------------- /pkg/glslang/test.zig: -------------------------------------------------------------------------------- 1 | const glslang = @import("main.zig"); 2 | 3 | var initialized: bool = false; 4 | 5 | /// Call this function before any other tests in this package to ensure that 6 | /// the glslang library is initialized. 7 | pub fn ensureInit() !void { 8 | if (initialized) return; 9 | try glslang.init(); 10 | } 11 | -------------------------------------------------------------------------------- /pkg/gtk4-layer-shell/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .gtk4_layer_shell, 3 | .version = "1.1.0", 4 | .fingerprint = 0x4b96f9483c6feeb1, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | .gtk4_layer_shell = .{ 8 | .url = "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz", 9 | .hash = "N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr", 10 | .lazy = true, 11 | }, 12 | .wayland_protocols = .{ 13 | .url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz", 14 | .hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S", 15 | .lazy = true, 16 | }, 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /pkg/harfbuzz/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .harfbuzz, 3 | .version = "11.0.0", 4 | .fingerprint = 0xbd60917cd18865d8, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // harfbuzz/harfbuzz 8 | .harfbuzz = .{ 9 | .url = "https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz", 10 | .hash = "N-V-__8AAG02ugUcWec-Ndp-i7JTsJ0dgF8nnJRUInkGLG7G", 11 | .lazy = true, 12 | }, 13 | 14 | .freetype = .{ .path = "../freetype" }, 15 | .macos = .{ .path = "../macos" }, 16 | .apple_sdk = .{ .path = "../apple-sdk" }, 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /pkg/harfbuzz/c.zig: -------------------------------------------------------------------------------- 1 | const builtin = @import("builtin"); 2 | 3 | pub const c = @cImport({ 4 | @cInclude("hb.h"); 5 | @cInclude("hb-ft.h"); 6 | if (builtin.os.tag == .macos) @cInclude("hb-coretext.h"); 7 | }); 8 | -------------------------------------------------------------------------------- /pkg/harfbuzz/errors.zig: -------------------------------------------------------------------------------- 1 | pub const Error = error{ 2 | /// Not very descriptive but harfbuzz doesn't actually have error 3 | /// codes so the best we can do! 4 | HarfbuzzFailed, 5 | }; 6 | -------------------------------------------------------------------------------- /pkg/harfbuzz/face.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | 4 | /// A font face is an object that represents a single face from within a font family. 5 | /// 6 | /// More precisely, a font face represents a single face in a binary font file. 7 | /// Font faces are typically built from a binary blob and a face index. 8 | /// Font faces are used to create fonts. 9 | pub const Face = struct { 10 | handle: *c.hb_face_t, 11 | 12 | /// Decreases the reference count on a face object. When the reference 13 | /// count reaches zero, the face is destroyed, freeing all memory. 14 | pub fn destroy(self: *Face) void { 15 | c.hb_face_destroy(self.handle); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /pkg/harfbuzz/font.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | const Face = @import("face.zig").Face; 4 | const Error = @import("errors.zig").Error; 5 | 6 | pub const Font = struct { 7 | handle: *c.hb_font_t, 8 | 9 | /// Constructs a new font object from the specified face. 10 | pub fn create(face: Face) Error!Font { 11 | const handle = c.hb_font_create(face.handle) orelse return Error.HarfbuzzFailed; 12 | return Font{ .handle = handle }; 13 | } 14 | 15 | /// Decreases the reference count on the given font object. When the 16 | /// reference count reaches zero, the font is destroyed, freeing all memory. 17 | pub fn destroy(self: *Font) void { 18 | c.hb_font_destroy(self.handle); 19 | } 20 | 21 | pub fn setScale(self: *Font, x: u32, y: u32) void { 22 | c.hb_font_set_scale( 23 | self.handle, 24 | @intCast(x), 25 | @intCast(y), 26 | ); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /pkg/harfbuzz/main.zig: -------------------------------------------------------------------------------- 1 | const blob = @import("blob.zig"); 2 | const buffer = @import("buffer.zig"); 3 | const common = @import("common.zig"); 4 | const errors = @import("errors.zig"); 5 | const face = @import("face.zig"); 6 | const font = @import("font.zig"); 7 | const shapepkg = @import("shape.zig"); 8 | const versionpkg = @import("version.zig"); 9 | 10 | pub const c = @import("c.zig").c; 11 | pub const freetype = @import("freetype.zig"); 12 | pub const coretext = @import("coretext.zig"); 13 | pub const MemoryMode = blob.MemoryMode; 14 | pub const Blob = blob.Blob; 15 | pub const Buffer = buffer.Buffer; 16 | pub const Direction = common.Direction; 17 | pub const Script = common.Script; 18 | pub const Language = common.Language; 19 | pub const Feature = common.Feature; 20 | pub const Face = face.Face; 21 | pub const Font = font.Font; 22 | pub const shape = shapepkg.shape; 23 | pub const Version = versionpkg.Version; 24 | pub const version = versionpkg.version; 25 | pub const versionAtLeast = versionpkg.versionAtLeast; 26 | pub const versionString = versionpkg.versionString; 27 | 28 | test { 29 | @import("std").testing.refAllDecls(@This()); 30 | } 31 | -------------------------------------------------------------------------------- /pkg/harfbuzz/shape.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | const Font = @import("font.zig").Font; 4 | const Buffer = @import("buffer.zig").Buffer; 5 | const Feature = @import("common.zig").Feature; 6 | 7 | /// Shapes buffer using font turning its Unicode characters content to 8 | /// positioned glyphs. If features is not NULL, it will be used to control 9 | /// the features applied during shaping. If two features have the same tag 10 | /// but overlapping ranges the value of the feature with the higher index 11 | /// takes precedence. 12 | pub fn shape(font: Font, buf: Buffer, features: ?[]const Feature) void { 13 | const hb_feats: [*c]const c.hb_feature_t = feats: { 14 | if (features) |fs| { 15 | if (fs.len > 0) break :feats @ptrCast(fs.ptr); 16 | } 17 | 18 | break :feats null; 19 | }; 20 | 21 | c.hb_shape( 22 | font.handle, 23 | buf.handle, 24 | hb_feats, 25 | if (features) |f| @intCast(f.len) else 0, 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /pkg/highway/bridge.cpp: -------------------------------------------------------------------------------- 1 | #include <hwy/targets.h> 2 | #include <stdint.h> 3 | 4 | extern "C" { 5 | 6 | int64_t hwy_supported_targets() { 7 | return HWY_SUPPORTED_TARGETS; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /pkg/highway/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .highway, 3 | .version = "1.2.0", 4 | .fingerprint = 0xdbcf1a7425023274, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // google/highway 8 | .highway = .{ 9 | .url = "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz", 10 | .hash = "N-V-__8AAGmZhABbsPJLfbqrh6JTHsXhY6qCaLAQyx25e0XE", 11 | }, 12 | 13 | .apple_sdk = .{ .path = "../apple-sdk" }, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /pkg/libintl/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .libintl, 3 | .version = "0.24.0", 4 | .fingerprint = 0x16434c723ba7278a, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | .gettext = .{ 8 | .url = "https://deps.files.ghostty.org/gettext-0.24.tar.gz", 9 | .hash = "N-V-__8AADcZkgn4cMhTUpIz6mShCKyqqB-NBtf_S2bHaTC-", 10 | .lazy = true, 11 | }, 12 | 13 | .apple_sdk = .{ .path = "../apple-sdk" }, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /pkg/libintl/libgnuintl.h: -------------------------------------------------------------------------------- 1 | #include "libintl.h" 2 | -------------------------------------------------------------------------------- /pkg/libpng/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .libpng, 3 | .version = "1.6.43", 4 | .fingerprint = 0xb7a09eb437ca8a79, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // glennrp/libpng 8 | .libpng = .{ 9 | .url = "https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz", 10 | .hash = "N-V-__8AAJrvXQCqAT8Mg9o_tk6m0yf5Fz-gCNEOKLyTSerD", 11 | .lazy = true, 12 | }, 13 | 14 | .zlib = .{ .path = "../zlib", .lazy = true }, 15 | .apple_sdk = .{ .path = "../apple-sdk" }, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /pkg/libxml2/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .libxml2, 3 | .version = "2.11.5", 4 | .fingerprint = 0xf268267b0b8b040d, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | .libxml2 = .{ 8 | .url = "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz", 9 | .hash = "N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK", 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /pkg/libxml2/override/config/win32/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIBXML_WIN32_CONFIG__ 2 | #define __LIBXML_WIN32_CONFIG__ 3 | 4 | #define SEND_ARG2_CAST 5 | #define GETHOSTBYNAME_ARG_CAST 6 | 7 | #define HAVE_SYS_STAT_H 8 | #define HAVE_STAT 9 | #define HAVE_FCNTL_H 10 | 11 | #if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1600) 12 | #define HAVE_STDINT_H 13 | #endif 14 | 15 | #if defined(_MSC_VER) && _MSC_VER < 1900 16 | #define snprintf _snprintf 17 | #define vsnprintf _vsnprintf 18 | #endif 19 | 20 | #endif /* __LIBXML_WIN32_CONFIG__ */ 21 | -------------------------------------------------------------------------------- /pkg/libxml2/override/include/libxml/xmlversion.h: -------------------------------------------------------------------------------- 1 | // This recreates parts of the generated libxml/xmlversion.h.in that we need 2 | // to build libxml2 without actually templating the header file. We define most 3 | // of the defines in that file using flags to the compiler in libxml2.zig 4 | 5 | #ifndef __XML_VERSION_H__ 6 | #define __XML_VERSION_H__ 7 | 8 | #include <libxml/xmlexports.h> 9 | 10 | // We are not GCC. 11 | #define XML_IGNORE_FPTR_CAST_WARNINGS 12 | #define XML_POP_WARNINGS 13 | #define LIBXML_ATTR_FORMAT(fmt,args) 14 | #define LIBXML_ATTR_ALLOC_SIZE(x) 15 | #define ATTRIBUTE_UNUSED 16 | #define XML_DEPRECATED 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /pkg/macos/animation.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("animation/c.zig").c; 2 | 3 | /// https://developer.apple.com/documentation/quartzcore/calayer/contents_gravity_values?language=objc 4 | pub extern "c" const kCAGravityTopLeft: *anyopaque; 5 | pub extern "c" const kCAGravityBottomLeft: *anyopaque; 6 | pub extern "c" const kCAGravityCenter: *anyopaque; 7 | 8 | test { 9 | @import("std").testing.refAllDecls(@This()); 10 | } 11 | -------------------------------------------------------------------------------- /pkg/macos/animation/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/macos/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .macos, 3 | .version = "0.1.0", 4 | .fingerprint = 0x45e2f6107d5b2b2c, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | .apple_sdk = .{ .path = "../apple-sdk" }, 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /pkg/macos/carbon.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("carbon/c.zig").c; 2 | 3 | test { 4 | @import("std").testing.refAllDecls(@This()); 5 | } 6 | -------------------------------------------------------------------------------- /pkg/macos/carbon/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/macos/dispatch.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("dispatch/c.zig").c; 2 | pub const data = @import("dispatch/data.zig"); 3 | pub const queue = @import("dispatch/queue.zig"); 4 | pub const Data = data.Data; 5 | 6 | pub extern "c" fn dispatch_sync( 7 | queue: *anyopaque, 8 | block: *anyopaque, 9 | ) void; 10 | 11 | pub extern "c" fn dispatch_async( 12 | queue: *anyopaque, 13 | block: *anyopaque, 14 | ) void; 15 | 16 | test { 17 | @import("std").testing.refAllDecls(@This()); 18 | } 19 | -------------------------------------------------------------------------------- /pkg/macos/dispatch/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/macos/dispatch/data.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const foundation = @import("../foundation.zig"); 3 | const c = @import("c.zig").c; 4 | 5 | pub const Data = opaque { 6 | pub const DESTRUCTOR_DEFAULT = c.DISPATCH_DATA_DESTRUCTOR_DEFAULT; 7 | 8 | pub fn create( 9 | data: []const u8, 10 | queue: ?*anyopaque, 11 | destructor: ?*anyopaque, 12 | ) !*Data { 13 | return dispatch_data_create( 14 | data.ptr, 15 | data.len, 16 | queue, 17 | destructor, 18 | ) orelse return error.OutOfMemory; 19 | } 20 | 21 | pub fn release(data: *Data) void { 22 | foundation.c.CFRelease(data); 23 | } 24 | }; 25 | 26 | extern "c" fn dispatch_data_create( 27 | data: [*]const u8, 28 | len: usize, 29 | queue: ?*anyopaque, 30 | destructor: ?*anyopaque, 31 | ) ?*Data; 32 | -------------------------------------------------------------------------------- /pkg/macos/dispatch/queue.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | 4 | pub const Queue = *anyopaque; // dispatch_queue_t 5 | 6 | pub fn getMain() Queue { 7 | return c.dispatch_get_main_queue().?; 8 | } 9 | -------------------------------------------------------------------------------- /pkg/macos/foundation/base.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | 5 | pub const ComparisonResult = enum(c_int) { 6 | less = -1, 7 | equal = 0, 8 | greater = 1, 9 | }; 10 | 11 | pub const Range = extern struct { 12 | location: c.CFIndex, 13 | length: c.CFIndex, 14 | 15 | pub fn init(loc: usize, len: usize) Range { 16 | return @bitCast(c.CFRangeMake(@intCast(loc), @intCast(len))); 17 | } 18 | }; 19 | 20 | pub const FourCharCode = packed struct(u32) { 21 | d: u8, 22 | c: u8, 23 | b: u8, 24 | a: u8, 25 | 26 | pub fn init(v: *const [4]u8) FourCharCode { 27 | return .{ .a = v[0], .b = v[1], .c = v[2], .d = v[3] }; 28 | } 29 | 30 | /// Converts the ID to a string. The return value is only valid 31 | /// for the lifetime of the self pointer. 32 | pub fn str(self: FourCharCode) [4]u8 { 33 | return .{ self.a, self.b, self.c, self.d }; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /pkg/macos/foundation/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/macos/foundation/data.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const Allocator = std.mem.Allocator; 3 | const foundation = @import("../foundation.zig"); 4 | const c = @import("c.zig").c; 5 | 6 | pub const Data = opaque { 7 | pub fn createWithBytesNoCopy(data: []const u8) Allocator.Error!*Data { 8 | return @as( 9 | ?*Data, 10 | @ptrFromInt(@intFromPtr(c.CFDataCreateWithBytesNoCopy( 11 | null, 12 | data.ptr, 13 | @intCast(data.len), 14 | c.kCFAllocatorNull, 15 | ))), 16 | ) orelse error.OutOfMemory; 17 | } 18 | 19 | pub fn release(self: *Data) void { 20 | foundation.CFRelease(self); 21 | } 22 | 23 | pub fn getPointer(self: *Data) [*]const u8 { 24 | return @ptrCast(c.CFDataGetBytePtr(@ptrCast(self))); 25 | } 26 | 27 | pub fn getLength(self: *Data) usize { 28 | return @intCast(c.CFDataGetLength(@ptrCast(self))); 29 | } 30 | }; 31 | 32 | test { 33 | //const testing = std.testing; 34 | 35 | const raw = "hello world"; 36 | const data = try Data.createWithBytesNoCopy(raw); 37 | defer data.release(); 38 | } 39 | -------------------------------------------------------------------------------- /pkg/macos/foundation/type.zig: -------------------------------------------------------------------------------- 1 | pub extern "c" fn CFRelease(*anyopaque) void; 2 | pub extern "c" fn CFRetain(*anyopaque) void; 3 | -------------------------------------------------------------------------------- /pkg/macos/graphics.zig: -------------------------------------------------------------------------------- 1 | const affine_transform = @import("graphics/affine_transform.zig"); 2 | const bitmap_context = @import("graphics/bitmap_context.zig"); 3 | const color_space = @import("graphics/color_space.zig"); 4 | const font = @import("graphics/font.zig"); 5 | const geometry = @import("graphics/geometry.zig"); 6 | const image = @import("graphics/image.zig"); 7 | const path = @import("graphics/path.zig"); 8 | 9 | pub const c = @import("graphics/c.zig").c; 10 | pub const AffineTransform = affine_transform.AffineTransform; 11 | pub const BitmapContext = bitmap_context.BitmapContext; 12 | pub const ColorSpace = color_space.ColorSpace; 13 | pub const Glyph = font.Glyph; 14 | pub const Point = geometry.Point; 15 | pub const Rect = geometry.Rect; 16 | pub const Size = geometry.Size; 17 | pub const ImageAlphaInfo = image.ImageAlphaInfo; 18 | pub const BitmapInfo = image.BitmapInfo; 19 | pub const Path = path.Path; 20 | pub const MutablePath = path.MutablePath; 21 | 22 | test { 23 | @import("std").testing.refAllDecls(@This()); 24 | } 25 | -------------------------------------------------------------------------------- /pkg/macos/graphics/affine_transform.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | 5 | pub const AffineTransform = extern struct { 6 | a: c.CGFloat, 7 | b: c.CGFloat, 8 | c: c.CGFloat, 9 | d: c.CGFloat, 10 | tx: c.CGFloat, 11 | ty: c.CGFloat, 12 | 13 | pub fn identity() AffineTransform { 14 | return @bitCast(c.CGAffineTransformIdentity); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /pkg/macos/graphics/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/macos/graphics/font.zig: -------------------------------------------------------------------------------- 1 | const c = @import("c.zig").c; 2 | 3 | pub const Glyph = c.CGGlyph; 4 | -------------------------------------------------------------------------------- /pkg/macos/graphics/geometry.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | 5 | pub const Point = extern struct { 6 | x: c.CGFloat, 7 | y: c.CGFloat, 8 | }; 9 | 10 | pub const Rect = extern struct { 11 | origin: Point, 12 | size: Size, 13 | 14 | pub fn init(x: f64, y: f64, width: f64, height: f64) Rect { 15 | return @bitCast(c.CGRectMake(x, y, width, height)); 16 | } 17 | 18 | pub fn isNull(self: Rect) bool { 19 | return c.CGRectIsNull(@bitCast(self)); 20 | } 21 | 22 | pub fn getHeight(self: Rect) c.CGFloat { 23 | return c.CGRectGetHeight(@bitCast(self)); 24 | } 25 | 26 | pub fn getWidth(self: Rect) c.CGFloat { 27 | return c.CGRectGetWidth(@bitCast(self)); 28 | } 29 | }; 30 | 31 | pub const Size = extern struct { 32 | width: c.CGFloat, 33 | height: c.CGFloat, 34 | }; 35 | -------------------------------------------------------------------------------- /pkg/macos/iosurface.zig: -------------------------------------------------------------------------------- 1 | const iosurface = @import("iosurface/iosurface.zig"); 2 | 3 | pub const c = @import("iosurface/c.zig").c; 4 | pub const IOSurface = iosurface.IOSurface; 5 | 6 | test { 7 | @import("std").testing.refAllDecls(@This()); 8 | } 9 | -------------------------------------------------------------------------------- /pkg/macos/iosurface/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/macos/os.zig: -------------------------------------------------------------------------------- 1 | const log = @import("os/log.zig"); 2 | 3 | pub const c = @import("os/c.zig"); 4 | pub const signpost = @import("os/signpost.zig"); 5 | pub const Log = log.Log; 6 | pub const LogType = log.LogType; 7 | 8 | test { 9 | @import("std").testing.refAllDecls(@This()); 10 | } 11 | -------------------------------------------------------------------------------- /pkg/macos/os/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/macos/os/zig_macos.c: -------------------------------------------------------------------------------- 1 | #include <os/log.h> 2 | #include <os/signpost.h> 3 | 4 | // A wrapper so we can use the os_log_with_type macro. 5 | void zig_os_log_with_type( 6 | os_log_t log, 7 | os_log_type_t type, 8 | const char *message 9 | ) { 10 | os_log_with_type(log, type, "%{public}s", message); 11 | } 12 | -------------------------------------------------------------------------------- /pkg/macos/text/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/macos/text/ext.c: -------------------------------------------------------------------------------- 1 | #include <CoreText/CoreText.h> 2 | 3 | // A wrapper to fix a Zig C ABI issue. 4 | void zig_cabi_CTLineGetBoundsWithOptions( 5 | CTLineRef line, 6 | CTLineBoundsOptions options, 7 | CGRect *result 8 | ) { 9 | *result = CTLineGetBoundsWithOptions(line, options); 10 | } 11 | -------------------------------------------------------------------------------- /pkg/macos/text/font_manager.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const Allocator = std.mem.Allocator; 3 | const foundation = @import("../foundation.zig"); 4 | const FontDescriptor = @import("./font_descriptor.zig").FontDescriptor; 5 | const c = @import("c.zig").c; 6 | 7 | pub fn createFontDescriptorsFromURL(url: *foundation.URL) ?*foundation.Array { 8 | return @ptrFromInt(@intFromPtr(c.CTFontManagerCreateFontDescriptorsFromURL( 9 | @ptrCast(url), 10 | ))); 11 | } 12 | 13 | pub fn createFontDescriptorsFromData(data: *foundation.Data) ?*foundation.Array { 14 | return @ptrFromInt(@intFromPtr(c.CTFontManagerCreateFontDescriptorsFromData( 15 | @ptrCast(data), 16 | ))); 17 | } 18 | 19 | pub fn createFontDescriptorFromData(data: *foundation.Data) ?*FontDescriptor { 20 | return @ptrFromInt(@intFromPtr(c.CTFontManagerCreateFontDescriptorFromData( 21 | @ptrCast(data), 22 | ))); 23 | } 24 | -------------------------------------------------------------------------------- /pkg/macos/text/frame.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const Allocator = std.mem.Allocator; 4 | const foundation = @import("../foundation.zig"); 5 | const graphics = @import("../graphics.zig"); 6 | const text = @import("../text.zig"); 7 | const c = @import("c.zig").c; 8 | 9 | pub const Frame = opaque { 10 | pub fn release(self: *Frame) void { 11 | foundation.CFRelease(self); 12 | } 13 | 14 | pub fn getLineOrigins( 15 | self: *Frame, 16 | range: foundation.Range, 17 | points: []graphics.Point, 18 | ) void { 19 | c.CTFrameGetLineOrigins( 20 | @ptrCast(self), 21 | @bitCast(range), 22 | @ptrCast(points.ptr), 23 | ); 24 | } 25 | 26 | pub fn getLines(self: *Frame) *foundation.Array { 27 | return @ptrFromInt(@intFromPtr(c.CTFrameGetLines(@ptrCast(self)))); 28 | } 29 | }; 30 | 31 | test { 32 | // See framesetter tests... 33 | } 34 | -------------------------------------------------------------------------------- /pkg/macos/text/stylized_strings.zig: -------------------------------------------------------------------------------- 1 | const foundation = @import("../foundation.zig"); 2 | const c = @import("c.zig").c; 3 | 4 | pub const StringAttribute = enum { 5 | font, 6 | paragraph_style, 7 | writing_direction, 8 | 9 | pub fn key(self: StringAttribute) *foundation.String { 10 | return @ptrFromInt(@intFromPtr(switch (self) { 11 | .font => c.kCTFontAttributeName, 12 | .paragraph_style => c.kCTParagraphStyleAttributeName, 13 | .writing_direction => c.kCTWritingDirectionAttributeName, 14 | })); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /pkg/macos/video.zig: -------------------------------------------------------------------------------- 1 | const display_link = @import("video/display_link.zig"); 2 | const pixel_format = @import("video/pixel_format.zig"); 3 | 4 | pub const c = @import("video/c.zig").c; 5 | pub const DisplayLink = display_link.DisplayLink; 6 | pub const PixelFormat = pixel_format.PixelFormat; 7 | 8 | test { 9 | @import("std").testing.refAllDecls(@This()); 10 | } 11 | -------------------------------------------------------------------------------- /pkg/macos/video/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("../main.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/oniguruma/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .oniguruma, 3 | .version = "6.9.9", 4 | .fingerprint = 0xe3b537b18c5785a8, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // kkos/oniguruma 8 | .oniguruma = .{ 9 | .url = "https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz", 10 | .hash = "N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c", 11 | .lazy = true, 12 | }, 13 | 14 | .apple_sdk = .{ .path = "../apple-sdk" }, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /pkg/oniguruma/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cInclude("oniguruma.h"); 3 | }); 4 | -------------------------------------------------------------------------------- /pkg/oniguruma/init.zig: -------------------------------------------------------------------------------- 1 | const c = @import("c.zig").c; 2 | const Encoding = @import("types.zig").Encoding; 3 | const errors = @import("errors.zig"); 4 | 5 | /// Call once per process to initialize Oniguruma. This should be given 6 | /// the encodings that the program will use. 7 | pub fn init(encs: []const *Encoding) !void { 8 | _ = try errors.convertError(c.onig_initialize( 9 | @constCast(@ptrCast(@alignCast(encs.ptr))), 10 | @intCast(encs.len), 11 | )); 12 | } 13 | 14 | pub fn deinit() void { 15 | _ = c.onig_end(); 16 | } 17 | -------------------------------------------------------------------------------- /pkg/oniguruma/main.zig: -------------------------------------------------------------------------------- 1 | const initpkg = @import("init.zig"); 2 | const regex = @import("regex.zig"); 3 | const region = @import("region.zig"); 4 | const types = @import("types.zig"); 5 | 6 | pub const c = @import("c.zig"); 7 | pub const testing = @import("testing.zig"); 8 | pub const errors = @import("errors.zig"); 9 | 10 | pub const init = initpkg.init; 11 | pub const deinit = initpkg.deinit; 12 | pub const Encoding = types.Encoding; 13 | pub const Regex = regex.Regex; 14 | pub const Region = region.Region; 15 | pub const Syntax = types.Syntax; 16 | 17 | test { 18 | @import("std").testing.refAllDecls(@This()); 19 | } 20 | -------------------------------------------------------------------------------- /pkg/oniguruma/testing.zig: -------------------------------------------------------------------------------- 1 | const init = @import("init.zig"); 2 | const Encoding = @import("types.zig").Encoding; 3 | 4 | var initialized: bool = false; 5 | 6 | /// Call this function before any other tests in this package to ensure that 7 | /// the oni library is initialized. This should only be used for tests 8 | /// and only when you're sure this is the ONLY way that oni is being 9 | /// initialized. 10 | /// 11 | /// This always only initializes the encodings the tests use. 12 | pub fn ensureInit() !void { 13 | if (initialized) return; 14 | try init.init(&.{Encoding.utf8}); 15 | } 16 | -------------------------------------------------------------------------------- /pkg/opengl/build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn build(b: *std.Build) !void { 4 | const module = b.addModule("opengl", .{ .root_source_file = b.path("main.zig") }); 5 | module.addIncludePath(b.path("../../vendor/glad/include")); 6 | } 7 | -------------------------------------------------------------------------------- /pkg/opengl/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cInclude("glad/gl.h"); 3 | }); 4 | -------------------------------------------------------------------------------- /pkg/opengl/errors.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | const glad = @import("glad.zig"); 4 | 5 | pub const Error = error{ 6 | InvalidEnum, 7 | InvalidValue, 8 | InvalidOperation, 9 | InvalidFramebufferOperation, 10 | OutOfMemory, 11 | 12 | Unknown, 13 | }; 14 | 15 | /// getError returns the error (if any) from the last OpenGL operation. 16 | pub fn getError() Error!void { 17 | return switch (glad.context.GetError.?()) { 18 | c.GL_NO_ERROR => {}, 19 | c.GL_INVALID_ENUM => Error.InvalidEnum, 20 | c.GL_INVALID_VALUE => Error.InvalidValue, 21 | c.GL_INVALID_OPERATION => Error.InvalidOperation, 22 | c.GL_INVALID_FRAMEBUFFER_OPERATION => Error.InvalidFramebufferOperation, 23 | c.GL_OUT_OF_MEMORY => Error.OutOfMemory, 24 | else => Error.Unknown, 25 | }; 26 | } 27 | 28 | /// mustError just calls getError but always results in an error being returned. 29 | /// If getError has no error, then Unknown is returned. 30 | pub fn mustError() Error!void { 31 | try getError(); 32 | return Error.Unknown; 33 | } 34 | -------------------------------------------------------------------------------- /pkg/opengl/extensions.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const c = @import("c.zig").c; 3 | const errors = @import("errors.zig"); 4 | const glad = @import("glad.zig"); 5 | 6 | /// Returns the number of extensions. 7 | pub fn len() !u32 { 8 | var n: c.GLint = undefined; 9 | glad.context.GetIntegerv.?(c.GL_NUM_EXTENSIONS, &n); 10 | try errors.getError(); 11 | return @intCast(n); 12 | } 13 | 14 | /// Returns an iterator for the extensions. 15 | pub fn iterator() !Iterator { 16 | return Iterator{ .len = try len() }; 17 | } 18 | 19 | /// Iterator for the available extensions. 20 | pub const Iterator = struct { 21 | /// The total number of extensions. 22 | len: c.GLuint = 0, 23 | i: c.GLuint = 0, 24 | 25 | pub fn next(self: *Iterator) !?[]const u8 { 26 | if (self.i >= self.len) return null; 27 | const res = glad.context.GetStringi.?(c.GL_EXTENSIONS, self.i); 28 | try errors.getError(); 29 | self.i += 1; 30 | return std.mem.sliceTo(res, 0); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /pkg/opengl/primitives.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("c.zig").c; 2 | 3 | pub const Primitive = enum(c_int) { 4 | point = c.GL_POINTS, 5 | line = c.GL_LINES, 6 | line_strip = c.GL_LINE_STRIP, 7 | triangle = c.GL_TRIANGLES, 8 | triangle_strip = c.GL_TRIANGLE_STRIP, 9 | 10 | // Commented out primitive types are excluded for parity with Metal. 11 | // 12 | // line_loop = c.GL_LINE_LOOP, 13 | // line_adjacency = c.GL_LINES_ADJACENCY, 14 | // line_strip_adjacency = c.GL_LINE_STRIP_ADJACENCY, 15 | // triangle_fan = c.GL_TRIANGLE_FAN, 16 | // triangle_adjacency = c.GL_TRIANGLES_ADJACENCY, 17 | // triangle_strip_adjacency = c.GL_TRIANGLE_STRIP_ADJACENCY, 18 | }; 19 | -------------------------------------------------------------------------------- /pkg/sentry/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .sentry, 3 | .version = "0.7.8", 4 | .fingerprint = 0xd177b4a12f6b3b79, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // getsentry/sentry-native 8 | .sentry = .{ 9 | .url = "https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz", 10 | .hash = "N-V-__8AAPlZGwBEa-gxrcypGBZ2R8Bse4JYSfo_ul8i2jlG", 11 | .lazy = true, 12 | }, 13 | 14 | .apple_sdk = .{ .path = "../apple-sdk" }, 15 | .breakpad = .{ .path = "../breakpad", .lazy = true }, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /pkg/sentry/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cInclude("sentry.h"); 3 | }); 4 | -------------------------------------------------------------------------------- /pkg/sentry/envelope.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | const Value = @import("value.zig").Value; 5 | 6 | /// sentry_envelope_t 7 | pub const Envelope = opaque { 8 | pub fn deinit(self: *Envelope) void { 9 | c.sentry_envelope_free(@ptrCast(self)); 10 | } 11 | 12 | pub fn writeToFile(self: *Envelope, path: []const u8) !void { 13 | if (c.sentry_envelope_write_to_file_n( 14 | @ptrCast(self), 15 | path.ptr, 16 | path.len, 17 | ) != 0) return error.WriteFailed; 18 | } 19 | 20 | pub fn serialize(self: *Envelope) []u8 { 21 | var len: usize = 0; 22 | const ptr = c.sentry_envelope_serialize(@ptrCast(self), &len).?; 23 | return ptr[0..len]; 24 | } 25 | 26 | pub fn event(self: *Envelope) ?Value { 27 | const val: Value = .{ .value = c.sentry_envelope_get_event(@ptrCast(self)) }; 28 | if (val.isNull()) return null; 29 | return val; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /pkg/sentry/level.zig: -------------------------------------------------------------------------------- 1 | /// sentry_level_t 2 | pub const Level = enum(c_int) { 3 | debug = -1, 4 | info = 0, 5 | warning = 1, 6 | err = 2, 7 | fatal = 3, 8 | }; 9 | -------------------------------------------------------------------------------- /pkg/sentry/main.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("c.zig").c; 2 | 3 | const transport = @import("transport.zig"); 4 | 5 | pub const Envelope = @import("envelope.zig").Envelope; 6 | pub const Level = @import("level.zig").Level; 7 | pub const Transport = transport.Transport; 8 | pub const Value = @import("value.zig").Value; 9 | pub const UUID = @import("uuid.zig").UUID; 10 | 11 | pub fn captureEvent(value: Value) ?UUID { 12 | const uuid: UUID = .{ .value = c.sentry_capture_event(value.value) }; 13 | if (uuid.isNil()) return null; 14 | return uuid; 15 | } 16 | 17 | pub fn setContext(key: []const u8, value: Value) void { 18 | c.sentry_set_context_n(key.ptr, key.len, value.value); 19 | } 20 | 21 | pub fn removeContext(key: []const u8) void { 22 | c.sentry_remove_context_n(key.ptr, key.len); 23 | } 24 | 25 | pub fn setTag(key: []const u8, value: []const u8) void { 26 | c.sentry_set_tag_n(key.ptr, key.len, value.ptr, value.len); 27 | } 28 | 29 | pub fn free(ptr: *anyopaque) void { 30 | c.sentry_free(ptr); 31 | } 32 | 33 | test { 34 | @import("std").testing.refAllDecls(@This()); 35 | } 36 | -------------------------------------------------------------------------------- /pkg/sentry/transport.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | const Envelope = @import("envelope.zig").Envelope; 5 | 6 | /// sentry_transport_t 7 | pub const Transport = opaque { 8 | pub const SendFunc = *const fn (envelope: *Envelope, state: ?*anyopaque) callconv(.c) void; 9 | pub const FreeFunc = *const fn (state: ?*anyopaque) callconv(.c) void; 10 | 11 | pub fn init(f: SendFunc) *Transport { 12 | return @ptrCast(c.sentry_transport_new(@ptrCast(f)).?); 13 | } 14 | 15 | pub fn deinit(self: *Transport) void { 16 | c.sentry_transport_free(@ptrCast(self)); 17 | } 18 | 19 | pub fn setState(self: *Transport, state: ?*anyopaque) void { 20 | c.sentry_transport_set_state(@ptrCast(self), state); 21 | } 22 | 23 | pub fn setStateFreeFunc(self: *Transport, f: FreeFunc) void { 24 | c.sentry_transport_set_free_func(@ptrCast(self), f); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /pkg/sentry/uuid.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const c = @import("c.zig").c; 4 | 5 | /// sentry_uuid_t 6 | pub const UUID = struct { 7 | value: c.sentry_uuid_t, 8 | 9 | pub fn init() UUID { 10 | return .{ .value = c.sentry_uuid_new_v4() }; 11 | } 12 | 13 | pub fn isNil(self: UUID) bool { 14 | return c.sentry_uuid_is_nil(&self.value) != 0; 15 | } 16 | 17 | pub fn string(self: UUID) [36:0]u8 { 18 | var buf: [36:0]u8 = undefined; 19 | c.sentry_uuid_as_string(&self.value, &buf); 20 | return buf; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /pkg/simdutf/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .simdutf, 3 | .version = "5.2.8", 4 | .fingerprint = 0x7494ad640528a0d, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | .apple_sdk = .{ .path = "../apple-sdk" }, 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /pkg/spirv-cross/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .spirv_cross, 3 | .version = "13.1.1", 4 | .fingerprint = 0x7ea1d8312b06cca, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // KhronosGroup/SPIRV-Cross 8 | .spirv_cross = .{ 9 | .url = "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz", 10 | .hash = "N-V-__8AANb6pwD7O1WG6L5nvD_rNMvnSc9Cpg1ijSlTYywv", 11 | }, 12 | 13 | .apple_sdk = .{ .path = "../apple-sdk" }, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /pkg/spirv-cross/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cInclude("spirv_cross_c.h"); 3 | }); 4 | -------------------------------------------------------------------------------- /pkg/spirv-cross/main.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("c.zig").c; 2 | -------------------------------------------------------------------------------- /pkg/utf8proc/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = "utf8proc", 3 | .version = "2.8.0", 4 | .paths = .{""}, 5 | .dependencies = .{ 6 | .utf8proc = .{ 7 | .url = "https://github.com/JuliaStrings/utf8proc/archive/refs/tags/v2.8.0.tar.gz", 8 | .hash = "1220056ce228a8c58f1fa66ab778f5c8965e62f720c1d30603c7d534cb7d8a605ad7", 9 | }, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /pkg/utf8proc/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | @cInclude("utf8proc.h"); 3 | }); 4 | -------------------------------------------------------------------------------- /pkg/utf8proc/main.zig: -------------------------------------------------------------------------------- 1 | pub const c = @import("c.zig").c; 2 | 3 | /// Given a codepoint, return a character width analogous to `wcwidth(codepoint)`, 4 | /// except that a width of 0 is returned for non-printable codepoints 5 | /// instead of -1 as in `wcwidth`. 6 | pub fn charwidth(codepoint: u21) u8 { 7 | return @intCast(c.utf8proc_charwidth(@intCast(codepoint))); 8 | } 9 | 10 | /// Given a pair of consecutive codepoints, return whether a grapheme break is 11 | /// permitted between them (as defined by the extended grapheme clusters in UAX#29). 12 | pub fn graphemeBreakStateful(cp1: u21, cp2: u21, state: *i32) bool { 13 | return c.utf8proc_grapheme_break_stateful( 14 | @intCast(cp1), 15 | @intCast(cp2), 16 | state, 17 | ); 18 | } 19 | 20 | test {} 21 | -------------------------------------------------------------------------------- /pkg/utfcpp/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .utfcpp, 3 | .version = "4.0.5", 4 | .fingerprint = 0xcd99aeb2334ae11a, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // nemtrif/utfcpp 8 | .utfcpp = .{ 9 | .url = "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz", 10 | .hash = "N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH", 11 | .lazy = true, 12 | }, 13 | 14 | .apple_sdk = .{ .path = "../apple-sdk" }, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /pkg/utfcpp/empty.cc: -------------------------------------------------------------------------------- 1 | // Needed for Zig build to be happy 2 | void ghostty_utfcpp_stub() {} 3 | -------------------------------------------------------------------------------- /pkg/wuffs/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .wuffs, 3 | .version = "0.0.0", 4 | .fingerprint = 0x67c0c059de921c4f, 5 | .dependencies = .{ 6 | // google/wuffs 7 | .wuffs = .{ 8 | .url = "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz", 9 | .hash = "N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs", 10 | .lazy = true, 11 | }, 12 | 13 | // make-github-pseudonymous-again/pixels 14 | .pixels = .{ 15 | .url = "https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz", 16 | .hash = "N-V-__8AADYiAAB_80AWnH1AxXC0tql9thT-R-DYO1gBqTLc", 17 | .lazy = true, 18 | }, 19 | 20 | .apple_sdk = .{ .path = "../apple-sdk" }, 21 | }, 22 | .paths = .{ 23 | "build.zig", 24 | "build.zig.zon", 25 | "src", 26 | }, 27 | } 28 | -------------------------------------------------------------------------------- /pkg/wuffs/src/c.zig: -------------------------------------------------------------------------------- 1 | pub const c = @cImport({ 2 | for (defines) |d| @cDefine(d, "1"); 3 | @cInclude("wuffs-v0.4.c"); 4 | }); 5 | 6 | /// All the C macros defined so that the header matches the build. 7 | pub const defines: []const []const u8 = &[_][]const u8{ 8 | "WUFFS_CONFIG__MODULES", 9 | "WUFFS_CONFIG__MODULE__AUX__BASE", 10 | "WUFFS_CONFIG__MODULE__AUX__IMAGE", 11 | "WUFFS_CONFIG__MODULE__BASE", 12 | "WUFFS_CONFIG__MODULE__ADLER32", 13 | "WUFFS_CONFIG__MODULE__CRC32", 14 | "WUFFS_CONFIG__MODULE__DEFLATE", 15 | "WUFFS_CONFIG__MODULE__JPEG", 16 | "WUFFS_CONFIG__MODULE__PNG", 17 | "WUFFS_CONFIG__MODULE__ZLIB", 18 | }; 19 | -------------------------------------------------------------------------------- /pkg/wuffs/src/error.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | const c = @import("c.zig").c; 4 | 5 | pub const Error = std.mem.Allocator.Error || error{WuffsError}; 6 | 7 | pub fn check(log: anytype, status: *const c.struct_wuffs_base__status__struct) error{WuffsError}!void { 8 | if (!c.wuffs_base__status__is_ok(status)) { 9 | const e = c.wuffs_base__status__message(status); 10 | log.warn("decode err={s}", .{e}); 11 | return error.WuffsError; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /pkg/wuffs/src/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub const png = @import("png.zig"); 4 | pub const jpeg = @import("jpeg.zig"); 5 | pub const swizzle = @import("swizzle.zig"); 6 | pub const Error = @import("error.zig").Error; 7 | 8 | pub const ImageData = struct { 9 | width: u32, 10 | height: u32, 11 | data: []u8, 12 | }; 13 | 14 | test { 15 | std.testing.refAllDeclsRecursive(@This()); 16 | } 17 | -------------------------------------------------------------------------------- /pkg/zlib/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .zlib, 3 | .version = "1.3.1", 4 | .fingerprint = 0x73887d3aef823f9e, 5 | .paths = .{""}, 6 | .dependencies = .{ 7 | // madler/zlib 8 | .zlib = .{ 9 | .url = "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz", 10 | .hash = "N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o", 11 | .lazy = true, 12 | }, 13 | 14 | .apple_sdk = .{ .path = "../apple-sdk" }, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | (import 2 | ( 3 | let 4 | flake-compat = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.flake-compat; 5 | in 6 | fetchTarball { 7 | url = "https://github.com/edolstra/flake-compat/archive/${flake-compat.locked.rev}.tar.gz"; 8 | sha256 = flake-compat.locked.narHash; 9 | } 10 | ) 11 | {src = ./.;}) 12 | .shellNix 13 | -------------------------------------------------------------------------------- /src/apprt/browser.zig: -------------------------------------------------------------------------------- 1 | const internal_os = @import("../os/main.zig"); 2 | pub const resourcesDir = internal_os.resourcesDir; 3 | pub const App = struct {}; 4 | pub const Window = struct {}; 5 | -------------------------------------------------------------------------------- /src/apprt/gtk.zig: -------------------------------------------------------------------------------- 1 | //! Application runtime that uses GTK4. 2 | 3 | pub const App = @import("gtk/App.zig"); 4 | pub const Surface = @import("gtk/Surface.zig"); 5 | pub const resourcesDir = @import("gtk/flatpak.zig").resourcesDir; 6 | 7 | test { 8 | @import("std").testing.refAllDecls(@This()); 9 | 10 | _ = @import("gtk/inspector.zig"); 11 | _ = @import("gtk/key.zig"); 12 | } 13 | -------------------------------------------------------------------------------- /src/apprt/gtk/style-dark.css: -------------------------------------------------------------------------------- 1 | .transparent { 2 | background-color: transparent; 3 | } 4 | 5 | .terminal-window .notebook paned > separator { 6 | background-color: rgba(36, 36, 36, 1); 7 | background-clip: content-box; 8 | } 9 | -------------------------------------------------------------------------------- /src/apprt/gtk/style-hc-dark.css: -------------------------------------------------------------------------------- 1 | .transparent { 2 | background-color: transparent; 3 | } 4 | -------------------------------------------------------------------------------- /src/apprt/gtk/style-hc.css: -------------------------------------------------------------------------------- 1 | .transparent { 2 | background-color: transparent; 3 | } 4 | -------------------------------------------------------------------------------- /src/apprt/gtk/ui/1.0/menu-headerbar-split_menu.blp: -------------------------------------------------------------------------------- 1 | using Gtk 4.0; 2 | 3 | menu menu { 4 | section { 5 | item { 6 | label: _("Split Up"); 7 | action: "win.split-up"; 8 | } 9 | 10 | item { 11 | label: _("Split Down"); 12 | action: "win.split-down"; 13 | } 14 | 15 | item { 16 | label: _("Split Left"); 17 | action: "win.split-left"; 18 | } 19 | 20 | item { 21 | label: _("Split Right"); 22 | action: "win.split-right"; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/apprt/gtk/ui/1.2/config-errors-dialog.blp: -------------------------------------------------------------------------------- 1 | using Gtk 4.0; 2 | using Adw 1; 3 | 4 | Adw.MessageDialog config_errors_dialog { 5 | heading: _("Configuration Errors"); 6 | body: _("One or more configuration errors were found. Please review the errors below, and either reload your configuration or ignore these errors."); 7 | 8 | responses [ 9 | ignore: _("Ignore"), 10 | reload: _("Reload Configuration") suggested, 11 | ] 12 | 13 | extra-child: ScrolledWindow { 14 | min-content-width: 500; 15 | min-content-height: 100; 16 | 17 | TextView { 18 | editable: false; 19 | cursor-visible: false; 20 | top-margin: 8; 21 | bottom-margin: 8; 22 | left-margin: 8; 23 | right-margin: 8; 24 | 25 | buffer: TextBuffer error_message {}; 26 | } 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/apprt/gtk/ui/1.5/config-errors-dialog.blp: -------------------------------------------------------------------------------- 1 | using Gtk 4.0; 2 | using Adw 1; 3 | 4 | Adw.AlertDialog config_errors_dialog { 5 | heading: _("Configuration Errors"); 6 | body: _("One or more configuration errors were found. Please review the errors below, and either reload your configuration or ignore these errors."); 7 | 8 | responses [ 9 | ignore: _("Ignore"), 10 | reload: _("Reload Configuration") suggested, 11 | ] 12 | 13 | extra-child: ScrolledWindow { 14 | min-content-width: 500; 15 | min-content-height: 100; 16 | 17 | TextView { 18 | editable: false; 19 | cursor-visible: false; 20 | top-margin: 8; 21 | bottom-margin: 8; 22 | left-margin: 8; 23 | right-margin: 8; 24 | 25 | buffer: TextBuffer error_message {}; 26 | } 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/apprt/gtk/ui/1.5/prompt-title-dialog.blp: -------------------------------------------------------------------------------- 1 | using Gtk 4.0; 2 | using Adw 1; 3 | 4 | Adw.AlertDialog prompt_title_dialog { 5 | heading: _("Change Terminal Title"); 6 | body: _("Leave blank to restore the default title."); 7 | 8 | responses [ 9 | cancel: _("Cancel") suggested, 10 | ok: _("OK") destructive, 11 | ] 12 | 13 | focus-widget: title_entry; 14 | 15 | extra-child: Entry title_entry {}; 16 | } 17 | -------------------------------------------------------------------------------- /src/apprt/gtk/ui/README.md: -------------------------------------------------------------------------------- 1 | # GTK UI files 2 | 3 | This directory is for storing GTK blueprints. GTK blueprints are compiled into 4 | GTK resource builder `.ui` files by `blueprint-compiler` at build time and then 5 | converted into an embeddable resource by `glib-compile-resources`. 6 | 7 | Blueprint files should be stored in directories that represent the minimum 8 | Adwaita version needed to use that resource. Blueprint files should also be 9 | formatted using `blueprint-compiler format` as well to ensure consistency 10 | (formatting will be checked in CI). 11 | 12 | `blueprint-compiler` version 0.16.0 or newer is required to compile Blueprint 13 | files. If your system does not have `blueprint-compiler` or does not have a 14 | new enough version you can use the generated source tarballs, which contain 15 | precompiled versions of the blueprints. 16 | -------------------------------------------------------------------------------- /src/apprt/none.zig: -------------------------------------------------------------------------------- 1 | const internal_os = @import("../os/main.zig"); 2 | pub const resourcesDir = internal_os.resourcesDir; 3 | pub const App = struct {}; 4 | pub const Surface = struct {}; 5 | -------------------------------------------------------------------------------- /src/benchmark/CApi.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const cli = @import("cli.zig"); 3 | const state = &@import("../global.zig").state; 4 | 5 | const log = std.log.scoped(.benchmark); 6 | 7 | /// Run the Ghostty benchmark CLI with the given action and arguments. 8 | export fn ghostty_benchmark_cli( 9 | action_name_: [*:0]const u8, 10 | args: [*:0]const u8, 11 | ) bool { 12 | const action_name = std.mem.sliceTo(action_name_, 0); 13 | const action: cli.Action = std.meta.stringToEnum( 14 | cli.Action, 15 | action_name, 16 | ) orelse { 17 | log.warn("unknown action={s}", .{action_name}); 18 | return false; 19 | }; 20 | 21 | cli.mainAction( 22 | state.alloc, 23 | action, 24 | .{ .string = std.mem.sliceTo(args, 0) }, 25 | ) catch |err| { 26 | log.warn("failed to run action={s} err={}", .{ 27 | @tagName(action), 28 | err, 29 | }); 30 | return false; 31 | }; 32 | 33 | return true; 34 | } 35 | -------------------------------------------------------------------------------- /src/benchmark/main.zig: -------------------------------------------------------------------------------- 1 | pub const cli = @import("cli.zig"); 2 | pub const Benchmark = @import("Benchmark.zig"); 3 | pub const CApi = @import("CApi.zig"); 4 | pub const TerminalStream = @import("TerminalStream.zig"); 5 | pub const CodepointWidth = @import("CodepointWidth.zig"); 6 | pub const GraphemeBreak = @import("GraphemeBreak.zig"); 7 | pub const TerminalParser = @import("TerminalParser.zig"); 8 | 9 | test { 10 | @import("std").testing.refAllDecls(@This()); 11 | } 12 | -------------------------------------------------------------------------------- /src/benchmark/options.zig: -------------------------------------------------------------------------------- 1 | //! This file contains helpers for CLI options. 2 | 3 | const std = @import("std"); 4 | 5 | /// Returns the data file for the given path in a way that is consistent 6 | /// across our CLI. If the path is not set then no file is returned. 7 | /// If the path is "-", then we will return stdin. If the path is 8 | /// a file then we will open and return the handle. 9 | pub fn dataFile(path_: ?[]const u8) !?std.fs.File { 10 | const path = path_ orelse return null; 11 | 12 | // Stdin 13 | if (std.mem.eql(u8, path, "-")) return std.io.getStdIn(); 14 | 15 | // Normal file 16 | const file = try std.fs.cwd().openFile(path, .{}); 17 | errdefer file.close(); 18 | 19 | return file; 20 | } 21 | -------------------------------------------------------------------------------- /src/build/gtk.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub const Targets = packed struct { 4 | x11: bool = false, 5 | wayland: bool = false, 6 | }; 7 | 8 | /// Returns the targets that GTK4 was compiled with. 9 | pub fn targets(b: *std.Build) Targets { 10 | // Run pkg-config. We allow it to fail so that zig build --help 11 | // works without all dependencies. The build will fail later when 12 | // GTK isn't found anyways. 13 | var code: u8 = undefined; 14 | const output = b.runAllowFail( 15 | &.{ "pkg-config", "--variable=targets", "gtk4" }, 16 | &code, 17 | .Ignore, 18 | ) catch return .{}; 19 | 20 | const x11 = std.mem.indexOf(u8, output, "x11") != null; 21 | const wayland = std.mem.indexOf(u8, output, "wayland") != null; 22 | 23 | return .{ 24 | .x11 = x11, 25 | .wayland = wayland, 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /src/build/mdgen/ghostty_1_header.md: -------------------------------------------------------------------------------- 1 | % GHOSTTY(1) Version @@VERSION@@ | Ghostty terminal emulator 2 | 3 | # NAME 4 | 5 | **ghostty** - Ghostty terminal emulator 6 | 7 | # DESCRIPTION 8 | 9 | Ghostty is a cross-platform, GPU-accelerated terminal emulator that aims to push 10 | the boundaries of what is possible with a terminal emulator by exposing modern, 11 | opt-in features that enable CLI tool developers to build more feature rich, 12 | interactive applications. 13 | 14 | There are a number of excellent terminal emulator options that exist today. 15 | The unique goal of Ghostty is to have a platform for experimenting with modern, 16 | optional, non-standards-compliant features to enhance the capabilities of CLI 17 | applications. We aim to be the best in this category, and competitive in the 18 | rest. 19 | 20 | While aiming for this ambitious goal, Ghostty is a fully standards compliant 21 | terminal emulator that aims to remain compatible with all existing shells and 22 | software. You can use this as a drop-in replacement for your existing terminal 23 | emulator. 24 | -------------------------------------------------------------------------------- /src/build/mdgen/main_ghostty_1.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const gen = @import("mdgen.zig"); 3 | 4 | pub fn main() !void { 5 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 6 | const alloc = gpa.allocator(); 7 | 8 | const writer = std.io.getStdOut().writer(); 9 | try gen.substitute(alloc, @embedFile("ghostty_1_header.md"), writer); 10 | try gen.genActions(writer); 11 | try gen.genConfig(writer, true); 12 | try gen.substitute(alloc, @embedFile("ghostty_1_footer.md"), writer); 13 | } 14 | -------------------------------------------------------------------------------- /src/build/mdgen/main_ghostty_5.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const gen = @import("mdgen.zig"); 3 | 4 | pub fn main() !void { 5 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 6 | const alloc = gpa.allocator(); 7 | 8 | const output = std.io.getStdOut().writer(); 9 | try gen.substitute(alloc, @embedFile("ghostty_5_header.md"), output); 10 | try gen.genConfig(output, false); 11 | try gen.genKeybindActions(output); 12 | try gen.substitute(alloc, @embedFile("ghostty_5_footer.md"), output); 13 | } 14 | -------------------------------------------------------------------------------- /src/build/webgen/main_actions.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const help_strings = @import("help_strings"); 3 | const helpgen_actions = @import("../../input/helpgen_actions.zig"); 4 | 5 | pub fn main() !void { 6 | const output = std.io.getStdOut().writer(); 7 | try helpgen_actions.generate(output, .markdown, true, std.heap.page_allocator); 8 | } 9 | -------------------------------------------------------------------------------- /src/build/zig.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | 4 | /// Require a specific version of Zig to build this project. 5 | pub fn requireZig(comptime required_zig: []const u8) void { 6 | // Fail compilation if the current Zig version doesn't meet requirements. 7 | const current_vsn = builtin.zig_version; 8 | const required_vsn = std.SemanticVersion.parse(required_zig) catch unreachable; 9 | if (current_vsn.major != required_vsn.major or 10 | current_vsn.minor != required_vsn.minor) 11 | { 12 | @compileError(std.fmt.comptimePrint( 13 | "Your Zig version v{} does not meet the required build version of v{}", 14 | .{ current_vsn, required_vsn }, 15 | )); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/cli.zig: -------------------------------------------------------------------------------- 1 | const diags = @import("cli/diagnostics.zig"); 2 | 3 | pub const args = @import("cli/args.zig"); 4 | pub const action = @import("cli/action.zig"); 5 | pub const ghostty = @import("cli/ghostty.zig"); 6 | pub const CompatibilityHandler = args.CompatibilityHandler; 7 | pub const compatibilityRenamed = args.compatibilityRenamed; 8 | pub const DiagnosticList = diags.DiagnosticList; 9 | pub const Diagnostic = diags.Diagnostic; 10 | pub const Location = diags.Location; 11 | 12 | test { 13 | @import("std").testing.refAllDecls(@This()); 14 | } 15 | -------------------------------------------------------------------------------- /src/cli/README.md: -------------------------------------------------------------------------------- 1 | # Subcommand Actions 2 | 3 | This is the cli specific code. It contains cli actions and tui definitions and 4 | argument parsing. 5 | 6 | This README is meant as developer documentation and not as user documentation. 7 | For user documentation, see the main README or [ghostty.org](https://ghostty.org/docs). 8 | 9 | ## Updating documentation 10 | 11 | Each cli action is defined in it's own file. Documentation for each action is defined 12 | in the doc comment associated with the `run` function. For example the `run` function 13 | in `list_keybinds.zig` contains the help text for `ghostty +list-keybinds`. 14 | -------------------------------------------------------------------------------- /src/cli/tui.zig: -------------------------------------------------------------------------------- 1 | const builtin = @import("builtin"); 2 | 3 | pub const can_pretty_print = switch (builtin.os.tag) { 4 | .ios, .tvos, .watchos => false, 5 | else => true, 6 | }; 7 | -------------------------------------------------------------------------------- /src/config/ErrorList.zig: -------------------------------------------------------------------------------- 1 | const ErrorList = @This(); 2 | 3 | const std = @import("std"); 4 | const Allocator = std.mem.Allocator; 5 | 6 | pub const Error = struct { 7 | message: [:0]const u8, 8 | }; 9 | 10 | /// The list of errors. This will use the arena allocator associated 11 | /// with the config structure (or whatever allocated used to call ErrorList 12 | /// functions). 13 | list: std.ArrayListUnmanaged(Error) = .{}, 14 | 15 | /// True if there are no errors. 16 | pub fn empty(self: ErrorList) bool { 17 | return self.list.items.len == 0; 18 | } 19 | 20 | /// Add a new error to the list. 21 | pub fn add(self: *ErrorList, alloc: Allocator, err: Error) !void { 22 | try self.list.append(alloc, err); 23 | } 24 | -------------------------------------------------------------------------------- /src/config/testdata/theme_dark: -------------------------------------------------------------------------------- 1 | background = #EEEEEE 2 | -------------------------------------------------------------------------------- /src/config/testdata/theme_light: -------------------------------------------------------------------------------- 1 | background = #FFFFFF 2 | -------------------------------------------------------------------------------- /src/config/testdata/theme_simple: -------------------------------------------------------------------------------- 1 | # A simple theme 2 | background = #123ABC 3 | -------------------------------------------------------------------------------- /src/crash/main.zig: -------------------------------------------------------------------------------- 1 | //! The crash package contains all the logic around crash handling, 2 | //! whether that's setting up the system to catch crashes (Sentry client), 3 | //! introspecting crash reports, writing crash reports to disk, etc. 4 | 5 | const dir = @import("dir.zig"); 6 | const sentry_envelope = @import("sentry_envelope.zig"); 7 | 8 | pub const minidump = @import("minidump.zig"); 9 | pub const sentry = @import("sentry.zig"); 10 | pub const Envelope = sentry_envelope.Envelope; 11 | pub const defaultDir = dir.defaultDir; 12 | pub const Dir = dir.Dir; 13 | pub const ReportIterator = dir.ReportIterator; 14 | pub const Report = dir.Report; 15 | 16 | // The main init/deinit functions for global state. 17 | pub const init = sentry.init; 18 | pub const deinit = sentry.deinit; 19 | 20 | test { 21 | @import("std").testing.refAllDecls(@This()); 22 | } 23 | -------------------------------------------------------------------------------- /src/crash/minidump.zig: -------------------------------------------------------------------------------- 1 | pub const reader = @import("minidump/reader.zig"); 2 | pub const stream = @import("minidump/stream.zig"); 3 | pub const Reader = reader.Reader; 4 | 5 | test { 6 | @import("std").testing.refAllDecls(@This()); 7 | } 8 | -------------------------------------------------------------------------------- /src/crash/minidump/stream.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const Allocator = std.mem.Allocator; 4 | 5 | const log = std.log.scoped(.minidump_stream); 6 | 7 | /// The known stream types. 8 | pub const thread_list = @import("stream_threadlist.zig"); 9 | 10 | /// A stream within the minidump file. A stream can be either in an encoded 11 | /// form or decoded form. The encoded form are raw bytes and aren't validated 12 | /// until they're decoded. The decoded form is a structured form of the stream. 13 | /// 14 | /// The decoded form is more ergonomic to work with but the encoded form is 15 | /// more efficient to read/write. 16 | pub const Stream = union(enum) { 17 | encoded: EncodedStream, 18 | }; 19 | 20 | /// An encoded stream value. It is "encoded" in the sense that it is raw bytes 21 | /// with a type associated. The raw bytes are not validated to be correct for 22 | /// the type. 23 | pub const EncodedStream = struct { 24 | type: u32, 25 | data: []const u8, 26 | }; 27 | 28 | test { 29 | @import("std").testing.refAllDecls(@This()); 30 | } 31 | -------------------------------------------------------------------------------- /src/crash/testdata/macos.dmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/crash/testdata/macos.dmp -------------------------------------------------------------------------------- /src/datastruct/main.zig: -------------------------------------------------------------------------------- 1 | //! The datastruct package contains data structures or anything closely 2 | //! related to data structures. 3 | 4 | const blocking_queue = @import("blocking_queue.zig"); 5 | const cache_table = @import("cache_table.zig"); 6 | const circ_buf = @import("circ_buf.zig"); 7 | const intrusive_linked_list = @import("intrusive_linked_list.zig"); 8 | const segmented_pool = @import("segmented_pool.zig"); 9 | 10 | pub const lru = @import("lru.zig"); 11 | pub const BlockingQueue = blocking_queue.BlockingQueue; 12 | pub const CacheTable = cache_table.CacheTable; 13 | pub const CircBuf = circ_buf.CircBuf; 14 | pub const IntrusiveDoublyLinkedList = intrusive_linked_list.DoublyLinkedList; 15 | pub const SegmentedPool = segmented_pool.SegmentedPool; 16 | 17 | test { 18 | @import("std").testing.refAllDecls(@This()); 19 | } 20 | -------------------------------------------------------------------------------- /src/font/Glyph.zig: -------------------------------------------------------------------------------- 1 | //! Glyph is a single loaded glyph for a face. 2 | const Glyph = @This(); 3 | 4 | /// width of glyph in pixels 5 | width: u32, 6 | 7 | /// height of glyph in pixels 8 | height: u32, 9 | 10 | /// left bearing 11 | offset_x: i32, 12 | 13 | /// top bearing 14 | offset_y: i32, 15 | 16 | /// coordinates in the atlas of the top-left corner. These have to 17 | /// be normalized to be between 0 and 1 prior to use in shaders. 18 | atlas_x: u32, 19 | atlas_y: u32, 20 | -------------------------------------------------------------------------------- /src/font/opentype.zig: -------------------------------------------------------------------------------- 1 | pub const sfnt = @import("opentype/sfnt.zig"); 2 | 3 | const svg = @import("opentype/svg.zig"); 4 | const os2 = @import("opentype/os2.zig"); 5 | const post = @import("opentype/post.zig"); 6 | const hhea = @import("opentype/hhea.zig"); 7 | const head = @import("opentype/head.zig"); 8 | 9 | pub const SVG = svg.SVG; 10 | pub const OS2 = os2.OS2; 11 | pub const Post = post.Post; 12 | pub const Hhea = hhea.Hhea; 13 | pub const Head = head.Head; 14 | 15 | test { 16 | @import("std").testing.refAllDecls(@This()); 17 | } 18 | -------------------------------------------------------------------------------- /src/font/res/CodeNewRoman-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/CodeNewRoman-Regular.otf -------------------------------------------------------------------------------- /src/font/res/CozetteVector.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/CozetteVector.ttf -------------------------------------------------------------------------------- /src/font/res/GeistMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/GeistMono-Regular.ttf -------------------------------------------------------------------------------- /src/font/res/Inconsolata-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/Inconsolata-Regular.ttf -------------------------------------------------------------------------------- /src/font/res/JetBrainsMonoNerdFont-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/JetBrainsMonoNerdFont-Bold.ttf -------------------------------------------------------------------------------- /src/font/res/JetBrainsMonoNerdFont-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/JetBrainsMonoNerdFont-BoldItalic.ttf -------------------------------------------------------------------------------- /src/font/res/JetBrainsMonoNerdFont-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/JetBrainsMonoNerdFont-Italic.ttf -------------------------------------------------------------------------------- /src/font/res/JetBrainsMonoNerdFont-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/JetBrainsMonoNerdFont-Regular.ttf -------------------------------------------------------------------------------- /src/font/res/JetBrainsMonoNoNF-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/JetBrainsMonoNoNF-Regular.ttf -------------------------------------------------------------------------------- /src/font/res/JuliaMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/JuliaMono-Regular.ttf -------------------------------------------------------------------------------- /src/font/res/KawkabMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/KawkabMono-Regular.ttf -------------------------------------------------------------------------------- /src/font/res/Lilex-VF.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/Lilex-VF.ttf -------------------------------------------------------------------------------- /src/font/res/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/font/res/MonaspaceNeon-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/MonaspaceNeon-Regular.otf -------------------------------------------------------------------------------- /src/font/res/NotoColorEmoji.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/NotoColorEmoji.ttf -------------------------------------------------------------------------------- /src/font/res/NotoEmoji-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/NotoEmoji-Regular.ttf -------------------------------------------------------------------------------- /src/font/res/TerminusTTF-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/res/TerminusTTF-Regular.ttf -------------------------------------------------------------------------------- /src/font/shaper/testdata/arabic.txt: -------------------------------------------------------------------------------- 1 | غريبه لاني عربي أبا عن جد 2 | واتكلم الانجليزية بطلاقة اكثر من ٢٥ سنه 3 | ومع هذا اجد العربيه افضل لان فيها الكثير من المفردات الاكثر دقه بالوصف 4 | -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CC00...U+1CCFF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CC00...U+1CCFF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CC00...U+1CCFF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CC00...U+1CCFF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CC00...U+1CCFF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CC00...U+1CCFF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CC00...U+1CCFF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CC00...U+1CCFF-9x17+1.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CD00...U+1CDFF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CD00...U+1CDFF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CD00...U+1CDFF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CD00...U+1CDFF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CD00...U+1CDFF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CD00...U+1CDFF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CD00...U+1CDFF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CD00...U+1CDFF-9x17+1.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CE00...U+1CEFF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CE00...U+1CEFF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CE00...U+1CEFF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CE00...U+1CEFF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CE00...U+1CEFF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CE00...U+1CEFF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1CE00...U+1CEFF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1CE00...U+1CEFF-9x17+1.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1FB00...U+1FBFF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1FB00...U+1FBFF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1FB00...U+1FBFF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1FB00...U+1FBFF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1FB00...U+1FBFF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1FB00...U+1FBFF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+1FB00...U+1FBFF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+1FB00...U+1FBFF-9x17+1.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+2500...U+25FF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+2500...U+25FF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+2500...U+25FF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+2500...U+25FF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+2500...U+25FF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+2500...U+25FF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+2500...U+25FF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+2500...U+25FF-9x17+1.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+2800...U+28FF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+2800...U+28FF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+2800...U+28FF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+2800...U+28FF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+2800...U+28FF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+2800...U+28FF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+2800...U+28FF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+2800...U+28FF-9x17+1.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+E000...U+E0FF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+E000...U+E0FF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+E000...U+E0FF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+E000...U+E0FF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+E000...U+E0FF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+E000...U+E0FF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+E000...U+E0FF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+E000...U+E0FF-9x17+1.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+F500...U+F5FF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+F500...U+F5FF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+F500...U+F5FF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+F500...U+F5FF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+F500...U+F5FF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+F500...U+F5FF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+F500...U+F5FF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+F500...U+F5FF-9x17+1.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+F600...U+F6FF-11x21+2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+F600...U+F6FF-11x21+2.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+F600...U+F6FF-12x24+3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+F600...U+F6FF-12x24+3.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+F600...U+F6FF-18x36+4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+F600...U+F6FF-18x36+4.png -------------------------------------------------------------------------------- /src/font/sprite/testdata/U+F600...U+F6FF-9x17+1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/font/sprite/testdata/U+F600...U+F6FF-9x17+1.png -------------------------------------------------------------------------------- /src/input/KeymapNoop.zig: -------------------------------------------------------------------------------- 1 | //! A noop implementation of the keymap interface so that the embedded 2 | //! library can compile on non-macOS platforms. 3 | const KeymapNoop = @This(); 4 | 5 | const Mods = @import("key.zig").Mods; 6 | 7 | pub const State = struct {}; 8 | pub const Translation = struct { 9 | text: []const u8 = "", 10 | composing: bool = false, 11 | mods: Mods = .{}, 12 | }; 13 | 14 | pub fn init() !KeymapNoop { 15 | return .{}; 16 | } 17 | 18 | pub fn deinit(self: *const KeymapNoop) void { 19 | _ = self; 20 | } 21 | 22 | pub fn reload(self: *KeymapNoop) !void { 23 | _ = self; 24 | } 25 | 26 | pub fn translate( 27 | self: *const KeymapNoop, 28 | out: []u8, 29 | state: *State, 30 | code: u16, 31 | mods: Mods, 32 | ) !Translation { 33 | _ = self; 34 | _ = out; 35 | _ = state; 36 | _ = code; 37 | _ = mods; 38 | return .{ .text = "", .composing = false }; 39 | } 40 | -------------------------------------------------------------------------------- /src/inspector/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | pub const cell = @import("cell.zig"); 3 | pub const cursor = @import("cursor.zig"); 4 | pub const key = @import("key.zig"); 5 | pub const page = @import("page.zig"); 6 | pub const termio = @import("termio.zig"); 7 | 8 | pub const Cell = cell.Cell; 9 | pub const Inspector = @import("Inspector.zig"); 10 | 11 | test { 12 | @import("std").testing.refAllDecls(@This()); 13 | } 14 | -------------------------------------------------------------------------------- /src/inspector/units.zig: -------------------------------------------------------------------------------- 1 | pub fn toKibiBytes(bytes: usize) usize { 2 | return bytes / 1024; 3 | } 4 | -------------------------------------------------------------------------------- /src/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const build_config = @import("build_config.zig"); 3 | 4 | /// See build_config.ExeEntrypoint for why we do this. 5 | const entrypoint = switch (build_config.exe_entrypoint) { 6 | .ghostty => @import("main_ghostty.zig"), 7 | .helpgen => @import("helpgen.zig"), 8 | .mdgen_ghostty_1 => @import("build/mdgen/main_ghostty_1.zig"), 9 | .mdgen_ghostty_5 => @import("build/mdgen/main_ghostty_5.zig"), 10 | .webgen_config => @import("build/webgen/main_config.zig"), 11 | .webgen_actions => @import("build/webgen/main_actions.zig"), 12 | .webgen_commands => @import("build/webgen/main_commands.zig"), 13 | }; 14 | 15 | /// The main entrypoint for the program. 16 | pub const main = entrypoint.main; 17 | 18 | /// Standard options such as logger overrides. 19 | pub const std_options: std.Options = if (@hasDecl(entrypoint, "std_options")) 20 | entrypoint.std_options 21 | else 22 | .{}; 23 | 24 | test { 25 | _ = entrypoint; 26 | } 27 | -------------------------------------------------------------------------------- /src/main_bench.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | const benchmark = @import("benchmark/main.zig"); 4 | 5 | pub const main = benchmark.cli.main; 6 | -------------------------------------------------------------------------------- /src/main_gen.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | const synthetic = @import("synthetic/main.zig"); 4 | 5 | pub const main = synthetic.cli.main; 6 | -------------------------------------------------------------------------------- /src/main_wasm.zig: -------------------------------------------------------------------------------- 1 | // This is the main file for the WASM module. The WASM module has to 2 | // export a C ABI compatible API. 3 | const std = @import("std"); 4 | const builtin = @import("builtin"); 5 | 6 | comptime { 7 | _ = @import("os/wasm.zig"); 8 | _ = @import("font/main.zig"); 9 | _ = @import("terminal/main.zig"); 10 | _ = @import("config.zig").Wasm; 11 | _ = @import("App.zig").Wasm; 12 | } 13 | 14 | pub const std_options = struct { 15 | // Set our log level. We try to get as much logging as possible but in 16 | // ReleaseSmall mode where we're optimizing for space, we elevate the 17 | // log level. 18 | pub const log_level: std.log.Level = switch (builtin.mode) { 19 | .Debug => .debug, 20 | .ReleaseSmall => .warn, 21 | else => .info, 22 | }; 23 | 24 | // Set our log function 25 | pub const logFn = @import("os/wasm/log.zig").log; 26 | }; 27 | -------------------------------------------------------------------------------- /src/math.zig: -------------------------------------------------------------------------------- 1 | /// Matrix type 2 | pub const Mat = [4]F32x4; 3 | pub const F32x4 = @Vector(4, f32); 4 | 5 | /// 2D orthographic projection matrix 6 | pub fn ortho2d(left: f32, right: f32, bottom: f32, top: f32) Mat { 7 | const w = right - left; 8 | const h = top - bottom; 9 | return .{ 10 | .{ 2 / w, 0, 0, 0 }, 11 | .{ 0, 2 / h, 0, 0 }, 12 | .{ 0.0, 0.0, -1.0, 0.0 }, 13 | .{ -(right + left) / w, -(top + bottom) / h, 0.0, 1.0 }, 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /src/os/dbus.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | 4 | /// Returns true if the program was launched by D-Bus activation. 5 | /// 6 | /// On Linux GTK, this returns true if the program was launched using D-Bus 7 | /// activation. It will return false if Ghostty was launched any other way. 8 | /// 9 | /// For other platforms and app runtimes, this returns false. 10 | pub fn launchedByDbusActivation() bool { 11 | return switch (builtin.os.tag) { 12 | // On Linux, D-Bus activation sets `DBUS_STARTER_ADDRESS` and 13 | // `DBUS_STARTER_BUS_TYPE`. If these environment variables are present 14 | // (no matter the value) we were launched by D-Bus activation. 15 | .linux => std.posix.getenv("DBUS_STARTER_ADDRESS") != null and 16 | std.posix.getenv("DBUS_STARTER_BUS_TYPE") != null, 17 | 18 | // No other system supports D-Bus so always return false. 19 | else => false, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /src/os/kernel_info.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | 4 | pub fn getKernelInfo(alloc: std.mem.Allocator) ?[]const u8 { 5 | if (comptime builtin.os.tag != .linux) return null; 6 | const path = "/proc/sys/kernel/osrelease"; 7 | var file = std.fs.openFileAbsolute(path, .{}) catch return null; 8 | defer file.close(); 9 | 10 | // 128 bytes should be enough to hold the kernel information 11 | const kernel_info = file.readToEndAlloc(alloc, 128) catch return null; 12 | defer alloc.free(kernel_info); 13 | return alloc.dupe(u8, std.mem.trim(u8, kernel_info, &std.ascii.whitespace)) catch return null; 14 | } 15 | 16 | test "read /proc/sys/kernel/osrelease" { 17 | if (comptime builtin.os.tag != .linux) return null; 18 | const allocator = std.testing.allocator; 19 | 20 | const kernel_info = getKernelInfo(allocator).?; 21 | defer allocator.free(kernel_info); 22 | 23 | // Since we can't hardcode the info in tests, just check 24 | // if something was read from the file 25 | try std.testing.expect(kernel_info.len > 0); 26 | try std.testing.expect(!std.mem.eql(u8, kernel_info, "")); 27 | } 28 | -------------------------------------------------------------------------------- /src/os/mouse.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | const assert = std.debug.assert; 4 | const objc = @import("objc"); 5 | 6 | const log = std.log.scoped(.os); 7 | 8 | /// The system-configured double-click interval if its available. 9 | pub fn clickInterval() ?u32 { 10 | return switch (builtin.os.tag) { 11 | // On macOS, we can ask the system. 12 | .macos => macos: { 13 | const NSEvent = objc.getClass("NSEvent") orelse { 14 | log.err("NSEvent class not found. Can't get click interval.", .{}); 15 | return null; 16 | }; 17 | 18 | // Get the interval and convert to ms 19 | const interval = NSEvent.msgSend(f64, objc.sel("doubleClickInterval"), .{}); 20 | const ms = @as(u32, @intFromFloat(@ceil(interval * 1000))); 21 | break :macos ms; 22 | }, 23 | 24 | else => null, 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/os/pipe.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | const windows = @import("windows.zig"); 4 | const posix = std.posix; 5 | 6 | /// pipe() that works on Windows and POSIX. For POSIX systems, this sets 7 | /// CLOEXEC on the file descriptors. 8 | pub fn pipe() ![2]posix.fd_t { 9 | switch (builtin.os.tag) { 10 | else => return try posix.pipe2(.{ .CLOEXEC = true }), 11 | .windows => { 12 | var read: windows.HANDLE = undefined; 13 | var write: windows.HANDLE = undefined; 14 | if (windows.exp.kernel32.CreatePipe(&read, &write, null, 0) == 0) { 15 | return windows.unexpectedError(windows.kernel32.GetLastError()); 16 | } 17 | 18 | return .{ read, write }; 19 | }, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/os/wasm/target.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | const options = @import("build_options"); 4 | 5 | /// The wasm target platform. This is used to toggle certain features 6 | /// on and off since the standard triple target is often not specific 7 | /// enough (i.e. we can't tell wasm32-freestanding is for browser or not). 8 | pub const Target = enum { 9 | browser, 10 | }; 11 | 12 | /// Our specific target platform. 13 | pub const target: ?Target = if (!builtin.target.isWasm()) null else target: { 14 | const result = @as(Target, @enumFromInt(@intFromEnum(options.wasm_target))); 15 | // This maybe isn't necessary but I don't know if enums without a specific 16 | // tag type and value are guaranteed to be the same between build.zig 17 | // compilation and our own source compilation so I have this just in case. 18 | std.debug.assert(std.mem.eql(u8, @tagName(result), @tagName(options.wasm_target))); 19 | break :target result; 20 | }; 21 | -------------------------------------------------------------------------------- /src/renderer/Options.zig: -------------------------------------------------------------------------------- 1 | //! The options that are used to configure a renderer. 2 | 3 | const apprt = @import("../apprt.zig"); 4 | const font = @import("../font/main.zig"); 5 | const renderer = @import("../renderer.zig"); 6 | const Config = @import("../config.zig").Config; 7 | 8 | /// The derived configuration for this renderer implementation. 9 | config: renderer.Renderer.DerivedConfig, 10 | 11 | /// The font grid that should be used along with the key for deref-ing. 12 | font_grid: *font.SharedGrid, 13 | 14 | /// The size of everything. 15 | size: renderer.Size, 16 | 17 | /// The mailbox for sending the surface messages. This is only valid 18 | /// once the thread has started and should not be used outside of the thread. 19 | surface_mailbox: apprt.surface.Mailbox, 20 | 21 | /// The apprt surface. 22 | rt_surface: *apprt.Surface, 23 | 24 | /// The renderer thread. 25 | thread: *renderer.Thread, 26 | -------------------------------------------------------------------------------- /src/renderer/WebGL.zig: -------------------------------------------------------------------------------- 1 | //! Renderer implementation for WebGL in the browser. 2 | pub const WebGL = @This(); 3 | -------------------------------------------------------------------------------- /src/renderer/shaders/glsl/bg_color.f.glsl: -------------------------------------------------------------------------------- 1 | #include "common.glsl" 2 | 3 | // Must declare this output for some versions of OpenGL. 4 | layout(location = 0) out vec4 out_FragColor; 5 | 6 | void main() { 7 | bool use_linear_blending = (bools & USE_LINEAR_BLENDING) != 0; 8 | 9 | out_FragColor = load_color( 10 | unpack4u8(bg_color_packed_4u8), 11 | use_linear_blending 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/renderer/shaders/glsl/full_screen.v.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | void main() { 4 | vec4 position; 5 | position.x = (gl_VertexID == 2) ? 3.0 : -1.0; 6 | position.y = (gl_VertexID == 0) ? -3.0 : 1.0; 7 | position.z = 1.0; 8 | position.w = 1.0; 9 | 10 | // Single triangle is clipped to viewport. 11 | // 12 | // X <- vid == 0: (-1, -3) 13 | // |\ 14 | // | \ 15 | // | \ 16 | // |###\ 17 | // |#+# \ `+` is (0, 0). `#`s are viewport area. 18 | // |### \ 19 | // X------X <- vid == 2: (3, 1) 20 | // ^ 21 | // vid == 1: (-1, 1) 22 | 23 | gl_Position = position; 24 | } 25 | -------------------------------------------------------------------------------- /src/renderer/shaders/glsl/image.f.glsl: -------------------------------------------------------------------------------- 1 | #include "common.glsl" 2 | 3 | layout(binding = 0) uniform sampler2D image; 4 | 5 | in vec2 tex_coord; 6 | 7 | layout(location = 0) out vec4 out_FragColor; 8 | 9 | void main() { 10 | bool use_linear_blending = (bools & USE_LINEAR_BLENDING) != 0; 11 | 12 | vec4 rgba = texture(image, tex_coord); 13 | 14 | if (!use_linear_blending) { 15 | rgba = unlinearize(rgba); 16 | } 17 | 18 | rgba.rgb *= vec3(rgba.a); 19 | 20 | out_FragColor = rgba; 21 | } 22 | -------------------------------------------------------------------------------- /src/renderer/shaders/test_shadertoy_invalid.glsl: -------------------------------------------------------------------------------- 1 | vec2 curve(vec2 uv) 2 | { 3 | uv = (uv - 0.5) * 2.0; 4 | uv *= 1.1; 5 | uv.x *= 1.0 + pow((abs(uv.y) / 5.0), 2.0); 6 | uv.y *= 1.0 + pow((abs(uv.x) / 4.0), 2.0); 7 | uv = (uv / 2.0) + 0.5; 8 | uv = uv *0.92 + 0.04; 9 | return uv; 10 | } 11 | 12 | // Missing mainImage! 13 | -------------------------------------------------------------------------------- /src/simd/base64.cpp: -------------------------------------------------------------------------------- 1 | #include <simdutf.h> 2 | 3 | extern "C" { 4 | 5 | size_t ghostty_simd_base64_max_length(const char* input, size_t length) { 6 | return simdutf::maximal_binary_length_from_base64(input, length); 7 | } 8 | 9 | size_t ghostty_simd_base64_decode(const char* input, 10 | size_t length, 11 | char* output) { 12 | simdutf::result r = simdutf::base64_to_binary(input, length, output); 13 | if (r.error) { 14 | return -1; 15 | } 16 | 17 | return r.count; 18 | } 19 | 20 | } // extern "C" 21 | -------------------------------------------------------------------------------- /src/simd/index_of.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | 4 | extern "c" fn ghostty_simd_index_of( 5 | needle: u8, 6 | input: [*]const u8, 7 | count: usize, 8 | ) usize; 9 | 10 | pub fn indexOf(input: []const u8, needle: u8) ?usize { 11 | const result = ghostty_simd_index_of(needle, input.ptr, input.len); 12 | return if (result == input.len) null else result; 13 | } 14 | 15 | test "indexOf" { 16 | const testing = std.testing; 17 | try testing.expect(indexOf("hello", ' ') == null); 18 | try testing.expectEqual(@as(usize, 2), indexOf("hi lo", ' ').?); 19 | try testing.expectEqual(@as(usize, 5), indexOf( 20 | \\XXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 21 | \\XXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXXXX 22 | , ' ').?); 23 | try testing.expectEqual(@as(usize, 53), indexOf( 24 | \\XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 25 | \\XXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXXXX 26 | , ' ').?); 27 | } 28 | -------------------------------------------------------------------------------- /src/simd/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | const codepoint_width = @import("codepoint_width.zig"); 4 | pub const base64 = @import("base64.zig"); 5 | pub const index_of = @import("index_of.zig"); 6 | pub const vt = @import("vt.zig"); 7 | pub const codepointWidth = codepoint_width.codepointWidth; 8 | 9 | test { 10 | @import("std").testing.refAllDecls(@This()); 11 | } 12 | -------------------------------------------------------------------------------- /src/simd/vt.h: -------------------------------------------------------------------------------- 1 | #if defined(GHOSTTY_SIMD_VT_H_) == defined(HWY_TARGET_TOGGLE) 2 | #ifdef GHOSTTY_SIMD_VT_H_ 3 | #undef GHOSTTY_SIMD_VT_H_ 4 | #else 5 | #define GHOSTTY_SIMD_VT_H_ 6 | #endif 7 | 8 | #include <hwy/highway.h> 9 | 10 | HWY_BEFORE_NAMESPACE(); 11 | namespace ghostty { 12 | namespace HWY_NAMESPACE { 13 | 14 | namespace hn = hwy::HWY_NAMESPACE; 15 | 16 | } // namespace HWY_NAMESPACE 17 | } // namespace ghostty 18 | HWY_AFTER_NAMESPACE(); 19 | 20 | #if HWY_ONCE 21 | 22 | namespace ghostty { 23 | 24 | typedef void (*PrintFunc)(const char32_t* chars, size_t count); 25 | 26 | } // namespace ghostty 27 | 28 | #endif // HWY_ONCE 29 | 30 | #endif // GHOSTTY_SIMD_VT_H_ 31 | -------------------------------------------------------------------------------- /src/stb/main.zig: -------------------------------------------------------------------------------- 1 | const c = @cImport({ 2 | @cInclude("stb_image.h"); 3 | @cInclude("stb_image_resize.h"); 4 | }); 5 | 6 | // We'll just add the exports of the functions or types we actually use 7 | // here, no need to export everything from the C lib if we don't use it. 8 | pub const stbi_load_from_memory = c.stbi_load_from_memory; 9 | pub const stbi_image_free = c.stbi_image_free; 10 | pub const stbir_resize_uint8 = c.stbir_resize_uint8; 11 | -------------------------------------------------------------------------------- /src/stb/stb.c: -------------------------------------------------------------------------------- 1 | // For STBI we only need PNG because the only use case we have right now 2 | // is the Kitty Graphics protocol which only supports PNG as a format 3 | // besides raw RGB/RGBA buffers. 4 | #define STBI_ONLY_PNG 5 | 6 | // We don't want to support super large images. 7 | #define STBI_MAX_DIMENSIONS 131072 8 | 9 | #define STB_IMAGE_IMPLEMENTATION 10 | #include <stb_image.h> 11 | 12 | #define STB_IMAGE_RESIZE_IMPLEMENTATION 13 | #include <stb_image_resize.h> 14 | -------------------------------------------------------------------------------- /src/synthetic/main.zig: -------------------------------------------------------------------------------- 1 | //! The synthetic package contains an abstraction for generating 2 | //! synthetic data. The motivating use case for this package is to 3 | //! generate synthetic data for benchmarking, but it may also expand 4 | //! to other use cases such as fuzzing (e.g. to generate a corpus 5 | //! rather than directly fuzzing). 6 | //! 7 | //! The generators in this package are typically not performant 8 | //! enough to be streamed in real time. They should instead be 9 | //! used to generate a large amount of data in a single go 10 | //! and then streamed from there. 11 | //! 12 | //! The generators are aimed for terminal emulation, but the package 13 | //! is not limited to that and we may want to extract this to a 14 | //! standalone package one day. 15 | 16 | pub const cli = @import("cli.zig"); 17 | 18 | pub const Generator = @import("Generator.zig"); 19 | pub const Bytes = @import("Bytes.zig"); 20 | pub const Utf8 = @import("Utf8.zig"); 21 | pub const Osc = @import("Osc.zig"); 22 | 23 | test { 24 | @import("std").testing.refAllDecls(@This()); 25 | } 26 | -------------------------------------------------------------------------------- /src/terminal/kitty.zig: -------------------------------------------------------------------------------- 1 | //! Types and functions related to Kitty protocols. 2 | 3 | const key = @import("kitty/key.zig"); 4 | pub const color = @import("kitty/color.zig"); 5 | pub const graphics = @import("kitty/graphics.zig"); 6 | 7 | pub const KeyFlags = key.Flags; 8 | pub const KeyFlagStack = key.FlagStack; 9 | pub const KeySetMode = key.SetMode; 10 | 11 | test { 12 | @import("std").testing.refAllDecls(@This()); 13 | } 14 | -------------------------------------------------------------------------------- /src/terminal/kitty/graphics_render.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const assert = std.debug.assert; 3 | const testing = std.testing; 4 | const terminal = @import("../main.zig"); 5 | 6 | /// A render placement is a way to position a Kitty graphics image onto 7 | /// the screen. It is broken down into the fields that make it easier to 8 | /// position the image using a renderer. 9 | pub const Placement = struct { 10 | /// The top-left corner of the image in grid coordinates. 11 | top_left: terminal.Pin, 12 | 13 | /// The offset in pixels from the top-left corner of the grid cell. 14 | offset_x: u32 = 0, 15 | offset_y: u32 = 0, 16 | 17 | /// The source rectangle of the image to render. This doesn't have to 18 | /// match the size the destination size and the renderer is expected 19 | /// to scale the image to fit the destination size. 20 | source_x: u32 = 0, 21 | source_y: u32 = 0, 22 | source_width: u32 = 0, 23 | source_height: u32 = 0, 24 | 25 | /// The final width/height of the image in pixels. 26 | dest_width: u32 = 0, 27 | dest_height: u32 = 0, 28 | }; 29 | -------------------------------------------------------------------------------- /src/terminal/kitty/testdata/dog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/terminal/kitty/testdata/dog.png -------------------------------------------------------------------------------- /src/terminal/kitty/testdata/image-png-none-50x76-2147483647-raw.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/terminal/kitty/testdata/image-png-none-50x76-2147483647-raw.data -------------------------------------------------------------------------------- /src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647-raw.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647-raw.data -------------------------------------------------------------------------------- /src/terminal/kitty/testdata/image-rgb-zlib_deflate-128x96-2147483647-raw.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/src/terminal/kitty/testdata/image-rgb-zlib_deflate-128x96-2147483647-raw.data -------------------------------------------------------------------------------- /src/terminal/res/glitch.txt: -------------------------------------------------------------------------------- 1 | Ḡ̴͎͍̜͎͔͕̩̗͕͖̟̜͑̊̌̇̑͒͋͑̄̈́͐̈́́̽͌͂̎̀̔͋̓́̅̌̇͘̕͜͝͝h̶̡̞̫͉̳̬̜̱̥͕͑̾͛̒̆̒̉̒̑͂̄͘ͅǫ̷̨̥͔͔͖̭͚͙̯̟̭̘͇̫̰͚̺̳̙̳̟͚̫̱̹̱͒̂̑͒͜͠ͅş̴̖̰̜̱̹͙̅͒̀̏͆̐̋͂̓͋̃̈̔̂̈͛̐̿̔́̔̄͑̇͑̋̈́͌͋̾̃̽̈́̕͘̚͘͘͘͠͠t̵̢̜̱̦͇͉̬̮̼͖̳̗̥̝̬͇͕̥̜͕̳̱̥̮͉̮̩̘̰̪̤͉͎̲͈͍̳̟̠͈̝̫͋̊̀͐̍̅̀̄̃̈́̔̇̈́̄̃̽̂̌̅̄̋͒̃̈́̍̀̍̇̽̐͊̾̆̅̈̿̓͒̄̾͌̚͝͝͝͝͝t̴̥̼̳̗̬̬͔͎̯͉͇̮̰͖͇̝͔̳̳̗̰͇͎͉̬͇̝̺̯͎͖͔̍͆͒̊̒̔̊̈́̿̊̅͂̐͋̿͂̈̒̄͜͠͠ÿ̴̢̗̜̥͇͖̰͎̝̹̗̪̙̞̣̳͎̯̹͚̲̝̗̳̳̗̖͎̗̬͈͙̝̟͍̥̤͖͇̰͈̺͛̒̂͌̌̏̈̾̓̈́̿͐̂̓̔̓̂̈́͑͛͊͋̔̿̊͑͌̊̏͘͘̕͘͠͝ 2 | -------------------------------------------------------------------------------- /src/terminal/sanitize.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | /// Returns true if the data looks safe to paste. 4 | pub fn isSafePaste(data: []const u8) bool { 5 | return std.mem.indexOf(u8, data, "\n") == null and 6 | std.mem.indexOf(u8, data, "\x1b[201~") == null; 7 | } 8 | 9 | test isSafePaste { 10 | const testing = std.testing; 11 | try testing.expect(isSafePaste("hello")); 12 | try testing.expect(!isSafePaste("hello\n")); 13 | try testing.expect(!isSafePaste("hello\nworld")); 14 | } 15 | -------------------------------------------------------------------------------- /src/terminfo/main.zig: -------------------------------------------------------------------------------- 1 | //! Package terminfo provides functionality related to terminfo/termcap files. 2 | //! 3 | //! At the time of writing this comment, the focus is on generating terminfo 4 | //! files so that we can maintain our terminfo in Zig instead of hand-writing 5 | //! the archaic (imo) terminfo format by hand. But eventually we may want to 6 | //! extract this into a more full-featured library on its own. 7 | 8 | pub const ghostty = @import("ghostty.zig").ghostty; 9 | pub const Source = @import("Source.zig"); 10 | 11 | test { 12 | @import("std").testing.refAllDecls(@This()); 13 | } 14 | -------------------------------------------------------------------------------- /src/unicode/main.zig: -------------------------------------------------------------------------------- 1 | pub const lut = @import("lut.zig"); 2 | 3 | const grapheme = @import("grapheme.zig"); 4 | const props = @import("props.zig"); 5 | pub const table = props.table; 6 | pub const Properties = props.Properties; 7 | pub const getProperties = props.get; 8 | pub const graphemeBreak = grapheme.graphemeBreak; 9 | pub const GraphemeBreakState = grapheme.BreakState; 10 | 11 | test { 12 | @import("std").testing.refAllDecls(@This()); 13 | } 14 | -------------------------------------------------------------------------------- /test/cases/vttest/1_1.sh: -------------------------------------------------------------------------------- 1 | function test_do { 2 | xdotool type "vttest" 3 | xdotool key Return 4 | sleep 1 5 | xdotool type "1" 6 | xdotool key Return 7 | } 8 | -------------------------------------------------------------------------------- /test/cases/vttest/1_1.sh.alacritty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_1.sh.alacritty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_1.sh.ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_1.sh.ghostty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_1.sh.xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_1.sh.xterm.png -------------------------------------------------------------------------------- /test/cases/vttest/1_2.sh: -------------------------------------------------------------------------------- 1 | function test_do { 2 | xdotool type "vttest" 3 | xdotool key Return 4 | sleep 1 5 | xdotool type "1" 6 | xdotool key Return 7 | sleep 0.5 8 | xdotool key Return 9 | } 10 | -------------------------------------------------------------------------------- /test/cases/vttest/1_2.sh.alacritty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_2.sh.alacritty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_2.sh.ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_2.sh.ghostty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_2.sh.xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_2.sh.xterm.png -------------------------------------------------------------------------------- /test/cases/vttest/1_3.sh: -------------------------------------------------------------------------------- 1 | function test_do { 2 | xdotool type "vttest" 3 | xdotool key Return 4 | sleep 1 5 | xdotool type "1" 6 | xdotool key Return 7 | sleep 0.5 8 | xdotool key Return 9 | sleep 0.5 10 | xdotool key Return 11 | } 12 | -------------------------------------------------------------------------------- /test/cases/vttest/1_3.sh.alacritty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_3.sh.alacritty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_3.sh.ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_3.sh.ghostty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_3.sh.xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_3.sh.xterm.png -------------------------------------------------------------------------------- /test/cases/vttest/1_4.sh: -------------------------------------------------------------------------------- 1 | function test_do { 2 | xdotool type "vttest" 3 | xdotool key Return 4 | sleep 1 5 | xdotool type "1" 6 | xdotool key Return 7 | sleep 0.5 8 | xdotool key Return 9 | sleep 0.5 10 | xdotool key Return 11 | sleep 0.5 12 | xdotool key Return 13 | } 14 | -------------------------------------------------------------------------------- /test/cases/vttest/1_4.sh.alacritty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_4.sh.alacritty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_4.sh.ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_4.sh.ghostty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_4.sh.xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_4.sh.xterm.png -------------------------------------------------------------------------------- /test/cases/vttest/1_5.sh: -------------------------------------------------------------------------------- 1 | function test_do { 2 | xdotool type "vttest" 3 | xdotool key Return 4 | sleep 1 5 | xdotool type "1" 6 | xdotool key Return 7 | sleep 0.5 8 | xdotool key Return 9 | sleep 0.5 10 | xdotool key Return 11 | sleep 0.5 12 | xdotool key Return 13 | sleep 0.5 14 | xdotool key Return 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/vttest/1_5.sh.alacritty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_5.sh.alacritty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_5.sh.ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_5.sh.ghostty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_5.sh.xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_5.sh.xterm.png -------------------------------------------------------------------------------- /test/cases/vttest/1_6.sh: -------------------------------------------------------------------------------- 1 | function test_do { 2 | xdotool type "vttest" 3 | xdotool key Return 4 | sleep 1 5 | xdotool type "1" 6 | xdotool key Return 7 | sleep 0.5 8 | xdotool key Return 9 | sleep 0.5 10 | xdotool key Return 11 | sleep 0.5 12 | xdotool key Return 13 | sleep 0.5 14 | xdotool key Return 15 | sleep 0.5 16 | xdotool key Return 17 | } 18 | -------------------------------------------------------------------------------- /test/cases/vttest/1_6.sh.alacritty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_6.sh.alacritty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_6.sh.ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_6.sh.ghostty.png -------------------------------------------------------------------------------- /test/cases/vttest/1_6.sh.xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/1_6.sh.xterm.png -------------------------------------------------------------------------------- /test/cases/vttest/launch.sh: -------------------------------------------------------------------------------- 1 | function test_do { 2 | xdotool type "vttest" 3 | xdotool key Return 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/vttest/launch.sh.alacritty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/launch.sh.alacritty.png -------------------------------------------------------------------------------- /test/cases/vttest/launch.sh.ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/launch.sh.ghostty.png -------------------------------------------------------------------------------- /test/cases/vttest/launch.sh.xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/vttest/launch.sh.xterm.png -------------------------------------------------------------------------------- /test/cases/wraptest.sh: -------------------------------------------------------------------------------- 1 | function test_do { 2 | xdotool type "wraptest" 3 | xdotool key Return 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/wraptest.sh.alacritty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/wraptest.sh.alacritty.png -------------------------------------------------------------------------------- /test/cases/wraptest.sh.ghostty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/wraptest.sh.ghostty.png -------------------------------------------------------------------------------- /test/cases/wraptest.sh.xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostty-org/ghostty/68418ecd53ee4b43714d15e7e555c5f89f121f0f/test/cases/wraptest.sh.xterm.png -------------------------------------------------------------------------------- /test/run-all.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Run all of the test cases. All test cases are found by traversing 4 | # the "cases" directory, finding all shell files, and executing the 5 | # "./run-host.sh" command for each. 6 | 7 | DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) 8 | 9 | # We always copy the bin in case it was rebuilt 10 | cp ${DIR}/../zig-out/bin/ghostty ${DIR}/ 11 | 12 | # Build our image once 13 | IMAGE=$(docker build --file ${DIR}/Dockerfile -q ${DIR}) 14 | 15 | # Unix shortcut to just execute ./run-host for each one. We can do 16 | # this less esoterically if we ever wanted. 17 | find ${DIR}/cases \ 18 | -type f \ 19 | -name '*.sh' | \ 20 | sort | \ 21 | parallel \ 22 | --will-cite \ 23 | ${DIR}/run-host.sh \ 24 | --case '{}' \ 25 | --rewrite-abs-path \ 26 | $@ 27 | -------------------------------------------------------------------------------- /test/run-host.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # This runs a single test case from the host (not from Docker itself). The 4 | # arguments are the same as run.sh but this wraps it in docker. 5 | 6 | DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) 7 | IMAGE=$(docker build --file ${DIR}/Dockerfile -q ${DIR}) 8 | 9 | docker run \ 10 | --init \ 11 | --rm \ 12 | -v ${DIR}:/src \ 13 | --entrypoint "xvfb-run" \ 14 | $IMAGE \ 15 | --server-args="-screen 0, 1600x900x24" \ 16 | /entrypoint.sh $@ 17 | -------------------------------------------------------------------------------- /vendor/nerd-fonts/README.md: -------------------------------------------------------------------------------- 1 | We have a copy of the `font-patcher` file from `nerd-fonts` here, fetched from 2 | https://github.com/ryanoasis/nerd-fonts/blob/master/font-patcher. 3 | 4 | This is MIT licensed, see `LICENSE` in this directory. 5 | 6 | We use parse a section of this file to codegen a lookup table of the nerd font 7 | scaling rules. See `src/font/nerd_font_codegen.py` in the main Ghostty source 8 | tree for more info. 9 | 10 | Last fetched commit: ebc376cbd43f609d8084f47dd348646595ce066e 11 | --------------------------------------------------------------------------------