Posted by: DanielRM | March 9, 2009

Opening files

Since I last posted almost a month ago now, promising to expand on my comment that one component had reached a semi-usable state, I have neglected to pay any attention to this blog other than occasionally thinking ‘yes, I really need to make that post’. Rest assured that I have not been quite so lax with bene itself.

One of the buzzwords of the moment, and what looks to be a movement with an increasing momentum within the open-source community (even stretching itself into the GNOME project), is that of the document-oriented desktop.

This is opposed to the traditional application-oriented desktop in which the program is the key. Application-oriented designs are the sort of thing developers would come up with; they’re constantly looking for ways to tweak things, so nothing should be hidden.

The focus of document-oriented desktops is to minimise the amount of conscious interaction between the user and the program in favour of leaving the user to simply get on with working with his documents. The theory is that it promotes greater usability and efficiency; the user doesn’t think of how to work with their program but instead how to work with their data. No longer does the user think of Evince or epdfview or Acrobat; they think of ‘a PDF viewer’.

Likewise there is increasingly an attempt to increase the dynamism of the desktop, with recognition that old static models just don’t cut it any more. Thus there is a move away from manual saving and undo/redo histories towards applying a revision control system to every document, with ‘milestones’ taking the place of the old save system. The aim is to minimise data loss and maximise workflow. Then there are many other potentially world-changing ideas; it really is a whole new paradigm.

I’m hoping that bene can take the best parts of these ideas. That’s the point, really.

The first component of bene I wrote was a shell script to open specific files using specific applications, part of a move towards a document-oriented environment. It really bothers me that I can’t choose to open just this file in Gnumeric, just this file in gedit.

I’m an A-Level student who makes notes for politics and physics using his laptop. I use ODT almost exclusively as my file format for these notes; however, I really don’t need the overhead of Openoffice.org Writer in politics lessons; I don’t need the power of OO.o just to make notes. So I use Abiword for politics notes.

But on the other hand, I do need the power of OO.o for physics lessons. I need embedded spreadsheets and diagrams and equations in my documents; Abiword can’t do all of this.

The problem is when we continue notes from previous lessons; I can’t just double-click a file in the file-browser when I’m in politics because Writer is set as the default application for opening .odt files. I find it quite frankly shocking that in the year 2009 we’re still unable to choose to open a specific file by default in a different application to other files of its type.

That’s the point then of this first bene module; to open a file using the specified application. It has very little error-handling at the moment, and the code’s not as clean or elegant as it could be. It’ll be improved though.

#!/bin/bash
## This script opens a file with the appropriate application, which might be different for some files than others, even of the same type. Thus one might want to open the vast majority of PNG images in an image viewer such as gthumb, but open photos from a wedding in the GIMP.

## Import necessary code
source core/bene-settings-manager.sh

## Assign the first argument to the command variable
command="$1"
## Assign the second argument to the file variable
file="$2"

## Create the config file if it does not exist
if [ ! -e $HOME/.bene/bene-applications ]; then
echo "Configuration file not found"
echo "Attempting to create file"
create_file="$HOME/.bene/bene-applications"
## Inherited from core/bene-settings-manager.sh
_create-config-file
fi

echo "$command"

_open-file () {
## Check to see if the file has been opened before; identify it by the inode number so it's not affected by changes in path
inode="`ls -i $file | cut -d " " -f 1`"
if [ ! `grep "$inode" ~/.bene/bene-applications | sed -e "s,${inode}|[^|]*,${inode},"` ]; then
echo "File has not been opened before, adding to config file"
echo "Choosing an application to open with"
_get-app
_set-file-new
fi

## Take the application for this file from the config file
application=`grep "$inode" ~/.bene/bene-applications | cut -d '|' -f 2`

## Launch the application for the file
echo "Opening $file with $application"
$application $file

## If the inode number should change when the application closes then update the inode entry in the config file
echo "Updating the inode number"
newinode="`ls -i $file | cut -d " " -f 1`"
sed -i -e "s,${inode}|[^|]*,${newinode}|${application}," "$HOME/.bene/bene-applications"

}

## Function to get the application to open a file with using Zenity GTK dialogs
_get-app () {
## Set the default application to be xdg-open so it's opened with a suitable application if a specific one isn't chosen
application="/usr/bin/xdg-open"
## Choose between opening with a specific application or the default
choice=`zenity --list --radiolist --text="What do you wish to open this file with?" --column Option --column Action 1 "Use the default application to open it" 0 "Open this file with a specific application"`

## Choose the application for this file if it was chosen to use a specific application
if echo $choice | grep "specific"; then
application=`zenity --entry --title="Choose application" --text="Please enter the path of the application you wish to open this file with.
Use '/usr/bin/xdg-open' if you wish to use the default application."`
fi
}

## Function to insert a new entry into the config file
_set-file-new () {
## Echo the file's inode number and the application, seperated by |, into the config file
echo "$inode|$application" >> "$HOME/.bene/bene-applications"
}

## Function to change the application associated with a file
_reset-file () {
inode="`ls -i $file | cut -d " " -f 1`"
echo "getting app"
_get-app
sed -i -e "s,${inode}|[^|]*,${inode}|${application}," "$HOME/.bene/bene-applications"
}

## Function to delete a file and app from the config file
_delete-file () {
inode="`ls -i $file | cut -d " " -f 1`"
sed -i -e "s,${inode}|[^|]*,," "$HOME/.bene/bene-applications"
sed -i -e '/^$/d' "$HOME/.bene/bene-applications"
}

if [ "$command" == "--open" ]; then
echo "Opening $file"
_open-file
elif [ "$command" == "--delete" ]; then
echo "Deleting $file's entry"
_delete-file
elif [ "$command" == "--reconfigure" ]; then
echo "Reconfiguring $file"
_reset-file
else
echo "Command not recognised"
exit
fi

exit

Posted by: DanielRM | March 9, 2009

Dependencies

Every desktop environment has dependencies, and we all hate managing them.
My intention is that bene itself should have as few dependencies as possible, and one way of achieving this is modularity. Make as many things optional as possible; if there’s a feature which it’s merely pleasant to have rather than essential to the spirit of bene then don’t make it required.
Currently bene offers very little of this, to be fair, but the impending rewrite will fix this. It’s a goal I’ve had in mind from the start and one I will keep.
bene’s dependency management, on the other hand, I like to think works well. In order to avoid the hell of catering for every package manager out there (at some point I will write modules for them, though; it’s an important feature on my todo list) at the moment it uses a directory of shell scripts, one for each dependency, to determine whether it’s there or not and also give important metadata about the dependency. This metadata needs expanding though.
This is the example script which would ideally be used as a base for all real dependencies. It’s not got execute permission, unlike the real ones; this prevents the settings manager from running it and finding out that the dependency ‘example’, which in this case is obviously not a real dependency, doesn’t exist.

#!/bin/bash
## Copy this file, modify it as needed and then make it executable to use it

depends_name="filename" ## The filename of the dependency
required="required" ##
custom_location="" ## If you know where the file should be or have a custom location for it then put it here

use_whereis="true" ## Set this to false if you don't wish to use whereis if your custom location fails
use_locate="true" ## Set this to false if you don't wish to use locate if both other methods fail
## locate will not be used if $required is not optional, no matter what $use_locate is

## An exit status of 0 means the dependency was found

## Attempt to find it in the custom location
if test -e "$custom_location"; then
echo "$required dependency $depends_name found"
exit 0
fi

## Attempt to find it using whereis
if [[ "$use_whereis" == "true" ]]; then
if whereis "$depends_name" | sed -e 's/'"$depends_name"'://' | sed -e /^$/d | grep "" > /dev/null; then
echo "$required dependency $depends_name found"
exit 0
fi
fi

## Last attempt to find the dependency with locate; high likelihood of false positives - don't use this for required dependencies!
if [[ "$use_locate" == "true" ]]; then
if [[ "$required" == "optional" ]]; then
locate "$depends_name" > /dev/null && echo "$required dependency $depends_name found" && exit 0
fi
fi

## If your dependency has been found then the script should not reach this far
echo "$required dependency $depends_name not found"
## If an exit value of 2 is returned then the calling program should abort as a non-optional dependency is missing
if [[ "$required" == "optional" ]]; then
exit 1
else
exit 2
fi

Posted by: DanielRM | March 8, 2009

The settings manager

Every environment, it seems, has a settings manager of some kind, and it’s my personal opinion that GNOME’s bloody irritating gnome-settings-daemon is practically a textbook on how not to do it.

With its tendency to monopolise a system in terms of setting wallpapers, screensavers and GTK themes it is bad enough, but what is worse is the way in which it does so.

There is little modularity of which I am aware; why can’t I make it call Nitrogen, my preferred wallpaper application, to set the wallpaper for example? Why can’t I set one GTK theme for some applications and another for other applications (an ability which comes in very useful when you want to use a dark theme, which most web browsers inherit very badly from)?

Why, especially, are so many GNOME applications programmed not to take some acceptable defaults, or rely on a backup config file, when they can’t find a running gnome-settings-daemon process, and instead will immediately and without asking launch it to destroy my wallpaper and carefully crafted balance of themes within my Openbox desktop?

Why isn’t changing my preferred panel easier, rather than relying on arcane gconf modification and .desktop entries? Isn’t part of the aim of GNOME to be simple?

I suppose my frustrations boil down to the question of why, in short, can’t GNOME be less of an arrogant pig when it comes to my environment and actually allow some flexibility in the applications used?

Don’t get me wrong; on the whole I like GNOME. It’s certainly more elegant than most of the credible alternatives; xfce to my mind is crippled and KDE looks like someone let a tasteless and flamboyant three year old loose with plasticine and glitter. If I were feeling generous I might call it avant-garde.

I want to avoid making the same mistakes in bene. There will be a settings manager, but it won’t run all the time; I don’t see any need for it to do so.  Instead any applications which need to read a setting can source it by running the settings manager when needed; there should be no need to run any component of bene longer than it’s needed.

In addition, bene should be flexible. It already shows some flexibility merely in in the existence of its file opening script, which is soon to be rewritten to have an even greater amount of flexibility in addition to functionality.

At the moment the settings manager’s main role is to handle dependencies and define some generic functions for other components. It’s very incomplete, largely because I didn’t plan it; I’m going to rewrite it and expand it in future however. The main reason for this post, to be honest, was so that the later post on the open-file script would be useful, as the open-file script sources the settings manager.

#!/bin/bash
echo "SM - Hello from the settings manager" ## Check for dependencies
echo "SM - Checking for dependencies"
for file in `ls core/dependencies/*.sh`
do
if [[ ! "$file" == "core/dependencies/example.sh" ]]; then
$file
if [ $? -eq 2 ]; then
## A required dependency was not found; exit
exit 1
fi
fi
done ## Check for config directory
if [ ! -e "$HOME/.bene/" ]; then
mkdir "$HOME/.bene"
fi ## Define function to create config files; only to be used by scripts sourcing this one
_create-config-file () {
if [ `touch "$create_file"` ]; then
echo "SM:$FUNCNAME - File not created, exiting script"
exit 1
else
echo "SM:$FUNCNAME - File created successfully"
fi
}

Posted by: DanielRM | February 13, 2009

Hello world!

Apologies if this post is a bit disjointed. I’m slightly unsure about what the content should be at the moment.

I first announced the bene project in the #ubuntu-uk channel on the Freenode IRC network as ‘hopefully fun, likely naive, certainly unnecessary and, more likely than not, already doomed before it begins.’

The first three are almost certainly still the same. The last… well, the project has begun, and the first component has reached a semi-usable state (more about that later). It was then wrong to say it was doomed before it began.

It still has time to become so, of course. Ah well.

What is bene, then?

This is quite a good question. When I announced it on IRC I described it as a desktop environment, and certainly that’s the objective – to create a lightweight, functional and above all modern desktop environment.

I’ve seen a thousand and one brilliant ideas for the future of the Linux desktop experience on these here Intertubes, and so far I’ve not really seen any implemented. I’ve also had a few ideas myself which I’ve not seen implemented, and which I don’t expect to see implemented because I can’t code the patches myself.

Ideally bene should be lighter than GNOME and at most only slightly heavier than Xfce, but with the functionality that people have come to expect of modern environments.

A great problem here, I feel, will be maintaining this slimness while forging ahead with the innovations I hope that bene will.

One phrase can summarise the idea that should lie at the heart of bene, and that is ‘paradigm shift’. bene should perpetually be pushing the frontiers of technology, attempting to keep one step ahead of everyone else. And this causes problems in that we cannot build on the efficiencies of the past; we can’t reuse code which hasn’t been written.

At some point I’ll make a list of components which should be the baseline for bene to be considered a ‘minimal’ environment; in the meantime feel free to make suggestions.

Categories

Follow

Get every new post delivered to your Inbox.