Note: Development is paused for now as I finish up my PhD. I have a lot of plans for this as soon as I have time. If you use the project and have issues, please open an issue for me to address when I have time.
This project consists of two simple tools for interacting with windows. The first, window_manager, allows you to save (and later refocus) any window with a single command. The second communicates with Kanata's TCP server to set application-specific keybinds.
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
This project consists of two simple tools for interacting with windows. The first, window_manager, allows you to save (and later refocus) any window with a single command. The second communicates with Kanata's TCP server to set application-specific keybinds.
This is a work in project (especially when it comes to documentation), but the
binaries are fully-functional, and their --help
sections should tell you all
you need.
I am actively working to get these tools working in Linux. See below.
To get started, all you need to do is run:
.../path/to/kanata_helper_daemon.exe --port=<kanata-port-number>
For example, if you had launched Kanata with:
kanata.exe -p 1337
You would run:
.../path/to/kanata_helper_daemon.exe --port=1337
When you switch your application focus, kanata_helper_daemon will send a message to Kanata telling it to switch layers. The requested layer name is the name of the window's process. For example, if you opened Firefox, kanata_helper_daemon would attempt to switch to the layer named "firefox". If you're not sure what a window's process name is, take a look at kanata_helper_daemon's console output. Note that layer names are case-sensitive.
For full functionality, you'll want to point kanata_helper_daemon to your Kanata config file, like so: .
.../path/to/kanata_helper_daemon.exe --port=1337 --config-file=.../path/to/config/file.kbd
The daemon will parse your config file to gather a list of all your layer names. If a process name does not match one of your layer names, it will return to the layer named "default". WARNING: kanata_helper_daemon currently only supports single-file configurations, so any layers defined in files added with include will not be parsed. If you don't have a layer named "default", or you just want to use a different layer for this, you can specify the name like so:
.../path/to/kanata_helper_daemon.exe --port=1337 --config-file=.../path/to/config/file.kbd --default-layer=my-default-layer
You will likely want to run this daemon in the background so that you don't need to keep a console window open. To do so, you can use the following syntax in PowerShell:
Start-Process .../path/to/kanata_helper_daemon.exe --port=1337 --config-file=.../path/to/config/file.kbd --default-layer=my-default-layer -WindowStyle Hidden
If you wish to kill this background process, you can do so (again in PowerShell) with:
Stop-Process -Name kanata_helper_daemon
This tool allows you to programatically activate specific windows. Do you often find yourself searching through a million icons on your taskbar to find that one browser window? This is the tool for you.
Usage is relatively straightforward. The command:
/path/to/window_manager.exe --save-window=0
saves the currently-focused window to index 0, and:
/path/to/window_manager.exe --load-window=0
will later bring that window to the front and focus it. The window's index can be
any number from 0-999.
Saved windows are stored in a .ini file. By default, this will be "saved_windows---path
argument:
`/path/to/window_manager.exe --path=.../path/to/your/file.ini --save-window=0`
Both window title and handle (basically, a number that is a unique identifier for that particular window) are stored. This allows window_manager to activate a window after it has been closed and reopened (handle changed, but title hopefully remained the same) or if the window title changes (e.g. you change tabs in your browser). Since this utility is run on-demand, and there is no background daemon, it is limited in what it can do to keep track of your windows. Each time you activate a window it will update the saved handle and title, but if a window's handle and title change between activations window_manager won't know where to find the window.
Obviously, running this utility directly from the terminal isn't very useful. It is intended
to be bound to your keyboard. You can see a Kanata configuration that does this in examples
.
See the open issues for a full list of proposed features (and known issues).
Building the project should be pretty straightforward. However, I'm new to Win32 development, so these instructions may be incomplete. Please open an issue if you have problems.
git clone https://github.com/reidprichard/window_tools.git
) or download its zip.CMake is the easiest way to build. You may need to have a recent version of Visual Studio installed to get access to MSVC.
cmake ..
cmake --build .
Alternatively, if you don't have CMake installed, you can build with GCC (tested with mingw64):
gcc ./src/kanata_helper_daemon.c ./src/utils.c -lWs2_32 -o kanata_helper_daemon.exe
to build _kanata_helperdaemon. If you get errors along the lines of undefined reference to '__imp_WSAStartup'
, it's not finding the Ws2_32 library. (This shouldn't be an issue if you're using mingw64.) You'll have to use your Google-Fu here.gcc ./src/window_manager.c ./src/utils.c -o window_manager.exe
to build _windowmanager.If built with a method other than CMake, --version
will output 0.0.0.
Since the Windows implementation relies on the win32 API, adding Linux will entail a full rewrite. It seems that KDE Plasma's API doesn't provide ways to get/set the focused window, but that functionality is available in KWin scripting. I've previously written a KWin script to set the focused window, but I'm not sure about listening to the active window (for _kanata_helperdaemon) or about calling KWin scripts from C.
Here is how KWin scripts can be called from the command line.
This looks like a good starting point, though I don't know Rust. I would appreciate any help here. I have no plans to implement this in Gnome, but I would love a collaborator to make that happen.
Perhaps this is doable with the Wayland protocols? Or KWayland? Way out of my league here.
I'm brand new to git, brand new to the Win32 API, and not the most experienced C programmer, so I would love any improvements or critiques that could be made.
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
git checkout -b feature/AmazingFeature
)git commit -m 'Add some AmazingFeature'
)git push origin feature/AmazingFeature
)Distributed under the GNU General Public License v3.0 or later. See LICENSE.txt
for more information.
Project Link: https://github.com/reidprichard/window_tools