Java’s Nimbus look-and-feel and custom keymaps

I recently discovered that the Nimbus look-and-feel in Java ignores background colour that’s been set using setBackground() on a JEditorPane. Apparently this is not a bug; look-and-feels are allowed to ignore the colour that you specify with setBackground() (though this raises the question of why the method even exists). With Nimbus, it turns out, you can control background painting by setting a “client property” on the editor pane (using putClientProperty()) – specifically, you set the “Nimbus.Overrides” property to a UIDefaults object, which is essentially a property-value map. The “EditorPane[Enabled].backgroundPainter” property is supposed to be set to a BackgroundPainter which Nimbus will then use, though if you set it some other object type (such as a String or even a Color) it will ignore the property and instead paint the background using the colour that was set with setBackground() – which of course raises the question of why it couldn’t do this in the first place, but, meh, whatever; at least we have a solution. (Any properties which Nimbus needs that aren’t in your provided UIDefaults will be inherited from Nimbus’ default property set).

There is (of course) Only One Problem.

Setting the “Nimbus.Overrides” client property apparently prevents any custom keymaps that you might have assigned to the JEditorPane from working. This is true even when the UIDefaults table you provide is empty, implying that the mere act of assigning something to the Nimbus.Overrides property is changing behaviour of the look-and-feel, which is surely broken.

I’ve submitted a bug to Oracle (via bugs.java.com) though the hit rate on getting a response for them hasn’t been 100%, so we’ll see what happens. Once you submit you get the following text:

What’s Next?

We will review your report. Depending upon the completeness of the report and our ability to reproduce the problem, either a new bug will be posted, or we will contact you for further information. You will be notified by email in either case.

… (emphasis mine) – however I’ve submitted reports in the past which got no response. I will update this blog entry if/when I receive an acknowledgement. (A few minutes later – first update! I’ve received an automated email stating that “We are evaluating this report and have stored this with an Review ID: JI-9012303”).

Update 24/05/2104: I still haven’t heard anything, but today I discovered this. So, it looks like this was recognised as a bug, but I, the initial reporter, was never notified at all – this seems like poor form. At least my report wasn’t wasted.

Test case below.

Continue reading “Java’s Nimbus look-and-feel and custom keymaps”

Advertisements

Cinnamon (again) and hacky non-bugfixes

After getting frustrated with Ubuntu’s Unity interface to the point of wanting to bludgeon myself to death with a bag of squirrels, I tried out Cinnamon by manually installing the latest version. It’s actually pretty nice, except for one major annoyance: every time I get a skype message, it un-minimises the relevant chat window and brings it over the top of my current foreground window/process. This is really annoying. There is a bug entry in Cinnamon’s bug database, but it closes with this frankly disturbing comment by someone called Clement Lefebvre (clefebvre):

I don’t like the idea of this being configurable.. mainly because this isn’t a question of preference but a question of fixing a bug. The focus should always be taken when the user launches a new app and never be taken on his behalf when he doesn’t trigger the creation of new content.

For Skype, I fixed the bug with this https://github.com/linuxmint/Cinnamon/commit/c5bbcad1cc4cc8183f2556deef867d0fae5f0109

Well, right, it’s a bug and should be fixed properly, but, check out the fix:

if (!window || window.has_focus() || window.is_skip_taskbar() || window.get_wm_class() == “Skype”)

What the … it actually checks for Skype and handles it specially. That’s got to be wrong. Clement then goes on to say:

For other apps which face a similar issue, I’d like people to insert the following code at line 27 in /usr/share/cinnamon/js/ui/windowAttentionHandler.js:

global.log_error(“Focus stolen by : ” + window.get_wm_class());

Then restart cinnamon, and when the focus is stolen from you, click on the ^ applet, troubleshoot, looking glass, click on the error tab, and you should see the wm class name of the app which stole your focus. Give me that wm class name, and we’ll add it to Cinnamon.

Oh for fuck’s sake… this is not how you do these things. Fix the bug in Cinnamon, make it respond to notifications properly for all apps; don’t just implement a workaround on an app-by-app basis. Am I missing something here? Surely other window managers aren’t implementing this workaround (because they don’t need to, because they handle the notification correctly in the first place)? This doesn’t exactly inspire confidence in the quality of Cinnamon.

PHP, thou art a wart on the face of the web

I’ve long despised most dynamically typed languages, for reasons which I’ve yet to properly enunciate, but I’ve begun to loathe one above all the others: yes, I’m referring to the abomination that is PHP. I’ve never got around to properly writing about why I abhor it so much but I was recently given a link to an article on another blog, which contains (amongst a much larger and very well argued discussion) this little gem (reproduced with permission):

I can’t even say what’s wrong with PHP, because— okay. Imagine you have uh, a toolbox. A set of tools. Looks okay, standard stuff in there.

You pull out a screwdriver, and you see it’s one of those weird tri-headed things. Okay, well, that’s not very useful to you, but you guess it comes in handy sometimes.

You pull out the hammer, but to your dismay, it has the claw part on both sides. Still serviceable though, I mean, you can hit nails with the middle of the head holding it sideways.

You pull out the pliers, but they don’t have those serrated surfaces; it’s flat and smooth. That’s less useful, but it still turns bolts well enough, so whatever.

And on you go. Everything in the box is kind of weird and quirky, but maybe not enough to make it completely worthless. And there’s no clear problem with the set as a whole; it still has all the tools.

Now imagine you meet millions of carpenters using this toolbox who tell you “well hey what’s the problem with these tools? They’re all I’ve ever used and they work fine!” And the carpenters show you the houses they’ve built, where every room is a pentagon and the roof is upside-down. And you knock on the front door and it just collapses inwards and they all yell at you for breaking their door.

That’s what’s wrong with PHP.

I’ve not really ever had to write much PHP but I’ve sat looking over the shoulder of someone who was in the process of coding some small PHP scripts, and I was horrified. The problems with the ‘==’ operator, and the overloading of the function return types, were particularly unsettling. I’ve written previously about my difficulty in just compiling PHP so that it worked as I wanted – which just adds to the feeling that PHP was simply slapped together from a load of unrelated pieces, and it was only by chance that a turing-complete language emerged. One of these days I’ll get around to explaining just why dynamic languages are bad, but in the meantime get some entertainment (and perhaps education) by reading Eevee’s post.

2012-05-05 addendum: Add “insecure” to my list of gripes.

Evince installation documentation

I just upgraded Evince on my system. Initial attempts were unsuccessful; I got the following message when trying to start it:

(evince:22841): GLib-GIO-CRITICAL **: Settings schema ‘org.gnome.Evince.Default’ is not installed

I have no idea what this means so in the interim I try upgrading ‘glib’. This mostly goes without hiccups (except that newer versions of glib apparently have a dependency on libffi, for reasons which are tentatively explained in the glib README), however, I get the same error message when I try to start Evince. After some Googling, I discover the necessity of ‘compiling the schemas’:

# glib-compile-schemas /usr/share/glib-2.0/schemas

No mention at all of this in Evince build documentation. It looks like the schema might be compiled automatically if you “make install” Evince without setting DESTDIR, but frankly the necessity of compiling the schema should be documented.

X keyboard crap

I’m getting this in my log when I try to start X:

[  7780.894] (EE) Error compiling keymap (server-0)
[  7780.894] (EE) XKB: Couldn’t compile keymap
[  7780.894] XKB: Failed to compile keymap
[  7780.894] Keyboard initialization failed. This could be a missing or incorrect setup of xkeyboard-config.
[  7780.894]
Fatal server error:
[  7780.894] Failed to activate core devices.

What’s going on? “Couldn’t compile keymap” has to be one of the most useless error messages ever. Why can’t you compile the keymap??!

Update:

I renamed the “xkbcomp” executable and replaced it with a script which logged options and output before executing the original. I’m seeing this output:

The XKEYBOARD keymap compiler (xkbcomp) reports:
> Error:            Cannot open “/tmp/server-0.xkm” to write keyboard descriptio
>                   Exiting

… However, I don’t understand why it’s unable to create a file in /tmp. I’ve verified the file doesn’t already exist before xkbcomp is run, and that all users can create files in /tmp (the “t” bit is set).

Once again, the error message is bad: please tell my why you can’t open the file. (Hint: it’s called perror).

Update: (Solved!):

Turns out the permissions were the problem. They were:  rwxr-xrwt, i.e. the group was denied write permission. I didn’t think this was a problem seeing as “other” users are allowed to write files, but apparently that’s not how Linux permission checking works.

Lies, damned lies, and Rails documentation

I was recently playing with Rails again. A while back a site I was working on had an issue where the parameters from an uploaded form were all coming in as file objects – even the parts that didn’t correspond to uploaded files. The client in this case was some Java software using the Apache Httpclient library. We’d only recently upgraded Rails, and it turned out we were seeing the problem described here:

http://blogs.sun.com/mandy/entry/rack_and_content_type_fo

The problem was easily worked around. This led me on a hunt, however, for some documentation on how exactly you are meant to handle form uploads in Rails. About the only vaguely official-looking documentation I can find at this point is the Action Controller Overview guide, which has this to say:

Note that parameter values are always strings; Rails makes no attempt to guess or cast the type

Clearly baloney. If one of the form parts is a file upload, then what you get is an object with several methods defined including “read” to return the contents of the file as a string, as well as things like “original_filename” which tell you the filename as specified by the uploader. None of this is documented anywhere.

It’s this “we don’t need to document it” attitude that really annoys me about Rails. Sure, there’s all this magical stuff you can do with it and it has all these built-in goodies that can save you hours of coding just by using magic variable names (except for those times of course when you have to spend hours debugging, because you used one of those magic variable names by mistake and without realising). But there’s just no reliability with the API. The params hash for instance – what exactly am I allowed to do with a value I pull from the hash? Can I be sure that it will either be a string or one of these mysterious file upload objects? This isn’t the only omission in the documentation; for instance what does the “session” method in ActionController::Request actually return? What am I allowed to call on it?

This is the real strength of languages with strong typing – programs written in them are, to a certain degree, self-documenting. If I know what type a method actually returns then I know for certain what methods I can call. No nasty surprises when the framework developers suddenly decide to make it return a different kind of object!

Edit 27/8/2010: Another major strength of statically-typed languages that I forgot to mention is of course the ability to refactor code with the assistance of automated tools. As discussed in this blog post by Cedric (and I love the title).

FUSE, and ways in which it sucks.

I’ve just started toying around with Fuse. The possibilities of writing comprehensive filesystems in user space interests me, not the least because it makes development much easier before you move to kernel space.

I’ll say it right out, Fuse is certainly not the worst conceived / designed/ implemented piece of software by a long shot. The documentation isn’t great, but it’s not totally lacking either (which immediately puts Fuse a cut above a whole swathe of other open source projects). It’s not perfect however.

My main annoyance is the multi-threading support which, frankly, shouldn’t exist; i.e., it should be handled by the application and not the library. It is, generally, better when software layers are thin; it should be up to the app to do appropriate locking etc., and the library (in this case Fuse) should just specify in the documentation where the locking is needed (or rather, more usefully, where it is not needed). Ok, quibbles, and providing more functionality is hardly a crime; after all, the low-level layer is still available and (mostly) unobfuscated by the higher-level functionality.

The real issue is that linking against libfuse pulls in the pthread shared library as well, which is not so good. The pthread library incurs overhead (other than taking up memory/address space) because when it is loaded, locking and unlocking mutexes suddenly become real operations – which means fputc() and a whole bunch of other library functions become a weeny bit slower. (Don’t believe me? do “nm” on /lib/libc.so and /lib/libpthread.so and notice that they both define pthread_mutex_lock).  Fuse should really be split into two librarys, libfuse and libfuse_mt, and only the latter should require pthreads. (Or, as I suggested earlier, just ditch the multi-thread functionality altogether, leave it up to the application to pull in pthreads if it really needs it).

Another annoyance is the fuse_chan_receive function:

int fuse_chan_recv(struct fuse_chan **ch, char *buf, size_t size);

Notice that first argument? Not just a pointer, it’s a pointer-to-a-pointer. Why, great Zeus, why??! The function is meant to receive data from a channel, in what crazy circumstance would you want it to change the channel pointer itself to point at something else? And in fact, the function delegates to a another function via a pointer (embedded in **ch) to a fuse_chan_ops structure; in the library itself, as far as I can see, there are only two implementations (one to receive directly from the kernel, and another called mt_chan_receive) and neither of them does actually alter the value of *ch. If you have a look at the implementation of fuse_loop() though you’ll notice the author clearly had the possibility in mind, since he copies the channel into a temporary pointer variable (tmpch) before using fuse_chan_recv – so yes, the bad API design has caused increased code complexity.

The comments above the declaration of fuse_chan_recv don’t give any clue as to why it would ever modify the *ch value and incidentally ch is incorrectly documented as being a “pointer to the channel” when it is of course really a “pointer to a pointer to the channel”.

Oh, and the mt_chan_recieve function I mentioned earlier – well, it presumably has something to do with the multi-threading support, but it’s hard to be sure because the function lacks anything bearing the slightest resemblance to a comment, and there certainly isn’t any other explanation of what it does nor how it works.