Hai Vấn Đề Nhỏ Trong Lập Trình X Window - nói dối e blog

Hai Vấn Đề Nhỏ Trong Lập Trình X Window

So với Windows, hệ thống X Window thực ra dễ hiểu hơn nhiều và có thiết kế hợp lý hơn. Tuy nhiên, tài liệu hướng dẫn về nó thì vô cùng khan hiếm, đặc biệt là tài liệu bằng tiếng Trung. Tìm kiếm mãi chỉ thấy vài bài viết lác đác, sách chuyên môn cũng gần như không thấy :( Vì vậy với tôi, lập trình trên nền X Window vất vả hơn nhiều so với Windows.

Gần đây tôi gặp không ít vấn đề, trong đó có hai vấn đề đã giải quyết xong, xin ghi lại để chia sẻ: Bắt tín hiệu đóng cửa sổ Trên Windows thì đơn giản, chỉ cần xử lý thông báo WM_CLOSE. Đa số trường hợp, tín hiệu này không phải do hệ thống GUI gửi trực tiếp đến cửa sổ của bạn, mà thường là do explorer chuyển tiếp. Ngay cả khi tiến trình cửa sổ của bạn bị kẹt trong vòng lặp vô hạn không xử lý được thông báo, nút “X” trên thanh tiêu đề vẫn hoạt động bình thường.

Trong X Window, tôi nghĩ đơn giản là chỉ cần dùng sự kiện DestroyNotiify theo tài liệu hướng dẫn. Tuy nhiên dù thêm vào vòng lặp xử lý sự kiện thế nào cũng không kích hoạt được. Thao tác nhấp chuột vào nút “X” góc trên bên phải cửa sổ sẽ đưa ra hộp thoại cảnh báo, sau khi nhấn OK sẽ buộc đóng cửa sổ - tương tự như trường hợp cửa sổ Windows bị treo.

Hóa ra cần thực hiện các bước sau:

  1. Dùng XInternAtom để lấy atom WM_DELETE_WINDOW
  2. Gọi XSetWMProtocols để đăng ký atom này cho cửa sổ
  3. Trong vòng lặp sự kiện, xử lý phần ClientMessage để kiểm tra atom này, từ đó phát hiện yêu cầu đóng cửa sổ.

Khác biệt trong xử lý tự động lặp phím giữa X Window và Windows Khi giữ phím lâu, cả hai hệ điều hành đều mô phỏng chuỗi phím lặp. Nhưng khác biệt nằm ở chỗ: X Window tự động phát sinh cả thông báo KeyRelease (trên Windows chỉ có duy nhất một WM_KEYUP khi nhả phím).

Trên X Window, bạn sẽ nhận được chuỗi liên tiếp các cặp KeyPress/KeyRelease. Về mặt logic, cách xử lý này hợp lý hơn, nhưng lại gây khó khăn cho lập trình game - vì không thể đơn giản xác định người dùng có đang giữ phím hay không.

Tôi đã từng gặp vấn đề này từ lâu. Nhờ tìm kiếm tài liệu lúc đó mới biết có thể tắt chức năng tự động lặp phím trong giao thức X. Tuy nhiên hôm nay khi muốn bổ sung phần code này, tìm kiếm mãi không thấy :( (Chết tiệt, google.cn không lưu lịch sử tìm kiếm của tôi!).

Cuối cùng phát hiện ra hai giải pháp từ tài liệu chính thức:

  1. XAutoRepeatOn/XAutoRepeatOff: Tuy nhiên thao tác này ảnh hưởng toàn cục, thậm chí còn duy trì sau khi ứng dụng đóng lại.
  2. Giải pháp tối ưu: Sử dụng XQueryKeymap để kiểm tra trạng thái thực tế của bàn phím. Chỉ cần gọi hàm này khi xử lý sự kiện KeyRelease để xác định phím có thực sự đang bị giữ hay không.

P/s: Có ai là cao thủ X Window không? Tự mày mò một mình thật sự rất bế tắc.

0%