Get an ubuntu like login screen for archlinux

I am not the greatest fan of ubuntu, but I love their artwork. I’m not an user of ubuntu, so the usability and performance of unity in general is of little concern to me (although I do despise it), but I loved the look of it. In the simplest of words that I can put it in, it’s beautiful. What I especially loved was the graphical login. So, as it turns out, I wanted it for my arch. This is what I ended up with:

Background image by dethredic. Link to deviation at DeviantArt

Getting the packages

Before beginning, make a folder called ‘lightdm-inst’ or whatever it is you wish where you will be saving all your downloaded packages (trust me, there are going to be a lot of them).

Get lightdm from AUR

This is pretty easy to begin with. Download the lightdm package from here: http://aur.archlinux.org/packages.php?ID=40708. Save it to the folder ‘lightdm-inst’. Once downloaded, run the following command to install the dependencies for lightdm and lightdm-unity-greeter:

[thirtyseven@meanmachine lightdm-inst]$ sudo pacman -S accountsservice dbus-glib gnome-icon-theme gnome-themes-standard gtk3 libwebkit libxklavier gtk-engine-murrine gtk2 cantarell-fonts gnome-common gnome-doc-utils ttf-ubuntu-font-family gnome-icon-theme hicolor-icon-theme humanity-icons librsvg

As far as lightdm is concerned, it is pretty easy to install it. Pacman repositories have all its dependencies. Beyond this, all you have to do is make the package using makepkg and then install it:

[thirtyseven@meanmachine lightdm-inst]$ tar xvzf lightdm.tar.gz
[thirtyseven@meanmachine lightdm-inst]$ cd lightdm
[thirtyseven@meanmachine lightdm-inst]$ makepkg

This will download the source, build it and create a nice little package for you, which you can then install using:

[thirtyseven@meanmachine lightdm-inst]$ sudo pacman -U lightdm-1.0.6-8-x86_64.pkg.tar.xz

Remember the above method for installing packages from AUR if you are already not familiar with this. You’re going to have to do this often. It is also recommended that you install xorg-xephyr to help you test your lightdm installation and configuration:

[thirtyseven@meanmachine lightdm-inst]$ sudo pacman -S xorg-server-xephyr

Test your installation using the following command: lightdm --test-mode. The result (should) be something like:

Not exactly what we wanted right? What we need is the unity-greeter for lightdm. This one’s gonna hurt a bit.

Getting lightdm-unity-greeter

You might have a different experience from me since I have KDE as the only installed desktop environment on my machine. If you have GNOME, you might have a different experience (although just as unpleasant), or a relatively pleasant one, if you have both installed (I’m not sure, you’re just going to have to see this one for yourself).

Some of the dependencies are available on the pacman repositories (I’ve already mentioned them in the first `pacman` command), the two main that are not, and which you must get from AUR (get and install in the mentioned order) are:

  1. libindicator: AUR link
  2. ubuntu-wallpapers: AUR link
  3. gtk-engine-unico: AUR link (Dependency for light-themes)
  4. humanity-icons: AUR link (Dependency for ubuntu-mono)
  5. ubuntu-mono: AUR link (Dependency for light-themes)
  6. light-themes: AUR link
  7. lightdm-unity-greeter: AUR link

Get and install them (using pacman -U <package-name> as specified above IN THE ORDER mentioned. There’s a good chance that I might have missed out on a dependency here and there, in which case, just check with pacman first and the AUR next, but it is all there.

Once this is done, check out your login screen by the same command: lightdm --test-mode. This is how it looks:

So far, so good. But we really don’t want ubuntu branding, now do we? Before that, let us get lightdm to be our default display manager.

System settings to run on boot

You’ll have to make changes to your inittab file for this. Add this line to your /etc/inittab:

x:5:respawn:/usr/sbin/lightdm >& /dev/null

If you have similar lines for kdm, xdm, gdm etc. comment them. For example, my inittab looks like this:

#x:5:respawn:/usr/bin/xdm -nodaemon
#x:5:respawn:/usr/sbin/gdm -nodaemon
#x:5:respawn:/usr/bin/kdm -nodaemon
#x:5:respawn:/usr/bin/slim >/dev/null 2>&1
x:5:respawn:/usr/sbin/lightdm >& /dev/null

In case you use rc.conf instead of the inittab method for launching your display manager, then add `lightdm` to your list of daemons in arch linux, and remove any other display manager daemon.

Also, you’ll have to start the service:

systemctl enable lightdm.service

If you don’t have the systemctl binary, get it using:

sudo pacman -S systemd

More info and troubleshooting: LightDM – ArchWiki

Get some arch branding

Firstly, decided on the artwork you want to use. You might choose to not brand your graphical login with archlinux and might decided on anything else. I selected this image as my background: [dethredic.deviantart]ArchLinuxWallpaper

Now, select a logo that you wish to use (in place of the ‘ubuntu’) text that comes in the bottom right corner of the screen. There’s a lot of nice artwork available here. Since I had a dark background, I decided to go with one with the white text. MAKE SURE you download the PNG.

Save both images in some place ‘preferably the same lightdm-inst directory’. Since the logo is large, you might want to resize it. 221×70 worked like a nice size for me:

[thirtyseven@meanmachine lightdm-inst]$ mogrify -resize 212x70 archlinux-logo-light-1200dpi.png

Change the names of the two images to ‘archlinuxshow.png‘ and ‘archlogo.png‘ (This is just for our convenience). Now, let us set it to the login screen.

Configuring the branding

Copy the two files to /usr/share/unity-greeter:

[thirtyseven@meanmachine lightdm-inst]$ sudo cp archlinuxshow.png /usr/share/unity-greeter/ -v
[thirtyseven@meanmachine lightdm-inst]$ sudo cp archlogo.png /usr/share/unity-greeter/ -v

Now open the file /etc/lightdm/unity-greeter.conf using an editor:

(vim)

[thirtyseven@meanmachine lightdm-inst]$ sudo vim /etc/lightdm/unity-greeter.conf

(KDE, with Kate)

[thirtyseven@meanmachine lightdm-inst]$ kdesu kate /etc/lightdm/unity-greeter.conf

(GNOME, with Gedit)

[thirtyseven@meanmachine lightdm-inst]$ gksu gedit /etc/lightdm/unity-greeter.conf

Edit the two lines that start with `background` and `logo` (After the initial section that is prepended with a ‘#’). Change:

background=/usr/share/backgrounds/warty-final-ubuntu.png
logo=/usr/share/unity-greeter/logo.png

to

background=/usr/share/unity-greeter/archlinuxshow.png
logo=/usr/share/unity-greeter/archlogo.png

Now, run the test again:

Looks good, but there is something really really not right. There is this ugly grid of dots, and I don’t like it one bit.

Get rid of those ugly dots

Before you proceed. This tip was given by reader logicslayer:

To remove the dots, you can edit your uninty-greeter.conf. Change “draw-grid=true” to “draw-grid=false”.

I haven’t tested it, but if it works for you, great (not so great for me though… a lot of my hardwork just went down the drain). Anyways, thank you so much, logicslayer. Check out the comments for more tips regarding troubleshooting while installing via yaourt

If you’re happy with the result till now, you might as well stop here. The next step is a bit cumbersome and unless you are extremely obsessive and compulsive about getting the right look, the result, to you, wont be worth it.

The problem is that those dots are hard coded in the greeter. So, we’ll have to remove a bit of code here. Don’t be scared, it is really easy and simple. Just follow along.

Go back to your `lightdm-inst` folder. In that folder, perform the following commands:

[thirtyseven@meanmachine lightdm-inst]$ cd lightdm-unity-greeter/src/unity-greeter-0.1.1/src
[thirtyseven@meanmachine lightdm-inst]$ vim user-list.vala +252

When you run the last command, vim will open the file with the cursor at the beginning of a line. You just have to comment that line with a backslash. Basically, change this line:

bc.rectangle (grid_size - 1, grid_size - 1, width - grid_size * 2 + 2, height - grid_size * 2 + 2);

to

//bc.rectangle (grid_size - 1, grid_size - 1, width - grid_size * 2 + 2, height - grid_size * 2 + 2);

Save and quit the file. Now, go back to your `lightdm-inst/lightdm-unity-greeter` directory. What we need to do know is use `makepkg`, but such that it uses the source which we have just edited. There’s a slight problem with that. The PKGBUILD script will try to apply patches first (it’s scripted to do so), but what it expects is the downloaded source, not the one which we have edited and hence the patching process will fail, and hence we won’t get a package that reflects our changes. To circumvent this, open the PKGBUILD file in the `lightdm-inst/lightdm-unity-greeter` directory and change remove the following lines from the build() function in the script:

build() {
  cd "${srcdir}/unity-greeter-${pkgver}"

  # Apply Ubuntu patches
  for i in $(cat "${srcdir}/debian/patches/series" | grep -v '#'); do
    patch -Np1 -i "${srcdir}/debian/patches/${i}"
  done

  # Fix the problem where GNU ld cannot find x11
  patch -Np0 -i "${srcdir}/fix_ld_x11.patch"
  autoreconf -vfi

  ./configure 
    --prefix=/usr 
    --sysconfdir=/etc 
    --libexecdir=/usr/lib/lightdm

   make
}

The final build() function should look something like:

build() {
  cd "${srcdir}/unity-greeter-${pkgver}"
  autoreconf -vfi

  ./configure 
    --prefix=/usr 
    --sysconfdir=/etc 
    --libexecdir=/usr/lib/lightdm

   make
}

Once this is done, we are ready to make this package:

[thirtyseven@meanmachine lightdm-unity-greeter]$ makepkg -ef
[thirtyseven@meanmachine lightdm-unity-greeter]$ sudo pacman -U lightdm-unity-greeter-0.1.1-2-x86_64.pkg.tar.xz

Remember to use the `-ef` option for makepkg. This tells makepkg to use the existing source (-e) and overwrite any previously built packages (-f). You will have to change your branding configuration again (check out the previous section for that). Your images will all still be there, its just the configuration that will be rewritten. Make the necessary changes and test it:

And that, ladies and gentlemen, is a beautiful graphical login :)

Fun with 2D transformations and JavaScript

Semester end is here.. and that means PROJECTS. So, I had to do this project for Computer Graphics Lab. It’s actually a fun subject, not what is taught though, as we have to still write code in some 20 years old library (Yes, my Indian friends, graphics.h in TC.exe). Anyways, I (not so surprisingly) chose Qt to do my project in. The basic concept of the application is that the transformation matrix that is to be applied to an object, be parametric i.e. it be defined as a function over some parameter. I added a linear mapping of that parameter to time and used ECMAScript for the functional definition of the matrix.

Each cell is defined as an individual script. So we have a script called ‘m00′, ‘m01′ … ‘m22′, and there is an `init` script, which is run at the beginning of the animation. All scripts for the various cells are first evaluated after being wrapped into a function. This is important so that engine does not have to constantly evaluate the scripts every time the parameter changes. Once these functions are obtained, they are evaluated lazily by the engine as and when required.

The result is ‘raiden’. Rather than going on and on about the things it can do, I’ll just let screenshots do the talking:

Using the tabs, one can alternate between the two modes: “Workspace” and “Script Editor”. From the bottom right panel, select the Graphics Object you wish to transform, and specify the required parameters.

Set the minimum and maximum parameter values and the step. 24 steps are covered in one second. Begin and end can be of any magnitudes, but begin > end (if step is negative) and vice versa if step is positive.

Just a simple text box to input scripts. Nothing fancy.

The init script is run ONCE when the “Run” button is pressed. Use this to do any global computations, like computing the path of a bezier curve. You can also specify functions that can be called by any of the cell scripts.

In this screenshot, the script for the matrix cell at [0][0] is being written. When run, this function will be called with varying parameters to produce an animation.

Another cell script being edited.

In midst of animation. The top-left panel shows the current transformation matrix that is being applied, and the box on the top-left shows the current value of the parameter.

Code and technicalities

The current code is horrible. I’m pretty close to deadlines, and didn’t really bother much about conventions… so the haphazard way it is. Adding new Graphics Items is easy, if you plan to get the code, check out ‘AbstractGraphicsItem.h’ for more details. To get the code (you’ve been warned):


git clone byt3@rohanprabhu.com:raiden.git

and to get it running (linux, for windows try qmake.exe or just open it in QtCreator):


git clone byt3@rohanprabhu.com:raiden.git
cd raiden
qmake raiden.pro
make
./raiden

Download the write-up for the project from: http://rohanprabhu.com/files/raiden-writeup.pdf

TODO

  1. Add the ability to save/load code.
  2. Changing the active Graphics Item currently crashes the Workspace. Figure it out.
  3. There are some problems with the 3rd column, specifically, the one which control translation. Need to figure it out.
  4. The script editor is horrible and has serious issues with usability, but I don’t think I’m changing that any time soon.

Most of these issues should be solved by tomorrow, so maybe a clone then will give you a nice working copy :) Do mention your comments and suggestions. If you plan to share the screenshots, please link back to my site, but please don’t use the image urls from my server. I have all the images uploaded http://imgur.com/a/0g4dk, in case you feel like.

Please stop this facebook mindlessness

Our government has been busy. I mean really fucking busy. They have been passing laws which make absolutely no sense, and that too, in record time. And here’s the surprising part: Facebook users come to know about these laws and no media outlet ever does. Or maybe, our government does have a sense of humor. I mean it’s not like they have a country to run or anything.

At the same time almost anything can give you cancer. Going to theater’s is not safe, because that gives you aids or something. And doctors know fuck nothing about this. But obviously, facebook users trump doctors all the time.

The worst problem is that people don’t bother to check. You are already on facebook for god sake, you are already using a bloody web browser. You are one goddamn tab away from google. Here are a few examples:

If you find any important documents like Driving License (DL), Ration Card, Passport, Bank Passbook, Voter’s Card etc. missed by some one, simply put them into near by post boxes. They will be delivered to the owner and postal fee or fine will be collected from them”. New Law by Govt……click like and Pass on this useful & imp information….share as much as possible.

Firstly, when it comes to any official document, one is supposed to return it to the issuing authority. The documents are (generally) the property of the issuing authority, and not of the holder. A passport, regardless of nationality, if found MUST be reported to a passport office, because passports can be flagged as ‘discovered’ and these flags are traceable internationally. Moreover, there is absolutely no citation regarding this ‘law’ being passed.

In this case, if you’re reposting this, you’re just being ignorant dicks, because someone just might follow your advice and trash somebody’s passport for fuck sake.


ATTENTION……………….!!!!!!!!!!
Medical research unit of US has
found a new cancer in human
beings caused by ‘silver nitro-oxide’…..so whenever we buy mobile
recharge cards,they should not be
…………scratched by nail….coz they
contains ‘silver nitro-oxide’coating. ……which can cause
skin cancer…. ….copy n paste the
status and spread awareness……

This is my favorite one. First of all, there is NO compound called ‘Silver nitro-oxide’. If you ever paid attention in 11th standard, you would know that. But given the fact that you absolutely didn’t give a fuck in school when they were teaching you punctuation and grammar, this is no surprise to me. There is also nothing known as ‘Nitro oxide’. Nitrogen has a variety of oxides, but ‘Nitro oxide’ is not one of them. The best I’m willing to assume is you mean a compound of Silver, Nitrogen and Oxygen, or Silver Nitrate. Silver Nitrate (AgNO3) is NOT a carcinogen. Actually, it is an antiseptic. Secondly, metallic salts rarely look like metals (or shiny like the scratch cards). They mostly look packets of color I put in a bucket of water for holi. The scratch cards are made using Latex, which is a harmless polymer.[1]


If you have a function/party at your home and if there is excess food available at the end, don’t hesitate to call **** (only in India) – child helpline. They will come and collect the food. Please circulate this message which can help feed many children.

This is fucking horrible. First of all, you’re simple mindless if you thought this could have ANY merit at all. And if you had even an inkling of doubt, it would really help if you could check what you’re posting, because if this fucking thing gets viral, you are clogging the call lines of an already understaffed organization. This is from their official website [2]:

Warning : We understand there is a chain mail circulating that says – one should call up 1098 to pick up left over food after a party etc so that it is not wasted. This is not true. We are India ‘s only and most widespread Children’s phone emergency outreach service (1098) for children in need of care and protection. We do not pick up food or distribute food. This mail was not initiated by us, kindly do not circulate it. Your cooperation is appreciated.

SBI guidelines- Public News 4 a true Indian: Bcoz of written Rupee note, Indian Govt. has Rs.2638 cr loss per year..plz don’t write anything on Rupee Note bcoz they can’t be used for std transactio ns..Eg u can’t find written notes in ATM…plz paste it on ur status so that everyone become aware of the fact….a useful message is better than many jokes……..

There are just so many things wrong with this:

  • RBI makes notes, not SBI. And every-fucking-body knows that. This just goes to show that you’re just being tiny little cogs in a system that makes nonsense go viral without even bothering to read things once.
  • What are std transactions? You give me money, I give you herpes? But wait, you wrote something on your note. Here, settle for a common cold.
  • Torn notes and soiled notes are legal tender as long as more than half of the note is still intact (unless it looks like the cut is deliberate). This extend to notes that have doodles on them, if they currency denomination is clearly visible. [3]
  • Rs. 2638 crore loss? If RBI has to discard a 500 Rs. note, it doesn’t mean India loses 500 Rs. It is replaced back in circulation, keeping the economy still at the same level. Yes, minting a note does cost more than the written value on it at times, but understand that when it is in circulation, it generates a lot more value in commodity and services than what is written on it. Rs. 2638cr is clearly a made up number.

Well, there are many more such posts out there, but here’s a simple guideline one just needs to follow:

  • None of these posts contain even a single citation. There is no link to an official page, an official statement or even a press article.
  • If the number of punctuation marks is more than the number of alphabets, it most probably is fake.
  • Lawmaking in India is process of due deliberation. People don’t just get up in the morning, brush their teeth, have breakfast and make a new law.
  • We have a thousand agencies in our country to stop the marketing of something that when touched will kill you with super lasers.
  • Google is your friend.

EDIT: Another chain email/post that was supposedly forward, as pointed out by reader Rohan Mudaliar regarding the Supreme’s Court decision that accident victims must be tended to without being barred by formalities. This does have merit to it, and is true. However, since I don’t have the actual chain email/post, I cannot point out what portions of it are true and what are not.

A petition was filed by an NGO worker, Pt. Parmanand Katara, [Pt.Parmananda Katara vs. Union of Indian] and the act that was passed reads:

Constitution of India, 1950: Article 21–Obligation on
the State to preserve life–Every doctor has professional
obligation to extend services to protect life–All Govern-
ment hospitals/Medical institutions to pro vide immediate
medical aid in all cases.
Indian Medical Council Act, 1860: Section 33–Indian
Medical Council/Code of Medical Ethics–Clauses 10 and
13–Obligation to sick–Patient not to be neglected–Court
emphasized necessity to provide immediate medical aid.
Practice and Procedure: Medical professional–Law courts
will not summon unless evidence is necessary–Should not be
made to wait and waste time unnecessarily.

The entire document was released by the Judicial department of our National Information Center, and is available here.

Here is the Chandigarh Traffic police’s page regarding the same: http://www.chandigarhtrafficpolice.org/helpingvictims.php

And the 201st report from the Law Commission of India regarding the same: http://lawcommissionofindia.nic.in/reports/rep201.pdf

A mighty congratulations to all the KWin developers

KWin, being my “gate” project to KDE and to the open source world, has a special place in my heart. I haven’t worked with the people who have been there with the project since it’s inception, but I have worked with the code they have written. I have had the privilege of working with Lubos Lunak and Martin Graesslin. After reading this article on Phoronix, which clearly shows the advanced and mature stage KWin is at, and the bleeding-edge performance it offers.

In recent times, Martin has been extremely active in including performance improvements, driver support, cleaning and coding the KWin effects and the KWin effects API. The amount of work he has put in has paid off which has clearly shown off in the Phoronix benchmarks. This goes out to… amazing stuff Martin.

At this point, I would also like to congratulate Thomas Lubking (Sorry, I could not find a relevant URL) for his countless patches to KWin. Every developer, Matthias Ettrich, Cristian Tibirna, Lubos Lunak, Daniel M. Duley and the contributors, amazing stuff people. My heart goes out to you :)

P.S: I sincerely apologize for any omissions in here, which are purely incidental.

Amarok, EtherMedia, SoK and moving on

I applied for GSoC again this year, and sadly, I did not get selected to work on Amarok for KDE. Quite disheartening, yes, but then, Bart Cerneels sends me an awesome email, inviting me to work with him on the project via SoK.

No money this time (not very happy about that), but I do get a t-shirt (quite happy about that) and above and beyond all, the feature I plan to implement in Amarok for my SoK tenure is a really exciting idea.

I call this feature ‘EtherMedia’, and an excerpt from my proposal:

EtherMedia is a proposed addition for the Amarok audio player which enables users to share or stream their media with other users via networks like Instant Messaging. EtherMedia is built with strict semantics in mind and follows a highly deterministic protocol. The term ‘highly deterministic’ is covered further in this document. While the main focus of sharing is via IM networks during an ongoing conversation, EtherMedia works on the principles of ‘Ethers’. An ‘Ether’ is any medium with which this stream can be shared. The scope of this project is limited to implementing the IM channel to a complete functional implementation, but keeping open the option for more channels to be devleoped in the future.

Hmm, quite bookish, one would say. Allow me to illustrate. Consider the following to scenarios, both being, again, an excerpt from my proposal:

Firstly, consider this typical scenario, where Aliya wants to share her media:

  1. Aliya logs in, selects a playlist and goes to Playlist > Share with EtherMedia.
  2. Once she has decided the playlist/files to share, she can select which all users can listen to her shared playlist. This ‘userlist’ will be the list of all the contacts she has on Kopete, GAIM or any of the clients accessible via Telepathy. If she wishes to share it with a few of her contacts privately, she can set a passkey and only the users with that password can listen to that shared playlist.
  3. She can also select if she just wants her current playing track to appear in her status, clicking on which her contacts can stream over the current playing track. Or the status could also be a custom title like, ‘Listen to my new Melodic Death Metal compilation’
  4. On the other side of the IM conversation, the users she has selected to share it with will see a new chat window open up (or within the same window, if one is already open) saying ‘Aliya wants to share ‘Melodic Death Metal compilation’ with you [Browse]‘.
  5. Users on the other end of the IM application can then access the media, browse the library, stream it etc.

Also, consider the case, when Aliya shares here entire Media Library with her contacts. Now, her contact Betty, can perform the following actions:

  1. In her Kopete window, she sees a new link come up, saying ‘Aliya wishes to share her Media Library with you. [Browse]‘
  2. She wishes to browse all the songs Aliya has by the artist ‘Sigur Ros’. So, using the available filter editor she says ‘All songs by Sigur Ros’. This is translated directly to ‘playlist:(artist:Sigur Ros)’ and is sent to amarok on Aliya’s computer.
  3. Since, Aliya has allowed Betty to view her entire Media Library, Betty can now browse and stream all the songs from Aliya’s Media Library by the artist ‘Sigur Ros’.
  4. Alternatively, Betty can also request for Aliya’s entire Media Library’s metadata (albeit partial). The reason this does not happen by default is because it is quite common to have 3000-4000 songs. An entire library’s metadata can easily run into MBs which is not very favorable for hosting from home-oriented internet conections.

The entire proposal from which I have taken this excerpts since I was too lazy to type out those descriptions again is available here

Thanks go out to Lydia, Bart and the entire KDE team, and a special mention, as always to Eike Hein, the crazy sysadmin.. thanks for getting my git running :)

Restore in progress [almost there]

The posts are there, but the images are all gone :(
Forgot to back them up, thought that the ‘Export’ operation would take care of it all. Should’ve guessed not when the dump was just a xml file of ~300 kb.

[EDIT]
Trying to get my pictures and the theme back.

[EDIT2]
Pictures are back. Now getting my theme back.

[EDIT3]
Got my pictures and themes back. Getting back settings and Google analytics tracking.

[EDIT4]
Almost everything is back again. A little settings to be tweaked here and there…

Adding to KWin::Scripting

The current state of KWin scripting is quite incomplete and there are a lot of objects yet to be wrapped. Over a period of time, I didn’t see any commits to the scripting directory. So, I just thought that maybe, it would be a fault on my part to have not given enough documentation and to a good extent this happens to be true. Also, Martin contacted me recently asking me to put in some docs. In this document, I would like to outline the process of adding more functions and objects to the KWin Scripting system and the architecture as it is. Note that this document does not cover coding with KWin or the Qt Script subsystem in detail. This only outlines the architecture used to implement scripting in KWin. So if you are inexperienced with the QtScript module or KWin coding, I cannot assure that this document will be of extreme help to you. To begin with, allow me to present a few pointers when working with KWin scripting:

  1. There are three kinds of objects:
    • Singleton: These objects cannot be instantiated. Only one object of that type exists and is provided throughout the scripting interface. In the current implementation, the workspace object is an example of a singleton.
    • Floating: These objects cannot be instantiated and neither are available throughout the scripting scope but are available only as parameters of various triggered functions or return values of various function calls. All objects of type ‘client‘ are floating.
    • Instantiable: Instances of these objects can be created and they may or may not manifest into actual KWin objects (some manifest purely into scripting objects). For example, a ClientGroup can be instantiated, and it also manifests into an actual KWin object i.e. KWin::ClientGroup. On the other hand, a QTimer is also instantiable, but it manifests into a scripting object only (also in an object on the C++ side), but not a KWin object.
  2. The ‘workspace‘ object is the primary source of all events and generally, this is from where one can start interacting with what happens within the window manager.
  3. Despite KWin::Client being a QObject, QObjects are never directly exposed to the scripting interface. This is largely in part due to the fact that not all methods are defined as Q_INVOKABLE and at the same time, there seems to be no rationale supporting any kind of reflections in a window manager. Also, this was the architecture lunak desired and it allows us to finely control what and what not is exposed to the scripting interface.
  4. All wrappers are available under the SWrapper namespace. For example, the wrapper of KWin::Client is SWrapper::Client present in scripting/client.(h|cpp).
  5. For every script that is running, we need a seperate QScriptEngine object. Every singleton object that is present needs to have a seperate instance of every singleton object as a QScriptValue is tightly binded to the QScriptEngine in question. In the beginning, I had a single QScriptEngine which I made to just test and focus more on wrapping the various objects. When I made the switch to multiple QScriptEngines, it caused the inclusion of advanced objects like the WorkspaceProxy, which I will cover later on.

With that in mind, let’s proceed on to the way events are handled and managed in the KWin scripting implementation.

Signals and Slots

KWin scripting uses the Qt signals-and-slot mechanism to handle all events. As an outline, let’s take the case of two objects KWin::ObjectA and SWrapper::ObjectA. As is obvious, SWrapper::ObjectA wraps KWin::ObjectA and exposes it to the scripting interface. Now, KWin::ObjectA has an event, ateBacon which is emitted whenever ObjectA eats bacon. Also, this ‘emit’ is conceptual, as in, there may or may not be an associated signal with it. In such a case, here’s how KWin scripting is built up:

  1. A new signal is created in KWin::ObjectA called s_ateBacon.
  2. A new slot is created in SWrapper::ObjectA called sl_ateBacon.
  3. The slot in SWrapper::ObjectA generally re-emits another slot for, ‘ateBacon’, which can be caught by the scripting interface. The need for doing so is that the parameters of KWin::ObjectA are QScriptValues. This is so because, while adding events, it was decided that adding signals could be done in a way that would facilitate further development also and not just cater to the needs of scripting alone. If there are any signals which do not pass any parameters, the sl_ateBacon is not created and ‘KWin::ObjectA::s_ateBacon’ connects directly to the ‘SWrapper::ObjectA::teBacon’ signal.
  4. As is obvious that these signal and slot are connected, the connection may be carried out in either way: the constructor of KWin::ObjectA may perform the connections in it’s constructor or SWrapper::ObjectA might do it in it’s constructor, but it is always done in either of the constructors.

It is difficult to perfectly outline how exactly the connection procedure is, as it is different for different objects depending on whether it is a singleton, floating or an instantiable object. In the following sections, as I cover different objects and their wrapping, I will cover this.

Currently, not present in the KWSApi.html, but still present in the apidocs.xml file (look in your svn checkout in the kwin/scripting directory) is the various signals and slots used for handling events. For example,

<event name="currentDesktopChanged" signal="currentDesktopChanged" wslot="sl_currentDesktopChanged" wsignal="currentDesktopChaned">

In the above, signal, i.e., ‘currentDesktopChanged’ refers to the signal emitted by the SWrapper::Workspace object. This signal is emitted from the wslot, i.e., ‘SWrapper::Workspace::sl_currentDesktopChanged’ which is connected to wsignal, i.e., ‘KWin::Workspace::currentDesktopChanged’. To further clarify, let me show you how this looks in code:

This is from KWin::Workspace::setCurrentDesktop. This function is called to switch to a new desktop. This is exactly the function we are looking for when it comes to having an event for notifying the change of the current desktop. In here, we emit our signal ‘KWin::Workspace::currentDesktopChanged’.

bool Workspace::setCurrentDesktop(int new_desktop) {
    // .....
    // .....
    emit currentDesktopChanged(old_desktop);
    return true;
}

Now, looking over at the SWrapper::Workspace class, let us first look at scripting/workspace.h:

public slots:
    void sl_desktopPresenceChanged(KWin::Client*, int);
        
signals:
    void currentDesktopChanged(QScriptValue);

The signal ‘currentDesktopChanged(QScriptValue)’ can be directly accessed by the scripting interface as the SWrapper object is directly wrapped as QObject. More on that later.

Not all the signals of a wrapper are connected to the signals of the objects they wrap. For example, the ‘clientMinimized’ signal is emitted from the ‘KWin::Client’ object but both ‘SWrapper::Workspace’ and ‘SWrapper::Client’ connect to it. In this particular case, a different approach is needed, i.e., with a proxy object, which we will cover in later sections.

With that covered, let’s move on to the first and a quite important class, the KWinScripting object.

The KWinScripting object

This is the object that when instantiated, loads all the scripts and the corresponding configuration files. Details of how scripts are loaded is provided here. KWinScripting is declared in scripting/scripting.(h|cpp). Another class declared here is the ‘KWin::Script’, which is pretty self-explanatory. It simply holds information about the script file, the configuration file and most importantly, a pointer to the ‘SWrapper::Workspace’ object that is provided for the script and the QScriptEngine* that it is associated with. Changes to a workspace object within a script are reflected across all instances across the script, but NOT across different scripts. For example, if I have two files scripta.js and scriptb.js,

scripta.js
----------
workspace.prototype.moreBacon = function() {
    getMoreBacon();
}

print(workspace.moreBacon);

scriptb.js
----------
print(typeof workspace.moreBacon);

In scripta.js, the output would be ‘function’, whereas in scriptb.js, the output would be ‘undefined’. This behaviour is quite important and hence each singleton needs to have a seperate wrapper object for each script that is loaded.

KWinScripting’s basic job is to load and run scripts and also manage a WorkspaceProxy object. Unlike other singletons, the WorkspaceProxy is declared xactly once and a single instance is enough for all scripts that are executed. More on WorkspaceProxy later, let’s take a look at what happens inside a WorkspaceProxy object.

script->workspace = new SWrapper::Workspace(script->engine);
 
(script->workspace)->attach(script->engine);
((script->engine)->globalObject()).setProperty("QTimer", constructTimerClass((script->engine)));
((script->engine)->globalObject()).setProperty("ClientGroup", SWrapper::ClientGroup::publishClientGroupClass((script->engine)));
((script->engine)->globalObject()).setProperty("chelate", KWin::Chelate::publishChelate(script->engine));
((script->engine)->globalObject()).setProperty("ch", KWin::Chelate::publishChelate(script->engine));

This is the code from ‘KWinScripting::runScript(KWin::Script*)’ method, which in essence takes a KWin::Script object and initializes the basic set of objects for the scripting environment. This is what is happening, line-by-line:

  1. First, we create a new workspace wrapper object and call it’s attach method to attach it to a given QScriptEngine. What attach does is sets the SWrapper::Workspace object as the global object of the given scripting engine.
  2. Once a global object has been set, we can add more objects to it. All other singletons and instantiables are added here.
  3. Whenever you are creating an instantiable or a singleton object, make sure that the wrapper has a static method that when passed a QScriptEngine* object, it would return a QScriptValue which is binded to the QScriptEngine object.
  4. In the above case, we add the QTimer, ClientGroup (instantiable) and the chelate (singleton) objects to the QScriptEngine’s global object.

Again an inspection into these static methods would clearly illustrate how this procedure goes along. KWinScripting also has a slot called ‘sigException’ which is connected to the QScriptEngine’s signalHandlerException, to handle and report users. The current implementation outputs the error name, message and line number to stdout.

QObject::connect((script->engine), SIGNAL(signalHandlerException(const QScriptValue&)), this, SLOT(sigException(const QScriptValue&)));

KWinScripting also has a start method, which is the function that handles loading and running of the scripts. It basically makes a list of scripts that can be run and then calls ‘KWinScripting::runScript’ for each of those scripts. One of the important things this must do is initialize the ‘SWrapper::Workspace’ object by doing ‘SWrapper::Workspace::initialize’. The method needs to be passed a pointer to the ‘KWin::Workspace’ object so that it can wrap it. ‘initialize’ is a static method, so it can be and is done without creating any instance of the ‘SWrapper::Workspace’ object yet.

The ‘SWrapper::Workspace’ object

The ‘SWrapper::Workspace’ object contains a member called ‘centralObject’, which is the very pointer to the KWin::Workspace object we previously initialized using the ‘SWrapper::Workspace::initialize’ method. A look at the declaration of SWrapper::Workspace would show a huge list of slots and signals. All the signals that are present are accessible from the scritping interface and they are what provide events to the script. The slots that are listed receive events from the main objects and then convert the parameters to QScriptValues and then pass them on to the corresponding signal. Let’s inspect the ‘clientMaximizeSet’ event:

public slots:
    void sl_clientMaximizeSet(KWin::Client*, QPair);
    
signals:
    void clientMaximizeSet(QScriptValue, QScriptValue);

And the slot is defined as:

void SWrapper::Workspace::sl_clientMaximizeSet(KWin::Client* client, QPair<bool, bool> param)
    {
    if(centralEngine == 0)
        {
        return;
        }
    else
        {
        // LABEL 1
        QScriptValue temp = centralEngine->newObject();
        temp.setProperty("v", centralEngine->toScriptValue(param.first));
        temp.setProperty("h", centralEngine->toScriptValue(param.second));
        emit clientMaximizeSet(centralEngine->toScriptValue(client), temp);
        }
    }

Here, ‘centralEngine’ is a pointer to a QScriptEngine object that is unique to every SWrapper::Workspace object, i.e., it provides the class with the QScriptEngine it is wrapping an object for. In this example, in the first 3 lines it creates an object which creates a JavaScript object with two members ‘v’ and ‘h’ which essentially tell which directions the window was maximized in. And finally, when the associated slot is emitted, it wraps the corresponding KWin::Client, i.e., the client which was maximized in a QScriptValue and emits the event, which can then be caught by the scripting interface. And important thing to not here is:

centralEngine->toScriptValue(client)

or more accurately,

centralEngine->toScriptValue<KWin::Client*>(client);

The conversion functions and code is provided in meta.(h|cpp) and we shall get to the scripting meta-system in the later sections.

Now, if we were to look inside the constructor of the ‘SWrapper::Workspace’ object, once could notice a lot of connections that are being made. Let me take two examples here:

SWrapper::WorkspaceProxy* proxy = SWrapper::WorkspaceProxy::instance();

QObject::connect(centralObject, SIGNAL(desktopPresenceChanged(KWin::Client*, int)),
    this, SLOT(sl_desktopPresenceChanged(KWin::Client*, int))
);
                        
QObject::connect(proxy, SIGNAL(clientFullScreenSet(KWin::Client*, bool, bool)),
    this, SLOT(sl_clientFullScreenSet(KWin::Client*, bool, bool))
);

In the first line, it asks for an instance of a WorkspaceProxy object, which can be used to make multiple-client-to-multiple-workspace connections. There are two ways of connections that are done here:

  1. Connecting to signals emitted by the ‘KWin::Workspace’ object itself.
  2. Connecting to signals emitted by other classes, like ‘KWin::Client’. When doing so, it is no big deal for singletons, but it becomes a different isse for floating and instantiable classes. To overcome this problem, the WorkspaceProxy was introduced.

Whenever connections of the second type are required, the corresponding signal of the proxy object is connected with the slot in the workspace object. In connections of the first type, the signals are emitted by the workspace object and are connected appropriately.

The attach function: The ‘SWrapper::Workspace::attach’ function is what finally exports the workspace object as a QScriptValue to the QScriptEngine.

The exporting of objects

All the objects in the ‘SWrapper’ namespace have a corresponding exporting function, or a publishing function, which basically returns a QScriptValue that is the wrapped object. SWrapper::Workspace acheives this through the attach method. A few other objects, like KWin::Client for example, achieves this through the SWrapper::Client::generate object. These methods are static for singleton, floating and instantaible objects an instantiated object is needed to call this method.

Within this exporting function, the wrapper is supposed to add the various methods needed. Also, the entire SWrapper object is also exported (i.e. it’s signals and slots) using the QScriptEngine::newQObject method. As an example, let’s take the case of the SWrapper::Client object. To make a QScriptValue of a KWin::Client object, one can simply call QScriptEngine::toScriptValue(client). Every KWin::Client maintains a QHash called ‘scriptCache’, which maps a given QScriptEngine* to a ClientResolution. A ClientResolution is simply a QPair of a SWrapper::Client* and a QScriptValue. What is essentially happening here, is that it maintains a list of all the wrappers that have been generated for a given QScriptEngine. And this is what SWrapper::KWin::generate does:

  1. Given the object, it first looks into the scriptCache to see if a value like this has already been generated. If it has been, the previously generated value is returned. In essence, a KWin::Client is wrapped exactly once and only a single QScriptValue exists for a given KWin::Client (for a script).
  2. If no such QScriptValue is found, it makes a call to SWrapper::Client::newWrapper, requesting that a KWin::Client object be wrapped. The newWrapper functions goes through three steps to return a QScriptValue, the details of which are documented in the file itself. Keeping that in mind, I would like to just skip to the 3rd part, where all the functions are added:
value.setProperty("caption", eng->newFunction(caption, 0), QScriptValue::Undeletable);
value.setProperty("close", eng->newFunction(close, 0), QScriptValue::Undeletable);
value.setProperty("resize", eng->newFunction(resize, 1), QScriptValue::Undeletable);
value.setProperty("move", eng->newFunction(move, 1), QScriptValue::Undeletable);

Simply put, this is where all the magic is added to the javascript objects. Let’s dissect a line here:

value.setProperty("caption", eng->newFunction(caption, 0), QScriptValue::Undeletable)

The first argument gives the name of the property that is being set, in this case ‘caption’. Then, it makes a call to QScriptEngine::newFunction(function, length). The function provided here is always a static function having the QScriptEngine::FunctionSignature signature. Please note that although even a global function would do, always make sure these functions are within the namespace of the SWrapper::Object. Let’s take the first function in question, i.e. ‘client.caption’.

Given a script, which does:

var x = workspace.getAllClients()[1];
print(x.caption());
  1. The getAllClients() method is called on the workspace object.
  2. The SWrapper::Workspace::getAllClients makes a list of all available clients and converts it to a list of QScriptValue’s which are wrapped Client objects.
  3. Then the variable ‘x’ is set to the second client in the list
  4. Then when x.caption() is called, the native function SWrapper::Client::caption is called, which again returns a QScriptValue which contains the caption of the given window i.e. ‘x’.

For further enquiry, let’s go into the caption function [native]:

QScriptValue SWrapper::Client::caption(QScriptContext* ctx, QScriptEngine* eng)
    {
    KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());

    if(central == 0)
        {
        return QScriptValue();
        }
    else
        {
        return eng->toScriptValue(central->caption());
        }
    }

Firstly, we extract the ‘thisObject’, which is nothing but a QScriptValue of the very object that SWrapper::Client::generate returned, and then we convert it to a KWin::Client object using the QScriptEngine::fromScriptValue<KWin::Client*>(client) method. This method also is facilitated in meta.(h|cpp). Once we have the object, we can simply read it’s caption and pass it back to the calling function. The return value of this function is a QScriptValue which is what the calling script gets on invocation.

Adding properties is also simple, you can read up the docs on Qt Assistant for that one.

The WorkspaceProxy object

Finally, we get to the mysterious WorkspaceProxy object. First, let me present the scenario:

  • Every script results in a new QScriptEngine. Every QScriptEngine needs a unique SWrapper::Workspace object for it.
  • There are 10 clients on the workspace, and every client (i.e. a KWin::Client) has a minimized signal.
  • Now every, client’s minimized signal must cause the clientMinimized in every workspace object to be emitted.

This brings about two problems:

  • Whenever a new client is added, all its slots must be connected to all existing SWrapper::Workspace object.
  • Whenever a new script is run during runtime, all existing clients must be established connections to.

Hence, the WorkspaceProxy object was introduced. What it does is,

  • Every client that is instantiated, connects it’s signals to the slots of WorkspaceProxy.
  • The WorkspaceProxy re-emits a similar signal.
  • All Workspace objects connects to the WorkspaceProxy’s signals.

Creating a WorkspaceProxy instance is simple. Let’s say there is a signal emitted from a client saying ‘sl_ateBacon’ and the signal to be re-emitted is ‘ateBacon’. Just add the declaration in the workspaceproxy.h file:

public slots:
    sl_ateBacon(KWin::Bacon*);

signals:
    ateBacon(KWin::Bacon*);

and in the workspaceproxy.cpp file, just add the following line in the constructor:

PROXYPASS1(ateBacon, KWin::Bacon*);

if ateBacon takes 2 or 3 parameters, one can use the macros PROXYPASS2 and PROXYPASS3. Also note that, since WorkspaceProxy is used to connect clients to a workspace, it will always carry a KWin::Client* parameter. This is not a hard and fast rule, but since there have been no functions without it, there is no macro definition for a signal-slot pair without parameters. Do feel free to add one on your own if the need arises.

Also do note that, the ‘sl_’ in front of the slot name is prefixed in front of the slot name automatically. So, whenever you are making slots, do follow the convention.

Coming in the next iteration: Handling inheritance (the KWin::Toplevel and the KWin::Client case), the scripting meta-system, publishing functions for instantiable classes.

A petition to stop the usage of lightboxes

Lightboxes are good. When you want a full view of an image when you click on a thumbnail, or you click on something for additional details as they keep one on the same page without any hassles of clicking the back button or closing a pop-up window. I either ways prefer pop-up windows (only when I intend to open them), sine I find myself working much faster with new tabs, but I am taking the general viewpoint here, of a much wider user base. I agree that most of the people would find the lightbox method much more comfortable. However, when I don’t intend to open a lightbox, please don’t. It is irritatingobstructive and  in many cases makes a website look like a website from 1995 offering a free PC Virus scan.

Some website show auto lightboxes when a user is redirected to a site from a Google web search. Here’s an example:

If you visit daniweb.com by typing it in your address bar, you won’t see it. Follow a google url and you will see it. When I see such a lightbox, I don’t feel like joining your ‘network’. I go back to my search results and select a different link.

Another annoying example of such auto-lightboxes is the one filled with ‘Tweet about me‘, ‘Like ME‘ widgets. I understand that your daddy issues resulting in attention-seeking behavior need to be tended, but an explicit (as explicit as literally begging others to ‘Like’ you) and desperate attempt at the same needs to be addressed, and not tended.

I also hate those little bars you have at the bottom of your pages. They are ugly, and make me claustrophobic. Facebook started it all and it was a good feature, and it still is. But it is apt for facebook. It allows the user to interact with other users and perform a lot of tasks which are the primary focus of the website. As for others:

I have nothing to add. As for my reasons as to why I hate these boxes:

  1. I do a lot of browsing from my mobile phone using the Opera Mini browser. The thing with Opera mini is that it attempts and does a very good of job of rendering websites meant for desktop browsers and not only the one for mobile browsers. It handles scripting also in a very creative manner. The scripts are handled on a proxy server (maintained by Opera) side and any triggered event causes the page to reload with a state in which the event has triggered. Hence any changes in the web page owing to script execution causes a page reload and occurs on a remote server and it sucks to have to do that just to close a big damn box. Furthermore sometimes the boxes are so huge, that in an attempt by Opera to place the layout properly, I am never able to get to the close button. The crappy bottom bar takes up 50-60% of the browser viewport on mobile devices. And due to the small width of the same, the crappy bar is never visible anyways.
  2. A very specific reference to a very specific browser on a somewhat specific platform may not give one the reason enough to hear my proposal. My other reason is that these lightboxes break the very fabric of web browsing. These lightboxes sometimes have stateful information in it and are like a web frame (developers read: iframe) in themselves. But there is no reload, no back/forward buttons. For quite a few cases it is highly desirable to atleast have a reload feature, but my only option to close the damn lightbox with a button in some place hidden by your awesome navigation research in the realm of Web 2.0.
  3. A Lightbox focuses ones attention to the point the website is not about: Unless ofcourse your intention is to introduce me to single women. And your ‘Social Networking integration’ lightboxes would have got swirlies in high school. And they literally focus ones attention by blacking out the rest of the page or some similar gimmick.
  4. The timespan of a user visit on a page is very very small. Especially if he/she comes redirected from a web search. I remember reading a blog post which said that Google tries to keep it’s interface very simple and compresses it’s HTML (to that point that a company so into standards sends an HTML file without a DOCTYPE) because they found that for a delay of every second in loading the page, the number of users who exited the search doubled.
  5. They are seriously, seriously, annoying.

So, if you are a user, please leave a comment below signing up for the cause and if you’re a developer and agree with me, then make a difference. If you don’t, I would love to listen to your side of the story.

I literally need you to understand that my ‘literally’ is figuratively literally

Here’s a common conversation I have:

Me: That thing literally killed me.
Some Douchebag: You mean ‘figuratively‘.

Yes. I mean figuratively. When you make such a remark you are either doubting my reincarnation abilities or my language. And although I haven’t perfected my reincarnation skills yet, my language is pretty much okay. For once let’s assume that I know what I am speaking. In that case, what I mean is ‘That thing figuratively literally killed me’. In this sentence, ‘literally’ is for emphasis. I use it as a substitute for ‘almost’. And many people do that. Ask anyone who misuses or mixes the words ‘figuratively’ and ‘literally’ and much more often that not, they know precisely what both words mean.

The problem is, with the world being so fascinating and all, most of thing are not as remarkable as they are when told in third person. For example:

Me: Dude, he was almost crying.
Dude: Hmm. Happens.

and,

Me: Dude, he was literally crying.
Dude: OMG! Are you serious?

Now, in most of the cases, ‘dude’ knows that ‘he’ was not actually crying. The context is enough to tell him that. And that’s just how I use literally. You might have a problem of me misleading the listener, but when I say ‘fuck you’, I don’t really want to have sexual intercourse with you. Over a period of time, the meaning has developed around the world and that’s the way it is today. Similarly, for quite a few people it is the same case with ‘literally’. Which is why I propose that people use an automatic ‘figuratively’ qualifier to every ‘literally’ I ever use.

Me: Dude, he was (figuratively) literally crying.

The reason I can’t just use ‘figuratively’ is that it raises a nerd alert. I mean, just think about it yourself.

Dude: I propose that our assembly of friends traverse to the nearest source of edible hydrocarbons and perform actions necessary for our metabolic activities.
Me: Dude, the burger there figuratively smells of rat pee.
Dude: Nerd.

Or on the other hand,

Me: Dude, I’m literally gonna fuck you up.
Dude: Just chill, dude. It’s no big deal.

imagine the other scenario,

Me: Dude, I’ll figuratively fuck you up.
Dude: Hahaha

In case I want to use literally in the real sense, this is what I’ll probably say:

Me: Dude, he actually cried.

Moreover, to make my case, I’ll supply explicit details of the incident lined with a few possible predictions from myself. Because when something actually happens, I don’t need to convince you that it happened. It did and the scenario is OMG-compatible. However, when something almost happens, I need to convince you that it was very very close to actually happening. And anyways, it’s not long before ‘literally’ is going to become cliche. So, till that time, just let me use it without those bastard grammar nazis literally mind fucking my figuratively literallys.

Write the ‘Given’

Back when I was in school, which would be around 3 years back, I remember this line being repeated in almost every class: ‘Write the “Given”‘. No, it wasn’t spoken to me by a mentor-figure, nor does it have any philosophical implications. The case is that, whenever we were solving any numerical problems in physics (I think “numerical problems” is the local colloquial language, it simply means the problems in which you were supposed to do calculations, use the various formulae in a more practical scenario), or chemistry or any other subject, we used to (or were supposed to) follow a particular format in which we used to first write the data that was a part of the question. This was labelled in a coloumn called ‘Given’. So, I’d write something like, ‘Given: velocity (v = 10 m/s, acceleration (a) = 4 m/s2, distance (s) = 12 m, time (t) = ?’. And then I go ahead with the calculation and the quest of finding out whatever it is I’m trying to find out.

The thing here is that, every step of the answer has a certain amount of marks allotted to it. Get that step right and you’ll get marks for it. So, even the ‘Given’ section had marks allotted to it. So if you would just write the variables directly from the question alongwith their values, you get marks for it. Even if you don’t write anything else, no calculations, not even a hint so as to how to proceed with the problem, you would get whatever few marks were there for the ‘Given’ section. And I must tell you, it was easily atleast 10-20% of the marks that should be given for a complete solution (In a 5 mark question, you would get 1/2 or even 1 mark for writing the ‘Given’). So our teachers always used to tell us, even if you don’t know how to solve the problem, or how to proceed with it, just ‘Write the “Given”‘, so that you don’t end up getting a complete zero for the problem. Sometimes, which was actually quite a lot of times, there were students who really used to struggle with some weird formulae, end up with an equation no one had seen before and eventually get the problem wrong. If you would glance at their ‘struggle’ though, what you would see is sheer ingenuity. The things I’ve seen my friends do, the way they have twisted the entire equation, the way they have played with the variables, is quite often amazing. Sometimes, students even try “hacks”. Sometimes, you know the answer you have to arrive at. For example, if the question is “Prove that f(x) simplifies to g(x)”. So when you start distilling f(x), you know where you have to get to. These hacks are again a fun thing to study and look at. From silly things like, changing the equation in between hoping the corrector wouldn’t notice, to completely modifying the entire equation (mathematically legally) and arriving at something altogether different. I wouldn’t go as far to say that “every time” I saw something like this I was completely filled with awe. But yeah, an occasional masterpiece always used to come up after every exam. Sometimes students used to get it right also, but whenever they were wrong, it was rarely a fault in the concept. It was usually a small mistake, like writing the wrong co-effecient in between lines or a calculation error or something, which was an actually acceptable consequence of high brain activity in a pretty tense situation. When trying the same approach in a much more relaxed environment, the answers were arrived at with little or no trouble. However, in the end, the student didn’t get full marks because not only was his/her answer “wrong”, but he/she was, apparently, ‘heading in the wrong direction’. Almost every time I’ve seen something that is a result of such pure ingenuity, I have seen them getting just 1 mark out of the 5. And that too only for ‘writing the “Given”‘. Do the problem right, get everything right, even do some amazing symbol flipping, but if you forget to ‘Write the “Given”‘, you get only 4 out of 5.

The issue here is clearly that no-brainer activities are being awarded and some real talent is being overlooked, but I am not really interested in talking about it. A lot of newspapers, magazines and talks have already covered that. The point here is that, we, as students all throughout have been taught to game the system. The system says, give marks for “Given”, so there you go. Just write something an grab that one mark you can get. Although there have been teachers you have not only appreciated the ingenuity I mentioned before, but even awarded it reasonably, and even they were against the idea of ‘giving marks for “Given”‘, they had to. If I write “Given”, I am entitled to those marks, and there’s nothing anyone can do about it. Now, that’s the system, that’s in place. Don’t protest, don’t make an issue, just game the system for now, and we will do wonders later.

This article actually popped up in my mind after reading Thomas Friedman’s articles, Do believe the hype and It’s morning in India in the NY post. In ‘Do believe the hype’, he talks about EKO finance, a company which creates a secure money transfer system for one of the poorest section of India. Again an idea that is a result of ingenuity, one could also ponder that this scheme monetizes on a very poor section of the society, who can’t even provide for themselves the very basic needs of livelihood. The thing in India is (I am from India, so I would know), monetization does not relate directly to ‘exploitation’. And by that, I don’t mean to say that, we’re all good people who take care of each other. Trust me, we are mostly far from that. But the mindset here is that no one accuses them of monetizing, or ‘exploiting’ the poor people. There is no social impedement when it comes to making a livelihood as long as it is legal and moral. The point here is that EKO ‘made it work’ and that is what drives this nation. “Making things work”. We don’t really need a lot of infrstructure to handle things on an everyday basis, a lot of work in India is still done on an ad-hoc basis. A lot of transactions happen just by one’s word.

Allow me to quote an incident that happened with my sister. She and her husband were stationed out of the nation (while still having Indian citizenship) in a developed country (pardon me for not naming the country, because I absolutely do not want the reader to have any bias or reason to believe that I’m comparing my nation against theirs). While there, my sister gave birth to my adorable neice and they were planned a visit to India to meet family and friends and mostly for the birth ceremony of the newborn. While at the airport, they were told that the cradle would not be allowed as hand baggage and neither could they put it in the cargo (I don’t remember for what reason), so they must allow the airport staff to send it to their home. After generating a receipt for the ‘package’ and taking their signatures, and all other credentials, the package was on its way. Or was it? Months passed and they never received it. They had to go through a lot of people and telephone calls to finally track back the cradle and get it back.

While flying back from Mumbai, they were greeted with same situation. A man, in a typical khadi dress, took out a piece of paper from his front pocket and scribbled their name and address on it and told them that the package would reach their homes. The piece of paper was not from a clip board, or a notepad. There was no proper receipt, no guarantee, no tracking numbers. Just one piece of paper with a complete stranger. And three days later, the cradle was delivered to their home.

The point here is not the failure in the former case. I would say they were just unlucky and it happens occasionally. My point here is that without any of the technology or infrastructure as in the former case, the man at the Mumbai airport managed to get the cradle to their home. Now such a system ain’t bullet proof and it is obviously prone to failures. But my only point is, we Indians are now used to a lack of infrastructre. And at the same time we hve faced the demands in terms of performance and service owing to an economic boom. We have found out ways to work it through, and this is one of the points I would like to add to Mr. Friedman’s 2 point-list in ‘It’s morning in India’: ‘Making it work’. I rarely understand social sciences, so I wouldn’t say this is a point where India leads over China or anything. It’s just that, it’s amazing at times the things people pull off. Even in urban areas, there is always a gap between desire and possession. And people overcome that gap (which mostly is not monetary, but rather the result of inadequate supply) in various ways. Gaming the system and just making it work.

Coming back to the whole “school” scenario, this is not a rant about the educational system. The Educational system here is mostly horrible, does not encourage new ideas, overlooks talents… to name a few problems. I could go on and on since I face these problems on a daily basis. The thing here is, even though talent is ‘overlooked’, it is not ‘supressed’. We don’t see things as a ‘part’ of life, we see it as stages of life that we must live through. We do not have a very strong emotional attachment to any such ‘stage’. Get through college, if it means slogging, slog it through. Accept the system and then work through it for your own benefit. This also explains the widespread corruption, because we accept corruption just as easily.

I can count on my finger tips the number of people who actually take pride in being an ‘engineer’. I can’t say about other fields, since I’m mostly not aware, but the truth is on an average, we do lack a lot of driving passion. People often criticize the people who finish their B. Tech. (equivalent of B.E.) and then eventually take up a job in some company’s upper management. Engineering teaches one to think systematically, gives one the edge of understanding everything as a huge system. This method of working can be used anywhere and it does make a difference. It’s not about engineering, it’s just about any knowledge can be put to good use. And we can do it, because that’s what we’ve seen since a long time.

Inadequacy is a huge problem here. Supply is not always enough for the vast population that this country houses. This is what has always fuelled people to find a way out. To find a way to bridge that gap. Just making it work. By gaming the system, by finding a way out, by writing the “Given”.