How to efficiently and productively work on Linux OS?
I am one of those who puts on Caps Lock switching layouts because it is too lazy to press 2 keys when you can press one. I would even like 2 unnecessary keys: one I would use to turn on the English layout, and the second for Russian. But the second unnecessary key is a call to the context menu, which is so unnecessary that it is cut by many manufacturers of laptops. So you have to be content with what you have.
And when I switch windows, I don’t want to look for their icons on the taskbar, to look at the names when scrolling through Alt + Tab, to scroll through desktops, etc. I want to press a key combination (ideally, there’s only one, but there are no free unnecessary keys ) and immediately get into the window I need. For example, like this:
- Alt + F: Firefox
- Alt + D: Firefox (Private Browsing)
- Alt + T: Terminal
- Alt + M: Calculator
- Alt + E: IntelliJ Idea
Moreover, by pressing, for example, Alt + M, I want to see the calculator, regardless of whether this program is currently running. If it is running, then its window needs to be given focus, and if not, start the desired program and transfer focus when it loads.
For cases that are not covered by the previous scenario, I want to have universal keyboard shortcuts to which you can easily assign any of the open windows. For example, I have 10 combinations assigned from Alt + 1 to Alt + 0 that are not tied to any programs. I can just press Alt + 1 and the window that is currently in focus will receive focus when Alt + 1 is pressed.
Under the cut, a description of a couple more features and an answer to how to do this. But I’ll immediately warn you that such customization “for yourself” can cause a strong addiction and even breaking if necessary, use Windows, Mac OS or even someone else’s computer with Linux.
In fact, if you think about it, then we do not use many programs every day. A browser, terminal, IDE, some kind of messenger, file manager, calculator and, perhaps, that’s almost all. Not many key combinations are needed to cover 95% of everyday tasks.
For programs that have multiple windows open, one of them can be assigned as the main one. For example, several IntelliJ Idea windows are open, assigned to Alt + E. Under normal conditions, pressing Alt + E will open some window of this program, most likely the one that was opened first. However, if you press Alt + E when one of the windows of this program is already in focus, then this window will be assigned as the main one and focus will be transferred to it upon subsequent pressing of the combination.
The main window can be reassigned. To do this, you must first reset the combination, and then assign another window to it as the main one. To reset a combination, you need to press the combination itself, and then a special reset combination, I have it assigned to Alt + Backspace. This will invoke a script that will unassigned the main window for the previous combination. And then you can assign a new main window as described in the previous paragraph. Resetting a tied window to universal combinations is similar.
The introduction was long, but I wanted to first tell what we will do, and then explain how to do it.
For those who are tired of reading
But all the same, it will not work and immediately install and use. First, you have to figure out how the script finds the right window. Without this, it will not be possible to indicate to the script exactly where to transfer the focus. And you need to understand what to do if suddenly a suitable window was not found.
And I will not focus on how to configure script execution by pressing key combinations. For example, in KDE, this is in System Settings → Shortcuts → Custom Shortcuts. In other window managers, this should also be.
Wmctrl is a console utility for interacting with X Window Manager. This is a key script program. Let’s take a quick look at how you can use it.
To get started, list the open windows:
$ 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 Translator - Mozilla Firefox 0x04400218 0 Navigator.Firefox N/A Best publications of the day / smartSpate - Mozilla Firefox (Private Browsing) ...
The -l option displays a list of all open windows, and -x adds the class name (skype.Skype, Navigator.Firefox, etc.) to the output. We will need the window id (column 1), the class name (column 3) and the window name (last column).
You can try to activate some window using the -a option:
$ wmctrl -a skype.Skype -x
If everything went according to plan, then a Skype window should appear on the screen. If you use the -i option instead of the -x option, you can specify the window id instead of the class name. With id, the problem is that the window id changes every time the application starts and we cannot know it in advance. On the other hand, this attribute uniquely indicates a window, which may be important when an application opens more than one window. About this a little further.
- At this stage, we need to remember that we will search for the desired window using regex according to the output of wmctrl -lx. But this does not mean that we must use something complicated. Usually, a class name or window name is sufficient.
In principle, the basic idea should already be clear. In the global hotkeys/shortcuts settings for your window manager, we configure the desired combination to execute the script.
How to use scripts
First, you need to install the console utilities wmctrl and xdotool:
$ sudo apt-get install wmctrl xdotool
Next, you need to download the scripts and add them to $PATH. I usually put them 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
If there was no ~/bin directory, then it must be created and rebooted (or logged in), otherwise ~/bin will not get into $PATH. If everything is done correctly, then the scripts should be accessible from the console and Tab completion should work.
The main showing script takes 2 parameters: the first is a regex, by which we will search for the desired window, and the second parameter is the command that must be executed if the desired window was not found.
You can try to run a script, for example:
$ showwin "Mozilla Firefox$" firefox
If Firefox is installed, then its window should be given focus. Even if Firefox was not running, it should have started.
If it turned out, then you can try to configure the execution of commands on a combination. In the global hotkeys/shortcuts settings, add:
- Alt + F: showwin “Mozilla Firefox $” firefox
- Alt + D: showwin “Mozilla Firefox (Private Browsing) $” “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
And so on. Combinations of keys and software can be configured by everyone as it is convenient for him.
If everything turned out right, then according to the above combinations, we can switch between windows with a simple keystroke.
I will disappoint chrome lovers: it is incognito to distinguish an ordinary window from the wmctrl output, they have the same class names and window headers. In the proposed regex, the characters N * and I * are necessary only so that these regulars differ from each other and they can be assigned different windows as the main ones.
- To reset the main window of the previous combination (in fact for regex, which showwin was called for the last time), you need to call the showwinDetach script. I have this script assigned to the Alt + Backspace key combination.
The showwin script has another feature. When it is called with one parameter (in this case, the parameter is just an identifier), it does not check regex at all and considers all windows to be suitable. In itself, this seems useless, however, in this way we can designate any window as the main one and quickly switch to this particular window.
I have such combinations configured:
- Alt + 1: showwin “CustomKey1”
- Alt + 2: showwin “CustomKey2”
- Alt + 0: showwin “CustomKey0”
- Alt + Backspace: showwinDetach
This way I can bind any windows to Alt + 1 … Alt + 0 combinations. Just by pressing Alt + 1 I bind the current window to this combination. I can unbind by pressing Alt + 1, and then Alt + Backspace. Or close the window, this also works.
Further, I will tell you some technical details. You can not read them, but just try to configure and see. But I would still recommend understanding other people’s scripts before running them on your computer :).
How to distinguish different windows of one application
In principle, the very first example of “wmctrl -a skype.Skype -x” was working and can be used. But let’s look again at the example with Firefox, in which 2 windows are open:
0x04400003 0 Navigator.Firefox N/A Google Translator - Mozilla Firefox 0x04400218 0 Navigator.Firefox N/A Best publications of the day / smartSpate - Mozilla Firefox (Private Browsing)
The first window is the normal mode, and the second is Private Browsing. I would like to consider these windows as different applications and switch to them using different key combinations.
You need to complicate the script that switches windows. I used this solution: display a list of all windows, make grep by regex, take the first line with head, get the first column (this will be the window id) with cut, switch to the window by id.
There should be a joke about regular expressions and two problems, but in fact, I do not use anything complicated. I need regulars so that I can indicate the end of the line (the “$” character) and distinguish between “Mozilla Firefox $” and “Mozilla Firefox (Private Browsing) $”.
The command looks something like this:
$ wmctrl -i -a `wmctrl -lx | grep -i "Mozilla Firefox$" | head -1 | cut -d" " -f1`
Here you can already guess about the second feature of the script: if grep did not return anything, then the desired application is not open and you need to start it by running the command from the second parameter. And then periodically check to see if the right window has opened to give it focus. I will not focus on this, those who need it will look at the source.
When application windows are not distinguishable
So, we learned to transfer focus to the window of the desired application. But what if more than one window of an application is open? Which one should I focus on? The script above will most likely pass to the first open window. However, we would like more flexibility. I would like to be able to remember which window we need and switch to this window.
The idea was this: If we want to remember a certain window for a key combination, then we need to press this combination when the desired window is in focus. In the future, when you click this combination, the focus will be given to this particular window. Until the window closes or we do a reset for this showwinDetach script combination.
The showwin script algorithm is something like this:
- Check to see if we have previously remembered the id of the window to which focus should be passed.
- If you remember and such a window still exists, then we transfer the focus to it and exit.
- We look at which window is currently in focus, and if it suits our request, then we will remember its id to go to it in the future and exit.
- We turn to at least some suitable window if it exists or opens the desired application.
You can find out which window is currently in focus using the console utility xdotool, converting its output to hexadecimal format:
$ printf "0x%08x" `xdotool getwindowfocus`
Remembering something in bash is the easiest way to create files in a virtual file system in memory. On Ubuntu, this is connected by default in /dev/shm/. I can’t say anything about other distributions, I hope that this also exists. You can see the command:
$ mount -l | grep tmpfs
The script will create empty directories in this folder, like this: /dev/shm/$USER/showwin/$ SEARCH_REGEX/$WINDOW_ID. Additionally, with each call, it will create symlink /dev/shm/$USER/showwin/showwin_last on/dev/shm/$USER/showwin/$SEARCH_REGEX. This will be needed in order to remove the window id for a specific combination if necessary using the showwinDetach script.
What can be improved
First, the scripts must be configured by hand. Surely, because of the need to delve into and do a lot with your hands, many of you will not even try to configure the system. If it were possible to just put the package and configure everything easier, then perhaps it would gain some popularity. And there, look at the standard distributions, they would gash the application.
And perhaps easier can be done. If the id of the window allows you to find the id of the process that created it, and the id of the process to find out which team created it, then you could automate the configuration. In fact, I did not understand if what I wrote in this paragraph is possible. The fact is that for me personally it suits the way it works now. But if to someone other than me the whole approach seems convenient and someone improves it, then I will be happy to use the best solution.
Another problem, as I already wrote, is that in some cases windows cannot be distinguished from one another. So far I have only seen this with incognito in chrome/chromium, but perhaps somewhere else there is something similar. In extreme cases, there is always a variant of the universal combinations Alt + 1 … Alt + 0. Again, I use Firefox and for me personally this problem is not significant.
But a significant problem for me is that I use Mac OS for work and I couldn’t configure anything like that there. It seems to be able to deliver the wmctrl utility, but it does not really work on Mac OS. Something can be done with the Automator application, but it is so slow that it is not convenient to use it even when it works. I also couldn’t configure the key combinations so that they worked in all programs. If suddenly someone comes up with a solution – I will be glad to use it.
It turned out unexpectedly a lot of words for such seemingly simple functionality. I wanted to convey the idea and not overload the text, but I have not yet figured out how to tell it easier. It might be better in video format, but they don’t like it like that.
I talked a little about what is under the hood of the script and how to configure it. I did not go into the details of the script itself, but it is only 50 lines, it is not difficult to understand.
I hope that someone else will try this idea and perhaps even appreciate it. I can say for myself that the script was written about 3 years ago and it is VERY convenient for me. It is so convenient that it causes serious discomfort when working with other people’s computers. And with a working MacBook.