This web site has been retired. Please follow my activities at pztrick.com.

pZtrick.com

the personal site of patrick paul

Guake Tabs Indicator for GNOME 3 (Extension)

| Comments

Four Guake terminal tabs indicated at top (toggled by F1) This weekend I wrote my first GNOME 3 Extension. The GNOME Shell is the user interface of GNOME 3 and exposes a lot of extensibility via javascript and CSS styles.

I happened to be installing a new Ubuntu VM to run on the second monitor of my work desktop PC and decided to install gnome-shell ubuntu-gnome-desktop in lieu of xfce4 or Ubuntu Unity (useful instructions here). I was pleased to see Guake ran similarly as in my Xfce4 environment and noted that Guake dropped down not from the top of the screen but from the bottom of the top Gnome Shell panel.

Part of the reason I had originally disabled the native tab bar in Guake 4.4 was because it appeared on the bottom and interfered with the aesthetics of a drop-down terminal (as well as for its ugly gray UI), but the possibilty to extend the GNOME Shell to display tabs seemed like an opportunity to improve things.

Learning is fun

The project resulted in a crash course in javascript (well, hacking syntax, anyway, if not whatsoever comprehending the significance and purposes of its design) as well as learning about D-Bus inter-application communication on Linux platforms.

Whereas I could execute bash commands from my Python plugin to slot Guake interactions into Sublime Text 2, I was unable to find a way to execute bash commands in gjs (the GNOME javascript engine). Further, there is a dearth of really any documentation on GNOME Extension development. All I could do was to browse other extensions’ source on github and the GNOME 3 libraries in the GNOME git repository.

Other extensions often utilized D-Bus message passing to communicate with apps, and fortunately, I learned that Guake supported this API (albeit without much documentation there, either; I had to consult the Guake repository’s dbusiface.py file.).

Upstream limitations are not fun

I have a working extension available on github here. However, it was severely handicapped by some missing functionality upstream:

  • I cannot retrieve the tab name from the Guake D-Bus API. So, right now, each tab is named like so: guake0 guake1 guake2 etc.
    • While the D-Bus API does allow for executing arbitrary commands (e.g. echo "$USER@$(uname -n)") it does NOT pass the standard output back through the API such that I could use this expression for the tab name.
  • I cannot retrieve the number of tabs from the Guake D-Bus API.

For the second bullet, the two methods that proved useful as a work-around were to 1) select a tab by index and 2) get the current tab by index. When you select an index greater than the highest terminal session index, #2 would return a different selection (the highest, and not the highest + 1) – so by walking through select commands you can infer when you’ve hit the highest tab index.

However, this hack must hi-jack the Guake terminal from the user to cycle through the number of tabs because it is necessary to poll for changes in the Guake tabs every second or so (as a user may exit a terminal session at any time, or open a new tab, and I want to reflect those changes in the UI tabs indicator). The user experiences some flickering as the extension quickly jumps to the last tab and then attempts the last tab + 1 in order to determine if it is missing any tabs in the indicator. I haven’t noticed any actual input mistakes when typing quickly – but I do see the ocassional flicker. The extension tabs through terminal sessions very quickly I guess, just one time each second.

Styling

Everything is styled in CSS. A few events like enter-event and leave-event allow me to swap CSS class names for a mouse hover event, and I simply apply class names like guaketabs-inactive, guaketabs-active, and guaketabs-inactive-hover for the various states.

Repository

The repository is hosted here on github.

Next steps

I’m going to continue to improve this extension in my spare time. I’ll call this version 0.1 as it is working, albeit imperfectly. I will also try to pursue some additional API methods upstream:

  • org.guake.RemoteControl.get_tab_name which returns the tab name for the passed index argument (integer)
  • org.guake.RemoteControl.get_number_of_sessions which returns the number of tabs (and would spare my extension from hi-jacking the terminals input)
  • org.guake.RemoteControl.show_overlay which shows the overlay. Right now you can click to select a tab, but it will not also open the overlay. The only API method now is to toggle, and so clicking multiple tabs would result in the first click opening the overlay, and then the second click hiding, etc.

I don’t think it’s sufficient production quality to go on the extensions website, but I will effort getting these 2 API methods into the Guake project upstream (barring any opposition) so that Guake can play nice beginning with the 13.10 distribution this fall.

2013/5/20 Update

It looks best with the Date/Clock extension disabled (for now) I spent time today forking Guake upstream today and added three new D-Bus API methods: show hide get_tab_name and get_tab_count. These few features greatly enhance the usefulness of the indicators by 1) letting you click on a tap to immediately open it, 2) display the username/hostname/directory on the tab, and 3) greatly optimize the speed as it no longer needs to hijack the user’s terminal to determine how many tabs are open in Guake – it can query the API.

Hopefully, the Guake core team will be amenable to these changes.

2013/5/20 Update #2

The pull request was merged easily enough, so the extension is good to go for Guake version 0.4.5-dev+. These two master branches will have you up and running:


Revisions

  • 2013/5/20 – Added repositories for guake and guake-tabs-indicator with latest functionality (e.g. dbus_extras branches)
  • 2013/5/20 – Strike-through dbus_extras branches after upstream patch merged; add new master branch links.

Comments