Joining the Tiling WM Master Race

Written by Pete Corey on Dec 15, 2014.

Recently I decided to elevate my Linux Mint 17.1 development environment from its plebeian out-of-the-box Cinnamon origins to its rightful place among the glorious #TilingWMMasterRace. I thought I’d document the process of installing and configuring bspwm to help others looking to do something similar.

bspwm for dummies

For the initial setup and configuration of bspwm, I recommend you read and follow Bill Indelicato’s excellent guide, bspwm for dummies. It’s worth noting that in addition to the packages he lists, you should have build-essential installed when trying to build bspwm on Linux Mint. The steps in his guide can be distilled down to:

sudo apt-get install vim dmenu rxvt-unicode git build-essential xcb libxcb-util0-dev libxcb-ewmh-dev libxcb-randr0-dev libxcb-icccm4-dev libxcb-keysyms1-dev libxcb-xinerama0-dev
git clone https://github.com/baskerville/bspwm.git
git clone https://github.com/baskerville/sxhkd.git
cd ~/bspwm && make && sudo make install
cd ~/sxhkd && make && sudo make install
mkdir -p ~/.config/bspwm ~/.config/sxhkd
cp ~/bspwm/examples/bspwmrc ~/.config/bspwm/bspwmrc
cp ~/bspwm/examples/sxhkdrc ~/.config/sxhkd/sxhkdrc
chmod +x ~/.config/bspwm/bspwmrc
echo -e “sxhkd -f 100 & \nexec bspwm” > ~/.xinitrc

sxhkdrc changes

I run my linux dev environment as a virtual machine, which means that using super as my bspwm control key can cause issues. Thankfully it’s incredibly simple to remap these sxhkd hotkeys in ~/.config/sxhkd/sxhkdrc:

sed -i ‘s/super/alt/g’ ~/.config/sxhkd/sxhkdrc
sed -i ‘s/alt + alt/alt + ctrl/g’ ~/.config/sxhkd/sxhkdrc

.Xdefaults

~/.Xdefaults is where you configure the look and feel of urxvt. I started with a template ~/.Xdefaults I found online, switched to use Ubuntu Mono and borrowed a nice color scheme I found in this helpful article. You can see what the final result on my github.

.xinitrc and .xsession

On a system without a graphical login manager, you could simply log into your system and run startx to run ~/.xinitrc and run bspwm. However, Linux Mint uses the MDM Display Manager, which means that X is already running when we log in and we need to take an extra step to get bspwm running. Thankfully, all we need to do is make a symbolic link to ~/.xinitrc called ~/.xsession. When MDM logs us in, it will execute ~/.xsession, which will effectively execute our ~/.xinitrc and run bspwm.

ln -s ~/.xinitrc ~/.xsession

After making this link, log out, select “Run Xclient script” session and log back in. You should be greeted with a black screen. Hit alt + enter to open a terminal.

sxhkd -f 100

After initially following the steps in bspwm for dummies, I noticed that doing mouse based window resizes was incredibly slow. After a little research, I found this reddit thread that suggested a fix of limiting the maximum frequency for motion events to 100. You can check out sxhkd.c on github to see how this works. Look at max_freq and motion_interval. When a max_freq is specified and a motion_interval is calculated (> 0), the motion_notify method will return early, preventing sxhkd from spamming bspwm with commands.

Final Thoughts

This should leave you with a minimal, functional and clean bspwm setup. There’s definitely much more that can be done from here, but the road you take is up to you. Check out all of my dotfiles on github.

My current bspwm setup

My Meteor Hello World - countwith.me

Written by Pete Corey on Dec 8, 2014.

I decided to make a very simple webapp to get my feet wet with the Meteor framework. The result is countwith.me! The site is basically just a real-time, anonymous counter. Users can submit the next number in the sequence. If their number is incorrect, the count resets to 1. Even though it’s a mind-numbingly simple app, I learned quite a bit from it.

Using Grunt

My first instinct when building out a front-end for a project is to use Grunt and Bower. In order to prevent Meteor from trying to process and bundle all of my Grunt and Bower resources and dependencies, I decided to keep them in a hidden directory called .grunt, which Meteor ignores. Gruntfile.js is set up to watch scss for SASS changes, and then dump the compiled css file in the root directory. I have a grunt copy target set up to manually copy select resources (lodash.min.js, moment.min.js) out of .grunt/bower_components into js. Meteor finds these css and js resources and bundles them.

From what I’ve seen, using Grunt and Bower in this way isn’t the “Meteor way” of doing things. Instead, I should be using meteor packaged versions of the tools I need, like meteor-scss, meteor-lodash and meteor-moment. I’m not sure how I feel about this. I keep see the benefits of using things that only exist within the Meteor ecosystem, but at this point it seems like we’re just adding an extra, unnecessary layer of package management.

Subscription onReady

One of the first things I did was set up a template to iterate over a Counts collection and display the number in a span:

<template name="numbers">
    {{#each counts}}
        <span class="number {{#if wrong}}wrong{{/if}}">{{number}}</span>
    {{/each}}
</template>

As the collection began to grow, I was surprised to see that the data in the DOM would be initially incorrect when the app first started or was refreshed. A quick search led me to a StackOverflow answer that suggested not displaying data until the subscription onReady callback is called. A quick check of the docs made it pretty clear how the onReady callback works. By setting a session variable when the subscription was ready, I was able to hide the collection’s DOM elements until they were ready to be seen:

<section class="numbers {{#if notReady}}not-ready{{/if}}">
    <span class="number" contenteditable>???</span>
    {{> numbers}}
</section>

Publish/Subscribe and MiniMongo - Ohhhh, Now I Get It

As my Counts collection grew in size, I was beginning to have some severe performance problems. I spent several hours slamming my head against the Chrome Dev Tools trying to track down what I thought was some kind of memory leak. If only I had ready the Understanding Meteor Publications & Subscriptions article, I would be 3 hours richer.

Initially, I was using auto-publishing and setting up my sorting and limiting Counts query on the client:

if (Meteor.isClient()) {
    ...
    counts: function() {
        return Counts.find({}, {sort: {timestamp: -1}, limit: 30});
    },

After removing autopublish, I wanted to move that logic to the server, so I did just that:

if (Meteor.isClient()) {
    ...
    counts: function() {
        return Counts.find();
    },
...
if (Meteor.isServer()) {
    Meteor.publish('counts', function () {
        return Counts.find({}, {sort: {timestamp: -1}, limit: 30});
    });

However, after my client refreshed itself, I noticed that my data was not being updated when I submitted new numbers. I was under the impression that this server-side Counts query was not returning a reactive collection to the client. In a desperate attempt to fix the problem I removed the sorting and limiting from the server and moved them to the client. This worked, and I went about my business, oblivious to my impending doom.

if (Meteor.isClient()) {
    ...
    counts: function() {
        return Counts.find({}, {sort: {timestamp: -1}, limit: 30});
    },
...
if (Meteor.isServer()) {
    Meteor.publish('counts', function () {
        return Counts.find();
    });

Hours later, after reading through the previously linked Understanding Meteor article, I realized the errors of my ways. I also realized that the data being passed to the client was reactive, it simply didn’t look like it was updating because the default sort order was placing the new counts at the bottom of the list, out of sight. The ultimate fix was to sort and limit on the server, and sort on the client.

if (Meteor.isClient()) {
    ...
    counts: function() {
            return Counts.find({}, {sort: {timestamp: -1}});
        },
...
if (Meteor.isServer()) {
    Meteor.publish('counts', function () {
        return Counts.find({}, {sort: {timestamp: -1}, limit: 30});
    });

Conclusion

Check out countwith.me. Also check out its github repo. Ultimately, I’m very happy with how the project turned out. I never thought that such an incredibly simple webapp would teach me so much about a framework. Every little thing I learned about the framework gave me glimpses into much deeper topics that I’m anxious to explore. It’s interesting how such a seemsly simple framework can be so deeply nuanced.

Meteor First Impressions

Written by Pete Corey on Dec 2, 2014.

Recently I’ve been trying out the Meteor platform. Needless to say, I’m pretty pumped about it:

But seriously, from what I’ve read and experienced so far, I’m very excited about what Meteor has to offer. Going through the tutorial and seeing realtime data binding happening from the HTML template all the way up to the database is mind-blowing! In a previous post I wrote about my love for Firebase and my dreams for a realtime system architecture. Meteor seems like an amazing step in that direction. I’m looking forward to doing a lot more work with it in the near future!