Nhật ký phát triển GõKey - Tuần 7

<- Quay về trang chủ

Ngày 26/02/2023

Update Druid lên phiên bản 0.8.2

Anh @ledongthuc vừa đóng góp một PR để update Druid lên phiên bản 0.8.2, phiên bản này hỗ trợ nhiều tính năng hơn, fix nhiều bug hơn. Đây là một update quan trọng để unblock GõKey, cho phép chúng ta implement thêm nhiều feature từ phía UI.

Chi tiết có thể xem tại PR: https://github.com/huytd/goxkey/pull/27/files

Automated build cho PRs

Vẫn là anh @ledongthuc với một contribution khác, lần này là chức năng tự động build cho từng pull request. Với chức năng này, mỗi pull request cho GõKey sẽ được build và run unit test. Việc này sẽ tạo điều kiện dễ dàng hơn cho các bạn muốn contribute vào project.

Chi tiết có thể xem tại PR: https://github.com/huytd/goxkey/pull/30/files

Hiện tại chỉ mới build, nhưng sắp tới chúng ta có thể modify các Github Actions này để tự động cung cấp bản build để tất cả mọi người có thể download. Tuy nhiên ở thời điểm này mình chưa muốn cung cấp bản build vội, vì còn nhiều lỗi quá

Đóng cửa sổ GõKey khi nhấn nút Đóng

Và lần này, không ai khác, vẫn là anh @ledongthuc với PR implement nút "Đóng" trên cửa sổ GõKey. Khi người dùng nhấn vào nút này thì tất nhiên là cửa sổ GõKey sẽ... bị đóng.

Tuy nhiên, trên thực tế, sự kiện được phát đi khi nút này được nhấn là druid::HIDE_APPLICATION, sự kiện này sẽ gọi hàm NSApplication::hide() của macOS để ẩn cửa sổ chương trình đi, giống như khi chúng ta nhấn tổ hợp phím Cmd + H. Việc này giúp dễ dàng mở lại cửa sổ GõKey bằng cách click vào biểu tượng trên thanh Dock.

Chi tiết có thể xem tại PR:

Ngày 04/03/2023

Sửa lỗi khi gõ với chế độ CAPSLOCK ON

Cũng rất nhiều năm rồi mình chưa có đụng đến chức năng Caps Lock trên bàn phím, vì xài bàn phím nào mình cũng map phím đó lại thành Ctrl. Tuy nhiên đây thực sự là một thiếu sót khi phát triển bộ gõ mà lại không thèm đếm xỉa gì đến phím này =))

GõKey hoạt động tốt cả khi người dùng viết hoa hay viết thường (bằng cách nhấn giữ phím Shift), tuy nhiên khi người dùng bật Caps Lock lên thì nó vẫn nhận diện là đang viết thường, kết quả là:

User bật Caps Lock
User gõ: TOOI LAF NGUOIWF VIEETJ NAM

Kết quả mong đợi: TÔI LÀ NGƯỜI VIỆT NAM
Kết quả thực tế:  TôI là người việt NAM

Lỗi này xảy ra vì mình chỉ handle phím Shift cho trường hợp gõ các kí tự viết hoa, mà quên mất phím Caps Lock:

INPUT_STATE.push(if modifiers.is_shift() {
    c.to_ascii_uppercase()
} else {
    c
});

Và việc nhấn phím Shift được nhận diện thông qua việc kiểm tra event flag:

let flags = event.get_flags();
if flags.contains(CGEventFlags::CGEventFlagShift) {
    modifiers.add_shift();
}

Phím Shift có flag là CGEventFlagShift, nhưng mà không ngờ phím Caps Lock lại có flag là CGEventFlagAlphaShift, ông nào ở Apple lúc define đống flag này cũng thích đánh đố nhau dữ (jk).

Cách fix thì thôi coi như 2 flag trên cùng 1 tác dụng nhấn phím Shift, sau này có lỗi thì tính sau

if flags.contains(CGEventFlags::CGEventFlagShift)
|| flags.contains(CGEventFlags::CGEventFlagAlphaShift) {
    modifiers.add_shift();
}

Accessibility Request permission dialog

Vì GõKey hoạt động bằng cách bắt và modify các sự kiện phím, nên khi hoạt động trên macOS, người dùng phải tự tay cấp quyền Accessibility, thì ứng dụng mới hoạt động được. Nếu không thì bộ gõ vẫn sẽ khởi động lên nhưng không nhận hay gửi được phím.

Để tránh gây thắc mắc cho người dùng khi quyền Accessibility chưa được cấp, thì bộ gõ sẽ kiểm tra quyền này mỗi khi khởi động. Trên macOS, thì để kiểm tra quyền Accessibility, chúng ta sử dụng hàm AXIsProcessTrustedWithOptions:

pub fn ensure_accessibility_permission() -> bool {
    unsafe {
        let options = NSDictionary::dictionaryWithObject_forKey_(
            nil,
            msg_send![class!(NSNumber), numberWithBool: YES],
            kAXTrustedCheckOptionPrompt as _,
        );
        return AXIsProcessTrustedWithOptions(options as _);
    }
}

Hàm này còn cho phép bật hộp thoại yêu cầu cấp quyền nếu cần thiết. Tuy nhiên nếu chỉ bật hộp thoại này thôi thì nhiều khả năng là người dùng sẽ tắt nó đi mà không làm gì cả Nên mình cần implement thêm một màn hình để đưa ra hướng dẫn cấp quyền.

Như vậy, với việc implement chức năng này, thì GõKey cũng giải quyết được thêm một vấn đề khác đó là, khi người dùng cập nhật phiên bản mới, thì quyền Accessibilty sẽ bị mất (again, đây là bản build chưa notarized), chức năng này sẽ giúp phát hiện ra trường hợp đó và yêu cầu người dùng cấp quyền lại.

Nightly Build

Và như thế, sau 6 tuần phát triển, GõKey đã tạm đủ ổn định. Một lý do khiến nhiều người ngại xài thử là vì không muốn setup môi trường Rust để build, nên mình quyết định sẽ bắt đầu phát hành bản prebuilt binary để tải về.

Cách tải và sử dụng GõKey như sau:

  1. Download file GoKey.zip về, giải nén, được file Gõ Key.app
  2. Kéo thả file này vào thư mục /Applications của macOS, replace phiên bản cũ nếu có
  3. Cấp lại quyền Accessibility cho file Gõ Key.app trước khi sử dụng. Nếu chưa cấp thì GõKey sẽ tự động yêu cầu bạn cấp lại quyền.
  4. Click phải chuột vào Gõ Key.app chọn Open. Vì đây là file binary tải về từ internet, có thể macOS sẽ chặn và hỏi lại 2 lần, các bạn cứ click phải chuột và chọn Open 2 lần là okie. (Sau này khi hoàn thiện thì mình sẽ cung cấp bản build notarized).

Lưu ý, đây là bản build tự động, được publish sau mỗi lần tụi mình merge code vào main branch, nên chuyện có bug là miễn bàn rồi một vấn đề khác là: Bản build sẽ được update liên tục, vì thế mỗi lần các bạn download về và copy vào thư mục /Applications, thì cần phải cấp lại quyền Accessibility.

Ngày 05/03/2023

Hoàn thiện System Tray Menu

Vẫn là một PR đến từ anh @ledongthuc, lần này là về việc hoàn thiện chức năng của system tray icon và menu.

Với pull request này, chúng ta đã có thể tương tác với system tray icon để bật menu, bật tắt chế độ gõ tiếng Việt cũng như thoát ứng dụng GõKey.

Chi tiết implementation các bạn có thể tham khảo tại đây https://github.com/huytd/goxkey/pull/37