Giới thiệu
Trong thế giới phát triển phần mềm, việc quản lý không gian làm việc một cách hiệu quả là rất quan trọng. Bài viết này sẽ giới thiệu về một giải pháp mà tôi đã xây dựng để tối ưu hóa không gian làm việc trong i3wm (i3 Window Manager) bằng cách tạo ra một trình tải không gian làm việc động. Giải pháp này cho phép người dùng chuyển đổi giữa nhiều nhóm không gian làm việc khác nhau (như "Khách hàng", "Công ty" và "Cá nhân") mà không làm mất trạng thái và tăng cường năng suất làm việc.
Nội dung chính
- Tổng quan về không gian làm việc động
- Vấn đề với không gian làm việc hiện tại
- Giải pháp: Tạo không gian làm việc động
- Cấu hình i3 với AnyEvent::I3X::Workspace::OnDemand
- Mẹo và thủ thuật
- Các lỗi thường gặp và cách khắc phục
- Kết luận và bước tiếp theo
Tổng quan về không gian làm việc động
Tôi đã sử dụng i3wm như một trình quản lý cửa sổ trong nhiều năm. Mặc dù tôi rất thích làm việc với i3, nhưng có một điều khiến tôi cảm thấy khó chịu, đó là nó thiếu khả năng nhận biết ngữ cảnh. Tôi thường làm việc trong nhiều ngữ cảnh khác nhau: "Khách hàng", "Công ty" và "Cá nhân". Điều này có nghĩa là tôi có thể làm việc với một hoặc nhiều khách hàng cùng một lúc.
Vấn đề với không gian làm việc hiện tại
Với i3, bạn có thể tạo ra một số lượng lớn không gian làm việc, nhưng tôi thường chỉ sử dụng các không gian từ 1 đến 3 và từ 8 đến 0. Những không gian này chỉ có sẵn 6 không gian làm việc. Trong hầu hết các ngữ cảnh, tôi muốn có ba không gian làm việc: "debug", "cli" và "misc". Nếu chúng ta có ba ngữ cảnh, thì chúng ta sẽ sử dụng 1-3, 4-6 và 7-9 cùng với không gian 0 như một nơi trú ẩn an toàn.
Tuy nhiên, nếu có một khách hàng mới hoặc chúng ta muốn có các không gian làm việc khác nhau cho các ngữ cảnh "cá nhân"? Tôi không muốn nhớ trong ngữ cảnh nào tôi đang làm việc, tôi chỉ muốn nhớ rằng 1-3 là nơi tôi lập trình, 0 là nơi trú ẩn của tôi và mọi thứ khác chỉ cần được ẩn đi.
Giải pháp: Tạo không gian làm việc động
Tôi cần một giải pháp có thể xử lý các ngữ cảnh này mà vẫn bảo toàn trạng thái của những ngữ cảnh khác đã được sử dụng. Ban đầu, tôi đã bắt đầu với một script đơn giản bằng zsh nhưng nhanh chóng nhận ra rằng shell không phải là công cụ phù hợp cho công việc này. Tôi đã có một mối quan hệ mê hoặc với jq; tôi thích nó cho những việc nhanh chóng nhưng ghét nó cho những việc phức tạp. Tôi luôn quên cú pháp và với Perl (hoặc bất kỳ ngôn ngữ lập trình nào khác), tôi có thể làm việc với cấu trúc dữ liệu dễ dàng hơn.
Tôi cũng đã tìm hiểu về các sự kiện IPC từ i3 - bạn đã sử dụng chúng với i3-msg. Giờ đây, tôi muốn biết cách có thể kết nối với các sự kiện từ i3 để xác định các thay đổi trạng thái. Tôi đã làm được điều đó.
i3 cũng cung cấp một module Perl AnyEvent::I3. Xin cảm ơn các nhà phát triển i3.
AnyEvent::I3X::Workspace::OnDemand
Đầu tiên, tôi bắt đầu với một phương thức subscribe đơn giản kiểm tra sự kiện init để đảm bảo tôi có thể thấy việc tạo ra một không gian làm việc. Điều quan trọng là trong khi bạn định nghĩa một không gian làm việc trong cấu hình của i3, nó không thực sự được tạo ra ngay lập tức. Nó được tạo ra trong thời gian chạy khi bạn yêu cầu nó.
Khi sự kiện init xảy ra, mọi thứ khá đơn giản, chúng tôi thêm giao diện bằng append_layout và khởi động tất cả các ứng dụng mà chúng tôi muốn sử dụng. Để hỗ trợ điều này, tôi đã tạo ra một vài tham số:
- Một tham số khởi tạo có đường dẫn giao diện được định nghĩa. Tất cả các giao diện của bạn được lưu trữ ở đó.
- Một tham số khởi tạo có các không gian làm việc được định nghĩa.
- Một tham số khởi tạo định nghĩa các ứng dụng sẽ được khởi động.
- Một tham số khởi tạo định nghĩa các nhóm được sử dụng.
Cách thức hoạt động như thế nào? Bạn cấu hình các không gian làm việc, nhóm và ứng dụng như sau:
perl
use AnyEvent::I3X::Workspace::OnDemand;
my $i3 = AnyEvent::I3X::Workspace::OnDemand->new(
debug => 0,
layout_path => "$ENV{HOME}/.config/i3",
workspaces => {
foo => {
layout => 'foo.json',
},
bar => {
layout => 'bar.json',
groups => {
foo => undef,
bar => { layout => 'foo.json' },
}
},
baz => {
layout => 'baz.json',
groups => {
all => undef,
}
}
},
groups => [
qw(foo bar baz)
],
swallows => [
{
cmd => 'kitty',
match => {
class => '^kitty$',
}
},
{
cmd => 'firefox',
on => {
group => 'bar',
}
match => {
window_role => '^browser$',
}
},
{
cmd => 'google-chrome',
on => {
group => 'foo',
}
match => {
window_role => '^browser$',
}
}
],
);
Bảo vệ các trường hợp đặc biệt
Do các vấn đề về thời gian, bạn có thể gặp phải một không gian làm việc có một giao diện được định nghĩa nhưng chưa có gì khởi động. Do đó, chúng tôi cũng tìm kiếm sự kiện focus và ở đây chúng tôi cũng cố gắng khởi động các ứng dụng được định nghĩa trên không gian làm việc.
Khi người dùng chuyển đổi sang một không gian làm việc, chúng tôi sẽ duyệt cây i3 để tìm bất kỳ nút nào phù hợp với giao diện của chúng tôi và chúng tôi sẽ khởi động các ứng dụng thuộc về đó - chỉ khi chúng chưa được chạy.
Gửi sự kiện cho chính mình
Bây giờ, với logic này được định nghĩa, chúng tôi có thể đi vào việc thay đổi nhóm. Các thay đổi nhóm được gửi qua ticks:
bash
i3-msg -t send_tick group:personal
Điều này có nghĩa là logic không gian làm việc của chúng tôi cần lắng nghe các sự kiện tick. Điều này có nghĩa là tôi cần hỗ trợ nhiều loại sự kiện khác nhau.
Các loại sự kiện được hỗ trợ
Module hỗ trợ các loại sự kiện sau: workspace, barconfig_update (caveat emptor), tick, shutdown, output, mode, window, và binding. Các sự kiện quan trọng nhất đối với chúng tôi là: workspace, tick, và shutdown. Chúng có các hàm trợ giúp đơn giản on_workspace, on_tick và on_shutdown:
perl
$self->on_workspace($name, $type, $sub)
# Đăng ký một sự kiện không gian làm việc cho không gian làm việc $name của $type với $sub.
# $type có thể là bất kỳ sự kiện nào từ i3
$i3->on_workspace(
'www', 'init',
sub {
my $self = shift;
my $i3 = shift;
my $event = shift;
$self->append_layout($event->{current}{name}, '/path/to/layout.json');
}
);
$self->on_tick($payload, $sub)
# Đăng ký một sự kiện tick với $payload và thực hiện hành động.
Cấu hình i3
Bây giờ, điều duy nhất bạn cần làm trong cấu hình i3 của mình là cấu hình chúng. Tôi cá nhân sử dụng các chế độ gán từ i3 để tổ chức các lệnh tương tự thành một nhóm:
bash
# Không gian làm việc động
bindsym $mod+w mode "Activities"
mode "Activities" {
bindsym 0 exec i3-msg -t send_tick group:foo; mode default
bindsym 9 exec i3-msg -t send_tick group:bar; mode default
bindsym 8 exec i3-msg -t send_tick group:baz; mode default
bindsym Return mode "default"
bindsym Escape mode "default"
}
Giờ đây, tôi có thể chuyển đổi giữa gần như không giới hạn các ngữ cảnh. Tôi chỉ sử dụng ba, nhưng bạn có thể mở rộng hơn nữa.
Mẹo và thủ thuật
Để tạo một giao diện, bạn có thể sử dụng lệnh sau:
bash
i3-save-tree --workspace foo > ~/.config/i3/foo.json
Bạn sẽ cần chỉnh sửa JSON, ví dụ, cắt bỏ khối swallow, nhưng tôi sẽ để điều đó cho bạn và tài liệu trên trang web i3.
Các lỗi thường gặp và cách khắc phục
Khi làm việc với các không gian làm việc động, có thể gặp phải một số lỗi phổ biến như không khởi động được ứng dụng hoặc không tìm thấy không gian làm việc. Để khắc phục, hãy kiểm tra lại các cấu hình, đảm bảo rằng các ứng dụng đã được cài đặt và cấu hình chính xác. Bạn cũng có thể sử dụng các công cụ như i3-msg để kiểm tra trạng thái của không gian làm việc và ứng dụng.
Kết luận và bước tiếp theo
Giải pháp không gian làm việc động này giúp tôi quản lý không gian làm việc của mình hiệu quả hơn trong i3wm, cho phép tôi chuyển đổi giữa các ngữ cảnh khác nhau mà không làm mất trạng thái. Tôi dự định phát hành module i3-wod chính thức trong thời gian tới. Bạn có thể cài đặt module bằng cách chạy:
bash
cpanm AnyEvent::I3X::Workspace::OnDemand
Để có thêm thông tin và cập nhật, hãy theo dõi kho GitLab của tôi cho script i3-wod.
Tài nguyên tham khảo
Hãy bắt đầu tối ưu hóa không gian làm việc của bạn ngay hôm nay!