FAQ
Not logged in

Frequently Asked Questions

About Minx

  1. What is Minx?
  2. Why write yet another (tiling) window manager?
  3. Why not qtile?

Using Minx

  1. How do I start Minx?
  2. How do I customize border colors, etc.?
  3. How do I customize Minx's behaviour?
  4. How do I specify my own key bindings?
  5. How can I launch applications with key strokes?
  6. Which version of Minx am I using?

Design and Implementation

  1. What is minxlib?
  2. Why not use python-xlib?
  3. Why not use XCB instead of Xlib?
  4. How do I build Minx?
  5. Why Fossil instead of git or mercurial?
  6. Why dev1.x/rel1.x branches? Will there be 2.x, 3.x, etc.?
  7. Why Doxygen instead of Sphinx?

About Minx

What is Minx?

Minx Is Not Xmonad. That is, it is a poor imitator. Thus, like xmonad, Minx attempts to layout the top-level windows on your X screens by automatically tiling them.

Minx's overarching goals are:

Minx does not paint icons on your root window, have a clickable taskbar or panel for window selection, etc. All it does is manage the top-level windows as per your settings (layout algorithm to use, keybindings, and so on). Additionally, the only decoration Minx puts on top-level windows is a simple border. By default, this border is one pixel thick and is red for the currently focused window and white for all the others (but, of course, you can change that).

Another way in which Minx is minimal is in the small number of core principles it implements, namely:

That's it. All other features are built on top of this basic infrastructure. For example, Minx has no built-in notion of a workspace. Instead, it sports "bookmarks," which capture "snapshots" that record the current layout, window configuration, etc. This custom state is then added to the window manager, which has functions for searching for that state, retrieving it, and so on.

Apart from keeping the window manager's core small, these core ideas also help make it highly customizable and extensible.

Finally, when it comes to ease of configuration, Minx's defaults aim for a reasonable out-of-the-box end-user experience. Things that people would commonly want to customize involve a small and straightforward amount of Python code. But even more advanced configuration (e.g., implementing custom layouts, altering focus switching policy, etc.) is also fairly easy.


Yes, but xmonad is all that and more. So why bother writing yet another (tiling) window manager?

Mostly because I was not patient enough to unlearn enough of my imperative programming habits to fully understand Haskell and, thereby, configure xmonad to get the exact behaviour I wanted.

Of course, I could have switched to a different tiling window manager. And I did look into awesome, i3, StumpWM, and one or two others. Needless to say, in the end, I decided that if I wanted a window manager that worked exactly how I wanted, I'd best write my own.

In retrospect, I should probably have just spent the time and effort to really learn Haskell! When I started Minx, I thought to myself "There are a gazillion window managers out there. How hard can it be? I should be done in a few weeks."

Now, more than a few weeks into it, I can see this is going to take a while because:

  1. Low-level X programming is not quite as straightforward as I thought it would be.
  2. Figuring out the various support libraries (e.g., Boost) involves a fair amount of trial and error.
  3. Learning a new set of tools (version control, documentation generator, diagramming language) also takes time.
  4. Cleaning up code and writing good documentation slows down development a good deal.

On the other hand, at this point, I am committed to the project and am learning new things. So, I suppose I shouldn't complain.


Fine, if you're too dumb to grok Haskell and want to stick with something you know, i.e., Python, why not use qtile?

I did consider qtile. But I thought its dependencies were somewhat onerous and I was in no mood to check-out and build a bunch of libraries from their source-control repositories just to get a window manager working. If I was going to be using a "ready-made" window manager (and not roll my own), I just wanted to be able to install a couple of packages, read some docs to figure out how to customize it, and move on with my life.

Moreover, qtile has some things in it that, in my opinion, do not belong in a minimal window manager, viz., widgets. Such functionality should be left to other programs (e.g., adesklets, screenlets).

Minx, in contrast, only needs stock Xlib, Boost, and Python. You can install these using your system's package manager.

But, really, my arguments for rejecting xmonad, qtile, and other window managers in favour of writing my own are fairly weak and can be boiled down to "Because I can and I want to." So, before you flame me about it, if you like one of these other window managers, please continue to use 'em; they're quite fine programs and I am not dissing them or trying to proselytize you to switch to Minx.


Using Minx

How do I start Minx?

At this time, Minx cannot even be considered alpha software. Therefore, it does not do anything very useful and does not come neatly packaged. You have to check-out its source code and run it in a nested X server. See the Building and Testing HOWTO for more details.


How do I customize border colors, sizes, and other such simple attributes?

By default, window borders are one pixel; the active window's border is red, and inactive window borders are white. To change these defaults, you will have to create a minx.core.config object, assign the desired values to its attributes, and then pass this config object to the minx.core.wm constructor. Here is some sample code to show how to go about this:

   #!/usr/bin/env python

   import minx

   conf = minx.core.config()
   conf.active_border_size    = 2
   conf.active_border_color   = 0x00FF00 # green
   conf.inactive_border_color = 0x00FFFF # cyan

   minx.core.wm(conf).start()

For more info about the config class, have a look at its API documentation.

In addition to the border attributes, the minx.core.config class also allows you to configure logging, which can be useful for debugging. For details on this, refer to the logging HOWTO.


How can I define my own hook functions to tweak how Minx handles various events?

The main window manager object maintains a hooks attribute that maps predefined names to their corresponding hook functions. By default, most of these name-to-function mappings are empty. To add your own hook, you will have to call wm.hooks.add() after creating the wm object but before calling its start() method.

Here is a short example:

   #!/usr/bin/env python

   import minx

   def my_manage_hook(w):
       prop = w.properties()
       if prop['class'] == 'Xmessage' and prop['name'] == 'bar':
          return False
       return True

   wm = minx.core.wm()
   wm.hooks.add('manage_hook', my_manage_hook)
   wm.start()

With that bit of code, Minx will call my_manage_hook() whenever a new window is created, which checks whether the window is an Xmessage named "bar"; if so, the hook returns false to indicate to Minx that the window should not be managed. Other windows will be passed through to Minx for it to manage normally.

The Hooks HOWTO has a lot more information about customization via hooks. The Hooks List documents all the currently supported hooks.


How can I specify my own key bindings to trigger various functions?

Key bindings are simply hooks whose names follow the pattern shown below:

   [modifier-]*key

Thus, a key binding's name consists of zero or more hyphen-separated modifiers followed in the end by the name of a key. The supported modifiers are:

The following examples should clarify how key bindings are named:

Name Key Binding
C-A-T CTRL + ALT + T
S-F1 SHIFT + F1
A-Tab ALT + Tab
M-R META + R
M5-S Mod5 + S
C-C CTRL + C

To add your own key bindings, you will have to use Minx's hooks support. The following example shows you how you can use (in addition to the default ALT + Tab and ALT + SHIFT + Tab) the F1 and SHIFT + F1 keys to cycle the input focus:

   #!/usr/bin/env python

   import minx

   wm = minx.core.wm()
   wm.hooks.add(  'F1', wm.focus_next)
   wm.hooks.add('S-F1', wm.focus_prev)
   wm.start()

For more on key bindings, be sure to read the Key Bindings HOWTO. Additionally, the Hooks List documents all the default key bindings.


How can I launch applications using custom key bindings?

The wm class has a spawn() function that you can use for this purpose. In fact, there is a default key binding that calls wm.spawn() to launch a terminal window. In a similar vein, you could define keys as shown below:

    #!/usr/bin/env python

    import minx

    wm = minx.core.wm()
    wm.hooks.add('C-A-E', lambda: wm.spawn('emacs'))
    wm.hooks.add('C-A-F', lambda: wm.spawn('firefox'))
    wm.hooks.add('C-A-G', lambda: wm.spawn('gimp'))
    wm.start()

With that, CTRL + ALT + E will launch Emacs, CTRL + ALT + F will launch Firefox, and CTRL + ALT + G will launch The Gimp.


Which version of Minx am I using?

The minx module defines a version object. Converting this to a string will yield something of the form a.b.c, where a is the major version number, b the minor version number, and c the patch level.

Additionally, the minx.version object has three read-only attributes, viz., major, minor, and patch. These attributes are integers and allow you to individually determine and/or compare the three components of the full version number.

Here is some sample code illustrating version number determination:

   #!/usr/bin/env python

   import minx

   try:
      print('Minx version string: {}'.format(minx.version))
      print('Minx version: major = {}, minor = {}, patch = {}'.
            format(minx.version.major, minx.version.minor, minx.version.patch))
   except AttributeError: # no version attribute in minx module
      pass # probably using development version of Minx

Note that minx.version is not available in development versions of Minx. Only officially released versions of Minx have a version number assigned to them.


Design and Implementation

What is minxlib?

Minx is written in Python. minxlib is an Xlib wrapper written in C++ with its API exposed to the Python-based Minx core via Boost.Python. minxlib provides a high-level, object-oriented interface to Xlib that the Python parts of Minx can use.


Why not use python-xlib instead of writing a custom Xlib wrapper?

Lack of documentation.

Whatever its deficiencies, the C version of Xlib is pretty well-documented (also this).

When I tried python-xlib, I found there was a certain amount of guesswork involved in figuring out certain functions and just didn't want to struggle with it.

Additionally, by encapsulating the connection with the underlying display server in a custom abstraction, making Minx support something like Wayland will (hopefully) be a simple matter of reworking minxlib while leaving the higher-level window management logic unchanged.


Why not use XCB instead of Xlib?

Again, lack of documentation.


How do I build Minx?

Minx is written mostly in Python; so there's nothing to build. There is, however, a small C++ component, viz., minxlib, which you will have to build. See the Building and Testing HOWTO for the gory details.


Why are you using Fossil, an obscure version control system, instead of something more well known like SVN, git, or Mercurial?

I wanted to be able to do initial development without the need for a server. That pretty much ruled out SVN.

I am using git at work. While I appreciate some of its features, I find it somewhat tiresome. When it comes to version control, I firmly believe that, like plumbing, it should not stick out the walls. Put another way, I don't want to be an expert mechanic and have a full theoretical understanding of internal combustion engines to be able to drive my car.

While git may be perfect for the Linux kernel and other large projects that have adopted it, it is overkill for Minx, which will never reach that scale (in fact, I will probably be its only developer and user). So I wanted a simpler DVCS that would afford me the luxury of ignorance.

So far, I am happy with Fossil. I really like:

Fossil is certainly not perfect. Some annoyances include:

Despite these warts, all in all, I like Fossil. It doesn't impose an undue cognitive load and allows me to concentrate on Minx development instead of having to slow down to think about version control.

I have never used Mercurial. So I cannot comment on it.

NOTE: If you like another version control system (SVN, git, Mercurial, whatever), please continue to use it for your projects. I am not trying to put them down in any way. I am only pointing out why I am using Fossil for Minx. In other words, use what you like and don't tell me about it; I don't care about your opinion.


What's the deal with the dev1.x and rel1.x branches? Will there be 2.x, 3.x, etc. branches in the future?

Yes, once I'm done with developing 1.x, I plan on a distinctly different approach for the 2.x series. There will only be these two series, no 3.x and beyond.


Why are you using Doxygen to document the Minx API? Since Minx is essentially a Python library, wouldn't it be better to use Sphinx, which not only rhymes with Minx, but also seems to be a de facto standard now for Python projects?

I did consider Sphinx. In fact, originally, I wanted to put the Minx API documentation on ReadTheDocs. However, I balked once I realized that getting Sphinx to automatically generate the documentation for minxlib, the C++ part of Minx, would be a hassle.

Setting up a bridge between Sphinx and Doxygen seems like too much work without enough of a payoff especially because: