Alternative Fensterverwaltung in Linux

Ich gehöre zu denjenigen, die die Caps Lock-Taste für den Wechsel der Tastaturbelegung nutzen, weil es mir zu mühsam ist, zwei Tasten zu drücken, wenn ich nur eine drücken kann. Ich hätte sogar gerne zwei überflüssige Tasten: Eine würde ich zum Aktivieren der englischen Tastaturbelegung nutzen, und die andere für die russische. Aber die zweite überflüssige Taste ist die für das Kontextmenü, die so überflüssig ist, dass viele Laptop-Hersteller sie entfernen. Daher muss ich mit dem zufrieden sein, was vorhanden ist.

Außerdem möchte ich beim Wechseln zwischen Fenstern nicht deren Symbole in der Taskleiste suchen oder die Titel beim Scrollen durch Alt+Tab, durch die Arbeitsflächen blättern usw. Ich möchte eine Tastenkombination drücken (idealerweise sogar nur eine, aber es gibt keine freien überflüssigen Tasten mehr) und sofort in das Fenster gelangen, das ich brauche. Zum Beispiel so:

  • Alt+F: Firefox
  • Alt+D: Firefox (Privater Modus)
  • Alt+T: Terminal
  • Alt+M: Rechner
  • Alt+E: IntelliJ Idea
  • usw.

Außerdem möchte ich, wenn ich zum Beispiel auf Alt+M drücke, den Rechner sehen, unabhängig davon, ob dieses Programm momentan geöffnet ist oder nicht. Wenn es geöffnet ist, soll das Fenster den Fokus erhalten, und wenn nicht, das benötigte Programm gestartet werden und der Fokus übergeben werden, sobald es geladen ist.

Für Fälle, die von dem vorhergehenden Szenario nicht abgedeckt sind, möchte ich universelle Tastenkombinationen haben, denen beliebige der offenen Fenster einfach zugewiesen werden können. Beispielsweise habe ich 10 Kombinationen von Alt+1 bis Alt+0, die keiner bestimmten Anwendung zugeordnet sind. Ich kann einfach drücken Alt+1 und das Fenster, das gerade im Fokus ist, erhält den Fokus, wenn ich drücke. Alt+1.

Im Folgenden ist die Beschreibung noch einiger Funktionen und eine Antwort darauf, wie man das machen kann. Aber ich warne gleich, dass eine solche Anpassung 'auf sich selbst' eine starke Abhängigkeit verursachen und sogar Entzugserscheinungen hervorrufen kann, wenn man Windows, Mac OS oder sogar einen fremden Computer mit Linux verwenden muss.

Wenn man ehrlich nachdenkt, verwenden wir im Alltag nicht so viele Programme. Browser, Terminal, IDE, ein gewisser Messenger, Dateimanager, Rechner und das war's dann auch schon. Man braucht nicht viele Tastenkombinationen, um 95% der täglichen Aufgaben abzudecken.

Für Programme, bei denen mehrere Fenster geöffnet sind, kann eines davon als Hauptfenster festgelegt werden. Beispielsweise sind mehrere Fenster von IntelliJ Idea geöffnet, die auf Alt+Egesetzt sind. Unter normalen Bedingungen wird beim Drücken von Alt+E ein Fenster dieses Programms geöffnet, höchstwahrscheinlich das, das zuerst geöffnet wurde. Wenn man jedoch auf drückt, Alt+E Wenn eines der Fenster dieses Programms den Fokus hat, wird genau dieses Fenster als Hauptfenster festgelegt, und der Fokus wird bei nachfolgenden Tastenkombinationen an dieses Fenster weitergegeben.

Das Hauptfenster kann neu zugewiesen werden. Dazu muss die Kombination zuerst zurückgesetzt werden, und dann kann ein anderes Fenster als neues Hauptfenster zugewiesen werden. Um die Kombination zurückzusetzen, drücken Sie die Kombination selbst und dann eine spezielle Reset-Kombination, bei mir ist sie zugewiesen auf Alt+Backspace. Dies ruft ein Skript auf, das die Zuweisung des Hauptfensters für die vorherige Kombination aufhebt. Anschließend kann ein neues Hauptfenster gemäß den Anweisungen im vorherigen Absatz zugewiesen werden. Das Zurücksetzen des zugewiesenen Fensters auf universelle Kombinationen erfolgt auf ähnliche Weise.

Die Einleitung ist lang geworden, aber ich wollte zunächst erklären, was wir tun werden, und dann erläutern, wie es gemacht wird.

Für diejenigen, die das Lesen satt haben

Kurz gesagt, der Link zu den Skripten befindet sich am Ende des Artikels.

Aber trotzdem wird es nicht sofort möglich sein, es einzurichten und zu verwenden. Zuerst muss man herausfinden, wie das Skript das richtige Fenster findet. Ohne das wird es nicht möglich sein, dem Skript anzugeben, wohin der Fokus genau gegeben werden soll. Und es muss verstanden werden, was zu tun ist, falls kein passendes Fenster gefunden wird.

Ich werde auch nicht darauf eingehen, wie man die Ausführung von Skripten durch Tastenkombinationen einrichtet. Zum Beispiel in KDE unter Systemeinstellungen → Tastenkombinationen → Benutzerdefinierte Tastenkombinationen. In anderen Fenstermanagern sollte das ähnlich sein.

Einführung in wmctrl

Wmctrl ist ein Konsolendienstprogramm zur Interaktion mit dem X Window Manager. Es ist das Schlüsselprogramm für das Skript. Lassen Sie uns schnell einen Blick darauf werfen, wie man es verwenden kann.

Zunächst zeigen wir eine Liste der geöffneten Fenster an:

$ 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 Übersetzer - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Beste Veröffentlichungen des Tages / Habr - Mozilla Firefox (Privates Surfen)
...

Option -l zeigt eine Liste aller geöffneten Fenster an, und -x fügt der Ausgabe den Klassennamen hinzu (skype.Skype, Navigator.Firefox usw.). Wir benötigen hier die Fenster-ID (Spalte 1), den Klassennamen (Spalte 3) und den Fenstertitel (letzte Spalte).

Sie können versuchen, ein Fenster mit der Option zu aktivieren -a:

$ wmctrl -a skype.Skype -x

Wenn alles nach Plan läuft, sollte das Skype-Fenster auf dem Bildschirm erscheinen. Wenn anstelle der Option -x die Option verwendet werden -i, statt des Klassennamens kann die ID des Fensters angegeben werden. Das Problem mit der ID ist, dass sie sich bei jedem Start der Anwendung ändert und wir sie im Voraus nicht wissen können. Andererseits weist dieses Attribut eindeutig auf das Fenster hin, was wichtig sein kann, wenn die Anwendung mehr als ein Fenster öffnet. Dazu später mehr.

An dieser Stelle müssen wir uns merken, dass wir das benötigte Fenster mit einem Regex aus der Ausgabe suchen werden. wmctrl -lx. Aber das bedeutet nicht, dass wir unbedingt etwas Komplexes verwenden müssen. In der Regel reicht der Klassenname oder der Fenstertitel aus.

Grundsätzlich sollte die Hauptidee bereits klar sein. In den Einstellungen für globale Hotkeys/Tastenkombinationen Ihres Fenster-Managers konfigurieren wir die benötigte Kombination zum Ausführen des Skripts.

Wie man Skripte nutzt

Zuerst müssen Sie die Konsolenwerkzeuge installieren wmctrl und xdotool:

$ sudo apt-get install wmctrl xdotool

Dann müssen die Skripte heruntergeladen und hinzugefügt werden in $PATH. Ich lege sie normalerweise in ~/bin:

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

Wenn das Verzeichnis ~/bin nicht existierte, muss es erstellt werden und man muss sich neu anmelde (oder neu einloggen), sonst ~/bin wird es nicht in $PATH. Wenn alles richtig gemacht wurde, sollten die Skripte aus der Konsole verfügbar sein und die Tab-Vervollständigung sollte funktionieren.

Das Hauptskript showwin nimmt 2 Parameter an: der erste ist das Regex, mit dem wir das benötigte Fenster suchen, und der zweite Parameter ist der Befehl, der ausgeführt werden soll, wenn das gewünschte Fenster nicht gefunden wurde.

Sie können versuchen, das Skript auszuführen, zum Beispiel:

$ showwin "Mozilla Firefox$" firefox

Wenn Firefox installiert ist, sollte der Fokus auf sein Fenster gesetzt werden. Sogar wenn Firefox nicht gestartet wurde, sollte es jetzt gestartet werden.

Wenn es funktioniert hat, können Sie versuchen, die Ausführung von Befehlen auf Tastenkombinationen einzustellen. In den Einstellungen für globale Hotkeys/Tastenkombinationen fügen wir hinzu:

  • Alt+F: showwin «Mozilla Firefox$» firefox
  • Alt+D: showwin «Mozilla Firefox (Privater Modus)$» «firefox -private-window»
  • Alt+C: showwin «chromium-browser.Chromium-browser N*» chromium-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

Und so weiter. Jeder kann Tastenkombinationen und Software nach seinen Wünschen einstellen.
Wenn alles richtig gemacht wurde, können wir mit den oben angegebenen Kombinationen einfach zwischen Fenstern wechseln.

Ich enttäusche die Liebhaber von Chrome: Normale Fenster sind von einem Inkognito-Fenster anhand der Ausgabe nicht zu unterscheiden. wmctrl Das ist nicht möglich, da sie die gleichen Klassennamen und Fenstertitel haben. Die vorgeschlagenen Regex-Zeichen N* und I* sind nur erforderlich, damit sich diese regulären Ausdrücke voneinander unterscheiden und verschiedenen Fenstern als Hauptschnittstelle zugeordnet werden können.

Um das Hauptfenster der vorherigen Kombination zurückzusetzen (tatsächlich für den Regex, der showwin zum letzten Mal aufgerufen wurde), muss das Skript showwinDetachaufgerufen werden. Ich habe dieses Skript einer Tastenkombination zugeordnet. Alt+Backspace.

Das Skript showwin hat eine weitere Funktion. Wenn es mit einem Parameter (in diesem Fall ist der Parameter einfach eine ID) aufgerufen wird, überprüft es die Regex überhaupt nicht, sondern betrachtet alle Fenster als passend. Das wirkt auf den ersten Blick nutzlos, aber auf diese Weise können wir jedes Fenster als Hauptfenster zuordnen und schnell zu genau diesem Fenster wechseln.

Ich habe folgende Kombinationen eingerichtet:

  • Alt+1: showwin „CustomKey1“
  • Alt+2: showwin „CustomKey2“
  • Alt+0: showwin „CustomKey0“
  • Alt+Backspace: showwinDetach

So kann ich beliebige Fenster Kombinationen zuordnen. Alt+1Alt+0Einfach durch Drücken von Alt+1 ordne ich das aktuelle Fenster dieser Kombination zu. Ich kann die Zuordnung mit dem Drücken von Alt+1, und dann auf Alt+Backspacewidersprechen. Oder das Fenster schließen, auch das funktioniert.

Nun möchte ich ein paar technische Details erläutern. Man muss sie nicht lesen, sondern kann einfach versuchen, sie einzurichten und sich die Ergebnisse anzusehen. Ich empfehle jedoch trotzdem, sich mit fremden Skripten vertraut zu machen, bevor man sie auf seinem Computer ausführt. :)

Wie man verschiedene Fenster derselben Anwendung unterscheidet

Im Prinzip war das erste Beispiel „wmctrl -a skype.Skype -x“ funktional und kann genutzt werden. Aber schauen wir uns noch einmal das Beispiel mit Firefox an, in dem 2 Fenster geöffnet sind:

0x04400003  0 Navigator.Firefox                   N/A Google Translate - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Die besten Beiträge des Tages / Habr - Mozilla Firefox (Privates Browsen)

Das erste Fenster ist im Normalmodus, das zweite im Privaten Browsen. Diese Fenster würden wir gerne als verschiedene Anwendungen betrachten und zwischen ihnen mit unterschiedlichen Tastenkombinationen wechseln.

Das Skript zum Wechseln der Fenster muss komplizierter werden. Ich habe folgende Lösung verwendet: eine Liste aller Fenster ausgeben, eine grep Regex anwenden, die erste Zeile mit Hilfe von headentnehmen, die erste Spalte (das wird die ID des Fensters sein) mit Hilfe von cutentnehmen und dann auf das Fenster anhand der ID wechseln.

Es sollte einen Witz über reguläre Ausdrücke und zwei Probleme geben, aber tatsächlich verwende ich nichts Kompliziertes. Reguläre Ausdrücke benötige ich, um das Ende einer Zeile anzugeben (Symbol „$“) und um „Mozilla Firefox$“ von „Mozilla Firefox (Privates Browsen)$“ zu unterscheiden.

Das Team sieht ungefähr so aus:

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

Hier kann man bereits über die zweite Besonderheit des Skripts spekulieren: Wenn grep nichts ausgegeben hat, bedeutet das, dass die benötigte Anwendung nicht geöffnet ist und sie über den Befehl im zweiten Parameter gestartet werden muss. Danach sollte regelmäßig überprüft werden, ob das benötigte Fenster geöffnet wurde, um ihm den Fokus zu geben. Ich werde nicht weiter darauf eingehen; wer es braucht, kann sich den Quellcode ansehen.

Wenn die Fenster der Anwendung nicht unterscheidbar sind

Also, wir haben gelernt, wie man den Fokus auf das Fenster der benötigten Anwendung überträgt. Aber was, wenn mehr als ein Fenster der Anwendung geöffnet ist? Welchem von diesen soll der Fokus übertragen werden? Das obige Skript wird wahrscheinlich an das erste geöffnete Fenster weitergeben. Wir würden jedoch mehr Flexibilität wünschen. Es wäre schön, sich zu merken, welches Fenster genau wir brauchen, und zu diesem Fenster zu wechseln.

Die Idee war folgende: Wenn wir für eine Tastenkombination ein bestimmtes Fenster merken möchten, müssen wir diese Kombination drücken, während das benötigte Fenster den Fokus hat. Bei späterem Drücken dieser Kombination wird der Fokus genau auf dieses Fenster übertragen. Solange das Fenster nicht geschlossen wird oder wir diese Kombination im Skript zurücksetzen. showwinDetach.

Der Algorithmus des Skripts showwin sieht ungefähr so aus:

  • Prüfen, ob wir zuvor die ID des Fensters, dem wir den Fokus geben wollen, gespeichert haben.
    Wenn wir es gespeichert haben und dieses Fenster immer noch existiert, geben wir ihm den Fokus und beenden.
  • Wir sehen uns an, welches Fenster gerade im Fokus ist, und wenn es unseren Anforderungen entspricht, merken wir uns seine ID für den späteren Zugriff und beenden.
  • Wir wechseln zu einem beliebigen passenden Fenster, falls es existiert, oder öffnen die benötigte Anwendung.

Um herauszufinden, welches Fenster gerade im Fokus ist, kann man das Konsolenprogramm xdotool verwenden und dessen Ausgabe in das hexadezimale Format umwandeln:

$ printf "0xx" `xdotool getwindowfocus`

Etwas in bash zu speichern, ist am einfachsten, indem man Dateien im virtuellen Dateisystem in den Speicher erstellt. In Ubuntu ist solch ein Dateisystem standardmäßig angeschlossen /dev/shm/. Ich kann nichts über andere Distributionen sagen, ich hoffe, etwas Ähnliches gibt es auch dort. Man kann dies mit dem Befehl überprüfen:

$ mount -l | grep tmpfs

Das Skript wird in diesem Ordner leere Verzeichnisse erstellen, wie diese: /dev/shm/$USER/showwin/$SEARCH_REGEX/$WINDOW_ID. Zusätzlich wird es bei jedem Aufruf einen Symlink erstellen /dev/shm/$USER/showwin/showwin_last auf /dev/shm/$USER/showwin/$SEARCH_REGEX. Dies wird benötigt, um bei Bedarf die Fenster-ID für eine bestimmte Kombination mit Hilfe des Skripts zu löschen. showwinDetach.

Was verbessert werden könnte

Zunächst müssen die Skripte manuell konfiguriert werden. Wahrscheinlich werden viele von euch aufgrund der Notwendigkeit, sich einzuarbeiten und viel manuell zu erledigen, nicht einmal versuchen, das System zu konfigurieren. Wäre es möglich, einfach ein Paket zu installieren und alles einfacher zu konfigurieren, könnte es möglicherweise an Beliebtheit gewinnen. Vielleicht würde die Anwendung sogar in die Standarddistributionen integriert.

Und möglicherweise könnte man es einfacher gestalten. Wenn man durch die ID des Fensters die ID des Prozesses, der es erstellt hat, ermitteln kann, und durch die ID des Prozesses herausfinden kann, welcher Befehl ihn erstellt hat, könnte man die Konfiguration automatisieren. Tatsächlich habe ich mich nicht damit beschäftigt, ob das, was ich in diesem Absatz geschrieben habe, möglich ist. Fakt ist, dass ich persönlich mit der aktuellen Funktionsweise zufrieden bin. Aber wenn jemand anderes den Ansatz als praktisch empfindet und es verbessert, werde ich gerne die bessere Lösung nutzen.

Ein weiteres Problem, wie ich bereits erwähnt habe, besteht darin, dass man in einigen Fällen Fenster nicht voneinander unterscheiden kann. Ich habe das bisher nur bei Incognito in Chrome/Chromium beobachtet, aber vielleicht gibt es so etwas auch anderswo. Im Extremfall gibt es immer die Möglichkeit universeller Kombinationen. Alt+1Alt+0Ich benutze übrigens Firefox und für mich persönlich ist dieses Problem nicht wesentlich.

Ein wesentliches Problem für mich ist jedoch, dass ich beruflich Mac OS verwende und ich dort nichts Ähnliches konfigurieren konnte. Das Tool wmctrl konnte ich anscheinend installieren, aber es funktioniert auf Mac OS nicht richtig. Man kann etwas mit der Anwendung Automator, aber es läuft so langsam, dass es selbst dann unangenehm zu bedienen ist, wenn es funktioniert. Ich konnte auch die Tastenkombinationen nicht so einstellen, dass sie in allen Programmen funktionieren. Falls jemand eine Lösung findet - ich würde mich freuen, sie zu benutzen.

Zum Abschluss

Es sind unerwartet viele Worte für eine scheinbar einfache Funktionalität geworden. Ich wollte die Idee vermitteln und den Text nicht überladen, aber ich habe noch nicht herausgefunden, wie ich es einfacher erzählen kann. Vielleicht wäre es im Videoformat besser, aber das wird hier nicht gerne gesehen.

Ich habe ein wenig darüber erzählt, was unter der Haube des Skripts steckt und wie man es konfiguriert. Ich bin nicht auf die Einzelheiten des Skripts eingegangen, aber es sind nur 50 Zeilen, und es ist nicht schwer, sich einzuarbeiten.

Ich hoffe, dass jemand diese Idee ausprobiert und sie vielleicht sogar schätzt. Für mich kann ich sagen, dass das Skript vor etwa 3 Jahren geschrieben wurde und ich damit SEHR zufrieden bin. So zufrieden, dass es beim Arbeiten an fremden Computern ernsthafte Unannehmlichkeiten verursacht. Und mit meinem Arbeits-MacBook.

Link zu den Skripten

Quelle: habr.com

60GB SSD 8Gb DDR4