The other day, I found out that on Windows you can replace explorer.exe with an arbitrary program. This led me to thinking about replacing the window manager with something more manageable. Unfortunately, you can't really replace the window manager, the decorations are always going to be handled by the compositor built in. However, the win32 api does allow you to move windows around, change their properties, and close them from an unrelated process. So, while I can't make a whole window manager, I can try to make a program to tile my windows.
I've mentioned before that I use xmonad, so obviously I would base it off of that. For anything event based on the desktop, there's no reason for me to use anything other than Python, since there's no bottlenecks in program logic (the longest part would be win32 api calls) and the win32 apis for Python are pretty mature (although missing good documentation, not too surprising since not a lot of people want to use it). I originally planned this as just a propoganda post for Pyler, but there's not too much interesting to talk about in the ideas of the manager itself, it's basically a clone of xmonad in Python. So you can basically just check out the project on GitHub
. The more interesting parts are in the code.
For the config file, I used an idea I found in xmonad and ipython, which is making the config file simply a source file in the language implementation, in this case Python. I like this a lot better in Python than in Haskell (although even in Haskell it's better than some key value or xml style config) because, if the package is created correctly, it allows you to duck punch any of the code you like, which basically allows the user to edit the program to do whatever they want without having to edit any built in source code. I've used this idea before
The config allows you to define hotkey functions that can call arbitrary functions, either built in, available through pyler modules (currently the only available module is
. Hotkeys are described as a tuple, the first element is a mask, using bitwise or to select mutliple mods, e.g.
would match holding the windows button and the shift button when you press the key. The second element of the tuple is the key pressed, e.g.
would match j,
matches the enter key, etcetera. The keys are defined in
. The value for the dictionary is a function to be called. The function must take at least one value, which is the key that was pressed. A finished hotkey description might look like this:
. So, for instance, by default, super-shift-Q by default ends the program, so it is described by
. Functions take in one parameter, which is the hotkey that was pressed. If you want to use multiple parameters, you can use a lambda to call the function, like for switching to the different workspaces, which looks a little like this:
(mod_super,k_1): lambda x: actions.switch_workspace(x,1)
. Unfortunately Python doesn't have the cool lazy functions like Haskell does, but lambdas make it pretty easy, just slightly more syntactically ugly.
Classes vs. Modules:
The other day at work, I was working on a program for for work and had a question about program structure. Ever since I started using object oriented programming, I've been creating Python programs in a Java style (which is weird, since I don't even like Java), where I would create an "application" object that would serve as the main loop or encapsulation for global variables and callbacks. This led to a kind of crazy program structure like this:
self.config = config.Config()
#Generally some gui code here
if __name__ == "__main__":
app = myApp()
This seemed like it might be some extra, unnecessary constructs just to encapsulate variables, especially since the myApp object is never referenced from anywhere outside of itself. I wanted to do some research about what the accepted practice of structuring Python programs was. Apparently, though, there has been no discussion on this subject whatsoever, so I have no arguments to weigh and decide what's best. Because of this, I decided to build Pyler with a module structure, like this:
#global variable definitions
if __name__ == "__main__":
In addition, I tried to not use classes for anything except what I consider to be a "thing". So, for instance, a window is a "thing", so it's a class. Config, on the other hand, is not a thing, therefor it is a module. Tilers could be considered either one, but since they aren't something you need more than one instance of, I decided modules would be better.
In some places, this is obviously superior. For instance, there's no reason to have a wrapper class for the keycodes module. You could have
kc = keycodes.KeyCodes(); kc.mod_shift
, it makes much more sense just to have the keycodes be properties of the keycodes module. In some places it's less obvious. For registering hotkeys, you need to keep track of which hotkeys have been registered, since all the windows api gives you is a hotkey id that you need to get the real hotkey based in. So you can keep the hotkeys as part of the module, or you can make a class that keeps track of the hotkeys. On the one hand, the module can have that as a property, just a dictionary in this case. You can also make a class that would have to get initialized, which some might argue makes more sense. Personally I prefer the module way.
After this, though, I still don't know which is the "right" way to do it. I'm going to have to take some more time to think about it.