Timer Applet 2.1.2

•February 27, 2009 • 1 Comment

Timer Applet 2.1.2 is another minor release that fixes an incompatibility with the latest version of the notification daemon.

Timer Applet 2.1.1

•February 15, 2009 • 4 Comments

The 2.1.1 release works around an API-breaking change in the version of libnotify used in Fedora 10.

Timer Applet 2.1

•February 2, 2009 • 2 Comments

Timer Applet 2.1 is now available. This release includes a bunch of bug fixes, updated localizations, and a couple major changes:

  • Time transposition (based on a patch by Matt Corks). Example: 62.5 in the “Minutes” field will now be converted to 1 hour, 2 minutes, 30 seconds.
  • GStreamer for playing sounds (patch from Philipp Kern)

cron/anacron not running your script?

•January 8, 2009 • Comments Off

If you dropped a script into one of the /etc/cron.* directories, but it isn’t being run, try this in a terminal:

run-parts –test /etc/cron.daily
(replacing ‘/etc/cron.daily’ with whichever actual folder contains your script)

This will list the scripts that cron or anacron would run (the –test option tells it to show, but not actually execute, the scripts). Your script should appear in the output listing. If it doesn’t, verify that:

  1. your script is executable, and
  2. the name of the script has only letters, digits, underscores, and hyphens

#1 is easy to understand, but let me explain #2. By default (at least on Ubuntu), /etc/crontab and /etc/anacrontab are setup to execute the contents of the /etc/cron.* directories using a command like this:

run-parts –report /etc/cron.daily

but according to the run-parts man page:

If  neither the –lsbsysinit option nor the –regex option is given then the names must consist entirely of upper and lower case letters, digits, underscores, and hyphens.

This means that run-parts will just ignore scripts that are not named properly!

Editing code with gedit

•December 24, 2008 • Comments Off

gedit is a nice text editor, but with its plugin system it can also make a great code editor. These are my customizations for editing code (mainly Python) in gedit:

Preferences

  • Display line numbers
  • Highlight current line
  • Display right margin (so I know when I’m putting too much on one line)
  • Enable automatic indentation

Plugins

  • File Browser Pane (included) – Sidebar for browsing and opening files
  • Indent Lines (included) – Indent/unindent selected text
  • Snippets (included) – Expand abbreviations to snippets of boilerplate text.
  • Code Comment (gedit-plugins) – Comment/uncomment selected text
  • Draw Spaces (gedit-plugins) – Show tab and space characters
  • Smart Spaces (gedit-plugins) – When using spaces for indentation, this lets you unindent by pressing backspace once, rather than pressing it as many times as the number of spaces you use for one level of indentation.
  • completion – Auto-complete words
  • snapopen – Quickly open files using regex
  • autotab – Detect whether the tab key should insert a tab or spaces, based on what’s being used for indentation in the rest of the file

For Ubuntu, I’ve noted the plugins that are included with the standard gedit installation and the ones that come as part of the ‘gedit-plugins’ package. You can also go to the gedit Plugins page to see what other plugins are available.

ATI fglrx Dual Monitor and No Video Flicker!

•December 23, 2008 • Comments Off
I finally have an xorg.conf file gives me a dual-monitor desktop and
flicker-free video playback while Compiz is enabled. Here’s my setup:
  • Ubuntu 8.10 “Intrepid Ibex”
  • Driver: fglrx
  • Compiz Visual Effects enabled
  • Primary LCD monitor: 1680×1050 resolution
  • Secondary LCD monitor (positioned to the right of the primary monitor): 1024×768 resolution

The following is the contents of my xorg.conf file (most of the important stuff is in the “Device” section). Hopefully others with similar setups will find this useful:

Section “Monitor”
Identifier “Configured Monitor”
EndSection

Section “Screen”
Identifier “Default Screen”
Monitor “Configured Monitor”
Device “Configured Video Device”
DefaultDepth 24
EndSection

Section “Module”
Load “glx”
Disable “dri2″
EndSection

Section “Device”
Identifier “Configured Video Device”
Driver “fglrx”

# Fix video flickering when Compiz is enabled.
Option “TexturedVideo” “off”

# Comment out the following line if you want to mirror the primary monitor instead of extend it.
Option “DesktopSetup” “horizontal”

Option “ForceMonitors” “lvds,crt2″
EndSection

Update: I forgot to mention a couple things:

  • I’m using the version of fglrx provided by envyng.
  • After updating the xorg.conf file, I had to open up the “Screen Resolution” settings panel and change the “Resolution” drop-down menu from “1680 x 1050 (16:10)” to “3360 x 1050″.

Watchable Monad in Python

•July 21, 2007 • Comments Off

Dan has an interesting new post about monads. I was still a bit fuzzy about the concept after reading the post, so he recommended that I rewrite the “watchable” monad in Python. Here it is:

# * Monad structure:#    (((func1, state1), (func2, state2), (funcN, stateN)), watched_val)## * Watcher function signature:#    watcher_func(state, prev_watched_val)#      state will be equal to None on the first call

def make_watchable(watched_val):   return ((), watched_val)

def join_watchable(watchable):   outer_watchers = watchable[0]   inner_watchers = watchable[1][0]   inner_value = watchable[1][1]   return (outer_watchers + tuple([watcher for watcher in inner_watchers if watcher not in outer_watchers]),           inner_value)

def wrap_func_for_watchable(orig_func):   def make_updated_watchers(watchers, prev_val):       return tuple([(watcher_func, watcher_func(state, prev_val)) for watcher_func, state in watchers])   return lambda watchable: (make_updated_watchers(watchable[0], watchable[1]),                             orig_func(watchable[1]))

def add_watcher(watchable, watcher_func):   return join_watchable((((watcher_func, None),), watchable))

# Sample watcher functions

def count_modifications_watcher(state, prev_val):if state == None:   return 1else:   return state + 1

def track_history_watcher(state, prev_val):if state == None:   return (prev_val,)else:   return state + (prev_val,)

# Usage

>>> increment_watchable = wrap_func_for_watchable(lambda x: x + 1)>>> double_watchable = wrap_func_for_watchable(lambda x: 2 * x)>>> watched_zero = add_watcher(add_watcher(make_watchable(0), count_modifications_watcher), track_history_watcher)>>> >>> increment_watchable(watched_zero)(((<function track_history_watcher at 0xb7dd84c4>, (0,)), (<function count_modifications_watcher at 0xb7dd848c>, 1)), 1)>>> watched_two = increment_watchable(increment_watchable(watched_zero))>>> increment_watchable(double_watchable(watched_two))(((<function track_history_watcher at 0xb7dd84c4>, (0, 1, 2, 4)), (<function count_modifications_watcher at 0xb7dd848c>, 4)), 5)

Reading up a bit also helps. I found Wikipedia to be a good reference:
http://en.wikipedia.org/wiki/Monads_in_functional_programming

Dan also recommends this:
http://www.cs.toronto.edu/~sme/presentations/cat101.pdf

Carefully reviewing the Lisp examples and reading the above two links made a second reading of his post much more understandable for me.

Reading Lisp again was also strangely refreshing, but we definitely need some kind of in-browser paren matching. Maybe there’s some JavaScript magic somewhere? But even if such as thing existed, I doubt you’d be able to get it to work in WordPress. Oh well. Thanks for another excellent post Dan!

GObject Memory Management Conventions

•July 4, 2007 • Comments Off

Reference counting is a fairly simple memory management concept: increment the reference count of an object you want to keep and decrement the reference count when you don’t need the object anymore. In GObject, you use g_object_ref() to increment and g_object_unref() to decrement the reference count of an object (GObject also has the concept of floating references that complicates things a little, but it’s still pretty easy to understand. I’ll just ignore floating references for now, but if you want to learn more about whether they’re necessary or why they’re in GObject, this is an interesting thread to read through). But just understanding the mechanics of reference counting isn’t enough if you want to effectively use a reference-counted API. You really want to understand the memory management conventions of the API so that you know when you actually “own” an object.

While working on some GObject-derived classes, I started to wonder if I was incrementing and decrementing reference counts at the correct times. I was confused by the fact that the g_value_get_object() method would return an object reference (the caller is not responsible for decrementing the reference count), but g_object_get() would return an object copy (the caller is responsible for decrementing the reference count). Reference counting APIs usually rely on naming conventions to indicate whether the caller will receive a reference or a copy, so I expected some standard behavior for “get” methods. Judging by other methods I’ve used in the GObject API, it looks like “get” methods should return object references rather than copies. It worried me that one of the most-used “get” methods in GObject, g_object_get(), has behavior inconsistent with that convention. After a bit of searching, I finally stumbled upon a few nuggets of information. The first post highlights some of the naming inconsistencies I encountered. The reply to that message explains that conventions were proposed a while ago but were never formally adopted, and he also links to the proposed conventions for reference.

Although I’m sure some attempt is made at maintaining consistency in function naming and reference counting semantics in GObject and related APIs, I really hoped that there was a formal set of guidelines that API developers could follow and that API users could refer to. It really is a annoying to have to either refer to the docs or browse the source code to figure out if a particular method’s return value must be unreferenced. Using naming conventions would not only make GObject-based APIs both individually consistent and consistent among each other, but it would also let developers know the exact reference counting behavior of a method just by looking at its name. I remember reading over some of Apple’s API docs, and both Core Foundation and Cocoa have a standard set of memory management guidelines. Something similar for GObject would be very nice.

The Return to C and GObject

•July 2, 2007 • 2 Comments

Lately I’ve been playing around with the GObject system in C again. Mostly because I want to better understand how it works. I dabbled a bit with creating GObject-derived classes when I was working on the C version of Timer Applet, but soon after I took a break from C to port Timer Applet to Python, so I didn’t really get very deeply into it. (Update: I realized this is a bit unclear. Technically I’m still using GObject through the Python bindings, but I wanted to learn more about the native C API for GObject because that is what GTK+ and GNOME are written in, and it’s just interesting to see how OO can be done in C).

So now I’m back in C. First of all, welcome back type declarations. :) I like the self-documenting nature of type declarations, especially in function/method arguments. It makes it much easier to understand how a particular function is used. Sometimes when reading other people’s Python code, I would have to follow call chains in reverse (by grepping through the source files for the function names) in order to figure out what the types of the arguments ultimately were (if there is smarter way to do this, please let me know). You could probably argue that this would not be a problem with better documentation, but why rely on someone to voluntarily document something when you can have strict enforcement by the compiler? I still like Python though. It’s just a different beast compared to C and has many advantages of its own.

A big annoyance about going back to C has been header files! After working with higher-level languages like C# or Python, having to create and maintain header files is just horrible. Why do I have to change two files whenever I want to add or remove a method or change a method’s signature?? But I wanted to learn GObject, and GObject is written in C, so let’s move on. :)

From my experience so far, creating new GObject-derived classes is a bit tedious in C (which I guess is to be expected), but it’s not too bad once you get used to it. You encounter a lot of friction in the beginning. It’s very difficult to stay on track and get anything useful done because you’re constantly trying to figure out how to create things like signals and properties. But once you get the hang of things, all that boilerplate code becomes understandable and almost second nature. Overall, it’s been a good learning experience. It’s nice to better understand the foundation on which GNOME is built.

Timer Applet 2.0

•April 27, 2007 • 15 Comments

Update: Fixed layout of example code.

So…first blog entry. :) Let’s get to the good stuff: Timer Applet 2.0!

I’m really excited about this release because it brings some extra polish that I’ve been meaning to add for a long time. I’ve re-written the entire applet in Python, so there are definitely some drastic under-the-hood changes, but let’s talk about the user-visible changes.

Here’s a quick overview:

  • New icon
  • Countdown animation with a “pie” meter
  • One-click selection of timer presets
  • Streamlined saving of new presets
  • Cleaner first-time experience with the Start Timer dialog
  • After a timer finishes, periodically redisplay the notification bubble until the user stops the timer
  • GConf option for notification beep using internal speakers (this needs verification)
  • D-Bus API

New Icon
I’m no artist, but I tried my best to make something decent. I think it’s at least an improvement over the old one. :)

timer-applet-logo-old-no-alphatimer-applet-logo-no-alpha
old icon vs. new icon

Countdown Animation
A running timer will now show a “pie” meter that will indicate how much time is remaining.

timer-running-showing-time

One-Click Presets
Previously, if you wanted to load a preset in the Start Timer dialog, you would have to double-click a preset or highlight it and click ‘Load Selected Preset’. Now, each item in the list of presets is a button that you can just click once to load the preset. Fewer clicks and we no longer need that ‘Load Selected Preset’ button cluttering up the dialog.

start-timer-dialog-oldstart-timer-dialog
old vs new Start Timer dialog

Streamlined Saving of Presets
The most common thing you would probably need to do in the Start Timer dialog is create a preset, so now there’s a ‘Save as Preset’ button that will create a preset out of the duration and name that you currently have entered in the fields. You can now create a preset from the comfort of the Start Timer dialog. The ‘Add’, ‘Edit’, and ‘Delete’ buttons have been replaced with a ‘Manage Presets’ button that will take you to the Manage Presets dialog, where you get access to all of the preset management options.

Cleaner First-Time Experience
A brand-new user, with no presets, will see a simplified Start Timer dialog without the presets list (if there are no presets, then why show it, right?). The list of presets will only appear if there is at least one preset.

start-timer-dialog-first-time

Periodic Redisplay of Notification Bubble
After a timer finishes, the notification bubble will keep reappearing until you click on the button to stop the timer. This is just another way to remind the user that the timer has finished, in addition to the blinking timer. BTW, the blinking happens faster now, so that it’s more noticeable.

Internal Speaker Beep
I’ve added a GConf setting for making your internal PC speaker beep when a timer finishes. Since this probably won’t be used by many people, I chose not to expose it in the UI. My computer doesn’t have an internal speaker though, so I haven’t been able to test this feature. Please give it a try and let me know if it works. :) You can find the GConf key here:

/apps/panel/applet_*/prefs/play_beep

where * is some integer. It’s up to you to figure out which GConf entry corresponds to your current instance of Timer Applet. :) Or you can use the D-Bus API to figure it out….

D-Bus API
You can now use D-Bus to get the list of timer IDs (an ID looks like ‘applet_*’, where * is some integer; this is the same as the applet’s GConf key). With the timer ID, you can get the corresponding Timer object and use it to start, pause/continue, or stop a Timer Applet instance.

Here’s some sample code:

#!/usr/bin/env python

import dbus

bus = dbus.SessionBus()timer_manager = bus.get_object('net.sourceforge.timerapplet.TimerApplet',                               '/net/sourceforge/timerapplet/TimerApplet/TimerManager')timer_id_list = timer_manager.GetTimerIDList()if len(timer_id_list) > 0:    first_timer_id = timer_id_list[0]    print 'Starting timer with ID: %s' % first_timer_id

    timer = bus.get_object('net.sourceforge.timerapplet.TimerApplet',                           '/net/sourceforge/timerapplet/TimerApplet/Timers/' + first_timer_id)

    # Start() takes: name, hours, minutes, seconds    # Name can be an empty string.    timer.Start('Laundry', 0, 45, 0)else:    print 'There are no Timer Applets in the panel.'

The TimerManager has only one method: GetTimerIDList().

Each Timer has these methods:

  • Start(name, hours, minutes, seconds)
  • PauseContinue()
  • Stop()

I tried to keep the API as simple as possible, so if it doesn’t meet your needs, let me know and I’ll try to work something out.

Phew, that was my first post. Done. :)