Well, yesterday was a really interesting day. So interesting that I only left my place to get some food. It was all research, programming and testing. Well, not all, but most of it. At the end of the day, I didn’t achieve what I was looking for, but did come up with a temporary solution. And as a result, I had only about 3 hours of sleep until now. I’m going to crash just after writing this blog post.
UPDATE : The post is no longer relevant since the issue mentioned in this post has been fixed in a kernel upgrade (i think 3.8.0-27), but still can be used as a reference on how to write a simple app indicator
Okay, flash back! I had installed Ubuntu 13.04 a while back, just after 2 days of it’s release on April 25th of this year. Anyways, the install went well, but many things that used to work on my 12.04 had broken in this release. Of course, this is a new release and I hoped that upcoming (kernel) updates would fix the problems, but after two months, my problems persisted. The most nagging of these problems were the “Dummy Output” sound problem and the lack of control over brightness. I had to use alsa force-reload every time on boot and it wasn’t nice. Funnily enough, the solution was very simple. I had never noticed this during my search for an answer to fix this problem, but I did yesterday. I just had to disable the Speech Dispatcher from running. /etc/defult/speech-dispatcher file and change RUN=yes to RUN=no .
Alright, so since the sound is fixed, we can come to the second problem, which is the lack of brightness control. I had encountered this problem before in 10.04 release years ago, but 12.04 worked perfectly out of the box. I never cared about it until now. I had to save my battery from draining out. And my eyes from getting blown up too. So, I started searching. And this continued for a few hours, trying to find if there’s some PPA or some work around that someone has already posted. I visited the Ubuntu IRC channel, and I must say hat they have been very helpful. Anyway, at the end of the day, the only thing I had in my hand was a command
# X is a number between 490 and 4882
echo X | sudo tee /sys/class/backlight/intel_backlight/brightness
So, anyway, I knew what I had to do to get it working. Ubuntu for some reason was using dell_backlight instead of intel_backlight. The first thing that came to my mind was writing an app in C++ and I did. I opened my QT Creator and made a small app that uses a slider and modifies the above said file. I set the values as said in this answer at Askubuntu. But that isn’t enough. I had to edit a file owned by root. So, either I had to change the group for the backlight file or make my app run as root. I had to search for different methods. Some said that setting the SUID bit does the trick, but unfortunately, it didn’t. Then I read about PAM (Pluggable Authentication Module), and got it running, but again, I encountered some problems. Finally, I had to opt for a very simple solution. Frankly, I didn’t like this much, but it was the simplest. Allow write access to the backlight file for all users. Yes. That’s right. I added the command
# Allow users to write to file
chmod 777 /sys/class/backlight/intel_backlight/brightness
to the /etc/rc.local file, since the permissions are reset on every boot. So, now, my little app worked. And by little, I mean, really little. The interface has nothing but a slider. Here’s a screenshot.
See, I wasn’t kidding when I said it’s really small. But then again, that’s all I wanted. But using this app was difficult. I would have to open it every time I needed to adjust brightness. So what’s the solution? An app indicator sounds good right. The best thing is that it is accessible. So I rushed to the Ubuntu Developers page for App Indicators which contains some nice examples. I borrowed the PyGTK example and built my indicator on top of it. Unfortunately, I couldn’t add a slider or a spinner widget as a menu item. I’m still searching for ways to do this. So the next best thing I could do was to add steps 1-10. I had to pre-define the brightness values for each step in a list. Anyways, once it was done, it looked like this.
I’m also thinking of making a configuration file to put the maximum and minimum values retrieved from the backlight file. But that is for another day. For now, here’s the source if you want. It’s pretty self explanatory and if it is not, it’s commented to give a little description.
# Authors: Rahul ES <firstname.lastname@example.org>
# Web : http://brokenbulb.site40.net/blog
# This program is free software: you can redistribute it and/or modify it
# under the terms of either or both of the following licenses:
# 1) the GNU Lesser General Public License version 3, as published by the
# Free Software Foundation; and/or
# 2) the GNU Lesser General Public License version 2.1, as published by
# the Free Software Foundation.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the applicable version of the GNU Lesser General Public
# License for more details.
# You should have received a copy of both the GNU Lesser General Public
# License version 3 and version 2.1 along with this program. If not, see
from gi.repository import Gtk
from gi.repository import AppIndicator3 as appindicator
#predefined brightness values
brightness = ['490' ,'978','1466','1954','2442','2930','3418','3906','4394','4882']
# create menu
menu = Gtk.Menu()
#update menu items to show the selected item
count = 1
# loop though menu items and mark the currently selected item
for item in menu.get_children():
if count == selected:
temp = '<%d>' % count
temp = ' %d ' % count
count = count + 1
# menu item response
def menuitem_response(w, buf):
# get the currently selected brightness index, by extracting the number from string
menuVal = re.findall(r'\d+',buf)
j = int(menuVal)
# open file and change the brightness value to selected
bFile = open("/sys/class/backlight/intel_backlight/brightness",'wb')
# call function to update the menu, passing currently selected index
if __name__ == "__main__":
ind = appindicator.Indicator.new (
#open file to get read current brightness value
oFile = open("/sys/class/backlight/intel_backlight/brightness",'r')
val = int(oFile.read())
bVal = str(val)
# create menu items
for i in range(10):
if str(brightness[i]) == bVal:
buf = "<%d>" % (i+1)
buf = " %d " % (i+1)
menu_items = Gtk.MenuItem(buf)
# connectmenu item up with a function
menu_items.connect("activate", menuitem_response, buf)
# show the items
Now, if you want this to work, you will have to do some things first. The first and foremost thing is to make the backlight file writable for regular users at every reboot. So add the the following line just above the exit 0 in the /etc/rc.local file.
chmod 777 /sys/class/backlight/intel_backlight/brightness
The next thing I did was to move my python source file to /usr/bin so that I don’t have to use the entire path to run it. Also, don’t forget to make the file executable.
mv indicate-brightness.py /usr/bin/indicate-brightness.py
sudo chmod +x /usr/bin/indicate-brightness.py
Finally, I added the file to my start-up applications (Just type “startup” in dash to get the Startup Applications window). Click Add and fill in the details. Screenshot