All Projects → ntrrgc → right-window

ntrrgc / right-window

Licence: MIT license
Utility to move the focus between windows following cardinal directions

Programming Languages

C++
36643 projects - #6 most used programming language
CMake
9771 projects

Projects that are alternatives of or similar to right-window

Nscde
Modern and functional CDE desktop based on FVWM
Stars: ✭ 526 (+2822.22%)
Mutual labels:  x11, desktop-environment
Unclutter Xfixes
A rewrite of unclutter using the x11-xfixes extension
Stars: ✭ 236 (+1211.11%)
Mutual labels:  x11
Alttab
The task switcher for minimalistic window managers or standalone X11 session
Stars: ✭ 196 (+988.89%)
Mutual labels:  x11
Libagar
Cross-Platform GUI Toolkit (stable)
Stars: ✭ 212 (+1077.78%)
Mutual labels:  x11
Glmark2
glmark2 is an OpenGL 2.0 and ES 2.0 benchmark
Stars: ✭ 199 (+1005.56%)
Mutual labels:  x11
Xidlehook
GitLab: https://gitlab.com/jD91mZM2/xidlehook
Stars: ✭ 216 (+1100%)
Mutual labels:  x11
Sara
Originally a fork of catwm, now an offspring of dwm with a streamlined featureset, plus some bspwm.
Stars: ✭ 179 (+894.44%)
Mutual labels:  x11
darkine-kde
Darkine KDE - Theme for KDE Plasma 5 desktop > Mirror of https://git.rokin.in/Rokin/darkine-kde
Stars: ✭ 41 (+127.78%)
Mutual labels:  desktop-environment
Microwindows
The Nano-X Window System
Stars: ✭ 230 (+1177.78%)
Mutual labels:  x11
Frankenwm
🖼️ Fast dynamic tiling X11 window manager
Stars: ✭ 209 (+1061.11%)
Mutual labels:  x11
Xcolor
Lightweight color picker for X11
Stars: ✭ 209 (+1061.11%)
Mutual labels:  x11
Xf86 Input Wacom
X.Org driver for Wacom devices
Stars: ✭ 201 (+1016.67%)
Mutual labels:  x11
Dewm
A pure go autotiling window manager written with literate programming
Stars: ✭ 225 (+1150%)
Mutual labels:  x11
Chamferwm
A tiling X11 window manager with Vulkan compositor.
Stars: ✭ 200 (+1011.11%)
Mutual labels:  x11
X11docker
Run GUI applications and desktops in docker and podman containers. Focus on security.
Stars: ✭ 3,797 (+20994.44%)
Mutual labels:  x11
Azpainter
Full color painting software for Unix-like systems for illustration drawing. This is un-official little fixed repository for package maintainers of image editor AzPainter (based on "mlib" toolkit). Official repository - http://azsky2.html.xdomain.jp/arc/download.html
Stars: ✭ 179 (+894.44%)
Mutual labels:  x11
Xvfbwrapper
Manage headless displays with Xvfb (X virtual framebuffer)
Stars: ✭ 209 (+1061.11%)
Mutual labels:  x11
X11 Packages
Packages using the X Window System.
Stars: ✭ 213 (+1083.33%)
Mutual labels:  x11
PropagandaTiles
Propaganda, is a collection of "seamless tiles;" which are drawn in such a way that they do not appear to repeat at the edges.
Stars: ✭ 85 (+372.22%)
Mutual labels:  desktop-environment
Egpu Switcher
🖥🐧 Setup script for eGPUs in Linux (Xorg)
Stars: ✭ 252 (+1300%)
Mutual labels:  x11

right-window

This is a small utility to move the focus between windows in a desktop environment following a cardinal direction. For instance:

right-window -f right

will focus the window next to the right. Available directions are left, right, up and down.

The -f (--focus) parameter tells the right-window command to focus the found window . Alternatively, -s (--swap) replaces the current window with the found window, swapping their position and size.

You can also use -g (--get-id) to print the system identifier of the matched window. This is useful if you want to use right-window as a starting point for creating other utilities.

The command is intended to be bound as a series of hotkeys, e.g:

Win+H: right-window -f left
Win+L: right-window -f right
Win+K: right-window -f up
Win+J: right-window -f down

Win+Shift+H: right-window -s left
Win+Shift+L: right-window -s right
Win+Shift+K: right-window -s up
Win+Shift+J: right-window -s down

Multi-monitor is supported.

Desktop support

This utility was written with the bspwm window manager in mind, as an alternative to similar commands like bspc node --focus east but having more intuitive multi monitor support (see bspwm issue #380).

There are currently two different binary builds of right-window:

  • right-window-bspwm: Uses bspc command as a subprocess to query and manipulate the window manager. This is the recommended way to use the utility in bspwm. Building it does not require to have bspwm installed.

  • right-window-x11: Uses Xlib as an alternative for other X11-based window managers. It uses common _NET_WM extensions to interact with the window manager.

    The focus command -f should work fine on most window managers. Unfortunately, swapping windows with -s does not work completely well on many window managers for a lack of a consistent way of querying and setting window position in X11.

    Common issues are negative positions not being supported (see _NET_MOVERESIZE_WINDOW specification), window borders not accounted and spurious offsets. Help in this area is appreciated.

Adding support for other window managers is possible implementing the interface rw::WindowManager from wm_abstract.h. All that is required are three methods for querying the list of currently active windows, focusing them and swapping their position and size. See the comments in the source code for more details. Additionally a compiler flag and an #include directive pointing to the new window manager class must be added to available_wm.cpp and CMakeLists.txt.

Building

You can use the typical building procedure for a CMake project:

mkdir build && cd build
cmake <path to project>
make

Speed

This tool is meant to be executed each time a movement hotkey is pressed, so the program execution time matters. Initially it was written in Python, but later the tool was rewritten in C++ to drastically reduce the process time from 60-80 milliseconds Python requires just to load the interpreter to only 2 milliseconds which is way under a frame, as long as the executable is cached in memory.

The measurements were made on a Linux system.

Window search algorithm

The problem of finding the next window to the right (or any other direction) is actually harder than it looks since there are many ambiguous cases.

This is the algorithm this utility implements in order to choose what window is next to any direction.

For simplicity, the following instruction assume you want to find the next window to the right.

  1. Begin with a list of all the currently visible windows.

  2. Discard any window that is definitely to the left. This is defined as any window whose rightmost border is to the left of the left border of the focused window.

    +------+ +------+ +------+
    |      ‖ |      | |      ‖  
    |  A   ‖ |  B*  | |  C   ‖  
    |      ‖ |      | |      ‖
    +------+ +------+ +------+  B is focused
        +------+                A is discarded
        |      ‖
        |  D   ‖
        |      ‖
        +------+
    
  3. Check if there are any remaining windows that share vertical range with the focused one. In that case, discard the others. Otherwise, skip this step.

    +------+          +------+
    |      |          ‖      ‖  
    |  A*  | +------+ ‖  B   ‖  
    |      | ‖      ‖ ‖      ‖
    +------+ ‖      ‖ +------+  A is focused
             |      |           D is discarded
             |  C   | +------+        
             |      | |      |                      
             |      | |  D   |                       
             |      | |      |        
             +------+ +------+        
    
  4. Of the remaining windows, pick the one whose left border is nearest to the right border of the focused window. In case of a tie where two or more windows have the same X position for their left border, pick all of them.

    +-----+ +-----+ +-----+
    |     | ‖  B  | |  C  |
    |  A* | +-----+ +-----+  A is focused
    |     | +-------------+  C is discarded
    |     | ‖      D      |
    +-----+ +-------------+
    
  5. If at this step we still have several windows, pick the most recently used (which is also the topmost one in the Z-stack).

In the source code the algorithm deals with generalizations of left, right, up and down in order to work in all four directions without really writing it four times.

Therefore, the right border is called the agreeing border (as it's in the same direction we intend to move), the left border is called the opposite border, the vertical range is called perpendicular range and being to the right (when right is the direction we're moving) is named being next.

directions.h contains the concrete definition for those concepts for all four directions, which should be quite unsurprising.

Feasible improvements

Here are some things that I would like to add to this utility but I'm not in mad need of them.

###Window clipping

Most window managers allow you to place windows on top of other windows, occluding them to the point of being invisible without being minimized. This is an issue because the user is unlikely to want to use directional movement to focus a window that is currently invisible.

This could be prevented by adding a window clipping algorithm that before starting the search algorithm would filter out any window whose rectangle is completely covered by windows on top.

This is the kind of geometric problem people write academic papers about. Fortunately there are implementations there that are small, efficient, easy to use and free. You can find one of such implementations by Angus Johnson at vendor/clipper.hpp.

Currently I do most of my work in bspwm, a tiling window manager. As such, I never have windows covering other windows so I don't really need this.

###Microsoft Windows support

There is (hopefully) nothing Linux-specific in this code, so it should be possible to add MS Windows as another window manager.

For anyone potentially pursuing this endeavour — including myself of the future, here is a list of relevant WINAPI functions:

Hopefully it can't be harder than X11.

License

MIT License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].