How I wrote my jQuery-like prototype

Not python, but let’s try something different…

One thing people don’t realize is that at the core, jQuery is based on a very simple idea that’s easy to implement but is really cool and helpful. In this article I’ll describe something others have tackled before but here’s how I approached the fundamentals of a jQuery-like lib.

What is $?

So, the entire jQuery ease of use boost comes from the very great and mysterious “$” we use all the time. But what is $? Are we extending javascript in such a way that $ is a new keyword? Well, since jQuery is just a library we obviously build off our existing notions of Javascript. This leaves us with one option.
$ must be an object. But what kind of object is it? We still can do cool stuff like:

$("#id");

So…

$ is a function

But… but how? We said it has to be an object and note that we can still do things like:

$.ajax

Well, actually, a function in Javascript is an object. Let’s see an example of what this would look like.

var $ = function(o) {
};

$.ajax = {};

The concept of jQuery

The concept of jQuery is really about that magic function we call $. We get an object/object descriptor and return a special object. These special objects are actually jQuery’s extended objects and these are the ones allowing us to make all these cool operations on elements and anything basically. They literally extend the functionality provided. The magic comes in the cool abstractions smart objects make for us like bulk changes – objects that are array of smart objects.

Simple jQuery skeleton

Here’s a simple skeleton, we’ll call our cool function _ instead of $ just for fun:

var _ = function(o) {

	if(typeof o != "undefined") // Return improved object
	{
		var k = o; // let k be the smart/improved object
		if(typeof k == "string") // object descriptor
		{
			k = k.substring(1,k.length);
			if(o.charAt(0) == '#' || o.charAt(0) == '/' || o.charAt(0) == '.') {
				if(o.charAt(0) == '#')		
					k = getByAttribute(k, "id");
				if(o.charAt(0) == '/')
					k = getByAttribute(k, "name");
				if(o.charAt(0) == '.')
					k = document.getElementsByClassName(k);
			} else { // find object in document
				k = document[o];
			}
		}
		
		// extend object
		if (k) {
			// Array handling
			if (k.length) {
				if(k.length == 1) { // if a single, use only it.
					k = k[0];
				} else { // if multiple, extend array of objects
					k.foreach = function(operation)
					{
						return _.foreach(k, operation);
					};
				}
			}

			k.debug = function()
			{
				alert(k);
			};
		}
		
		return k;
	}
 };
 
 _.foreach = function(v, op)
{
	if (typeof op != "function") {
		console.warn("[_] op is not a function!");
	}
		
	var res = [];
	for(var i = 0; i < v.length; i++)
	{
		res.push(op(v[i]));
	}

	return res;
}

Note: getByAttribute() is a cross-browser function that I haven’t shown, which basically finds the element/s with the searched attribute.

While incomplete, this is a good beginning.
In this example _ returns smart objects, and has a function called foreach that does an operation for an iterable object. Each smart object has a debug() function that simply alerts itself. In addition, each smart array has a foreach() function that automatically uses _.foreach().

Summary

We now understand a little better how jQuery is made and the concepts that enable it to be this great abstraction and boosting utility with such power. $ is a constructor for these jQuery improved objects that allow us these additional functionalities. $ also serves as an object that allows for additional general functionality as well. To dive deeper I’d suggest you just go look at the code as jQuery is open source and well-documented. Last thing to cherish the brilliance that is actually in the annoying functions like the getByAttribute() we mentioned earlier. These preserve compatibility while trying to keep the performance good, and we should be greatful for the jQuery team that we don’t have to write or see that code ever again.

Writing a Desktop Environment with Python

Introduction

So, writing a desktop environment is a difficult task to say the least.

We need so many components and it seems impossible, and working alone it kind of is. Still, even though it might sound surprising – it IS feasible to make a nice little prototype of desktop environment alone, which is what I did.

We’re gonna focus on linux DE.

Now it’s in no way a standard Desktop Environment but it is another proof of how slowly but surely we abstract the computer and our frameworks become more and more solid. I’d like to see at as a way to continue the TinyWM tradition.

To see the final product you can check:  Github

Yeah, it’s not the most impressive stuff but it gets the job done and it’s still in prototype at this stage so we don’t know how good it’ll end up but I think it’s good enough for me to share some knowledge as the internet lacked the info and made some barriers for python users.

So… how do you write it in python? Wasn’t it mostly C/C++ code?

First of all, because of WMs like TinyWM the path is pretty clear now – python has imported Xlib and replaced the C structs and functions with classes and methods instead which is comfortable but unfortunately lacking a bit in documentation.

My goto docs are: the pyxlib docs

So indeed we’re seeing an even nicer level of abstraction. We need not bother ourselves with sockets and the X11 protocol directly, we can use a wrapper that handles that stuff. You can consider using XCB as well but I liked the Xlib resources and import to python.

We can use Gtk to make our extra apps like our launcher.

Making the Window Manager

To make the window manager all we need to do is follow the paths of some already nice prototypes like TinyWM. It provides it’s extremely small python code in that same page. You can run it just like that.

Taking it a step further

Making stuff like resize is easy, the one thing that is really lacking in guidance is the stacking. So we need to implement a click to raise mechanism.

To make it there are two steps:

First, we bind our left click to the window:

# grab_window_events is method inside our even manager/handler

FOCUS_BUTTON = 1 # left click

def grab_window_events(self, window):

window.grab_button(FOCUS_BUTTON, 0, True,
Xlib.X.ButtonPressMask,
Xlib.X.GrabModeSync,
Xlib.X.GrabModeSync,
Xlib.X.NONE,
Xlib.X.NONE,
None)

So now we grabbed the FOCUS_BUTTON which is the left click (button code 1), but wait this means that any click events that we intercept won’t be consumed at the target window. We’ve disabled the mouse click for the target window.

To fix it, note that this time we use Xlib.X.GrabModeSync. This should be the only time but it’s important as we’re going to see.

Then, we handle the grabbing:

def handle_mouse_press(self, event):

if event.detail == FOCUS_BUTTON:
# focus: raise window
event.window.configure(stack_mode=Xlib.X.Above)
self.wm.display.allow_events(Xlib.X.ReplayPointer, event.time)

handle_mouse_press is the method that handles the event where

event.type == Xlib.X.ButtonPress.

And now the important part:

self.wm.display.allow_events(Xlib.X.ReplayPointer, event.time)

This is why we used GrabModeSync. We select our display and allow ReplayPointer via XAllowEvents .

This allows us to let the events re-enter the event queue while ignoring synchronous button grabs. Which means that we grab the event and then re-send it while ungrabbed. This allows us to raise the window while still having the mouse clicks work normally.

Note that the python usage of this was nowhere to be found on the net and also the guidance to use XAllowEvents.

Hope this helps a soul out there.

Creating a Launcher

To create a launcher we can use psutil to search for open processes. It’s cross platform which is great. I used psutil.pids() to probe the processes.

To create any graphics I used Gtk 3 (which is what you should use). You can make it in python but be sure to use gi.repository instead of the old gtk package.

Here’s how to import:

from gi import require_version
require_version(‘Gtk’, ‘3.0’)
# import gtk
from gi.repository import Gtk, Gdk, GdkPixbuf, GLib

Here I also imported Gdk, GdkPixbuf (which is an object for stretching images to a size of your liking) and GLib (which is used for multithreading).

I didn’t use it yet but to get notified about closing/opening we can use pyinotify on “/proc” to get the events. To make transparent backgrounds you need to use Cairo and connect our window to a “draw” event:

window.connect(“draw”, self.area_draw)

and some more preparations:

window.visual = window.screen.get_rgba_visual()
if window.visual != None and window.screen.is_composited():
window.set_visual(window.visual)
else:
print “Advance graphics aren’t supported!”

we can use the next draw function:

def area_draw(self, widget, cr):

cr.set_source_rgba(.0, .0, .0, .0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
cr.set_operator(cairo.OPERATOR_OVER)

Here we used Cairo graphics library. Simply import cairo after installing the library.

To make clickable images we can use Gtk.EventBox and add the Gtk.Image. Finally, we connect it to the button_press_event and we’re done. In my launcher I made it so that a click would terminate the app for example, but you can make it as complex as you want of course.

Now for the gtk multithreading. The easiest way is to seperate the gui updates from other updates so that we can use:

GLib.threads_init()

GLib.timeout_add_seconds(1, update_gui)

Gtk.main()

to update the gui each second for example. We start normally via Gtk.main() while having a callback to update the gui. Neat.

Conclusion

Well, that was a lot to cover but I just went for the highlights that are hard to find online. Now you too can create a shitty desktop envirnoment but it’s a step forward.

Obviously this is nothing compared to a full Desktop Environment, which has so much more components (read more here) but we finally have a “TinyDE”. And it’s entirely in python which is extra convenient.

Until next time =)