Quản lý cửa sổ thay thế trong Linux

Mình là một trong những người đặt Caps Lock chuyển đổi bố cục vì lười bấm 2 phím trong khi có thể bấm một phím. Tôi thậm chí còn muốn có 2 phím không cần thiết: Tôi sẽ sử dụng một phím để bật bố cục tiếng Anh và phím thứ hai cho tiếng Nga. Nhưng phím không cần thiết thứ hai là mở menu ngữ cảnh, điều này không cần thiết đến mức bị nhiều nhà sản xuất máy tính xách tay cắt bỏ. Vì thế bạn phải hài lòng với những gì mình có.

Và tôi cũng không muốn tìm kiếm biểu tượng của họ trên thanh tác vụ khi chuyển đổi cửa sổ hoặc bắt gặp tên khi cuộn qua Alt + Tab, cuộn qua máy tính để bàn, v.v. Tôi muốn nhấn một tổ hợp phím (lý tưởng nhất là chỉ một phím, nhưng không còn phím nào không cần thiết nữa) và ngay lập tức đến cửa sổ tôi cần. Ví dụ như thế này:

  • Alt+F: Firefox
  • Alt+D: Firefox (Duyệt web riêng tư)
  • Alt+T: Thiết bị đầu cuối
  • Alt+M: Máy tính
  • Alt+E: Ý tưởng IntelliJ
  • Vân vân.

Hơn nữa, bằng cách nhấn, ví dụ, trên Alt + M Tôi muốn xem máy tính bất kể chương trình này hiện có đang chạy hay không. Nếu nó đang chạy thì cửa sổ của nó cần được lấy tiêu điểm, còn nếu không, hãy chạy chương trình mong muốn và chuyển tiêu điểm khi nó tải.

Đối với những trường hợp không có trong tập lệnh trước, tôi muốn có các tổ hợp phím phổ quát có thể dễ dàng gán cho bất kỳ cửa sổ đang mở nào. Ví dụ: tôi có 10 kết hợp được chỉ định từ Alt + 1 để Alt + 0, không bị ràng buộc với bất kỳ chương trình nào. Tôi chỉ có thể nhấp vào Alt + 1 và cửa sổ hiện đang được lấy nét sẽ lấy nét khi được nhấp vào Alt + 1.

Bên dưới phần cắt có phần mô tả về một số tính năng khác và câu trả lời về cách thực hiện điều này. Nhưng tôi sẽ cảnh báo ngay cho bạn rằng việc tùy chỉnh như vậy “cho chính bạn” có thể gây nghiện nghiêm trọng và thậm chí rút lui nếu bạn cần sử dụng Windows, Mac OS hoặc thậm chí máy tính của người khác chạy Linux.

Trên thực tế, nếu bạn nghĩ về điều đó, chúng ta không sử dụng nhiều chương trình hàng ngày như vậy. Một trình duyệt, một thiết bị đầu cuối, một IDE, một loại trình nhắn tin nào đó, một trình quản lý tập tin, một máy tính và có lẽ đó gần như là tất cả. Không có nhiều tổ hợp phím cần thiết để thực hiện 95% công việc hàng ngày.

Đối với các chương trình có nhiều cửa sổ đang mở, một trong số chúng có thể được chỉ định là cửa sổ chính. Ví dụ: bạn có nhiều cửa sổ IntelliJ Idea đang mở và được gán cho Alt + E. Trong điều kiện bình thường, khi bạn nhấn Alt + E Một số cửa sổ của chương trình này sẽ mở ra, rất có thể là cửa sổ được mở đầu tiên. Tuy nhiên, nếu bạn bấm vào Alt + E khi một trong các cửa sổ của chương trình này đã được lấy nét, thì cửa sổ cụ thể này sẽ được chỉ định làm cửa sổ chính và nó sẽ là cửa sổ sẽ được lấy nét khi nhấn các kết hợp tiếp theo.

Cửa sổ chính có thể được chỉ định lại. Để thực hiện việc này, trước tiên bạn phải đặt lại tổ hợp, sau đó gán một cửa sổ khác làm cửa sổ chính. Để đặt lại một tổ hợp, bạn cần nhấn chính tổ hợp đó, sau đó nhấn một tổ hợp đặt lại đặc biệt, tôi đã gán nó cho Alt + Backspace. Điều này sẽ gọi một tập lệnh sẽ bỏ gán cửa sổ chính cho sự kết hợp trước đó. Và sau đó bạn có thể chỉ định một cửa sổ chính mới như được mô tả trong đoạn trước. Việc đặt lại cửa sổ được liên kết thành các kết hợp chung cũng diễn ra theo cách tương tự.

Phần giới thiệu có vẻ dài nhưng trước tiên tôi muốn nói về những gì chúng tôi sẽ làm và sau đó giải thích cách thực hiện.

Dành cho ai chán đọc

Nói tóm lại, liên kết đến các tập lệnh nằm ở cuối bài viết.

Nhưng bạn vẫn không thể cài đặt và sử dụng nó ngay được. Trước tiên, bạn sẽ phải tìm ra cách tập lệnh tìm thấy cửa sổ mong muốn. Nếu không có điều này, sẽ không thể cho kịch bản biết chính xác vị trí cần chuyển tiêu điểm. Và bạn cần hiểu phải làm gì nếu đột nhiên không tìm thấy cửa sổ phù hợp.

Và tôi sẽ không tập trung vào cách định cấu hình thực thi tập lệnh bằng cách nhấn tổ hợp phím. Ví dụ: trong KDE, nó nằm trong Cài đặt hệ thống → Phím tắt → Phím tắt tùy chỉnh. Điều này cũng xảy ra với các trình quản lý cửa sổ khác.

Giới thiệu wmctrl

wmctrl — tiện ích bảng điều khiển để tương tác với X Window Manager. Đây là chương trình chính cho kịch bản. Chúng ta hãy xem nhanh cách bạn có thể sử dụng nó.

Đầu tiên, hãy hiển thị danh sách các cửa sổ đang mở:

$ wmctrl -lx
0x01e0000e -1 plasmashell.plasmashell             N/A Desktop — Plasma
0x01e0001e -1 plasmashell.plasmashell             N/A Plasma
0x03a00001  0 skype.Skype                         N/A Skype
0x04400003  0 Navigator.Firefox                   N/A Google Переводчик - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Лучшие публикации за сутки / Хабр - Mozilla Firefox (Private Browsing)
...

Lựa chọn -l hiển thị danh sách tất cả các cửa sổ đang mở và -x thêm tên lớp vào đầu ra (Skype.Skype, Điều hướng.Firefox vân vân). Ở đây chúng ta cần id cửa sổ (cột 1), tên lớp (cột 3) và tên cửa sổ (cột cuối cùng).

Bạn có thể thử kích hoạt một số cửa sổ bằng tùy chọn -a:

$ wmctrl -a skype.Skype -x

Nếu mọi thứ diễn ra theo đúng kế hoạch, cửa sổ Skype sẽ xuất hiện trên màn hình. Nếu thay vì tùy chọn -x tùy chọn sử dụng -i, thì thay vì tên lớp, bạn có thể chỉ định id cửa sổ. Vấn đề với id là id cửa sổ thay đổi mỗi khi ứng dụng được khởi chạy và chúng ta không thể biết trước được. Mặt khác, thuộc tính này xác định duy nhất một cửa sổ, điều này có thể quan trọng khi một ứng dụng mở nhiều cửa sổ. Thêm về điều này một chút nữa.

Ở giai đoạn này, chúng ta cần nhớ rằng chúng ta sẽ tìm kiếm cửa sổ mong muốn bằng cách sử dụng biểu thức chính quy theo đầu ra wmctrl -lx. Nhưng điều đó không có nghĩa là chúng ta phải sử dụng thứ gì đó phức tạp. Thông thường tên lớp hoặc tên cửa sổ là đủ.

Về cơ bản, ý chính đã rõ ràng rồi. Trong cài đặt phím nóng/phím tắt chung cho trình quản lý cửa sổ của bạn, hãy định cấu hình tổ hợp cần thiết để thực thi tập lệnh.

Cách sử dụng tập lệnh

Đầu tiên bạn cần cài đặt tiện ích console wmctrl и xdotool:

$ sudo apt-get install wmctrl xdotool

Tiếp theo bạn cần tải xuống các tập lệnh và thêm chúng vào $ PATH. Tôi thường đặt chúng vào ~ / bin:

$ cd ~/bin
$ git clone https://github.com/masyamandev/Showwin-script.git
$ ln -s ./Showwin-script/showwin showwin
$ ln -s ./Showwin-script/showwinDetach showwinDetach

Nếu thư mục ~ / bin chưa có ở đó thì bạn cần tạo nó và khởi động lại (hoặc đăng nhập lại), nếu không ~ / bin sẽ không đánh $ PATH. Nếu mọi thứ được thực hiện chính xác thì các tập lệnh sẽ có thể truy cập được từ bảng điều khiển và quá trình hoàn thành Tab sẽ hoạt động.

Kịch bản chính showwin lấy 2 tham số: tham số đầu tiên là biểu thức chính quy, qua đó chúng ta sẽ tìm kiếm cửa sổ được yêu cầu và tham số thứ hai là lệnh cần được thực thi nếu không tìm thấy cửa sổ được yêu cầu.

Bạn có thể thử chạy một tập lệnh, ví dụ:

$ showwin "Mozilla Firefox$" firefox

Nếu Firefox được cài đặt, cửa sổ của nó sẽ được tập trung. Ngay cả khi Firefox không chạy thì nó vẫn phải khởi động.

Nếu nó hoạt động, thì bạn có thể thử định cấu hình thực thi các lệnh trên các tổ hợp. Trong cài đặt phím nóng/phím tắt chung, thêm:

  • Alt+F: showwin “Mozilla Firefox$” firefox
  • Alt+D: showwin "Mozilla Firefox (Duyệt web riêng tư)$" "firefox -private-window"
  • Alt+C: showwin "chromium-browser.Chromium-browser N*" crom-browser
  • Alt+X: showwin "chromium-browser.Chromium-browser I*" "chromium-browser -incognito"
  • Alt+S: showwin “skype.Skype” skypeforlinux
  • Alt+E: showwin “jetbrains-idea” idea.sh

V.v. Mọi người đều có thể định cấu hình các tổ hợp phím và phần mềm khi họ thấy phù hợp.
Nếu mọi thứ diễn ra chính xác, thì bằng cách sử dụng các kết hợp trên, chúng ta sẽ có thể chuyển đổi giữa các cửa sổ chỉ bằng cách nhấn phím.

Tôi sẽ làm những người yêu thích chrome thất vọng: nó có thể ẩn danh phân biệt một cửa sổ thông thường bằng đầu ra của nó wmctrl Bạn không thể, chúng có cùng tên lớp và tiêu đề cửa sổ. Trong biểu thức chính quy được đề xuất, các ký tự N* và I* chỉ cần thiết để các biểu thức chính quy này khác nhau và chúng có thể được chỉ định làm cửa sổ chính.

Để đặt lại cửa sổ chính của tổ hợp trước đó (thực tế là đối với biểu thức chính quy, showwin được gọi lần trước), bạn cần gọi tập lệnh showwinTách ra. Tôi đã gán tập lệnh này cho một tổ hợp phím Alt + Backspace.

Tại kịch bản showwin còn có một chức năng nữa. Khi nó được gọi với một tham số (trong trường hợp này tham số chỉ là một mã định danh), nó hoàn toàn không kiểm tra biểu thức chính quy mà coi tất cả các cửa sổ đều phù hợp. Bản thân điều này có vẻ vô ích, nhưng bằng cách này, chúng ta có thể chỉ định bất kỳ cửa sổ nào làm cửa sổ chính và nhanh chóng chuyển sang cửa sổ cụ thể đó.

Tôi có các kết hợp sau được cấu hình:

  • Alt+1: showwin "CustomKey1"
  • Alt+2: showwin "CustomKey2"
  • ...
  • Alt+0: showwin "CustomKey0"
  • Alt+Backspace: showwinDetach

Bằng cách này, tôi có thể liên kết bất kỳ cửa sổ nào với các tổ hợp Alt + 1...Alt + 0. Chỉ bằng cách nhấp chuột Alt + 1 Tôi liên kết cửa sổ hiện tại với sự kết hợp này. Tôi có thể hủy ràng buộc bằng cách nhấp vào Alt + 1, đó là Alt + Backspace. Hoặc đóng cửa sổ, điều đó cũng hoạt động.

Tiếp theo tôi sẽ cho bạn biết một số chi tiết kỹ thuật. Bạn không cần phải đọc chúng mà chỉ cần thử thiết lập chúng và xem. Nhưng tôi vẫn khuyên bạn nên hiểu tập lệnh của người khác trước khi chạy chúng trên máy tính của bạn :).

Cách phân biệt giữa các cửa sổ khác nhau của cùng một ứng dụng

Về nguyên tắc, ví dụ đầu tiên “wmctrl -a skype.Skype -x” đã hoạt động và có thể được sử dụng. Nhưng hãy xem lại ví dụ với Firefox, trong đó có 2 cửa sổ đang mở:

0x04400003  0 Navigator.Firefox                   N/A Google Переводчик - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Лучшие публикации за сутки / Хабр - Mozilla Firefox (Private Browsing)

Cửa sổ đầu tiên ở chế độ bình thường và cửa sổ thứ hai là Duyệt web riêng tư. Tôi muốn coi các cửa sổ này là các ứng dụng khác nhau và chuyển sang chúng bằng các tổ hợp phím khác nhau.

Cần phải làm phức tạp tập lệnh chuyển cửa sổ. Tôi đã sử dụng giải pháp này: hiển thị danh sách tất cả các cửa sổ, thực hiện grep bởi Regex, lấy dòng đầu tiên với cái đầu, lấy cột đầu tiên (đây sẽ là id cửa sổ) bằng cách sử dụng cắt, chuyển sang cửa sổ theo id.

Đáng lẽ phải có một trò đùa về biểu thức chính quy và hai vấn đề, nhưng thực tế là tôi không sử dụng bất cứ thứ gì phức tạp. Tôi cần các biểu thức chính quy để có thể chỉ ra phần cuối của dòng (ký hiệu “$”) và phân biệt “Mozilla Firefox$” với “Mozilla Firefox (Duyệt web riêng tư)$”.

Lệnh trông giống như thế này:

$ wmctrl -i -a `wmctrl -lx | grep -i "Mozilla Firefox$" | head -1 | cut -d" " -f1`

Ở đây bạn có thể đoán được tính năng thứ hai của tập lệnh: nếu grep không trả về bất cứ thứ gì thì ứng dụng mong muốn không mở và bạn cần khởi động nó bằng cách thực thi lệnh từ tham số thứ hai. Và sau đó kiểm tra định kỳ xem cửa sổ cần thiết đã mở chưa để chuyển tiêu điểm sang cửa sổ đó. Tôi sẽ không tập trung vào vấn đề này, ai cần thì sẽ xem nguồn.

Khi không phân biệt được cửa sổ ứng dụng

Vì vậy, chúng ta đã học cách chuyển tiêu điểm sang cửa sổ của ứng dụng mong muốn. Nhưng nếu một ứng dụng mở nhiều cửa sổ thì sao? Tôi nên tập trung vào cái nào? Đoạn script trên rất có thể sẽ chuyển sang cửa sổ mở đầu tiên. Tuy nhiên, chúng tôi muốn linh hoạt hơn. Tôi muốn có thể nhớ cửa sổ nào chúng ta cần và chuyển sang cửa sổ cụ thể đó.

Ý tưởng là thế này: Nếu chúng ta muốn ghi nhớ một cửa sổ cụ thể cho một tổ hợp phím thì chúng ta cần nhấn tổ hợp này khi cửa sổ mong muốn được lấy nét. Trong tương lai, khi bạn nhấn tổ hợp này, tiêu điểm sẽ được chuyển đến cửa sổ này. Cho đến khi cửa sổ đóng lại hoặc chúng tôi thiết lập lại tổ hợp tập lệnh này showwinTách ra.

Thuật toán tập lệnh showwin một cái gì đó như thế này:

  • Kiểm tra xem trước đó chúng tôi có nhớ id của cửa sổ cần chuyển tiêu điểm đến không.
    Nếu bạn nhớ và một cửa sổ như vậy vẫn tồn tại thì chúng ta chuyển tiêu điểm sang nó và thoát ra.
  • Chúng tôi xem cửa sổ nào hiện đang được lấy nét và nếu nó phù hợp với yêu cầu của chúng tôi thì hãy nhớ id của nó để truy cập vào cửa sổ đó trong tương lai và thoát ra.
  • Chúng tôi đi đến ít nhất một số cửa sổ phù hợp nếu nó tồn tại hoặc mở ứng dụng mong muốn.

Bạn có thể tìm ra cửa sổ nào hiện đang được lấy nét bằng tiện ích bảng điều khiển xdotool bằng cách chuyển đổi đầu ra của nó sang định dạng thập lục phân:

$ printf "0x%08x" `xdotool getwindowfocus`

Cách dễ nhất để ghi nhớ điều gì đó trong bash là tạo các tệp trong hệ thống tệp ảo nằm trong bộ nhớ. Trong Ubuntu, tính năng này được bật theo mặc định trong /dev/shm/. Tôi không thể nói bất cứ điều gì về các bản phân phối khác, tôi hy vọng rằng cũng có điều gì đó tương tự. Bạn có thể xem bằng lệnh:

$ mount -l | grep tmpfs

Tập lệnh sẽ tạo các thư mục trống trong thư mục này, như sau: /dev/shm/$USER/showwin/$SEARCH_REGEX/$WINDOW_ID. Ngoài ra, mỗi lần nó được gọi nó sẽ tạo ra một liên kết tượng trưng /dev/shm/$USER/showwin/showwin_last trên /dev/shm/$USER/showwin/$SEARCH_REGEX. Điều này sẽ cần thiết để, nếu cần, xóa id cửa sổ cho một kết hợp nhất định bằng cách sử dụng tập lệnh showwinTách ra.

Những gì có thể được cải thiện

Đầu tiên, các tập lệnh phải được cấu hình thủ công. Chắc hẳn do phải đi sâu và làm nhiều việc bằng tay nên nhiều bạn thậm chí sẽ không thử cấu hình hệ thống. Nếu có thể chỉ cần cài đặt gói và định cấu hình mọi thứ dễ dàng hơn thì có lẽ nó sẽ trở nên phổ biến hơn. Và sau đó hãy nhìn xem, ứng dụng sẽ được phát hành thành các bản phân phối tiêu chuẩn.

Và có lẽ nó có thể được thực hiện dễ dàng hơn. Nếu bằng id của một cửa sổ, bạn có thể tìm ra id của quá trình đã tạo ra nó và bằng id của quá trình, bạn có thể tìm ra lệnh nào đã tạo ra nó, thì có thể tự động hóa quá trình thiết lập. Thực sự tôi không hiểu những gì tôi viết ở đoạn này có khả thi hay không. Thực tế là cá nhân tôi hài lòng với cách nó hoạt động hiện nay. Nhưng nếu ai đó không phải tôi thấy toàn bộ cách tiếp cận này thuận tiện và ai đó cải thiện nó thì tôi sẽ vui lòng sử dụng giải pháp tốt hơn.

Một vấn đề khác, như tôi đã viết, là trong một số trường hợp, các cửa sổ không thể phân biệt được với nhau. Cho đến nay tôi chỉ quan sát thấy điều này ở chế độ ẩn danh trong chrome/crom, nhưng có lẽ có điều gì đó tương tự ở một nơi khác. Phương án cuối cùng là luôn có lựa chọn kết hợp phổ quát Alt + 1...Alt + 0. Một lần nữa, tôi sử dụng Firefox và đối với cá nhân tôi, vấn đề này không đáng kể.

Nhưng vấn đề quan trọng đối với tôi là tôi sử dụng Mac OS cho công việc và tôi không thể cấu hình bất cứ thứ gì tương tự ở đó. tính thiết thực wmctrl Tôi nghĩ tôi đã có thể cài đặt nó nhưng nó không thực sự hoạt động trên Mac OS. Có thể làm được điều gì đó với ứng dụng Máy tự động, nhưng nó chậm đến mức không thuận tiện khi sử dụng ngay cả khi nó đang hoạt động. Tôi cũng không thể thiết lập các tổ hợp phím để chúng hoạt động trong tất cả các chương trình. Nếu ai đó đột nhiên nghĩ ra giải pháp, tôi sẽ vui lòng sử dụng nó.

Thay vì một kết luận

Hóa ra đó là một số lượng từ lớn đến không ngờ cho một chức năng tưởng chừng như đơn giản như vậy. Tôi muốn truyền tải ý tưởng và không làm quá tải văn bản, nhưng tôi vẫn chưa tìm ra cách diễn đạt nó đơn giản hơn. Có lẽ nó sẽ tốt hơn ở định dạng video, nhưng ở đây mọi người không thích điều đó.

Tôi đã nói một chút về nội dung của tập lệnh và cách định cấu hình nó. Tôi không đi sâu vào chi tiết kịch bản nhưng nó chỉ có 50 dòng nên không khó hiểu.

Tôi hy vọng rằng người khác sẽ thử ý tưởng này và thậm chí có thể đánh giá cao nó. Tôi có thể nói về bản thân mình rằng kịch bản được viết cách đây khoảng 3 năm và nó RẤT thuận tiện cho tôi. Tiện lợi đến mức gây khó chịu nghiêm trọng khi làm việc với máy tính của người khác. Và với một chiếc MacBook đang hoạt động.

Liên kết đến các tập lệnh

Nguồn: www.habr.com

Thêm một lời nhận xét