3 puan yazan GN⁺ 2 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • Terminal uygulamalarının metin tabanlı oldukları için doğası gereği erişilebilir olduğu varsayımı, modern TUI dünyasında geçerliliğini yitiriyor; Ink, Bubble Tea ve tcell gibi çerçeveler ekran okuyucu kullanıcıları için daha düşmanca bir ortam oluşturabiliyor
  • CLI, stdin/stdout üzerinden akan doğrusal bir akıştır; çıktı zaman sırasıyla birikir. TUI ise terminali karakter hücrelerinden oluşan 2D bir ızgara olarak ele alır ve bu da ekran okuyucuların akışı takip etmesini zorlaştırır
  • gemini-cli, Ink’in React bileşen ağacını terminal ızgarasına göre yeniden çizmesi nedeniyle imleci spinner, zamanlayıcı ve sohbet geçmişi arasında gezdirerek Speakup ve NVDA’da tekrarlı okuma, çökme ve giriş gecikmesine yol açabiliyor
  • nano, vim, menuconfig ve Irssi gibi eski araçlar, imleci gizleme, tek sütunlu odak ve VT100 kaydırma bölgesi kullanımı sayesinde koordinat güncelleme gürültüsünü azaltıp giriş satırıyla etkileşimi en aza indiriyor
  • Erişilebilir terminal araçları geliştirmek için terminali bir tuval gibi ele alan bildirime dayalı UI çerçevelerinden ve agresif yeniden çizimden kaçınmak, bunun yerine basit ve doğrusal CLI akışına yakın bir davranış sağlamak gerekiyor

“Metin olduğu için erişilebilir” yanılgısı

  • Terminalde çalışan uygulamaların doğası gereği erişilebilir olduğu varsayımı, gerçek kullanım koşullarıyla örtüşmüyor
  • Grafikler, karmaşık DOM yapıları ya da WebGL tuvalleri olmadığı için ekran okuyucuların ham ASCII metnini kolayca yorumlayabileceği beklentisi, modern TUI’lerde boşa çıkıyor
  • Ink (JS/React), Bubble Tea (Go) ve tcell gibi terminal UI çerçeveleri geliştirici deneyimini (DX) iyileştirmeyi hedeflese de, görme engelli kullanıcılar için daha düşmanca ortamlar yaratabiliyor
  • Çoğu zaman modern TUI’ler, kötü uygulanmış grafik arayüzlerden bile erişilebilirlik açısından daha kötü olabiliyor

CLI ile TUI arasındaki yapısal fark

  • CLI: doğrusal akış

    • CLI, stdin/stdout temelli çalışır; bir komut girildiğinde sonuç alta eklenir ve imleç aşağı iner
    • Çıktı doğrusal biçimde ve zaman sırasına göre biriktiği için Speakup gibi çekirdek düzeyindeki ekran okuyucular için uygundur
  • TUI: 2D ızgara

    • TUI, terminal penceresini bir metin akışı olarak değil, her karakter hücresinin bir piksel gibi kullanıldığı 2D bir ızgara olarak ele alır
    • Zamansal akıştan vazgeçip mekânsal yerleşimi öne çıkardığı için ekran okuyucuların takip etmesi zor bir yapı ortaya çıkar

gemini-cli ile görünür hâle gelen sorun

  • gemini-cli, Node.js ve Ink çerçevesiyle yazılmış bir araçtır ve dışarıdan bakıldığında basit bir sohbet arayüzü gibi görünür
  • İçeride ise Ink, React bileşen ağacını terminal ızgarasına uyarlamaya çalışır
  • Speakup (Linux) ya da NVDA (Windows) ile kullanıldığında, uygulama sadece başarısız olmakla kalmaz; ekran okuyucuya sürekli okunacak içerik yağdırır
  • Tepkisel bir tuval gibi davranan ekran

    • Çerçeve ekranı tepkisel bir tuval gibi gördüğü için her güncelleme yeniden çizime yol açar
    • Yapay zeka “düşünürken” zamanlayıcıyı ya da spinner’ı güncellemek için donanım imlecini zamanlayıcının olduğu yere taşır, yeni zamanı yazar ve sonra eski konuma döndürür
    • Görsel kullanıcı için bu anlık bir davranıştır, ancak ekran okuyucu kullanan biri için “Responding... Time elapsed 1s... Responding... Time elapsed 2s...” gibi tekrar tekrar duyulur
    • İmleç durum göstergesi, spinner ve sohbet geçmişi arasında anlık olarak gezinirken Speakup da o anda imlecin altında ne varsa okumaya çalışır
    • Sonuçta zamanlayıcı güncellemeleriyle sohbet parçaları birbirine karışır ve kullanıcının gerçekten yazdığı içeriğe odaklanması zorlaşır
  • NVDA ve yapıştırma sırasında görülen kararsızlık

    • Windows’ta NVDA ile terminal açıp Linux makineye SSH üzerinden bağlandıktan sonra bir screen oturumuna girip metin yapıştırıldığında, NVDA hemen çökebilir ya da sistem ciddi biçimde kararsızlaşabilir
    • Her karakter girildiğinde ya da metin yapıştırıldığında uygulama durumu değişir ve çerçeve arayüzün yeniden render edilmesi gerektiğine karar verir
    • Sohbet geçmişi durumun bir parçasıysa, binlerce satırlık metnin yerleşimini anında yeniden çizmeye ya da yeniden hesaplamaya çalışır
    • Sohbet mesajı arttıkça bu sorun daha sık ortaya çıkar
    • Dinamik içerik bildirimlerinden kaçınmak için kullanılan Insert+5 kısayolu bile bu sorunu önleyemez
  • Giriş gecikmesi döngüsü

    • Ink gibi çerçeveler Node.js gibi tek iş parçacıklı ortamlarda çalıştığında, kayıt büyüdükçe performans kaybı da artar
    • Büyük metin blokları yapıştırıldığında binlerce satır için fark hesabı yapılması gerekir
    • Sistem ekranı nasıl yeniden çizeceğini hesaplamakla meşgul olduğundan giriş işleme gecikir
    • Tek bir tuşa basıldığında bile karakterin yeniden görünmesi için 10 saniyeye kadar beklemek gerekebilir

Eski araçlar neden çalışıyor?

  • nano, vim ve menuconfig gibi araçlar her zaman erişilebilirlikte kusursuz oldukları için kullanılmıyor
  • Esas nokta, bu araçların imleci tamamen gizleyebilmesi ya da imleç konumu takibinden doğan gürültüyü azaltabilmesidir
  • nano ve vim: imleci gizleme

    • nano, --constantshow gibi imleç konumunu gösteren bir seçenekle çalıştırıldığında veya vim belirli ayarlar olmadan kullanıldığında kullanılabilirlik bozulabilir
    • İmleç görünürken ve izleme etkinken Speakup, karakter yankısından önce imleç konumu güncellemelerini okur
    • Kullanıcı “a” yazdığında “a” yerine “Column 2”, “b” yazdığında ise “Column 3” duyabilir
    • Bu eski araçlar, görsel imleç veya durum çubuğu güncellemelerini bastıracak şekilde ayarlanabildiği için ekran okuyucunun koordinat güncellemelerine değil, karakter giriş akışına dayanmasını sağlayabilir
    • Modern çerçeveler ise genellikle “no-cursor” ya da “headless” modu sunmaz ve görsel imlecin zorunlu olduğunu varsayar
  • menuconfig: tek sütunlu odak

    • Linux çekirdeğinin menuconfig aracı, katı bir tek sütunlu odak koruduğu için çalışır
    • Kenarlıklar ve başlıklar olsa da etkin alan dikey bir listedir ve imleç bu listeye sabitlenir
    • İmleç bir saati güncellemek için sağ alta, sonra başlığı güncellemek için sol üste gitmez
    • Mekânsal karmaşıklık düşük kaldığı için ekran okuyucu yönünü kaybetmez
  • Irssi: kaydırma bölgesinden yararlanma

    • Irssi tesadüfen erişilebilir değildir; 20 yılı aşkın süredir özel bir render motoru üzerinden VT100 kaydırma bölgesi kullanan bir sohbet aracıdır
    • Yeni mesaj geldiğinde terminal sürücüsüne “1. satırdan 23. satıra kadar olan alanı kaydırma bölgesi olarak tanımla” talimatı verir
    • Ardından “yukarı kaydır” komutunu gönderir; terminal içeriği yukarı taşır ve ilgili alanın alt kısmına yeni metni çizer
    • Bu yaklaşım giriş satırıyla etkileşimi en aza indirir
    • Ekrandaki tüm karakterleri elle yeniden yazmak yerine terminalin donanımsal yeteneklerine dayanır
    • Modern çerçeveler bu tür donanımsal özellikleri göz ardı edip ekran durum farkını hesaplayarak karakterleri yeniden yazmayı tercih eder; bu da hesaplama maliyetini artırır ve erişilebilirliğe düşmanca davranır

gemini-cli sorunlarının ele alınışındaki problem

  • Google ve gemini-cli bakımcıları erişilebilirliğe önem veriyormuş gibi görünse de, depoda önemli erişilebilirlik gerilemeleri sahipsiz bırakılmış durumda
  • Issue #3435 ve Issue #11305 gibi erişilebilirlik gerilemeleri için ne bir tartışma, ne bir yol haritası, ne de bir düzeltme var
  • Issue #1553, bu tür erişilebilirlik başarısızlıklarını takip etmek için açılmış bir konuydu; ancak çözülmedi ve bir bot tarafından otomatik kapatıldı
  • Bot, uzun süredir etkinlik olmadığı ve birikmiş işleri yönetmek gerektiği yönündeki genel bir ifadeyle konuyu kapattı
  • Bakımcıların aylarca dokunmadığı gerekçesiyle erişilebilirlik raporlarını kapatmak, düzen sağlamak değil kanıtı gizlemektir
  • Bu, bir hatayı yeterince uzun süre görmezden gelirseniz artık yokmuş gibi davranılabileceği mesajını verir; oysa yazılım gerçekte görme engelli kullanıcılar için hâlâ kullanılamaz durumdadır
  • Projenin “Closed Issues” metriği daha iyi görünebilir, ancak erişilebilirlik sorunları çözülmüş olmaz

Erişilebilir terminal araçları geliştirmek için sonuç

  • Terminal uygulamalarında erişilebilirliği gerçekten önemsiyorsanız, terminali bir tuval gibi ele alan bildirime dayalı UI çerçevelerini kullanmayı bırakmalısınız
  • “Modern” TUI yığınları, geliştiricinin React benzeri kod yazmasını kolaylaştıracak şekilde optimize edildi ve bunun bedeli olarak makinenin metni verimli render etme yeteneği feda edildi
  • Uygulama kullanıcının imleci gizleyebilmesini garanti edemiyorsa ya da spinner ve zamanlayıcı göstermek için agresif yeniden çizime dayanıyorsa, ortaya erişilemez bir araç çıkar
  • Görme engelli kullanıcılar için geciken, sürekli bir şeyler okuyan ve imleci ekranın her yanına savuran “akıllı” TUI’ler yerine, basit ve doğrusal CLI akışı çok daha iyidir

1 yorum

 
GN⁺ 2 시간 전
Lobste.rs görüşleri
  • Bu yazı da diğer blog yazıları gibi güçlü biçimde AI destekli yazım kokusu taşıyor
    LLM’ler bu tür başlıkları seviyor: “The Architectural Flaw”, “The Lag Loop”, “Why The ‘Old Guard’ Works”, “The Lost Art of Scrolling Regions”, “The ‘Stale Bot’ excuse: A Case Study in Neglect”

    • Başlıktan itibaren AI tarafından seri üretilmiş bir yazı gibi okunuyor. Konunun kendisi yeni olduğu için spam diye şikâyet etmek biraz aşırı kaçmış olabilir ama 1) her yerde tekrarlanan aynı üsluba artık dayanamıyorum ve 2) bu durum içeriğin doğruluğundan da şüphe etmeme yol açıyor
      Harika bir blog yazısı olabilirdi ama yazar taslağı ChatGPT’ye verip işi orada bıraktıysa bu hem okura hem yazara zarar veriyor
    • LLM yazımında en nefret ettiğim özelliklerden biri, “The <hiç yerleşik olmayan kavram>” gibi yazarak sanki resmî bir kavrammış izlenimi vermesi
      Çok özel, tek seferlik bir soruna “klasik” demek de aynı şey
  • Gerçekten moral bozucu. Özetle Irssi gibi erişilebilir TUI’ler var ama modern TUI framework’leri bu emsalleri görmezden gelip grid diff hesaplamaları ve imleç hareketlerine dayanıyor
    Ekran okuyucular imleç hareket ettiğinde o konumdaki içeriği okuduğu için sonuç karmakarışık oluyor ya da büyük bir seslendirme spam’i oluşuyor

  • Buradaki teknik açıklamanın tamamen doğru olup olmadığından emin değilim
    Özellikle Ink uzun süre hiç artımlı render desteklemedi ve Ink kullanan uygulamaların çoğu da bunu hâlâ etkinleştirmiyor. O artımlı render da satır tabanlı, yani imleci gerçek zamanlayıcı konumuna götürmüyor
    Gemini CLI’de artımlı render’ı açmak için alternate buffer kullanımı gerekiyor ve bu da yerleşik ekran okuyucu dostu mod açıksa devre dışı bırakılıyor. İlgili seçeneklerin belgeleri burada
    Ek olarak Python’daki rich/textual, daha yavaş ve çoğunlukla tek iş parçacıklı bir dil üzerinde olmasına rağmen çoğu zaman Ink’ten çok daha hızlı. Binlerce satırlık diff hesaplamak zorunlu olarak o kadar yavaş değil, 10 saniye sürecek kadar hiç değil
    Kullanıcı deneyiminin hantal ve bozuk olduğundan şüphem yok ama öne sürülen kesin nedenin LLM halüsinasyonu olabileceği ya da eksik bilgiye dayanabileceği anlaşılıyor. Ink’in artımlı render’ı açık olsa bile anlatıldığı gibi çalışmıyor
    Gerçekte tüm ekranın yeniden çizilmesi ekran okuyucuyu şaşırtıyor olabilir ve satır tabanlı yeniden çizim de değişikliklerle ilgisiz rastgele kopuk metin parçalarını tekrar okutacak kadar kötü olabilir

  • Sadece TUI’leri suçlamak adil değil
    Asıl sorun, neredeyse tüm stack boyunca erişilebilirlik desteğinin berbat olması
    İlk olarak, GPU ile render yapan terminal emülatörlerinin çoğu sistemin sunduğu erişilebilirlik API’lerini hiç kullanmıyor. Metin GPU ile render edilince erişilebilirlik araçları onu “okuyamıyor”, sadece bir görsel gibi görüyor. Kitty, Alacritty ve WezTerm buna giriyor. Benim terminalim Ghostty macOS’ta erişilebilirlik API’si üzerinden okunabiliyor; iTerm2 ve Terminal.app de öyle
    İkinci olarak, TUI’nin erişilebilirlik bilgisini terminal emülatörüne iletmesi için hiçbir terminal sekansı ya da standart hareket yok. Terminal hücreleri, çalıştırma aralıkları ve bölgeler için ARIA benzeri açıklamalara denk bir şeye ihtiyaç var ama böyle bir girişim yok. TUI imleci düzgün kullansa bile birçok kullanım senaryosunda sorun çıkacak
    Örneğin Ghostty’de OSC133 ile erişilebilirlik API’sini entegre ederek her shell prompt’unu, girdiyi ve komutu sadece düz metin kutuları olarak değil, yapısal olarak anlamlı öğeler şeklinde sunmak için çalışıyorum. Bu da terminal spesifikasyonunun, TUI’lerin ve terminal emülatörlerinin birlikte uyumlu olması gerektiğini gösteriyor
    Tüm stack çürümüş durumda ve bunu gerçekten düzeltmeye çalışan insan da neredeyse yok. Ben de zamanım sınırlı olduğu için elimden geleni yapıyorum ama bu, ekosistem siyaseti de gerektiren devasa bir konu; tek başına üstesinden gelmek zor
    Bonus olarak, tuhaf ama korkunç gerçek şu ki AI burada erişilebilirlik iyileştirmelerine yardımcı oluyor. Birçok AI aracı erişilebilirlik API’lerini kullanarak ya da suistimal ederek pencere listesini okuyor ve girdi gerçekleştiriyor. Bu yüzden daha fazla uygulama, AI kullanım senaryoları nedeniyle erişilebilirlik entegrasyonunu çok daha ciddiye almaya başladı

    • Terminal gerçekten de küçük bir tarayıcıya dönüşüyor
  • Claude Code ile gemini-cli’nin readline tabanlı olmaması her gün beni sinirlendiriyor
    Bazı benzer tuş kombinasyonlarını eklemişler ama alışıldık readline kısayollarının uzun kuyruğu eksik
    Anthropic, “bunu web geliştirme gibi yapmalıyız” kararının bir hata olduğunu kabul edip readline ile yeniden başlayabilir
    Bu tür araçları geliştiren geliştiricilere tanıdık gelen geliştirme deneyiminin, bu araçları kullanan kullanıcılar için tanıdık olan kullanıcı deneyiminden daha önemli olduğu fikri yanlış

    • Bu sorunun büyük kısmının, Ink’in aslında bir render backend olmaktan memnun olup girdi widget’ları sunmamasından kaynaklandığını düşünüyorum
      Gerçekten iyi bakılan, ünlü üçüncü taraf çözümler de neredeyse yok. Esnek bir input box gerekiyorsa en baştan kendin yapman gerekiyor
      Textual’ın mükemmel Input widget’ı ya da JS ekosistemindeki başka bir kütüphane olan OpenTUI ile karşılaştırılabilir
    • readline GNU lisanslı değil miydi? Birisi sonunda GPL olmayan bir sürüm mü yaptı?
      LLM’leri sevmediğim için kötü bir UI benim açımdan kişisel olarak bir artı ama readline kullanmamanın da bir nedeni olabilir
  • kakoune ve helix gibi terminal editörlerinin, “imleci gizleme” hilesi kullanılmadıkça erişilebilirlik standartlarını geçmesinin zor olduğunu düşünüyorum
    Yine de büyük ihtimalle VS Code kadar erişilebilir değiller
    VS Code dışında erişilebilir, çapraz platform bir IDE-lite ya da IDE hangisi olabilir? VS Code’un giderek daha düşmanca tavır alması hoşuma gitmiyor. Belki JetBrains IDE’ler olabilir

    • emacspeak var ve Emacs için çok erişilebilir bir arayüz sağlıyor
      Dezavantajı, Emacs’in kendisi çapraz platform olsa da emacspeak’in TTS nedeniyle Linux’a zayıf bir bağımlılığı olabileceği. Ya da olmayabilir. Windows’ta hiç denemedim
    • Önce erişilebilirliğin kimin için olduğunu sormak gerekir. İşitme engelliler içinse yerel dilde yazı ve yerel işaret dili sunmak gerekir. ABD’de bu genelde ASL’dir
      Görme engelliler için erişilebilirlik söz konusuysa emacspeak ya da platformun görme engellilere yönelik erişilebilirlik araçları gerekir
      Erişilebilirlik bir spektrumdur, bir onay kutusu değil
  • Links’te ayrı bir Braille terminal modu var; sahte GUI öğelerini daha basit tam ekran menülere dönüştürüyor ve ok tuşlarıyla gezinmeyi de satır bazına indiriyor
    Bir başka ilginç örnek de edbrowse. Görme engelli Karl Dahlke’nin yaptığı bir metin modlu tarayıcı ama daha popüler metin modlu web tarayıcılarının aksine TUI kullanmıyor; ed tarzı bir komut satırı arayüzü kullanıyor

  • Eğer bu Ink framework ise, CLI’nin neden %100 CPU kullanıp sonsuza dek takılı kaldığını ve uzun sohbet geçmişini durmadan yeniden çizdiğini açıklıyor olabilir. Üzücü