Upgrading the Touchpad on a Thinkpad x240

This is a stock photo of a Thinkpad x240, stolen from the interwebs:

x240_stock

This is my own x240, which I bought back in January 2015.

x240_trackpad

If you know about Thinkpads, you probably noticed the difference right away. The x240 (and other models that year) suffered from an incredibly crappy buttonless touchpad. It’s so bad that it’s barely usable. Clicking is ridiculously inaccurate: there’s so much travel that the mouse pointer moves during a click, and there are no buttons to use instead. There were so many complaints that Lenovo replaced it with a better one in the next year’s lineup.

This weekend I finally got around to upgrading it with a touchpad replacement part for the x250. It cost $32 on ebay. This modification is popular, so you can find info about it scattered around in forums and such. I followed the instructions on this page, How to change an x240 trackpad, as it’s one of the clearest ones out there. I couldn’t find much info about the author, whose name appears only as “Michael” on that blog.

Some notes and tips from my experience:

1) Michael’s picture shows a set of wires connected to the touchpad along its side, but mine didn’t have them.

2) The touchpad sits in a well, held in place with adhesive tape, so to remove it, you just pry it off. The problem is that it’s hard to reach “under” the entire touchpad assembly, which is sort of like a sandwich with layers. I ended up partially prying off the top layer before I could get to the bottom and pry the whole thing from the case. Needless to say, this bent the touchpad.

I couldn’t figure out a way to avoid effectively destroying the old touchpad. But since it was so crappy, it was also somewhat satisfying.

3) Detaching and re-attaching the small ribbon cable from/to the underside of the touchpad is VERY tricky. The end of the ribbon is held in place to the connector on the touchpad by a thin black “latch” sitting just behind it. You CANNOT just yank the ribbon out. (This took me a while to figure out!) Lift the black latch, and the ribbon will slide from the connector easily. When connecting it to the new touchpad, tuck the ribbon end securely into the connector, then flip the latch down to lock it in place.

4) At first, the new touchpad wasn’t being recognized by the machine. It worked after I re-seated the ribbon in the connector and also reset the BIOS (as shown in this video: stick a paper clip end into the tiny hole beside the battery and press for 20 seconds). I should have tried those things separately, but got a bit too excited. So you may or may not have to do a BIOS reset.

So far so good. The new touchpad is definitely a big improvement. There’s much less click travel using the pad, and it feels snappier. I really like having the buttons.

The only quirk is that the surface of the touchpad now sits just a hair higher than the palm rest. It’s probably slightly more likely for my hand to accidentally brush it while typing, as compared to the original touchpad, but only time will tell for sure.

It feels like a totally different computer.

Annoyances in Xubuntu 16.04 LTS

This week, I installed Xubuntu on a new work computer. I’d previously sworn off Ubuntu, but I admit, I’m crawling back now… the reality is that Ubuntu has smoothed out many of the rough edges that I’m simply not willing to deal with at work. Sigh.

Even as generally polished as Xubuntu is, I did encounter a few hiccups.

1) To adjust settings for the screen locking software, light-locker, I needed to make sure the light-locker-settings package was installed. Nothing happened when I selected “Light Locker Settings” from the whisker menu, though, because it was crashing. I ran “light-locker-settings” via a terminal, and saw some python error messages.

Python was trying to import a module from python-gobject, which wasn’t installed and wasn’t a prerequisite for light-locker-settings for some reason.

After that error went away, I got another one about a missing function. To fix it, you have to manually patch two lines in a python file, as described in this bug report. [NOTE: This has been fixed as of 7/20/2016, in version 1.5.0-0ubuntu1.1 of light-locker-settings]

2) Another light-locker quirk: the mouse pointer becomes invisible when I lock the screen by hitting Ctrl-Alt-Del and then unlock it. To make it visible again, hit Ctrl-Alt-F1 to switch to a text console and then Ctrl-Alt-F7 to return to Xfce.

3) The “Greybird” theme is notorious for making it VERY difficult to resize windows by dragging the handles that appear when you mouse-over the window edges and bottom corners. The pointer has to be EXACTLY on an edge or corner; it won’t display the resize handle if you’re slightly off.

For reasons I don’t understand, the devs seem intent on not changing this. But enough users have complained that the Xubuntu blog even has a post about alternative ways to resize windows. The disregard for user experience here is simply mind-blowing.

I’ve grudgingly started using the Alt and right-click drag combo to resize windows.

Addendum:

4) Intermittent DNS problems: hostnames on our internal domain weren’t always resolving. This seems like a common problem on Ubuntu caused by dnsmasq. The solution is to disable it by commenting out the line “dns=dnsmasq” in /etc/NetworkManager/NetworkManager.conf and rebooting.

“Proxy mode” added in refine_viaf 1.4

A refine_viaf user recently commented that she would like to get Library of Congress IDs for the name candidates in OpenRefine, instead of VIAF IDs.

It would be ideal if the name IDs for LC and other sources could be additional fields in the JSON data returned from refine_viaf, which you could then extract using some GREL code. Unfortunately, OpenRefine doesn’t allow you to access additional fields on name candidate objects.

So I’ve created a separate “proxy mode” that returns IDs used by source institutions themselves, rather than the VIAF IDs. To use proxy mode, add a reconciliation service in OpenRefine using this URL format instead of the usual URL:

http://refine.codefork.com/reconcile/viafproxy/LC

One quirk is that OpenRefine will create broken hyperlinks for a few sources (at the moment, these are BNC, BNF, DBC, and NUKAT). This is due to the fact that the IDs in these URLs don’t match the name record IDs, which is a requirement for the hyperlinking mechanism to work properly.

In short, you can now use refine_viaf to reconcile “directly” against the name authority records of VIAF’s source institutions, which should be useful to many people.

The Linux Desktop bleeding edge

I’m having some trouble running Firefox 46, which was released in late April. I’ve had to roll back to 45.0.2 for now. No big deal, but my woes are pretty indicative of the complexities of the Linux desktop, so I thought it’d be interesting to write a little about it.

I run the “testing” distribution of Debian. Its stability lies somewhere between the “unstable” (things are largely untested) and “stable” (release quality) dists, so it’s pretty good, although the occasional hiccup is to be expected. My desktop environment is Xfce.

Firefox 46 contained a big change: the official binary releases are compiled using gtk3 instead of gtk2. I like using the official releases because the debian firefox package sometimes takes a little while to catch up to the latest version. For those who are unfamiliar, gtk is the graphics library for rendering the user interface, including all the widgets and their look-and-feel.

gtk3, in turn, has its own versions. In late March, gtk3 in Debian testing was updated to 3.20, which apparently contained some major changes from 3.19.

The problem is that Firefox 46 seems to work fine with pre-3.20 versions of gtk3; with 3.20, however, scrollbars, radio buttons and other widgets are rendered incorrectly or are even missing entirely. One of the bug reports can be found here.

You can apparently work around this issue if you use certain gtk3 themes. Not being a theme guru, I’m not sure exactly why; I was only able to determine this by experimenting with different themes and seeing how the Firefox rendering changed.

Okay, fine: I’d been using the default Xfce theme, which I quite like, but I’m willing to change it to make Firefox work. But I still encountered 2 problems with this workaround: 1) 3.20 is so new that many gtk3 themes included in Debian testing are broken because they haven’t been updated yet to be compatible. While I could get the scrollbars and radio buttons to work with some of these themes, there were often spacing issues around certain widgets, making UIs unusable or extremely annoying. 2) I need to find a theme that supports BOTH gtk2 and gtk3, since Xfce uses gtk2, otherwise I’ll end up with inconsistent look-and-feel across applications. Not all themes support both.

People complain about the state of the Linux desktop all the time, but the fact is, there are many moving parts that comprise a desktop environment. It’s a complex web of dependencies. Sometimes this means certain software packages have to be locked in to previous versions. Sometimes the newest version of a library can’t go into a distribution because it would break too many things that use it. Being able to run the latest and greatest versions of everything is a LOT harder than one might imagine.

In this case, I’m sure there will be a fix in Firefox and/or updates to the gtk3 themes soon enough.

Algorithms II: An Aside in Week 2 on Learning to Code

I finished Part I a while ago (yay!) and am currently in week 2 of Part II.

Tangential thoughts: a particularly challenging aspect of studying algorithms is proof of solvability and correctness. How can you tell if a computation is possible to solve at all? If you devise a new method for computing something, how do you know that it really works in every case? Mathematical reasoning can allow you to definitively prove that something does what you intended it to do. This is especially important when empirical verification makes it difficult or even impossible to cover all possible cases.

Sedgewick usually glosses the proofs in his lectures, since they’re not the core focus of the course. Some of these proofs are pretty hard to grasp even at a general level of description.

This aspect of algorithms dovetails with my excursion into functional programming in that both are deeply mathematical. They both indicate a view of computing as a branch of formal mathematics. Edsger Dijkstra was a strong proponent of this approach to computer science. I don’t claim to understand what this means in a very deep way, but I found the following example in Dijkstra’s essay, “On the Cruelty of Really Teaching Computer Science”, extremely helpful in starting to grasp this principle:

Consider the plane figure Q, defined as the 8 by 8 square from which, at two opposite corners, two 1 by 1 squares have been removed. The area of Q is 62, which equals the combined area of 31 dominos of 1 by 2. The theorem is that the figure Q cannot be covered by 31 such dominos.

Another way of stating the theorem is that if you start with squared paper and begin covering this by placing each next domino on two new adjacent squares, no placement of 31 dominos will yield the figure Q.

So, a possible way of proving the theorem is by generating all possible placements of dominos and verifying for each placement that it does not yield the figure Q: a tremendously laborious job.

The simple argument, however, is as follows. Color the squares of the squared paper as on a chess board. Each domino, covering two adjacent squares, covers 1 white and 1 black square, and, hence, each placement covers as many white squares as it covers black squares. In the figure Q, however, the number of white squares and the number of black squares differ by 2—opposite corners lying on the same diagonal—and, hence, no placement of dominos yields figure Q.

Not only is the above simple argument many orders of magnitude shorter than the exhaustive investigation of the possible placements of 31 dominos, it is also essentially more powerful for it covers the generalization of Q by replacing the original 8 by 8 square with any rectangle with sides of even length. The number of such rectangles being infinite, the former method of exhaustive exploration is essentially inadequate for proving our generalized theorem.

And this concludes my example. It has been presented because it illustrates, in a nutshell, the power of down-to-earth mathematics; needless to say, refusal to exploit this power of down-to-earth mathematics amounts to intellectual and technological suicide. The moral of the story is: deal with all elements of a set by ignoring them and working with the set’s definition.

The bombshell here is that learning to code shouldn’t be treated as a matter of what he calls its “operational semantics.” It’s a mistake to focus on what code does or how it behaves in its execution. Instead, you should think about code as a purely formal system:

… A programming language, with its formal syntax and with the proof rules that define its semantics, is a formal system for which program execution provides only a model. It is well-known that formal systems should be dealt with in their own right and not in terms of a specific model. And, again, the corollary is that we should reason about programs without even mentioning their possible “behaviors.”

This isn’t academic. When people often talk about the ability to “reason about code,” I think this is what they’re talking about. It’s a skill that can be hard to pin down exactly, but you can recognize it right away in the programmers who have it. They can well envision the challenges in designing a piece of software without being at a computer or writing any code; they can predict the consequences that a given change has for complex systems; and they can often effectively troubleshoot bugs by asking the right questions rather than rooting around in code. This is the holy grail of programming.

Needless to say, it’s a life-long pursuit.