- เดิมทีสภาพแวดล้อม Wayland มีโครงสร้างที่ คอมโพสิตรและตัวจัดการหน้าต่างรวมอยู่ในโปรแกรมเดียวกัน แต่ river 0.4.0 ได้ แยกสิ่งนี้ออกเป็นคนละโปรเซส
- โปรโตคอลใหม่ river-window-management-v1 มอบอำนาจด้านนโยบายทั้งหมดให้ตัวจัดการหน้าต่าง เช่น การจัดวางหน้าต่างและคีย์ไบน์ดิง พร้อมทั้งยังคงรักษา ความสมบูรณ์ของเฟรม (frame perfection) และประสิทธิภาพไว้ได้
- โครงสร้างนี้ทำงานได้โดยไม่มี ความหน่วงของอินพุต (latency) และรับประกันการเรนเดอร์ที่เรียบร้อยแม้ในเลย์เอาต์แบบไทล์ที่ซับซ้อน ผ่าน การอัปเดตสถานะแบบอะตอมมิก
- ด้วยโครงสร้างที่แยกออกจากกัน ตัวจัดการหน้าต่างจึง พัฒนาและรีสตาร์ตได้อย่างอิสระ และยังทำให้การเขียนด้วยภาษาระดับสูงทำได้ง่ายขึ้น
- แนวทางนี้ช่วยผลักดันให้ระบบนิเวศ Wayland มี ความหลากหลายของตัวจัดการหน้าต่างมากขึ้น และ river รองรับตัวจัดการที่เข้ากันได้แล้วมากกว่า 15 ตัว
โครงสร้างแบบดั้งเดิมของ Wayland และแนวทางการแยกของ river
- คอมโพสิตร Wayland แบบเดิมรวม 3 บทบาทคือ ดิสเพลย์เซิร์ฟเวอร์, คอมโพสิตร, ตัวจัดการหน้าต่าง ไว้ในโปรเซสเดียว
- ดิสเพลย์เซิร์ฟเวอร์ทำหน้าที่ส่งต่อเหตุการณ์อินพุตและส่งบัฟเฟอร์แสดงผลไปยังเคอร์เนล
- คอมโพสิตรนำบัฟเฟอร์จากหลายหน้าต่างมารวมกันเพื่อสร้างภาพสุดท้ายบนหน้าจอ
- ตัวจัดการหน้าต่างรับผิดชอบนโยบายของผู้ใช้ เช่น การจัดวางหน้าต่างและคีย์ไบน์ดิง
- ในโครงสร้าง X11 ดิสเพลย์เซิร์ฟเวอร์อยู่เป็นอีกโปรเซสหนึ่ง ทำให้เกิด การสื่อสารไปกลับที่ไม่จำเป็นและความหน่วง
- Wayland แก้ปัญหานี้ด้วยการรวมเซิร์ฟเวอร์กับคอมโพสิตรเข้าด้วยกัน แต่ การรวมตัวจัดการหน้าต่างเข้ามาด้วยไม่ใช่สิ่งจำเป็น
- river จึงคลายการผูกติดนี้และ แยกตัวจัดการหน้าต่างออกเป็นโปรแกรมต่างหาก
หลักการออกแบบของโปรโตคอล river-window-management-v1
- ออกแบบมาเพื่อให้ตัวจัดการหน้าต่างมี อำนาจควบคุมสูงสุด พร้อมยังคงข้อดีของ Wayland
- ไม่จำเป็นต้องมี การสื่อสารไปกลับทุกเฟรมหรือทุกเหตุการณ์อินพุต จึงไม่มีความหน่วงของอินพุต
- รักษา ความสมบูรณ์ของเฟรม (frame perfection): เมื่อมีการเปิดหน้าต่างใหม่หรือเปลี่ยนขนาดหน้าต่าง จะรับประกันว่า การอัปเดตหน้าจอไม่มีช่องว่างหรือการซ้อนทับ
- จะหน่วงการเรนเดอร์ไว้จนกว่าทุกหน้าต่างจะส่งบัฟเฟอร์ใหม่ แต่หากเกินเวลาที่กำหนดจะจัดการด้วย timeout
- ยิ่งแอปพลิเคชันมีการพัฒนามาอย่างดี ก็ยิ่งสามารถทำเฟรมซิงก์ให้สมบูรณ์ได้
โครงสร้างการจัดการหน้าต่างแบบอิง state machine
- โปรโตคอลแบ่งสถานะออกเป็น สถานะการจัดการหน้าต่าง และ สถานะการเรนเดอร์
- สถานะการจัดการหน้าต่าง: ขนาดหน้าต่าง, การเป็นเต็มหน้าจอ, คีย์บอร์ดโฟกัส, คีย์ไบน์ดิง เป็นต้น
- สถานะการเรนเดอร์: ตำแหน่งหน้าต่าง, ลำดับ, การตกแต่ง, การครอป เป็นต้น
- การเปลี่ยนแปลงต่าง ๆ จะถูกรวมและประมวลผลเป็น การอัปเดตแบบอะตอมมิก (manage/render sequence)
- คอมโพสิตรเป็นผู้เริ่ม sequence และหากไม่มีการเปลี่ยนสถานะ ตัวจัดการหน้าต่างจะคงอยู่ในสถานะรอ
- โครงสร้างนี้คือการ ทำให้แนวคิดที่มีอยู่แล้วโดยนัย ใน river-classic, sway และอื่น ๆ กลายเป็นรูปแบบที่ชัดเจนอย่างเป็นทางการ
ข้อดีของโครงสร้างแบบแยก
- นักพัฒนาตัวจัดการหน้าต่างสามารถ โฟกัสเฉพาะนโยบายได้ โดยไม่ต้องสร้างคอมโพสิตรทั้งชุดเอง
- ดีบักและรีสตาร์ตได้ง่าย และการแครชของตัวจัดการหน้าต่างจะไม่ทำให้เซสชันจบลง
- แม้เขียนด้วย ภาษาที่มี garbage collection ก็ไม่ทำให้ประสิทธิภาพลดลง และทำงานได้โดยไม่มีการหน่วงเฟรม
- ปัจจุบันมี ตัวจัดการหน้าต่างที่เข้ากันได้กับ river มากกว่า 15 ตัว แล้ว และคาดว่าจะขยายความหลากหลายได้ในระดับเดียวกับ X11
ข้อจำกัดและแผนในอนาคต
- ปัจจุบันโปรโตคอลรองรับเฉพาะ สภาพแวดล้อมเดสก์ท็อปแบบ 2D เท่านั้น ยังไม่รองรับ VR เป็นต้น
- เอฟเฟกต์ภาพที่ซับซ้อน (เช่น หน้าต่างสั่นไหว) อยู่นอกขอบเขต แต่แอนิเมชันแบบง่ายยังทำได้
- ในอนาคตมีการพิจารณารองรับ custom shader แต่ยังไม่ใช่แผนระยะสั้น
- river 0.4.0 เพียงพอสำหรับการใช้งานประจำวันแล้ว และมีแผน ปรับปรุง UX ก่อนเปลี่ยนผ่านสู่เวอร์ชัน 1.0.0
- เพื่อให้การพัฒนาดำเนินต่อไป มีการขอรับการสนับสนุนผ่าน liberapay, GitHub Sponsors, Ko-fi
ตัวอย่างและแกลเลอรี
- มีการยกตัวอย่างตัวจัดการหน้าต่างหลากหลายแบบที่ทำงานบน river
- Canoe: ตัวจัดการหน้าต่างแบบซ้อนหน้าต่างสไตล์คลาสสิก
- reka: ตัวจัดการหน้าต่างที่ทำงานบน Emacs
- tarazed: สภาพแวดล้อมเดสก์ท็อปแบบเน้นสมาธิ
- rhine: รองรับการจัดการหน้าต่างแบบเรียกซ้ำและแยกส่วน พร้อมรองรับแอนิเมชัน
- นอกจากนี้ยังมี ตัวจัดการหน้าต่างที่เข้ากันได้กับ river อีกจำนวนมาก
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
รู้สึกว่าเข้าใจได้ยากว่าทำไมในคอมเมนต์ถึงมี ความไม่พอใจ ต่อ Wayland (โปรโตคอล) มากขนาดนั้น
ไลบรารีอย่าง wlroots ก็จัดการส่วนที่หนักไปแล้ว และตอนนี้ river ก็มี abstraction ระดับสูงขึ้นมาให้
โปรเจ็กต์ Wayland อาจจะออก abstraction แบบนี้ได้เร็วกว่านี้ แต่ก็เป็นสิ่งที่ใครก็ทำได้อยู่แล้ว
สุดท้ายแล้วเราก็ได้พัฒนาการพวกนี้มา ฟรี ๆ เลยไม่เห็นว่าจำเป็นต้องบ่นเพราะไม่มีใครทำให้แทน
ปัญหา accessibility ก็ถูกมองเป็นความเสี่ยงด้านความปลอดภัย ทำให้การออกแบบยิ่งยากขึ้น และพอเข้าสู่ยุค Agentic AI ก็ยิ่งน่าสนใจขึ้นไปอีก
Pipewire กำลังเข้ามาเติมช่องโหว่ที่ Wayland ปล่อยไว้ แต่ก็ยังมีความรู้สึกว่าการออกแบบยังไม่เป็นมิตรกับผู้ใช้พอ
ถึงอย่างนั้นก็ยังคิดว่า Wayland แม้จะถอยหลังหนึ่งหรือสองก้าวบ้าง แต่ภาพรวมก็ยังเดินหน้าไปสองก้าว
มักตอบสนองในทำนอง “ไม่เอาวิธีฉันก็ไปซะ” และไม่ค่อยยืดหยุ่นต่อคำขอจากภายนอก
การที่ให้ใช้ฟรีก็เป็นเรื่องดี แต่เมื่อ Xorg หยุดพัฒนาและไม่มีทางเลือกอื่น การผลักดันแบบกึ่งบังคับก็ถือว่าเป็นปัญหา
พอเห็นโปรเจ็กต์นี้ก็เป็นครั้งแรกที่รู้สึกว่า Wayland ไม่ใช่การเสียเวลาเปล่า
คิดว่า display server ไม่จำเป็นต้องทำงานจัดการหน้าต่างที่ซับซ้อนไปด้วย
เดิมทีที่ Wayland รวม window manager กับ compositor เข้าด้วยกัน น่าจะเป็นเพราะมันคือ เส้นทางที่แรงต้านน้อยที่สุด
แต่ฟีเจอร์ remote access ก็ยังเป็นปัญหาอยู่ดี สิ่งที่เคยทำงานดีบน X11 กลับมีบั๊กเยอะบน Wayland
Wayland รวมมันเข้าด้วยกันเพื่อแก้ปัญหานี้ แต่ก็เกิดผลข้างเคียงอย่างอื่นตามมา
เส้นแบ่ง API วางไว้ดี ทำให้แชร์โค้ดกันได้ง่าย
เลยสงสัยว่าบั๊กการหมุน 90 องศาเป็นปัญหาฝั่ง compositor หรือฝั่ง wlroots กันแน่
รู้สึกว่านี่เป็นหนึ่งใน ข้อบกพร่องด้านการออกแบบ ของ Wayland ที่เพิ่งเริ่มมีการแก้ไขเสียที
กว่าที่โปรโตคอลร่วมจะลงตัวและ window manager ต่าง ๆ จะโตพอเทียบระดับ X11 ได้ ก็น่าจะต้องใช้เวลาอีก 15 ปี
แล้วสุดท้ายก็คงมีใครสักคนบอกว่าจะ “สร้างสิ่งที่ดีกว่า” แล้วทิ้ง Wayland ไปเริ่มใหม่อีก
เจอปัญหา UEFI จนเหนื่อย สุดท้ายก็ย้ายไปใช้ Samsung DEX
ข้อจำกัดไม่ได้เป็นเรื่องเทคนิคเท่าไร แต่เป็น ปัญหาทางการเมือง มากกว่า
ในฐานะคนใช้ Linux มา 25 ปี หลังย้ายมาใช้ Wayland เมื่อ 5 ปีก่อน ก็พอใจมากเพราะไม่มีปัญหา ภาพฉีก (tear) อีกเลย
ในมุมของนักพัฒนามันอาจมีงานเพิ่มขึ้น แต่ในฐานะผู้ใช้ถือว่าดีขึ้นชัดเจน
ชักสงสัยว่าตัวเองจะกลายเป็นคนที่พูดถึงฟีเจอร์เก่า ๆ ของ CDE ไม่เลิกรึเปล่า
River ยอดเยี่ยมอยู่แล้วตั้งแต่ก่อนแยกส่วน น่าติดตามมากว่าจะพัฒนาไปทางไหนต่อ
เคยย้ายไป Niri ชั่วคราว แต่สักวันก็คงกลับมาอีก
ถ้าเป็น ผู้ใช้ Xmonad ก็น่าจะเข้ากับ River ได้ดีที่สุด
เลยอยากรู้ว่าใน River หน้าต่างใหม่จะถูกแทรกเหนือหน้าต่างที่เลือกอยู่หรือเปล่า
หลังแยกส่วนแล้วก็อยากรู้ด้วยว่าโปรเจ็กต์ฝั่ง window manager จะใช้ชื่ออะไร
สุดท้ายแล้วเราก็กำลัง ประดิษฐ์ความสามารถของ X11 ขึ้นใหม่ทีละอย่าง
สักวันหนึ่งหน้าต่างบน Wayland อาจรู้ตำแหน่งของตัวเองได้ก็ได้
ดูแล้วคงต้องรอไปอีกพักใหญ่
ส่วนเดสก์ท็อปก็น่าจะถูกครองโดย Android, ChromeOS หรือ VM บน Windows/macOS
ฉันใช้ River window manager ที่ปรับแต่งเองแทบทั้งหมด
บน Hyprland ใช้ได้แค่ BSP tiling เป็นหลักเลยไม่สะดวก แต่บน River ทำ equal tiling ได้ตามต้องการ
การแยกส่วนครั้งนี้ส่งผลกับ workflow ของฉันมาก
ฉันก็เคยเป็นผู้ใช้ i3 มาก่อน และ hy3 ก็ทำให้ใช้ Hyprland ได้
การตั้งค่าของฉันรวมไว้ที่ dotfiles
เข้าใจว่าหนึ่งในแนวคิดการออกแบบหลักของ Wayland คือ การรวม window manager กับ compositor เข้าด้วยกัน
เลยสงสัยว่าทำไมถึงออกแบบแบบนั้น
Wayland แก้ตรงนี้ด้วยการจัดการแบบ synchronous เพื่อลดความไม่ตรงกันของภาพ
โปรโตคอลนี้จึงเป็นความพยายามที่จะแยกกราฟิกเซิร์ฟเวอร์กับ window manager ออกจากกัน โดยยังรักษาข้อได้เปรียบด้านประสิทธิภาพนั้นไว้
คิดว่าสิ่งที่เสียไปมากที่สุดเมื่อเทียบกับ X11 คือบน Wayland ไม่สามารถสลับ window manager แบบปลั๊กอิน ได้ง่าย
คนที่พยายามแก้ปัญหาแบบนี้ถือว่ามีค่ามากจริง ๆ
หวังว่าเลเยอร์อย่าง River หรือ Wayback จะช่วยทำหน้าที่นั้นได้
ฉันเองก็มีไอเดียเดสก์ท็อปเชิงทดลองอยู่ แต่สุดท้ายก็ต้องเริ่มบน X11 เพราะทำซ้ำได้เร็วกว่า
Wayland ยังมีจุดอ่อนเชิงออกแบบอยู่จริง
ไม่จำเป็นต้องให้มาตรฐานบังคับโครงสร้างแบบใดแบบหนึ่ง
ใช้ i3 มา 15 ปีแล้ว ทุกครั้งที่เห็นโปรเจ็กต์แบบนี้ก็อดสงสัยไม่ได้ว่า Wayland จำเป็นไปเพื่ออะไร
X11 แม้จะมีข้อเสีย แต่แทบทุกอย่างที่ต้องการก็ยังทำได้
ส่วน Wayland ดูจะมีแรงเสียดทานอยู่ตลอด
สำหรับคนใช้โน้ตบุ๊กนี่เป็นข้อดีใหญ่ และการรองรับ VRR หรือ HDR ก็ง่ายกว่า X.org มาก
เรื่องปรับ DPI แยกตามจอ, ป้องกันภาพฉีก, และการบล็อกไม่ให้แอปอัดหน้าจอโดยไม่ได้รับอนุญาต ถูกแก้มาให้เป็นพื้นฐานเลย
ไม่ต้องไปยุ่งกับ Xorg.conf อีกแล้ว คุณภาพชีวิตดีขึ้นมาก
ตอนนี้ก็ยังใช้สเกลต่างกันในแต่ละจออยู่
ฉันต้องการให้หน้าต่างรับอินพุตได้แม้ไม่ถูกโฟกัส ซึ่งตอนนี้มีข้อยกเว้นแค่การขยับเมาส์
สุดท้ายเลยต้องเปลี่ยนไปใช้ Window Event แต่ก็ยังไม่สะดวกอยู่ดี