[font=Verdana]#F8365B[/font]
So, figured I'd make a tutorial about wmutils, because it's nice. If you don't know, wmutils is a set of window manipulation utilities (man, would you believe it if I told you that's what wmutils stood for?), and NOT a window manager. It's written using C and the xcb library by two people using the aliases z3bra and dcat.
So, what is included with wmutils? Well, there's 3 repositories that wmutils has (all conveniently located on GitHub, see the bottom of this post). Installing everything from the core repository makes installs 13 binary files, all of which are listed here (and what they do as well):
chwb - Changes window border (there are only 2 variants of this, or 3 if you count my fork of /opt)
chwso - Changes window stacking order
ignw - Ignores windows
killw - Kills windows
lsw - Lists windows (root window can also be listed, as well as unmapped/invisible windows, and windows using override redirect, e.g. dmenu, lemonbar, generally speaking, this will be an X application that isn't managed by the window manager).
mapw - Maps windows (changes their visibility, useful for workspaces and iconifying windows, if the user wants).
pfw - Lists the currently focused windows id (this is the only command included in wmutils/core that does not require command line options. Sending any options results in the same output as not sending any at all).
wattr - Returns window attributes. You can get border size, window id, x offset, y offset, width, height, override redirect property (either 1 or 0), and whether the window is mapped or not (either 1 or 0).
wmp - Warp mouse cursor. This is pretty self explanatory.
wmv - Moves windows (not to be confused with wtp).
wrs - Resizes windows.
wtf - Changes window focus, focuses the window passed in.
wtp - Teleports windows (not be confused with wmv or wrs. Wtp can move windows AND resize them, but does not transfer focus to the newly teleported window)
These, however, aren't the only tools however. Installing wmutils/opt will give access to a few more tools, one of which is the most useful of them all, at least to me.
chwb2 - Changes a windows border (double border variant).
wew - Subscribes to X events (rather useful, especially for what will be discussed later)
wname - Returns the name of the window passed.
xmmv - Moves the window to the mouse pointer, when you click (according to man page. I haven't actually seen this work myself).
Knowing all this, let's quickly go over the UNIX way. Essentially, the UNIX way is just using a bunch of small systems to make a complex system (this isn't the only idea in the UNIX way, but it's what we'll be focusing on here). This means using the command line to our advantage. And in this tutorial specifically, piping.
At this point, you may want to install wmutils, both core and opt. I'll be showing you a sane method to actually using wmutils. Crazy, right?
[spoiler]
$ git clone https://github.com/wmutils/core.git
$ cd core
$ make
$ sudo make install
$ git clone https://github.com/wmutils/opt.git
$ cd opt
$ make
$ sudo make install
[/spoiler]
There's many methods that you could use to string each of these tools together into a functional window manager. However, like I stated earlier in the thread, we'll be using our command line (piping specifically) to our advantage.
So, what exactly does piping do? A really quick and dirty explanation is, it passes everything a program sends to STDOUT, and sends it to another programs STDIN. Here's an example:
$ example | thread
Everything "example" sends to STDOUT (anything logged really, console.log
in JavaScript, print
in Python, puts
in Ruby... you get the idea) is passed to "thread". So if example outputs "hi", the input into thread is "hi".
Which of these tools conveniently tells you everything you need, want to know, and more about X events? Wew. Alright, simple enough. We just need to be able to pipe wew, parse events, and write a handler for the events. Of course things will be much more complicated than just that, especially when you use a program that spawns multiple new [invisible] windows. You will also want to be able to execute binary files, and get responses. I've written a simple example JavaScript program, which you can find under this wall of text, but you can use any language you want.
var shell = {
async: require("child_process").exec,
sync: require("child_process").execSync
}; // Since this is just an example, loading both exec and execSynchronous functions would be rather useless, since I don't actually use the async version. However, I generally like to load both, and use sync for executing commands only. Having async allows me to fetch data from other shell commands.
var events = {
16: "chwb -c 0xffffff ", // (window created) changes window border to white
17: "" // (window destroyed) do nothing when windows are closed
// man wew - shows all events that can be outputted
};
process.stdin
.resume()
.setEncoding('utf8')
.on('data', function(stdin) {
var stdin = stdin.split("\n");
for (var index_0 = 0; index_0 < stdin.length; index_0++) {
var stdin_data_part = stdin[index_0].split(":"),
event = stdin_data_part[0],
window = stdin_data_part[1];
if (stdin_data_part != "") {
var event_cmd = events[event];
if (event_cmd)
shell.sync(event_cmd + window);
}
};
});
Like I said earlier, you can use any language you feel appropriate for the task of managing your windows. This is just a simple example! Once done, you will have to change around your xinitrc a bit in order to test your window manager.
# ... xinitrc
# executing wm
# Because wmutils is only a set of utilities, you shouldn't load any window manager, rather, just execute graphical applications. This will put you into an X session, where you can work.
exec urxvt
# Killining the urxvt window opened will in turn kill your X session. There are work arounds to this, assuming you want to keep your window manager open, but not urxvt. Also, you don't have to use urxvt, you can use xfce4-terminal, gnome-terminal, terminator, whatever you have available to you, or whatever you want to use. I use urxvt, so that's why that's in the example.
Once in the X session with the terminal you selected, you will have to start wew, and pipe it to your program.
$ wew | /tmp/path/to/program/note/it/shouldnt/be/in/tmp/or/really/this/lang.js
Well, there you have it. A quick, dirty, yet sane method to using no window manager at all. This small little guide was just written for fun, and so you can see the glory of wmutils. And the UNIX way, in a way. "Way, in way." Also, as a note, this isn't an extensive tutorial on making a window manager using wmutils. It's only an example (I'm also aware the wmutils isn't new).
https://github.com/wmutils/core - Core.
https://github.com/wmutils/opt - Optional.
https://github.com/wmutils/contrib - Some pre-written scripts, if you're too lazy or just want to toy with wmutils.