GNOME Break Timer: Week 6

It’s time to talk about my GSoC project again, where I’m making a new break timer app for GNOME. First, thank you, dear readers, for your feedback and support so far! It really helps to know other people are interested in this.

The last two weeks have been about tying up loose ends so I don’t get bogged down later on. First, I removed all traces of the old working title. This application is called GNOME Break Timer, now, instead of having several different names (and things that looked like names) strewn about. It probably only bothered me, but I’m really glad to have some logic on that front.

I got our cool introductory slideshow running. It appears if you launch Break Timer and breaks are not enabled. So, it will appear when you start Break Timer for the first time, and if you happen to turn it off at some point and want to start using it again. GtkStack was fantastic for this. It’s really nice to see GTK making animated transitions so easy, and apparently doing a pretty good job drawing them. I think it will be really exciting when applications are doing more of this in the future.

Incidentally, I updated the settings application to optionally support GTK 3.9+ with its very cool new gtk_window_set_titlebar function! I was a little disappointed to learn that I have to add the close button to the HeaderBar myself at the moment, which seems a little silly. So, I did some guessing about best practice (and borrowed some code from GNOME Clocks), then I made a little custom widget for the problem so I wouldn’t have to think about it any more.

#if HAS_GTK_3_10
using Gtk;
using Gd;

 * A Gtk.HeaderBar that expects to be set as the titlebar for a Gtk.Window.
 * If it is in titlebar mode, it adds a conventional close button and adjusts
 * its own titles accordingly.
public class WindowHeaderBar : HeaderBar { // Gtk.HeaderBar or Gd.HeaderBar
	private weak Gtk.Window owner_window;
	private Gtk.Button close_button;
	private Gtk.Separator close_separator;

	private bool is_titlebar;

	public WindowHeaderBar(Gtk.Window window) {
		this.owner_window = window;

		this.close_separator = new Gtk.Separator (Gtk.Orientation.VERTICAL);
		this.close_separator.valign = Gtk.Align.FILL;

		this.close_button = new Gtk.Button();
			new Gtk.Image.from_icon_name("window-close-symbolic", Gtk.IconSize.MENU)
		this.close_button.relief = Gtk.ReliefStyle.NONE;
		this.close_button.valign = Gtk.Align.CENTER;

		this.realize.connect(() => {

	public new void set_title(string? title) {
		if (this.is_titlebar && title == null) {
			title = this.owner_window.title;

	public void set_is_titlebar(bool is_titlebar) {
		this.is_titlebar = is_titlebar;

	private void on_close_button_clicked_cb() {
		var event = new Gdk.Event (Gdk.EventType.DESTROY);
		event.any.window = this.owner_window.get_window();
		event.any.send_event = 1;
		Gtk.main_do_event (event);

This widget belongs to a particular GtkWindow. When it is being used as a titlebar, it shows a Close button and borrows the title from that window when one is not set for the HeaderBar itself. You can see that happening in my video demo of the welcome slideshow. If it is not used as a titlebar, the widget behaves as usual – so, it looks like one of these:

Screenshot from 2013-07-26 19:20:37

Screenshot from 2013-07-26 19:20:19

Unfortunately, I can’t find a nice way for the widget to detect when it’s being used as a window’s titlebar, so it needs a set_is_titlebar method that gets called by the owner. Other than that, the ugliness is self-contained.

Another small change I’m very happy with is to how the break notifications appear. They are persistent, now, so as long as you need to take a break there will be a notification for it in the message tray. This makes them much tidier, and harder to miss. Now I just wish there was a way to have a notification banner stay open without needing to mark it as “critical” priority. I hate the idea that a “take a break” notification could take priority over a “low battery” notification…

How to install GNOME Break Timer

As always, I have been messing with my packages. If you want to try the latest test of GNOME Break Timer, there are two things you can do:

  • You can download this archive for the latest release and do the usual ./configure, make and make install thing. To build on Debian, it depends on libx11-dev, libxtst-dev, libxi-dev, as well as valac and libgtk3-dev (>= 3.7) and the other usual suspects.
  • Or, if you’re running Ubuntu 13.10 (or 13.04 with GNOME 3.8 installed), there’s a working PPA, so open a terminal and enter sudo add-apt-repository ppa:brainbreak/experimental && sudo apt-get update && sudo apt-get install gnome-break-timer. Note that the package has a different name than before (even though the repository is the same), so if you installed the brainbreak-experimental package earlier (thank you very much, by the way!), you’ll need to install gnome-break-timer anyway.

Next week, I’m going to make a serious effort to gather feedback on how this is working. I’m thinking of hooking up Piwik for some rudimentary statistics-gathering within the app. I’m not sure how much trouble it would be, or if it would be worth doing. We’ll see, anyway. I will also be looking at things outside Break Timer that could be changed to enable certain features, such as better lock screen notifications out of the box. GUADEC would be a perfect venue for that sort of thing, but unfortunately I won’t be there. (Next year, maybe?). Still, even if it’s just on IRC and mailing lists, it will be nice to poke my head outside this little corner I’ve been working in.

GNOME Break Timer: Week 4

My work is coming along nicely with the new break timer application for GNOME. I started off week three working on some extra pieces for the break monitor component. I disabled its big “take a break” overlay, and I added some new functionality: the screen locks automatically during a long break, there’s a new “break interrupted” notification that appears at just the right moment (like when you unlock the screen), and there are some helpful sounds when breaks start and stop.

With that bit behaving mostly as intended, for now, I switched over to the other half to the application: its settings screen. The new settings screen is very different from the old one. Actually, the way it’s presented is that the settings application is the break timer application, and it just continues running in the background when you close it. That makes a ton of sense, of course, but it’s different from how this is implemented so I’ll probably sound nonsensical for a bit as I get used to describing it that way.

The new settings screen (or whatever we call it now) is already feeling quite nice.
The new settings screen (or whatever we call it now) is already feeling quite nice.

It took a surprising amount of fiddling to get the break status to show up correctly in the new Break Timer application, but I learned some interesting things about Vala along the way. These two bits of the application talk to each other over dbus, so to make that easier I define my interface in a source file that is common between the two components, and then I implement it in the code that actually provides the dbus service. Here’s how that looks (in a very simplified, contrived form, of course):

// common/IMyService.vala:

public const string MY_BUS_NAME = "";
public const string MY_OBJECT_PATH = "/org/my/service";

[DBus (name = "")]
public interface IMyService : Object {
	public abstract string[] get_messages() throws IOError;

// service/main.vala:

[DBus (name = "")]
private class MyService : Object, IMyService {
	public string[] get_messages() {
		return {"Hello", "world"};

public int main(string[] args) {
	try {
		DBusConnection connection = Bus.get_sync(BusType.SESSION, null);
			new MyService()
	} catch (IOError error) {
		GLib.error("Error registering service on the session bus: %s", error.message);
	return 0;

// client/main.vala:

IMyService my_service = Bus.get_proxy_sync(

Vala does a great job making all of that just work, though I did run into some trouble when I tried to define a signal in my interface. Normally we just have the signal in the interface definition and it’s automatically available for any implementing class (think mixins), but something was getting muddled up somewhere and, while the signal was available to the application, it was never registered on dbus. So, my client application couldn’t use it. The obvious workaround is to just not implement the Vala interface with MyService (so it’s just private class MyService : Object {), but I hate to do that because the nice thing about using the same Vala interface on either end is you can’t change them independently. So, I’m less likely to do something dumb like change the DBus interface in a way that breaks part of the settings application. In the end I wasn’t using signals in my dbus interface anyway, so I didn’t have to deal with it.

Another curious puzzle I ran into was an annoying race condition, where the Break Timer application would detect the break monitor daemon on dbus, and try to talk to it, and then fail because the interface it was expecting was not available (unexpected error: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such interface `org.brainbreak.Breaks.TimerBreak' on object at path /org/brainbreak/Breaks/microbreak). This turned out to be a lot simpler than I originally assumed: I’m using GtkApplication, which registers the application ID on dbus in order to handle uniqueness. What happened is GtkApplication would acquire the well-known name of my break monitor daemon on dbus, then the settings application would get some CPU time and see the daemon’s name on dbus and try to talk to it, but at that stage the daemon had not actually initialized, so its break-tracking-related services weren’t registered, yet – just the name. The fix is really simple: the value for my GtkApplication’s application_id needs to be different from the well-known dbus name I use to access the break timer’s special dbus interface. I just changed application_id to that dbus name + “.Application”. Then, after all of the initialization is complete, I get the dbus connection object for the application and own a different name on the bus for the service that the application itself provides:

var connection = this.get_dbus_connection();
if (connection != null) {
	Bus.own_name_on_connection(connection, HELPER_BUS_NAME, BusNameOwnerFlags.REPLACE, null, null);
We have a lot of room to play with for cute little status messages.
We have a lot of room to play with for cute little status messages.

That all gave me a nice opportunity to explore some changes to the break schedule dialog, which is what’s left of the original break settings application. I got rid of the On / Off switch beside each break type, and instead I added a combo box to select a particular type of schedule: either micro breaks and full breaks, just micro breaks, or just full breaks. This helps to establish what full breaks and micro breaks are, and it allows us to present the different break schedules up front, instead of hiding that more meaningful choice behind a rather arcane assortment of switches.

The Schedule dialog has two fewer buttons, and some much more direct choices.
The Schedule dialog has two fewer buttons, and some much more direct choices.

I’m working on this with Ubuntu 13.04 and the GNOME 3 repository, so I’m trying to keep everything compatible with GTK 3.8. To use the wonderful new HeaderBar widget, I’m using libgd. It’s meant to be used as a git submodule, but I’m still using bzr for this project (pending an even more compelling reason to switch). So, I added an extra git clone command in my, which does essentially the same thing as git submodules. This is all a little strange, and the moment I switch this project to a git repository is getting very close, but for the time being I just feel a little happier pushing to Launchpad and getting that quick feedback when I break the build. With that said, there was an extra stumbling block with my fake libgd submodule and Launchpad: the build server wasn’t letting my build script access the internet to do its git clone libgd thing, but there is no way I am adding the libgd codebase to my project without a very good reason. So, I set up a git import for libgd in Launchpad, and I added one more line to my bzr-builder recipe: nest submodules lp:~dylanmccall/brainbreak/libgd libgd.

So, that means there’s still a working repository to play with the latest code! This version only works in an environment with GNOME 3.8 or above, like Fedora 19 or Ubuntu Saucy (or, if you’re feeling adventurous, Ubuntu 13.04 with the GNOME 3 PPA), but it does work! For Ubuntu, it’s a different repository than before: ppa:brainbreak/experimental. It should also build and run from source relatively smoothly.

That’s all for now. This is rough around the edges, but I think it’s starting to make sense. If you try it, please consider leaving a comment to share how it goes.

GNOME Break Timer: Week 2

I’m starting the third week of coding on my GSoC 2013 project, a new break timer application for GNOME. I spent the last two weeks working on an odd mix of little things. For the most part, my goal over that time was to make the gnome-break-timer project (previously brainbreak, still brainbreak in most places) nicer to work with. I’m a bit of a sucker for clean code, and, well…

By Manu Cornet, from Bonkers World
By Manu Cornet, from Bonkers World

So, to start off, I switched over to Automake from my old build system, which was using BuilDj and Waf. I’m still a big fan of those two, at least philosophically. In practice, Automake just seemed like a good choice because it’s familiar to people, and I really want to maintain a high bus factor for this project. This isn’t the sort of application that I would expect to have a continuous flow of regular contributors, so I think it’s important that someone can jump in and figure it out for without too many obstacles.

One interesting puzzle here was doing a convenience library with Automake and Vala. I started using convenience libraries for this project so I could strictly define different parts of the application. The idea is code at one level shouldn’t know anything about code above it, and we can formalize that by actually building these bits of code to separate objects that get linked together later. This also, conveniently, allows us to reuse the code that is common between the settings panel and the break timer daemon without needing to compile it twice. Not a big deal here, but I like it anyway.

I found lots of helpful information about doing convenience libraries with Automake, but Vala posed something of a problem because Automake doesn’t do everything for us with Vala (yet). I need to pass several extra flags to valac, both for the library and for the target that uses the library, and I need to do that without messing up build dependencies. I don’t want to run into cases where the build fails (or, worse, doesn’t fail!) until I run make clean. (For what it’s worth, the old build system with BuilDj and Waf figured this out wonderfully and generally rebuilt the thing about twice as fast as Automake, but I also hadn’t set up localization or config.h, so I guess that’s kind of moot). I checked out how some projects like Deja Dup were doing convenience libraries, and I came up with a handy reusable pattern: for the rather unhelpfully named “common” module:

	-include $(CONFIG_HEADER)

noinst_LTLIBRARIES = \

libcommon_la_SOURCES = \
	NaturalTime.vala \
	SessionStatus.vala \

libcommon_la_LIBADD = \

libcommon_la_VALAFLAGS = \
	--pkg gio-2.0 \
	--library common \
	--vapi common.vapi \
	-H common.h

junk_files = \
	$(libcommon_la_SOURCES:.vala=.c) \

	cd $(distdir) && rm -f $(junk_files)

	$(junk_files) \
	common.vapi \
	common.h for some code that uses that module:

	-include $(CONFIG_HEADER) \
	-I $(top_srcdir)/common


bin_PROGRAMS = \

brainbreak_settings_SOURCES = \
	ApplicationPanel.vala \
	BreakPanel.vala \
	BreakType.vala \
	main.vala \

brainbreak_settings_VALAFLAGS = \
	--pkg gtk+-3.0 \

brainbreak_settings_LDADD = \

brainbreak_settings_vala.stamp: \

junk_files = \
	$(brainbreak_settings_SOURCES:.vala=.c) \

	cd $(distdir) && rm -f $(junk_files)


Of course, I also rewrote a bunch of stuff which had been thrown together a little too hastily. I knew I would need to rewrite a lot of code, but I wanted to get the “rewrite and start over” bug out of my system in the beginning, and I think it worked. Allan Day already came up with some lovely mockups that I could start with, so I used those to guide me in choosing what needed work. As I worked through implementing different bits of his “take a break” UI, I noticed some aspects that would have been quite difficult with the design I had earlier. I squished and pulled things accordingly, giving the UI code a little more power and knowledge, and getting rid of needlessly arcane kinds of “reusable” code. But that’s all a little boring.

I’m really excited for the next bit. I will be working on a beautiful new Break Settings application, complete with GtkHeaderBar and (hopefully) a non-ridiculous time input widget. I’ll post some pictures and a new download soon!

My GSOC 2013 project: a new break timer application for GNOME

A little while ago, my proposal was accepted for Google Summer of Code 2013. So, this summer I will be working with Jasper St. Pierre and the GNOME project on a shiny new break timer application. We’re going to spend some time filling out the wiki page for the new break timer design, and from mid-June to mid-September I will try to implement it as well as I can.

A break timer application is pretty well what it says on the tin. It’s an application that can monitor your computer use and remind you to take a break every now and then. Things get a little tricky when we start thinking about how to make that sort of application effective. Among other things, gauging how much someone is using the computer is kind of fiddly, and people don’t really enjoy being interrupted all the time. If it’s done well, though, I think anyone can benefit from this type of application. Taking regular breaks isn’t just healthy for the body: it can keep your mind happy, too.

I’m excited about this project for a few reasons. First, I have been meaning to get involved with GNOME for a while, and I’m expecting to touch a few different projects in order to produce something seamless. This is also an itch I have wanted to scratch — I really want a good, shiny and new “take a break” app for a variety of reasons — and it’s an opportunity to tie up a loose end from a while ago. I actually already started on a new break timer app, but I never quite reached a releasable product. With my project this summer, I’m going to be starting with (some of) what I already made, which will allow me to iterate efficiently and, I hope, to create something beautiful and releasable by the deadline.

For the time being, I thought it might be fun to actually share the other one I keep mentioning, which has the strange working title “Brain Break”. It isn’t perfect, but if you’re interested in a take a break app made for GNOME 3 (and yes, that includes Unity), that uses GTK+3 and real desktop notifications (and not the old system tray), perhaps you will like it? I made it because I thought the existing options for break timer software were getting a little old, but also because those options didn’t really work for me: when there was a Skip or Postpone button, I got into the habit of pressing it as soon as I could. (I’m a computer nerd. Workarounds are my middle name). When there wasn’t, I would get angry at the software for interrupting me and I got into the habit of disabling it proactively (and then forgetting to turn it back on).

Brain Break doesn’t have a Postpone button or a Skip button, but it makes up for it with a “Take a break” overlay that blocks your screen without blocking input. So, you can finish that one last thing without needing to postpone or skip the break (or, for that matter, lose your train of thought). Because there’s no easy way to make the “Take a break” overlay go away, Break Break is hard to ignore, but it tries to be nice about it.

Brain Break is probably ready to use. I’ve been using it for ages, and I like it, at least. It’s on Launchpad at If you’re using Ubuntu, you can install it very easily from its PPA, Just open a terminal and run sudo add-apt-repository ppa:brainbreak/daily, then sudo apt-get update; sudo apt-get install brainbreak.

Brain Break's "take a break" screen is gentle, but hard to miss
Brain Break’s “take a break” screen is gentle, but hard to miss
Brain Break's settings tool
Use the break settings panel to set specific break times, or disable them for an hour

The new break timer app probably won’t be the same as Brain Break, but in order to make the new one as awesome as possible, maybe there’s something to learn from Brain Break? Please, try it out, and share your thoughts in the comments! You might like it, and either way I would love some feedback to get ideas flowing.

Reposted from June 11, with apologies to Planet Ubuntu. Hi there, Planet GNOME!

The Attack of the Crimson Plumber! – Ludum Dare 25

Continuing on my current trend of writing blog posts about a year late, let me tell you about my last Ludum Dare game!

One of these days, I will make a Ludum Dare game with an actual opponent. My Ludum Dare 25 game was no such achievement, but I ended up happier with it than my last one. The tight deadline led to some very satisfying late changes and workarounds, and only a few disastrous omissions.

It all started with a hideous tile system demo, of course.
It all started with a hideous tile system demo, of course.

The LD25 theme was “You are the villain.” I managed to come up with an idea reasonably quickly: the player needs to place traps in a side-scrolling platformer modelled after a Mario boss battle. As usual, that idea ballooned into something way more complicated than I could have handled in 48 or 72 hours. I had to do the hard part (editing!) while I made the thing. At its fullest, this would have demanded some fancy game mechanics to ensure the player doesn’t break the game and some fancy AI that can actually navigate traps. And then some even fancier AI that can navigate traps without being predictable or annoyingly capable.

Dreading all the decision-making around that, I doddled along for the first day and a half, mostly just fiddling with the base technology. I wanted some practice with HTML Canvas, so I grabbed the Dart SDK as well, since I thought that language looked pretty interesting. As might be expected, this was a really great combination — I barely had any trouble with it. Eventually, I came up with some rudimentary behaviour for the opponent, so it always walks ahead and jumps (or doesn’t jump) according to certain combinations of blocks in its path. The graphics looked bad and I felt somewhat relieved thinking that I just wasn’t going to bother subjecting anyone to this thing.

It got more complicated, and worse in just about every way.
It got more complicated, and worse in just about every way.

Then a friend convinced me to release it for some reason. What a jerk.

The painfully unreliable collision detection reminded me of those old handheld LCD games, so in the last few hours I changed most of the graphics to snap to a grid and I switched to a grey colour palette for the foreground, with a fixed coloured background. I also added a simple LCD ghosting effect, and I tinkered with buffers for some interesting effects.

I think it looks quite handsome, for about half an hour of work.

The rest of the game turned out more complicated than I had time for, so it all kind of falls apart if you look at it for more than a minute, but it was fun to explore Dart and HTML Canvas. I hadn’t used them before, and now that I’ve had some time to play around I feel really good about both of them. I hope I get to use them again some day! Next time, I’ll remember to implement timing code first.

That background gradient worked wonders.
That background gradient worked wonders.

If you want to play the game for some reason, it’s available on the web. It should work with any modern browser. The source is in a single .dart file (I mentioned it was terrible, right?), and all the rest is on the game’s entry page at

As always, other magical people made some amazing things. Here are some of my favourites:

  • Age of Umpires. Sort of reminds me of Konami Ice Hockey. Also, believe me: the referee mode is incredible.
  • Dance Man. This one is by Andrew Brown, my friend who did Baby Farm for LD23. Bizarre and yet brilliant, again, as usual.
  • Space Lord. Space invaders. Need I say more?

I typed this standing up

Almost five months ago, I switched to a standing desk. I am in love.

Yes, it is absolutely sane to be in love with a desk.

We made a standing desk out of processed trees. The result is modest, but I'm happy with it! Dads are great.
We made a standing desk out of processed trees. The result is modest, but I’m happy with it! Dads are great.

The idea with a standing desk is your body stays more active while you are at your desk, so you can read those health warnings about sitting all day with a sense of superiority. And we all like to feel superior. But I didn’t just switch to a standing desk because of how everything is killing us. I had a few reasons of my own! When I sit, I end up sitting wrong within minutes. This is a problem, because my choice of obsession (and profession) means I am doomed to a lot of fooling around with computers. For a long time, I assumed that doom required equal amounts of sitting. During my little internship at the David Suzuki Foundation, one of my awesome coworkers was thrilled with her standing desk, so that finally got the wheels turning for me.

Meanwhile, I was noticing that I never really solve much while I’m sitting at a desk. My brain works a lot better when I’m at least moving. The problem is my work environment wasn’t really made for moving around. There was a giant, allegedly comfortable chair in the way. I say “allegedly comfortable” because this is one of the other neat things. I considered actually buying an actually comfortable chair, then I realized I could change my desk, instead. Hundreds of dollars in savings, I thought.

Didn’t turn out that way, but it was still worth it.

I started off looking at different articles around the web for inspiration. Jorge Castro wrote a nice blog post about his own adventure building a standing desk on top of a metal frame, and Priceonomics has suggestions for cobbling together a standing desk from Ikea stuff. I momentarily entertained the idea of buying from Geekdesk, but, besides the price, I decided I would prefer to jump in head first with something that is not adjustable to sitting. If I make it easy to go back, I probably will.

So, I was looking at different bits of Ikea furniture that I could somehow jam together into something coherent, and soon enough my dad talked me out of all that. Instead, we (mostly he) built a new desk frame from scratch. This way we could get something at the right height from the start. After all, you don’t want to stand at an uncomfortable desk, and unlike sitting on a fancy chair, you can’t really adjust your standing height. There’s a sort of general guideline that the desk should be at a height where you can look straight ahead with your elbows at a 90° angle, and we ended up with something pretty close to that for me.

As might be expected, it looks slightly more flattering from the top.
As might be expected, it looks slightly more flattering from the top.

As well as the desk, I have collected some standing desk paraphernalia. After about two weeks I got a new, cheap office chair that adjusts almost as high as the desk. I haven’t used the chair as much as I expected — I can remember maybe eight specific occasions — but it is great for those long sessions of Crusader Kings 2. (Its height even resembles a throne, and it terrifies me. As it turns out, I would make a terrible king). Just last month I got a brand new anti-fatigue mat, which is under my rug in the photo. It’s an Imprint Comfort Mat, which has a durable surface and some sort of memory foam cushioning. It feels a lot like wearing a good pair of shoes. I got along fine without it for the weeks before, but I can see why that extra stress on the feet can make a big difference for some people, and I’m glad I have something for them now.

Speaking of gadgets, I quickly began to appreciate long cables. My headphones have an unusually long cord, and that used to bother me, but now that I’m a few feet higher and I like to wander away from my desk, the extra length is indispensable. Cables have been a problem in other spots, though. Many of them, like my video cable, are only just long enough. As it is, I can’t do much to hide them from view. They just reach to the top in the quickest possible way, which of course involves a giant knot. I really should hunt for some new cables, but at this stage it seems almost insurmountable. It makes me wish I had chosen differently every time I thought “I don’t need a longer cable — it just needs to reach around my desk.” So, uh, there’s my helpful advice.

Not actually the view out my window, but close enough.
Not actually the view out my window, but close enough.

My favourite thing with this standing desk is what it means for taking a break. Sitting down almost feels like a worthwhile, and entirely justified, change of pace, which is very refreshing. I still have my perpetually unfinished home-made “take a break” app running, and I have an easier time prying myself away from my computer when a micro break or a rest break comes along. I’m always one step closer to it, after all. Also, I think I’m biting my nails less! Weird, but exciting.

As for the standing part, it definitely took time to adjust. For the first few weeks, I had a weird habit of standing completely still at my desk. I guess that’s because I was so used to sitting still at my desk, but my feet didn’t thank me for it. As I have become used to the idea, I’m prone to stretch and move around more, so my feet aren’t being pressured in one way for the whole time. At this point, I definitely find it easier to walk around and look out a window when I’m pondering something. I haven’t decided if that really helps me to think, but at least it seems healthier. The bottom line is I feel more free when I’m doing computer stuff, and that’s really cool.

So, add me to the standing desk fan club, please! I don’t think I will be going back.