Wednesday, 7 October 2009

How about C# applets in Awn?

Recently I've been trying to make mono bindings for libawn, and I can say that this effort was successful and we have now experimental mono bindings. But since the bindings are very new, and there aren't any "real" applets written in C#, only a very limited subset of the functionality was tested, the bindings won't be part of the 0.4 release (though even the official Awn will support executing mono applets), but this should change for the next release (0.6).

Also one major issue is properly integrating the binding generation into our build system, so if there's any autotools guru, who'd like to help out, please feel free to take a look at it ;)

Of course you can find the mono-bindings branch on Launchpad > https://code.launchpad.net/~awn-core/awn/0.4-mono-bindings

This is how you can build the bindings:
  • get the above mentioned branch
  • if you don't have Awn 0.4 installed run `./autogen.sh && make && sudo make install`, otherwise you can skip this
  • `cd bindings/mono` and...
  • since the mono bindings have their own build system run `./autogen.sh`
  • if autogen spits any errors, you'll need to make it happy - install gapi stuff (gtk-sharp2-gapi package) etc.
  • now you need to `make -C sources api`
  • once the API xml files are generated (courtesy of previous step) you can just run `make && sudo make install`
If you get "Cannot open assembly '/usr/lib/mono/1.0/mcs.exe': No such file or directory." during the last make (as I do on Ubuntu 9.04) run `./configure CSC=/usr/bin/gmcs` (in the bindings/mono directory) and then repeat the last step.

Depending on what install prefix you used you might need to tell mono where to look for the libawn-sharp.dll file - if you used /usr/local as install prefix (which is the default) you will need to run Awn with `MONO_GAC_PREFIX=/usr/local/ avant-window-navigator`, otherwise you'll get an error like this when a mono applet is executed:
WARNING **: Could not load file or assembly 'libawn-sharp, Version=0.3.9.0, Culture=neutral, PublicKeyToken=c58bb20247732067' or one of its dependencies.

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'libawn-sharp, Version=0.3.9.0, Culture=neutral, PublicKeyToken=c58bb20247732067' or one of its dependencies.
File name: 'libawn-sharp, Version=0.3.9.0, Culture=neutral, PublicKeyToken=c58bb20247732067'

Now you're ready to hack Awn applets in C# (be sure to take a look at applets/unmaintained/mono-test in awn-extras branch for a small inspiration how to start). And now I have to show you this cool screenshot, which just shows Awn running 1 C applet, 4 python applets, 1 Vala applet and a mono applet:
Doesn't it look cool?

Sunday, 20 September 2009

New Awn background: Floaty!

Today I decided to take a stab at implementing new background style for Awn, it's pretty similar to "flat" background - code- and also look-wise, so it was pretty easy to do it.
Hopefully this will make more people happy, as this feature was requested a couple of times on our bug tracker.

Anyway kudos to wbar quys, cause it seems they had a background like this in their dock first.

And of course an obligatory screenshot:


And here's another screenshot of how it looks on the desktop:

Saturday, 25 July 2009

Recommended changes for 0.4 applets

As you may and may not have noticed, a couple of signals were recently added to both AwnIcon and AwnAppletSimple. These are "clicked", "long-press" and "context-menu-popup".

I think it's pretty clear what these do - you no longer need to connect to "button-press-event" (though you can), and switch through event.button, but that's not all. As h4writer (one of our core devs) mentioned some time ago, there are inconsistencies in clicking on the icons. Basically, in the past all applets did an action on the button press - as opposed to button release, which is common for button-type widgets. The clicked signal sorts out this inconsistency and fires when the icon gets the actual button-release event (meanwhile checking if it also got the button-press).
But that's still not all, if you use the clicked signal, you'll actually see that there's a subtle animation - the icon glows slightly while it's depressed - yay for eye-candy!

This way I'd like to appeal to you to make this simple transition in your applets, so that all 0.4 applets use the clicked signal instead of button-press-event.

As for the "context-menu-popup" signal, applets were doing this correctly - because popup menu is supposed to popup on the actual button-press, but it was added anyway for your convenience.

The last of the new signals long-press was added primarily because of taskmanager needs and gets emitted a second after button-press event (if there was no button-release meanwhile). Please don't use this forcefully, it is far from obvious that there can be an action on long-press.

Sunday, 28 June 2009

Migrating applets to Awn 0.4

Since we're trying really hard to get Awn 0.4 into a usable state with all the glory and most of the applets we had in the previous releases, I'll try to describe the important changes that happened in the API, so it's easier to convert existing applets to work in 0.4. Please note that if you were using onox's awnlib, the conversion should be painless, because it wraps libawn API and therefore applets did not need to be modified (but I might be wrong, onox will know better).

If you're interested in an article about how to write an actual applet from the beggining, I do plan to write that too, so check back later.
I also plan to write an article about the completely new functions/methods/classes, so you'll have to wait for that a bit as well.

Note that for the sake of simplicity I'll be using pythonish syntax, even though I mostly write C code, so here and there the class names etc. might more resemble C.

So here is a quick list of the most important changes:
  1. AwnApplet was completely revamped - now its base class is GtkPlug (as opposed to GtkEventBox) and it handles connecting to main Awn process, sending signals to whoever is interested, etc.
  2. therefore AwnPlug died.
  3. many (if not all) of AwnAppletSimple's methods were renamed.
  4. AwnAppletDialog is now AwnDialog.
  5. AwnTitle got also renamed to AwnTooltip.
  6. the job of AwnIcons now handles AwnThemedIcon (which is part of AppletSimple).
And now to show you some actual code, I'll help myself by looking at the modifications that were needed to get media-control applet to work in 0.4 (thank you `bzr diff` for making this easy):

I'll start with the AwnApplet(Simple) constructor. In 0.2 (note that I use 0.2 for Awn versions 0.2.x and 0.3.x, since the API was pretty much the same) you'd have:
class MyApplet(awn.AppletSimple):
def __init__(self, uid, orient, height):
awn.AppletSimple.__init__(self, uid, orient, height)
# do stuff

# creating an instance looked like this
if __name__ == '__main__':
awn.init (sys.argv[1:])
applet = MyApplet(awn.uid, awn.orient, awn.height)
# ...
This will now be:
class MyApplet(awn.AppletSimple):
def __init__(self, uid, panel_id):
# of course you can pass also the "applet-name", that's up to you
awn.AppletSimple(self, "applet-name", uid, panel_id)
# do stuff
# to get the former "height" ie. size of the applet, you can now do:
size = self.get_size()

# creating an instance is now:
if __name__ == '__main__':
awn.init (sys.argv[1:])
applet = MyApplet(awn.uid, awn.panel_id)
# ...
Now let's talk about the methods of AppletSimple, these methods no longer exist:
# imagine we have "self" an instance of awn.AppletSimple
self.set_title(text)
self.set_title_visibility(bool)
self.set_icon(pixbuf)
self.set_icon_context(cairo_context)
self.set_awn_icon(applet_name, icon_name)
self.get_awn_icons()

# and now the commonly used methods of AwnIcons:
self.get_awn_icons().get_icon_simple_at_height(height)
self.get_awn_icons().get_icon_simple() # returned icon with size equal to 48
But you can use these instead:
self.set_tooltip_text(text)
# if you want to show tooltip on mouse-over and hide it on mouse-out you DON'T
# need to call these, there are properties of AwnTooltip which handle it.
# this means you probably no longer need to connect to enter/leave-notify-events
# and show/hide the tooltip manually
# (for more info see "smart-behavior" property on libawn API pages)
self.get_tooltip().show() or self.get_tooltip().hide()
self.set_icon_pixbuf(pixbuf)
self.set_icon_context(cairo_context)
self.set_icon_name(icon_name) # applet_name is taken from what you passed to the constructor
self.get_icon() # returns awn.ThemedIcon

# you can get former AwnIcons functionality with:
self.get_icon().get_icon_at_size(size)

As for "awn.AppletDialog", the only thing you need to do is to substitute it for "awn.Dialog".

And that's it, these are all the changes that had to be done for media-control applet and it should hopefully help you convert your applet.

P.S.
Our API is still not officially "frozen", so there could be some more changes, but we will try to minimize them, for me the only unknown is malept's config client (awn.Config) which probably will need to be renamed, since it will be now part of libdesktop-agnostic, but other than that its API should be more or less compatible.

Also current version of libawn API can be currently found at http://www.stud.fit.vutbr.cz/~xhruby16/libawn/.

Edit: There was one more change to the AwnApplet constructor, now you need to pass canonical-name for the applet as first parameter. The code above was updated to reflect this change.

Saturday, 27 June 2009

Hello world!

Hi there, and thanks for stopping by at my blog.

So, I'll start by introducing myself - I'm a computer science student, who participates in a couple of open source projects. Currently I'm spending most of my open source development time working on Awn (avant-window-navigator), which is a shiny dock/panel for *nix platforms.

As one of Awn's core developers, I noticed that we don't have many tutorials on how to write Awn applets and such, and people usually have to turn to existing code. This might not always be the best source of tips, so I'll try to fill in the gap... There are also many interesting ideas flowing in the Awn-land, so I'll try to share some of them from time to time. Other than that... well who knows what will come to mind and what I'll have desperate need to share with the world. :)

And that's about it for the start, expect a real Awn-related tutorial soon.