1 puan yazan GN⁺ 2025-08-16 | 1 yorum | WhatsApp'ta paylaş
  • Ghostty ekibi GTK uygulamasını tamamen baştan yazdı ve GObject tür sistemini yoğun biçimde kullanmaya başladı
  • Bu süreçte Zig dili ile entegrasyon ve Valgrind ile bellek sorunlarının doğrulanması önemli rol oynadı
  • GObject sisteminin benimsenmesiyle önceye kıyasla bellek yönetimi ve özel widget geliştirme basitleşti
  • Valgrind kullanımının sonucunda Ghostty'nin bellek güvenliğinin büyük ölçüde iyileştiği görüldü
  • Yeni Ghostty GTK, kaynak koddan derlemelerde varsayılan hale geldi ve 1.2 sürümünde yer alacak

Giriş

  • Ghostty, macOS, Linux, FreeBSD destekleyen çapraz platform bir terminal emülatörüdür
  • Her platformda yerel GUI framework'lerini kullanarak farklılaşır
    • macOS: Swift ve Xcode tabanlı büyük ölçekli uygulama
    • Linux ve BSD: GTK tabanlı uygulama, X11/Wayland gibi sistemlerle doğrudan entegrasyon
    • Ortak çekirdek Zig ile yazılmıştır ve C ABI uyumlu API sunar
  • Mevcut yapıda GTK uygulamasının neden yeniden yazıldığına dair ayrıntılar için özgün PR'a bakılabilir
  • Bu yazı özellikle GObject tür sistemiyle entegrasyon ve Valgrind ile doğrulanan bellek sorunları üzerine odaklanır

GObject tür sistemi ve Zig

  • GTK kullanıldığında yapı gereği GObject tür sistemiyle arayüz kurmak gerekir
  • Geçmişte GObject sisteminden kaçınılarak referans sayımı olmayan Zig nesneleri ile GObject nesnelerinin yaşam döngüsü elle eşleştirilmeye çalışıldı, ancak bellek serbest bırakmanın düzgün çalışmaması sorunu tekrar tekrar ortaya çıktı
    • Örneğin Zig tarafındaki bellek serbest bırakılmışken GTK tarafındaki bellek yaşamaya devam ediyor ya da bunun tersi oluyordu
  • Bu yaklaşım yalnızca doğruluk sorunları yaratmakla kalmadı, aynı zamanda GTK'ye özgü özelliklerin (event signals, property binding, actions) kullanımını da zorlaştırdı
  • Somut bir örnek olarak, ayar (config) yapısı yeniden yüklendiğinde bağlı tüm GUI öğelerinin tutarlı şekilde güncellenmesi gerekiyordu; bu süreç karmaşık ve hataya açıktı
    • Artık Zig Config yapısı, onu saran referans sayımlı GhosttyConfig GObject ile yönetiliyor ve özellik değişikliği bildirimleri sayesinde değişiklikler uygulamanın geneline doğal biçimde yayılıyor
  • Özel GObject widget'ları oluşturmak da kolaylaştı; böylece Blueprint gibi modern GTK UI teknolojilerini kullanmak mümkün oldu
    • Son dönemde Blueprint'in devreye alınmasıyla GTK titlebar sekmeleri, animasyonlu zil çerçevesi gibi yeni özellikleri eklemek kolaylaştı

Valgrind, GTK ve Zig

  • Tüm geliştirme süreci boyunca Valgrind, bellek sızıntıları ve tanımsız bellek erişimleri gibi sorunları sistematik olarak doğrulamak için kullanıldı
  • GTK uygulamalarında Valgrind kullanmak zordur ve büyük boyutlu suppression dosyaları gerekir (yaklaşık %80'i GTK'nin kendisi, kalanı 3rd party kütüphaneler ve GPU sürücüleri içindir)
  • Tekrarlanan kontroller sayesinde yalnızca bazı durumlarda ortaya çıkan karmaşık bellek hataları önceden tespit edilebildi
    • Örneğin GObject WeakRef doğru başlatılmazsa hedef nesne daha sonra serbest bırakıldığında tanımsız bellek erişimi oluşur; bu durum Valgrind ile önceden yakalandı
  • Fiili deneyime göre, Zig kod tabanının içindeki sorunlar toplam yalnızca 2 adetti (1 sızıntı, 1 tanımsız erişim) ve bunlar da 3rd party C API entegrasyonu sırasında ortaya çıktı
    • Zig'in hata ayıklama amaçlı allocator'ü ve Valgrind entegrasyonu da işe yaradığını kanıtladı
  • Bulunan diğer bellek sorunlarının çoğu C API sınırlarında ve GObject sisteminin karmaşık yaşam döngüsü yönetiminden kaynaklandı
    • Sonuç olarak, karmaşık kütüphanelerin C API'lerini güvenli kullanmak için Valgrind benzeri araçlar gereklidir
  • Zig'in bellek güvenliğini destekleyen özelliklerinin etkisi yalnızca teorik tartışmalarla değil, somut proje deneyimiyle de doğrulandı

Sonuç

  • Bu, Ghostty'nin GUI bölümünü beşinci kez sıfırdan yeniden yapma deneyimi oldu
    • GLFW, macOS SwiftUI, macOS AppKit+SwiftUI, Linux GTK (prosedürel), Linux GTK+GObject tür sistemi sırasıyla
  • Tekrarlanan yeniden yazım sürecinde her seferinde yeni dersler ve teknik gelişim kazanıldı
    • Bu deneyimin bir kısmının macOS projesine de uygulanması planlanıyor
  • Ghostty GTK sisteminin bakım ekibinin aktif iş birliği de özellikle vurgulanıyor
  • Baştan yazılan yeni Ghostty GTK uygulaması artık kaynak koddan derlemelerin varsayılanı oldu ve 1.2 kararlı sürümünde yer alacak

1 yorum

 
GN⁺ 2025-08-16
Hacker News yorumu
  • GTK ile doğrudan çalışma deneyimim yok, ama anlattıklarınız kulağıma Zig ile Godot binding'leri yaparken yaşadığım sorunlara çok benzer geliyor. Godot'da sınıflar, sanal metotlar, property'ler, signal'lar gibi çok fazla OOP kavramı var. Ayrıca tüm bu kavramları ele almanıza ve kullanıcı tanımlı nesnelerle özellikler oluşturmanıza izin veren bir C API sunuyor. Engine nesnelerinin yaşam döngüsünü doğrudan yönetmeniz gerekiyor ve referans sayımlı nesnelerin ağaç yapısı da var. Özellikle yaşam döngüsü sorunlarını Zig deyimlerine uygun, en iyi API hâline getirmeye çalışınca iş aşırı karmaşıklaşıyor. Bu dertlerle uğraşırken oopz kütüphanesini de yaptım. API şu an hâlâ bu seviyede ve gerçek örnekleri burada görebilirsiniz. Ghostty frontend'ini bir Godot extension'ı olarak da yapmayı denemek isterim

    • Eskiden belirli bir dil için GTK binding'lerini doğrudan kullanırken rahatsız olduğumu hatırlıyorum. %98'i sorunsuzdu ama kalan %2'de, “bu fonksiyonun nesnenin referansını alıp almaması başka argümanlara göre değişiyor” gibi durumlar vardı ve bu yüzden nesne yaşam döngüsü analizi epey baş ağrıtıyordu
    • Hem teşekkür etmek istiyorum hem de C# Godot kodunu performanslı yazmaya çalışırken engine türleriyle sürekli karşılıklı dönüşüm yapmanın tekrar tekrar allocation üretmesi çok yorucu olmuştu. Binding'leri yaparken siz de buna benzer sorunlar yaşadınız mı diye merak ediyorum
    • Zig ile Godot binding'leri yapan bir proje olduğunu bilmiyordum. Hem Godot'yu hem Zig'i sevdiğim için bayağı heyecanlandım. Takipte olacağım
  • İyi programlamanın sonuçta sistemin sunduğu biçime uyum sağlamak olduğunu gösteren güzel bir örnek. OOP ya da bellek yönetimi hakkında ne düşünürseniz düşünün, GTK kullanıyorsanız GObject tip sistemiyle bir şekilde arayüz kurmak zorundasınız. İstemeseniz de bundan kaçış yok. Biz ise bundan kaçınmaya çalıştık ve sonuç olarak referans sayımlı nesnelerle referanssız nesnelerin ömürlerini birbirine bağlarken tam bir karmaşa çıktı. Ghostty GTK uygulamasında Zig belleğini serbest bırakınca GTK belleğinin serbest kalmaması ya da tersinin olması gibi hatalar tekrar tekrar yaşandı

    • GTK'nın böyle bir yapıya sahip olmasının nedenlerinden biri de Vala'nın ortaya çıkış hikâyesi. Vala, C#'tan ilham alıyor, GObject'i kullanıyor ve kodu C'ye transpile ediyor. Bu yüzden epey çok GTK uygulaması aslında Vala ile yazılmış durumda. İnsan bazen keşke D dili kullanılsaydı diyor. D birçok açıdan derlenen bir C# gibi hissettiriyor
    • Kötü bir sisteme boyun eğmek iyi bir şey değil, pragmatik bir seçimdir
  • OOP ve bellek yönetimi konusundaki görüşlerimi bir kenara bırakırsak, GTK kullanınca GObject tip sistemine dolanmanın kaçınılmaz olduğuna katılıyorum. Bu yüzden ben doğrudan GTK kullanmamayı seçtim. Tek tip bir UI temasının değerini görüyorum ama bana göre GTK'nın avantajları, onun bedeline katlanmaya yetecek kadar büyük değil. Açık kaynak uygulamalarda GTK çevresinde biraz uğraşmış biri olarak, GTK ve GObject'in bakış açısının benim eğilimlerimle pek örtüşmediğine ikna oldum. GTK'nın var olmasından rahatsız değilim. Ben kullanmamayı seçtiğim sürece sorun yok ama bazı insanların bunun benim seçim hakkım olduğunu düşünmemesi tuhaf geliyor. Sonuçta o, sayısız GUI toolkit'inden sadece biri ve teknik olarak oldukça rafine bir toolkit olmasına rağmen, keşke GTK'nın payı biraz daha az olsaydı da o cilalama başka, yapısal olarak daha iyi toolkit'lere gidebilseydi diye düşünüyorum. Tabii benim iyi bulduğum şey herkes için iyi olmak zorunda değil. GTK kullananların ne kadarı mecburen kullanıyor, ne kadarı bunun en iyi araç olduğunu düşünüyor merak ediyorum

    • GTK ve GObject'in güçlü biçimde opinionated tarzının benim düşünce yapımla da pek uyuşmadığına katılıyorum. GNOME ekosisteminin yönüyle de pek uyuştuğumu söyleyemem. Ghostty'de Linux için GTK kullanmak oldukça pragmatik bir seçim. Ghostty'nin platform-native olma hedefinin özellikle Linux tarafında ne anlama geldiği burada tanımlanıyor. GTK Linux'ta en yaygın kullanılan seçenek ve çoğu uygulama ekosistemine en doğal şekilde uyuyor, dolayısıyla bu kararı vermek zorunda kaldılar. İleride libghostty üzerine üçüncü taraflarca farklı frontend'ler yapılmasını umuyorum. Örneğin Wayland-native Ghostty frontend'i olan Wraith var. Çok havalı
    • Bence GTK'nın Linux'ta bu kadar yaygın olmasının temel sebebi tam olarak “C binding”e sahip olması. Bu yüzden neredeyse her dil için binding ya hazır geliyor ya da otomatik üretmesi kolay oluyor. Buna karşılık Qt, C++ ve Python'a fazla bağlı olduğu için erişilebilirliği ciddi biçimde düşüyor. Geliştiricinin hangi dili kullandığından bağımsız olarak onu bulunduğu yerde karşılamak önemli. Ayrıca karmaşık masaüstü uygulamaları yazarken, eski tarz imperative UI toolkit'leri aslında oldukça pragmatik; doğrulanmış widget'ları bol ve kalıpları tanıdık. Yeni yaklaşımlarda ise tersine, küçük şeyleri bile kendiniz kurcalamak zorunda kalıyorsunuz ve biraz karmaşıklaşınca iş epey zorlaşıyor
    • “GTK kullanmamakta özgürsün ama bazı insanlar sanki bu senin seçimin değilmiş gibi davranıyor” kısmında, genelde nasıl itirazlarla karşılaştığınızı merak ediyorum. Benim açımdan GTK'nın asıl güçlü tarafı erişilebilirlik ya da Latin olmayan alfabelerle giriş gibi, kendi başına toolkit yapan geliştiricilerin çoğu zaman önemsemediği alanları oldukça iyi çözmesi gibi görünüyor
  • İlginç bir bilgi: Ghostty ve bazı diğer GTK uygulamalarında fare pencerenin dışına çıkıp yeniden girince ilk scroll tıklaması yok sayılıyor. Bunun sebebi 2015'te ilk kez raporlanan çok eski bir hata. Hata bağlantısı. Bugüne kadar da düzeltme planı yok; bakımcıların tavrı Wayland'i beklemek yönünde

    • Aslında bu sorun GTK'nın kendisinde değil, XInput2'de gibi görünüyor. Elbette GTK bunu Chromium'un kullandığı heuristic gibi bir yöntemle aşabilir ama kök neden daha üst katmanda, yani XInput2 tarafında
    • İlgili hata raporunu ve bağlı issue'ları okuyunca, birkaç kez düzeltme girişimi olduğunu ama kaçınılmaz olarak bazı heuristic'lere dayanmak zorunda kalındığını ve bunun da eldeki problemden daha kötü yan etkiler doğurduğunu görmek mümkün. Sonuçta mesele temelde X11 tabanında başladığı için, anlamlı ilerleme ancak oradaki kök sorun çözülürse olur gibi duruyor. Ama X11 artık fiilen bakım modunda olduğu için, hayranları “zaten kusursuz çalışıyor, ek işe gerek yok” demeye devam ettikçe bundan umutlu olmak zor. Geriye kalan tek yol, Wayland geçişini beklemek gibi görünüyor
  • “Valgrind ile her adımı doğruladım” kısmında, aslında bu kadar bariz olmasına rağmen benim hiç düzenli yaptığım bir şey olmadı ve başka geliştiricilerde de pek görmedim. Genelde Valgrind ancak belirli bir bug ya da performans düşüşü ortaya çıkınca devreye giriyordu. Geliştirme süreci boyunca Valgrind'i, özellikle Memcheck ve Helgrind'i, proaktif biçimde kullanmak aracın güvenilirliğini çok artırır ve bug'ları sonradan yüzlerce commit'i taramadan, ortaya çıktıkları anda yakalamayı sağlayabilir gibi geliyor

    • Ben kendi adıma C ve C++ kullanırken valgrind'i hep düzenli kullandım. valgrind ve asan'in yakaladığı hatalar çoğu zaman anında crash olarak ortaya çıkmıyor; daha çok gözden kaçan ama arada bir beliren, sinir bozucu bug'lara dönüşüyor ve bu yüzden kök sebebi bulmak çok zor oluyor. Aralarında güvenlik açıkları da bulunabiliyor. Bir de küçük bellek sızıntıları zamanla birikince, sonra gerçekten büyük bir sorun çıktığında, önceden birikmiş sayısız küçük sızıntı asıl nedeni bulmayı daha da zorlaştırıyor. O yüzden proaktif kullanım bence çok değerli
    • Valgrind'i, özellikle memcheck'i, bug raporunu derinlemesine debug etmeye geçmeden önce kolay düzeltilebilecek sorunları erkenden yakalamak için proaktif kullandım. Ama en büyük sıkıntı performans maliyetinin yüksek olması; interaktif kullanım deneyimi pek iyi değil. Yine de testleri arada bir Valgrind altında çalıştırmak büyük fayda sağlıyor
    • Yine de Valgrind aşırı yavaş ve pahalı olduğu için onu doğrudan kod değiştir-derle-test döngüsüne koymak zor. Test döngüsünde, örneğin nightly ya da otomasyon tarafında kullanılabilir ama iyi entegre etmek için ek emek gerekiyor
  • Ghostty kullanırken Mac'te nano'ya çok satırlı yapıştırma yapamamak beni çok rahatsız ediyor. Galiba terminalin “bracketed pasting”i nasıl ele aldığıyla ilgili ama nedense iterm2 ya da Term'de bu sorun yok

    • Ghostty bir terminal yerine geçen uygulama olarak %99 oranında beni memnun ediyor ama kopyala-yapıştır sorunu gerçekten sinir bozucu ve neredeyse her gün karşıma çıkıyor
    • Yeni bir bilgisayarda varsayılan terminal olarak Ghostty kullanmaya başladığımdan beri en büyük eksiklik arama özelliğinin olmaması oldu. Normalde çıktıda belirli bir şeyi bulmak için sık sık kısayolu kullanırım ama burada bu yok. Nitekim issue içinde de en sık dile getirilen eksiklik bu
    • Ubuntu'ya uzaktan bağlandığımda Ghostty içinde nano hiç çalışmıyor
      $ nano
      Error opening terminal: xterm-ghostty.
      
      Aynı ortamda macOS terminali ya da VSCode gömülü terminali sorunsuz çalışıyor
    • Bu gerçekten bir bug olabilir, bence rapor etmelisiniz
    • Cmd+F gibi bir komut araması olmaması benim için en kritik eksik
  • Zig yerine Rust kullanılsaydı bellek hataları önlenir miydi diye merak ediyorum. Sorunların çoğu Zig/C etkileşiminden çıkmış gibi duruyor, bu yüzden Rust'ta da benzer olurdu sanırım. Go geliştiricisi olarak tahmin yürütüyorum ama C ile büyük ölçekte entegrasyonda gerçekten daha fazla güvenlik aracı sunan bir dil var mı merak ediyorum

    • Rust olsaydı bir problemi engellerdi ama geri kalanlar büyük ölçüde aynı olurdu. Dediğiniz gibi asıl sorun C API sınırı ve onun semantiklerinde olduğu için gerçek güvenlik wrapper'ın kalitesine bağlı. Rust'ın zaten iyi sınanmış wrapper ekosistemleri olduğu için o açıdan elde yazılmış Zig wrapper'larına göre daha az riskli olabilirdi ama sonuçta kökten farklı olmazdı. Örneğin Rust'ın yakalayabileceği türden bir undefined memory access gerçekten de bu PR içinde düzeltilmiş. Pratikte yanlış bellek ilk frame'e kopyalanmıştı ama hiçbir yerde kullanılmadığı ya da gönderilmediği için ciddi bir etki yaratmamıştı. Yine de elbette doğru değildi
    • Rust da C/GObject ile FFI sınırında manuel bellek ve yaşam döngüsü yönetimi gerektiriyor. Rust'ın borrow checker'ı dış kodun bellek kullanımını doğrulayamıyor
    • Yazının ana fikirlerinden biri de zig + valgrind kombinasyonuyla beklenenden çok daha az bellek sorunu yaşanmış olması
    • Rust ile C binding'i yazmak çok daha zor. Bu yüzden Rust ile GTK binding'leri yazmak pratikte mümkün bile olmayabilirdi
  • Ghostty gibi GPU tabanlı uygulamaları, ayrıca Alacritty, WezTerm, Zed gibi araçları kullanınca daha hızlı ve daha iyi hissettim. Ama ironik biçimde bu tür uygulamalar Nvidia sürücülerinin sınırlarını daha görünür hâle getiriyor. Eskiden GPU'yu pek kullanmadığım için fark etmemiştim ama Regolith i3wm gibi compositorsuz ortamlarda da, sway/Wayland tarafında da ekran paylaşımı, uykudan dönüş, crash gibi konularda Nvidia sürücüleri gerçekten berbattı. Farklı sürümleri de denedim, 550/560/575/580, hepsi aynıydı. Meğer uzun zamandır durum böyleymiş, ben yeni fark etmişim

    • Ben de Wayland'de benzer deneyimler yaşadım. X11'de compositing efektlerini kapatınca hem 1050Ti hem de eski AMD kartımda (radeon sürücüsü gerekiyor) her şey sorunsuz çalışıyordu. Buna karşılık Wayland'de takılma, crash, bozuk görüntü gibi sorunlar vardı
  • GTK tip sisteminin koda nüfuz etmesine izin vermeden büyük bir uygulama yazabildim. Ama bunun karşılığında sınıf kalıtımı ya da extension yerine, tüm bileşenleri birbirine lambda bağlayarak ilişkilendirdim. Sonuç çok da dağınık olmadı ama klasik GTK tarzına alışkın geliştiriciler için kafa karıştırıcı olabilirdi

  • Ghostty etrafındaki abartılı ilgiyi pek anlayamıyorum. Arayüzünde sekmeler ve context menu dışında pek bir şey yok; böyle entegrasyon işleri ve yeniden yazımlar buna gerçekten değer mi emin değilim. Belki iterm2 gibi daha güçlü bir GUI ortamı kurmak istiyorlardır diye düşünüyorum. Kitty, sekmeleri OpenGL ile kendisi çiziyor, yani tamamen özelleştirilebilir ve karmaşık framework'lere entegrasyonla vakit kaybetmeyip çok pratik özellikleri daha hızlı ekliyor; örneğin son komut çıktısını pager içinde sarmalama gibi. Uzak kullanım tarafı da Kitty'de iyi

    • Ghostty'nin arayüzü yalnızca sekmelerden ibaret değil; split görünüm, “process exited” banner'ı, kapatma onay diyaloğu, başlık değiştirme diyaloğu, güvenli olmayan yapıştırma algılama, animasyonlu bildirim zili, dropdown terminal, ilerleme çubuğu gibi beklenenden daha fazla şey var. Mac'te ayrıca Apple Shortcuts ve Spotlight entegrasyonu da bulunuyor. Elbette bunların hepsi GUI toolkit olmadan da saf biçimde uygulanabilirdi ama Ghostty'nin misyonu her platformda native toolkit kullanıp uygulamanın gerçekten “yerel” hissettirmesi. Bu yaklaşımı sevmiyorsanız Kitty'nin yaptığı gibi metin sekmeleri de gayet iyi bir tercih. Sonuçta burada değerler ve öncelikler farklı. İleride farklı GUI genişlemeleri de planlanıyor ve platforma özgü native özelliklerle, örneğin iCloud senkronizasyonu gibi şeylerle daha derin entegrasyon hedefleniyor
    • “Kovid özellikleri daha hızlı yaptı” iddiası konusunda, bu hesabın Kovid'in kendisi olabileceğine dair bir geçmiş olduğu için dikkatli olmak lazım. HN ve Reddit'te Kitty'yi tarafsız tanıtıyormuş gibi yapıp geliştiriciyi eleştirdiğini gördüğümü hatırlıyorum. Hatta eski yorum geçmişine bakılması için bağlantı da verilmiş
    • Yukarıdaki olumlu açıklamaya ek olarak, bence asıl oyun değiştirici olan şey ‘libghostty’nin ortaya çıkmış olması. WebKit gibi, isteyenin drop-in olarak ekleyip hemen kullanabileceği güçlü bir terminal uygulama motoru
    • Ben de uzun süre terminal arayışıyla oradan oraya savruldum. Ghostty benim için kusursuz ideal değil ama sonunda yeterince memnun kaldığım bir şey bulamayınca geçtiğim seçenek oldu. Bu da benim için başlı başına anlamlı bir tercih. Çoğu zaman belirleyici neden “şu özelliğe bayıldım” değil, “ciddi bir sorun çıkarmıyor, o yüzden kullanmaya devam ediyorum” oluyor ve bu da aslında önemli bir artı
    • Fontlar Ghostty'de Kitty'ye kıyasla çok daha güzel render ediliyor. Neovide daha da güzel görünüyor ama hâlâ sekme desteği yok ve pili daha fazla tüketiyor