Thursday, February 21, 2008

Modify Ctrl-Alt-Del Keyboard Shortcut in Ubuntu

The Ubuntu desktop has a simple GUI to modify keyboard shortcuts, but I noticed that any changes to the Ctrl-Alt-Del key combination would not work. The problem was that no matter where I assigned the Ctrl-Alt-Del shortcut, it would always open the "Logout" menu. The workaround for this bug is typed out in this post.

1. Make sure to disable the "Log out" action from the Keyboard Shortcuts editor (System->Preferences->Keyboard Shortcuts), by highlighting the line and pressing the "Backspace" key.


2. Open the Configuration Editor (System Tools->Configuration Editor), and disable the metacity Ctrl-Alt-Del binding under /apps/metacity/global_keybindings. Do this by right-clicking the key with the Ctrl-Alt-Del binding (i.e "run_command_1") and selecting "Unset Key"


3. In the same window, go to the next folder /apps/metacity/keybinding_commands. Select the matching command from the previous step (i.e. "command_1") and unset the key in the same manor as step 2. Close the Configuration Editor.


4. Finally, go back to the Keyboard Shortcuts app, and now select the new action for Ctrl-Alt-Del. Everything should work as expected now.
.... Read more!

Saturday, February 9, 2008

Countdown Alarm

Recently I was looking for a "countdown alarm clock" in Linux and decided to write a Bash script to do the job. The goal was to allow the user to enter a target date and time, then display a clock with the remaining time. An example of the output is below.

Features:

  • Remaining time stays at top left corner of the screen and continuously updates.
  • Update!: Output time inserted in Xterm title bar.
  • Target time can be specified using natural language string. (i.e. Feb 21 5PM 2010)
  • Remaining time displayed in years, months, days, hours, minutes, and seconds remaining.
  • Year, month, and day output is optional depending on the length of the remaining time.
Implementation:

It might seem complicated to do this, but the Unix 'date' utility handles almost all of the program logic for us. For example, to convert a generic date string into the number of seconds from Jan 1st, 1970:
date -d "DATE STRING" +%s

The date command can then easily do the reverse operation, using the output of the first command, where "SECONDS" is number of seconds from Jan 1st, 1970:
date -d @SECONDS

Some screen drawing tricks were accomplished with special terminal escape commands. These are used to move the cursor out of the way, and clear the line before each update.

Code: countdown.sh
#!/bin/bash
BLINK=1
INPUT_DATE=$@
STOP=`date -d "$INPUT_DATE" +%s`
[ $? == 0 ] || exit -1

function print_time
{
   echo -ne "\033]0;$@\007"   # update window title
   echo -ne "$@"              # update terminal
}

clear

while [ 1 ]; do
   NOW=`date +%s`
   TIME=''
   
   if [ $STOP -gt $NOW ]; then
      REMAIN=$[ $STOP - $NOW ]

      YEAR=`date -u -d @$REMAIN +%Y`
      YEAR=$[ $YEAR - 1970 ]
      [ $YEAR -gt 0 ] && TIME="${TIME}$YEAR year"
      [ $YEAR -gt 1 ] && TIME="${TIME}s"
      [ $YEAR -gt 0 ] && TIME="${TIME}, "

      MONTH=`date -u -d @$REMAIN +%_m`
      MONTH=$[ $MONTH - 1 ]
      [ $MONTH -gt 0 ] && TIME="${TIME}$MONTH month"
      [ $MONTH -gt 1 ] && TIME="${TIME}s"
      [ $MONTH -gt 0 ] && TIME="${TIME}, "

      DAY=`date -u -d @$REMAIN +%_d`
      DAY=$[ $DAY - 1 ]
      [ $DAY -gt 0 ] && TIME="${TIME}$DAY day"
      [ $DAY -gt 1 ] && TIME="${TIME}s"
      [ $DAY -gt 0 ] && TIME="${TIME}, "

      TIME="${TIME}`date -u -d @$REMAIN +%T`"
      print_time $TIME
   else
      [ $BLINK -eq 1 ] && print_time "00:00:00"
      [ $BLINK -eq 0 ] && print_time ""
      BLINK=$[ $BLINK ^ 1 ]
   fi

   echo -ne "\e[s"            # save cursor position
   echo -ne "\e[1000;1000f"   # move cursor to bottom right of screen

   sleep 0.5 
   echo -ne "\e[u"   # restore cursor position
   echo -ne "\r"     # move cursor to start of line
   echo -ne "\e[0K"  # clear line
done

.... Read more!