ทีมพัฒนา Ghostty terminal emulator ได้เสร็จสิ้นการเขียนแอปพลิเคชัน GTK ใหม่ทั้งหมดสำหรับระบบ Linux และ BSD โดยหันมาใช้ระบบ GObject type system อย่างเต็มรูปแบบ หลังจากประสบปัญหาการจัดการหน่วยความจำในการพัฒนาครั้งก่อน นี่เป็นครั้งที่ห้าที่ส่วน GUI ถูกเขียนใหม่ตั้งแต่เริ่มต้น ซึ่งแสดงให้เห็นถึงความท้าทายในการสร้างแอปพลิเคชันที่เป็น platform-native อย่างแท้จริง
ประวัติการเขียน GUI ใหม่:
- การใช้งาน GLFW
- macOS กับ SwiftUI
- macOS กับ AppKit + SwiftUI
- Linux กับ GTK (แนวทางแบบ procedural)
- Linux กับ GTK + ระบบ GObject แบบเต็มรูปแบบ (ปัจจุบัน)
ปัญหาการจัดการหน่วยความจำผลักดันให้เขียนใหม่ทั้งหมด
การพัฒนา GTK ครั้งแรกหลีกเลี่ยงการใช้ระบบ GObject type system ส่งผลให้เกิดบั๊กที่เกิดขึ้นอย่างต่อเนื่อง โดยหน่วยความจำที่จัดการโดย Zig หรือหน่วยความจำที่จัดการโดย GTK จะถูกปลดปล่อยอย่างไม่ถูกต้อง ปัญหา lifetime mismatches เหล่านี้สร้างปัญหาการ crash ทั้งหมดที่รบกวนแอปพลิเคชัน ทีมพัฒนาค้นพบว่าการต่อสู้กับระบบ reference-counting ของ GTK แทนที่จะยอมรับมันนั้นไม่เกิดประโยชน์
การพัฒนาใหม่ได้ห่อหุ้ม Zig structures เช่นระบบ configuration ด้วย reference-counted GObjects ซึ่งช่วยให้ระบบแจ้งเตือนการเปลี่ยนแปลง property ของ GTK สามารถจัดการการอัปเดตทั่วทั้งแอปพลิเคชันได้อย่างเป็นธรรมชาติ ขจัดการจัดการหน่วยความจำด้วยตนเองที่ซับซ้อนซึ่งเคยทำให้เกิดการ crash การโหลด configuration ใหม่ซึ่งเคยเป็นกระบวนการที่ใช้ CPU มากและเสี่ยงต่อข้อผิดพลาด ตอนนี้ทำงานได้อย่างราบรื่นผ่านกลไกในตัวของ GTK
การทดสอบ Valgrind เผยผลลัพธ์ที่น่าประหลาดใจ
ตลอดกระบวนการเขียนใหม่ ทีมได้ทดสอบทุกฟีเจอร์ผ่านเครื่องมือวิเคราะห์หน่วยความจำ Valgrind ผลลัพธ์ที่ได้ท้าทายสมมติฐานทั่วไปเกี่ยวกับความปลอดภัยของหน่วยความจำในภาษาโปรแกรมมิ่งต่างๆ โค้ดเบส Zig แสดงความเสถียรที่น่าทึ่งโดยมีเพียง memory leak หนึ่งครั้งและปัญหา undefined memory access หนึ่งครั้งในโค้ดเบสที่มีขนาดใหญ่ ซับซ้อน และมีหลาย thread
โค้ดเบส Zig ของเรามี leak หนึ่งครั้งและ undefined memory access หนึ่งครั้ง นั่นทำให้ฉันประหลาดใจมาก (ในทางที่ดี)
ปัญหาหน่วยความจำอื่นๆ ที่ค้นพบระหว่างการทดสอบเกิดขึ้นที่ขอบเขต C API โดยเฉพาะในการจัดการ lifetime ที่ซับซ้อนของระบบ GObject สิ่งนี้เสริมความจริงที่ว่าการรับประกันความปลอดภัยของหน่วยความจำมักจะพังทลายเมื่อข้ามขอบเขตภาษา โดยไม่คำนึงถึงคุณสมบัติความปลอดภัยของภาษาต้นทาง
ผลการวิเคราะห์หน่วยความจำ:
- โค้ดเบส Zig : พบการรั่วไหลของหน่วยความจำ 1 จุด และการเข้าถึงหน่วยความจำที่ไม่ได้กำหนดค่า 1 จุด
- ขอบเขต C API : พบและแก้ไขปัญหาหลายสิบจุด
- ระบบ GTK/GObject : แก้ไขบั๊กการจัดการอายุการใช้งานหลายจุดเรียบร้อยแล้ว
- วิธีการทดสอบ: การวิเคราะห์ด้วย Valgrind ในทุกฟีเจอร์และ PR
ชุมชนถกเถียงเกี่ยวกับแนวทาง Platform-Native
การเขียนใหม่ได้จุดประกายการอ้าเถียงเกี่ยวกับบทบาทของ GTK ในระบบนิเวศ Linux และว่าความซับซ้อนนั้นคุ้มค่าหรือไม่ นักพัฒนาบางคนตั้งคำถามว่างานการรวมระบบที่กว้างขวางนั้นคุ้มค่าหรือไม่สำหรับสิ่งที่เป็นเพียงแท็บและเมนูบริบท คนอื่นๆ โต้แย้งว่าการครอบงำของ GTK และสัญญาของคุณสมบัติการเข้าถึงทำให้มันเป็นตัวเลือกที่เหมาะสมสำหรับแอปพลิเคชัน Linux
การถกเถียงขยายไปเกินกว่าการพิจารณาทางเทคนิคไปสู่การพิจารณาเชิงปรัชญาเกี่ยวกับการออกแบบส่วนติดต่อผู้ใช้ ในขณะที่บางคนชอบแนวทางที่เรียบง่ายเช่นการเรนเดอร์ OpenGL แบบกำหนดเองของ Kitty ภารกิจของ Ghostty มุ่งเน้นที่การรวมระบบ platform-native ที่รู้สึกคุ้นเคยกับผู้ใช้ภายในสภาพแวดล้อมเดสก์ท็อปที่พวกเขาเลือก
การรองรับแพลตฟอร์มของ Ghostty :
- macOS: แอปพลิเคชัน Swift พร้อม Xcode
- Linux/BSD: แอปพลิเคชัน GTK พร้อมการผสานรวม X11/Wayland โดยตรง
- Core: ไลบรารี Zig ที่ใช้ร่วมกันพร้อมความเข้ากันได้กับ C ABI
- Frontend ของบุคคลที่สาม: รองรับผ่าน libghostty (เช่น Wraith สำหรับ Wayland )
มองไปข้างหน้า
แอปพลิเคชัน GTK ที่เขียนใหม่จะจัดส่งเป็นค่าเริ่มต้นใน Ghostty เวอร์ชัน 1.2 ซึ่งจะมาถึงในสัปดาห์ที่จะมาถึง ทีมวางแผนที่จะใช้ประโยชน์จากการรวมระบบ GTK ใหม่สำหรับฟังก์ชัน GUI ที่ขยายออกไป รวมถึงไดอะล็อกการตั้งค่าแบบ native และคุณสมบัติการรวมระบบแพลตฟอร์มที่ลึกขึ้นเช่นการซิงค์การกำหนดค่าอัตโนมัติบน macOS
สำหรับผู้ใช้ที่ชอบทางเลือกอื่นแทน GTK แกนกลาง libghostty แบบโมดูลาร์ช่วยให้ frontend ของบุคคลที่สามทำงานได้ โปรเจ็กต์เช่น Wraith แสดงให้เห็นแล้วถึงการพัฒนาแบบ Wayland-native ที่ข้าม GTK ทั้งหมด แสดงให้เห็นว่าสถาปัตยกรรมรองรับแนวทางที่แตกต่างกันในการออกแบบส่วนติดต่อผู้ใช้