Tôi đã tạo một thư viện cho phép đưa UI ứng dụng của mình lên thanh tác vụ Windows 11
(github.com/airtaxi)Gần đây tôi đã công bố một thư viện cho phép chèn trực tiếp UI ứng dụng vào bên trong thanh tác vụ (taskbar) của Windows 11. Tên của nó là Deskband11Lib, và nếu cài qua NuGet thì bạn có thể biến ứng dụng WinUI 3 hoặc WPF thành widget trên thanh tác vụ.
Tôi sẽ lần lượt giải thích vì sao tôi làm ra nó, nó hoạt động như thế nào, và cả widget PoC mà tôi đã thực sự đưa lên Store.
Bối cảnh: Deskband đã biến mất trên Windows 11
Cho đến Windows 10, vẫn có tính năng Deskbands cho phép hiển thị các thanh công cụ nhỏ trên thanh tác vụ. Khi chuyển sang Windows 11, tính năng này đã bị loại bỏ hoàn toàn. Với những ai muốn đặt các “widget nhỏ luôn hiển thị” như điều khiển media, giám sát hệ thống hay khởi chạy nhanh trên thanh tác vụ, đây là một thay đổi khá đáng tiếc.
Cảm hứng: Deskband11 của zadjii
Cách đây không lâu tôi thấy zadjii/Deskband11 trên GitHub, và cách tiếp cận cốt lõi của nó thực sự rất hay.
Đặt một cửa sổ WinUI 3 trong suốt lên trên thanh tác vụ, gán
SetParentđể biến cửa sổ đó thành HWND con của thanh tác vụ, sau đó thiết lập vùng clip theo kích thước nội dung để nó trông như một phần của thanh tác vụ.
Rốt cuộc thì nó “chỉ là một cửa sổ nổi trên thanh tác vụ”, nhưng ý tưởng này quá thông minh. Tuy nhiên, chính dự án gốc cũng tự mô tả là “mức code hackathon”, nên vẫn có những điểm chưa đủ để mang thẳng vào sản phẩm thực tế.
Vì thế tôi đã biến nó thành một thư viện
Vì đây là một ý tưởng quá đáng tiếc nếu bị bỏ phí, tôi đã viết lại nó thành thư viện để ai cũng có thể dùng chỉ với một dòng dotnet add package.
- GitHub: https://github.com/airtaxi/Deskband11Lib
- NuGet:
Deskband11Lib.WinUI/Deskband11Lib.Wpf
Cách dùng rất đơn giản
Tạo một cửa sổ WinUI 3 rồi truyền nó vào TaskbarContentHost là xong.
var window = new MainWindow();
var host = new TaskbarContentHost(window, rootElement, new TaskbarContentHostOptions
{
PreferredWidth = 360,
PreferredHeight = 48
});
await host.AttachWhenLayoutReadyAsync();
window.Activate();
Với WPF thì API gần như giống hệt. Thư viện sẽ tự xử lý việc phát hiện căn chỉnh thanh tác vụ (trái/giữa), tránh chồng lấn với nút Start và vùng thông báo, khôi phục khi Explorer khởi động lại, cũng như cả animation khi layout thay đổi.
Đã mất khá nhiều thời gian để làm cho nó hoạt động đúng
Khi chạy nguyên xi mã nguồn gốc thì đúng là nó có khởi chạy, nhưng vị trí và kích thước cửa sổ lại bị tính sai rất kỳ lạ. Vì mã gốc là code viết trong hackathon, lúc đầu tôi không thể xác định liệu đó là do cách triển khai thanh tác vụ của Windows 11 đã thay đổi sau các bản cập nhật, hay bản thân mã gốc vốn đã lệch ngay từ đầu. Cả hai đều có thể là nguyên nhân, nên cách duy nhất là mổ xẻ từng phần phía thanh tác vụ để tự kiểm tra xem trên các bản build hiện tại nó thực sự được xác định như thế nào. Hơn nữa, bản gốc hoàn toàn không tính đến các trường hợp như nút Start nằm ở giữa hay các thành phần như nút Widgets, nên khi thư viện hóa tôi phải xử lý thêm những phần này.
Vì vậy, từ mã gốc tôi chỉ tham khảo cách dùng UI Automation và một số Win32 API để lấy kích thước/vị trí cửa sổ, còn toàn bộ logic tính toán khoảng trống thì tôi viết lại từ đầu. Cần phải đọc vị trí của nút Start, nhóm nút ứng dụng trên thanh tác vụ, nút Widgets và vùng thông báo để tính ra phần không gian còn lại; ngoài ra vị trí xuất hiện khoảng trống còn thay đổi tùy việc thanh tác vụ đang căn trái hay căn giữa, nên những chỗ như vậy cũng phải được tính đến lại từ đầu.
Tôi đã thực sự làm một ứng dụng và đưa nó lên Store: BarPlay
Vì muốn kiểm chứng xem thư viện này có thực sự dùng được hay không, tôi đã làm một ứng dụng bằng chính nó và đăng lên Microsoft Store. Tên ứng dụng là BarPlay.
Đây là một widget hiển thị thumbnail, tiêu đề và các nút điều khiển của media đang phát ngay trên thanh tác vụ. Nó hoạt động với mọi ứng dụng hỗ trợ Windows System Media Transport Controls (SMTC), như Spotify, trình duyệt, ứng dụng YouTube PWA, v.v. Tôi đã biên dịch bằng NativeAOT để giảm thiểu thời gian khởi động và mức sử dụng tài nguyên.
Liên kết ứng dụng trên Microsoft Store
Tôi đã giới thiệu thử trước với một số người quen xung quanh, và phản hồi khá tốt.
Có thể dùng vào đâu?
Bạn có thể đặt nội dung được tạo bằng WinUI 3 hoặc WPF vào một vị trí luôn hiển thị mà không cần mở cửa sổ riêng. Có thể nghĩ đến những trường hợp như bộ đếm giờ, điều khiển phát media (như BarPlay), trạng thái build hay thông báo CI, giám sát hệ thống, quick launcher hoặc chuyển tài khoản, hay chỉ báo thông báo.
Vì có thể mang nguyên vẹn control và style của chính ứng dụng mình lên thanh tác vụ, tôi nghĩ đây gần như là thư viện .NET duy nhất có thể hiện thực kiểu trải nghiệm này trên Windows 11, nơi Deskband đã biến mất.
Tổng hợp liên kết
- Deskband11Lib (thư viện)
- NuGet (WinUI)
- NuGet (WPF)
- BarPlay (Proof of Concept, Store)
- BarPlay (mã nguồn)
- Nguồn cảm hứng ban đầu (zadjii/Deskband11)
Phát hành theo giấy phép MIT, và bạn có thể bắt đầu bằng cách sao chép các dự án mẫu (Deskband11Lib.WinUI.Sample, Deskband11Lib.Wpf.Sample). Mọi phản hồi, issue và PR đều được chào đón. Nếu bạn tạo ra một widget thanh tác vụ thú vị, hãy cho tôi biết nhé.
2 bình luận
Ồ, ý tưởng này hay thật đấy
Cảm ơn bạn! Thật ra mình chỉ đóng gói nó thành thư viện thôi, và mình nghĩ là nhờ ý tưởng của người đã làm ra bản gốc.. hehe