Profile cover photo
Profile photo
Ian Hickson

Michael Giacchino is totally welcome to write my life's theme and background music if my Miranda/Sondheim partnership doesn't pan out.
Add a comment...

I propose the following aphorism:

Indexing into a string type makes as much sense as indexing into an integer type.
Commenting is disabled for this post.

Post has attachment
My new favourite song!
Add a comment...

Post has attachment
I guess this staffer for the house permanent select committee on intelligence hasn't yet taken unconscious bias training...

(This is from the November 11th interview of Glenn Simpson. For contrast, there's an earlier meeting, from November 8th, where the introductions were conducted by the "senior counsel here at the House Permanent Select Committee on Intelligence, for the majority", who explicitly requested Ms Clattenburg's introduction. So it's not all bad up on the hill.)

See also:
Add a comment...

In Flutter, we occasionally get the question "how do you set a negative margin?". This usually comes after people find the Container widget's "margin" property, try to set it to a negative value, and find that it asserts with a message saying padding must be positive. It turns out that Container's idea of margin and padding is actually just to put a Padding widget on the outside of its DecoratedBox for the margin, and a Padding widget on the inside for the padding. Many complicated-looking widgets in Flutter tends to decompose in this way.

So how would you get a negative-margin-like effect in Flutter?

To answer this question you first have to define what "negative margins", or really "margins" in general, really are. In CSS, margins have various meanings in the various layout models, most commonly, they are one of several values that contribute to computing the offset that the block layout model uses to place subsequent children; a negative total margin in this case merely means the next child is placed above the bottom of the previous child instead of after it.

In Flutter, as in CSS, there are several layout models; however, there is currently no widget that is equivalent to the CSS block layout model (which supports margin collapsing, negative margins, skipping floats, etc). Such a layout model could certainly be implemented, it just hasn't been implemented yet, at least not in the framework itself.

To implement such a layout model, you would create a RenderBox descendant similar to RenderFlex or RenderListBody, probably providing a way to set the margins of each child using a ParentDataWidget in the same way that Flex children can have their `flex` configured using the Expanded widget.

Probably the most complicated part of designing a new layout model like this would be deciding how to handle overflow or underflow, when the children are too big or too small to fit the constraints passed to this new layout render object. The RenderFlex render object has a way to distribute the space if the children underflow, and considers it an error if they overflow (in debug mode, this is shown by a yellow-and-black striped warning area and a message logged to the console); the RenderListBody render object on the other hand takes the view that the constraints must be unbounded in the main axis, which means you can basically only use this layout model inside a list (hence the name).

If writing a new layout model is not attractive, you could use one of the existing layout widgets that allow overlapping children. Stack is the obvious choice, where you set the explicit positions of each child and they can overlap arbitrarily (this is vaguely similar to the CSS absolute position layout model). Another option is the CustomMultiChildLayout widget, which lets you layout and position each child in turn. With this, you could position each child one after the other, simulating negative margins by setting the position of the subsequent child to a value that's derived from the size and position of the previous child, but such that the subsequent child's top is above the previous child's bottom.

If there's interest in a block-like layout model, we could certainly implement it (please file a bug and describe the model you'd like implemented, or, implement it yourself and send a pull request for review). So far, though, we've not found that it has been that useful in practice, at least not useful enough to justify the complexity.

And that's why the answer we usually give to the question of "how do you do negative margins" ends up being a higher-level question in return: what effect are you really trying to achieve?
Add a comment...

I'm installing a new Linux desktop.

It's frankly embarrassing how terrible it still is. If you told me in the 90s that I'd still be hand-editing .Xresources files in 2017, I'd have laughed you out of the room. Terminals are still proudly proclaiming that they support pseudo-transparency. They all have terrible names. They seem to fall into two camps, either unusable (the rxvt family, xterm, pterm, etc) or they use an unholy amount of memory (Gnome terminal, etc). There seems to be no widely-supported way to configure a high-dpi monitor (e.g. Chrome honours Xft.dpi, but urxvt and pterm don't). I wanted to do a network install, but UEFI support in Linux installers is so primitive that I had to bootstrap by sending grub over and then having grub launch the installer. And don't even get me started on the mishmash that is networking or boot scripts and so on...
Commenting is disabled for this post.

Flutter's first big app launched this past Friday, the official Hamilton app!

The app was written by an agency (, but we (the Flutter team) helped them in the last few weeks to solve some problems they found with the framework. Mostly the big problem we ran into was around performance of rounded corner clips, but we were able to resolve those issues before launch. We also tracked down some hit testing issues. My favourite bug was with hit testing on tab bars.

We have code to make sure that when you fling a list, if you tap the list while it's scrolling, you don't actually trigger whatever's under the list, instead, you stop the list. This makes sense, because otherwise you have no way to stop the list without triggering random buttons.

Separate from this, we have code to make sure that when you change tabs, we scroll the tab you picked into view over a fixed period (about 300ms if I recall correctly).

Now, what happens when the tab is already in view? Well, we started this 300ms animation that... does nothing. It scrolled by zero pixels over 300ms. And since a scroll was happening, while that was going on you couldn't tap another tab (because the first tap was just stopping the animation). So this meant that if you tapped back and forth between two tabs, it did the first, then dropped the next tap, then did the third, then dropped the fourth, etc! Not a good user experience.

It was tricky to figure out what was going on, because when we looked at the dumps, we could see an animation was happening, but it wasn't immediately obvious that the animation was over zero distance. Luckily we were able to use some of our debug flags to narrow it down.

The fix ended up being really simple (about two lines, plus many dozens of lines of tests): just make sure that if you animateTo() a position you've already reached, do nothing!

Now that we've proved it's possible to ship a big app with flutter, our next step is to fill in the big holes: internationalization (mostly meaning localization and right-to-left support in layout), inline video, improving low-end phone performance, documentation of the animation system, that kind of thing.
Commenting is disabled for this post.

Post has attachment
Captain Disillusion is excellent.
Add a comment...

Post has attachment
This is sort of like the plot to a Daniel Suarez book, though less plausible. Ahem.
Commenting is disabled for this post.

Post has attachment
The typography and general graphic design of street signs in the US is just atrocious. These are just three that I happened to see on my walk home today, and they're not even close to the worst I've seen here.
3 Photos - View album
Commenting is disabled for this post.
Wait while more posts are being loaded