Nicholas Rinard Keene's Little Bit

I don't have a lot to say, but this is my little bit.

Monday, June 9, 2025

eBay seller 'stuckinlove7' is a scam

eBay is a fun place to find random stuff for sale direct from sellers. Some of those sellers are scammers and eBay doesn't do a lot about that, partially because it is difficult and partially because they already made their money. Everyone else has low priority after eBay gets its cut.

I get it. Screw me. Okay. All I can do about it is tell the internet that 'stuckinlove7' is a scammer, they ship empty boxes to wrong addresses on purpose. It's a common scam and incidentally 'fratolle_0' also runs the same scam.

Now my broad readership can protect themselves. Cheers.

Friday, April 25, 2025

CSS improvements for Gnome Nautilus

I customized my Gnome UI in some ways that I think are really important.

  • The active window is bordered by several pixels of the highlight color, which makes it more visible and also gives the mouse a few pixels by which to resize the window. I have often been frustrated by single-pixel window borders, whats the point of that?
  • The active window also lifts up with a shadow behind it, making it feel extra engaged.
  • The nautilus window uses subtly shaded stripes when listing files, so that the eye has an easy time scanning over from the filename to the metadata.
  • The nautilus window list items lift up with a box shadow and a text shadow when rolled over, and all of the effects apply to selected items too.
  • Similar effects work in the sidebar.



.nautilus-window .view row:nth-child(odd) {

   background-color: rgba(255, 0, 0, 0.05);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.05);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.05);

margin-top: -3px;

}


.nautilus-window .view row:nth-child(even) {

   background-color: rgba(0, 0, 0, 0.10);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.00);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.00);

margin-top: -3px;

}


.nautilus-window .view row:nth-child(odd):hover {

   background-color: rgba(0, 0, 0, 0.05);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.20);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.20);

}


.nautilus-window .view row:nth-child(even):hover {

   background-color: rgba(0, 0, 0, 0.10);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.25);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.25);

}



.nautilus-window .view row:nth-child(odd):selected {

   background-color: rgba(0, 255, 128, 0.05);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.20);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.20);

}


.nautilus-window .view row:nth-child(even):selected {

   background-color: rgba(0, 255, 128, 0.10);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.20);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.20);

}





list {

   background-color: rgba(0, 255, 128, 0.90);

   border-top-style: solid;

   border-top-width: 3px;

   border-top-color: rgba(0, 0, 0, .10);

}

overlay {

   border-top-style: dashed;

   border-top-width: 1px;

   border-top-color: rgba(0, 0, 0, .10);

}


list row {

   background-color: rgba(0, 0, 0, 0.10);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.00);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.00);

}


list row:hover {

   background-color: rgba(0, 0, 0, 0.10);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.20);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.20);

}

list row:selected {

   background-color: rgba(0, 255, 128, 0.12);

   border-right-style: solid;

   border-right-width: 3px;

   border-right-color: rgba(0, 0, 0, 0.20);

   border-bottom-style: solid;

   border-bottom-width: 3px;

   border-bottom-color: rgba(0, 0, 0, 0.20);

}


@import 'colors.css';

Wednesday, May 18, 2022

TEK Cleave Keyboard Review

My history with keyboards started as a senior in college when my wrists started to hurt. I decided then and there that I would spend my career using properly ergonomic keyboards, which meant split columnar. My first was in 2002, a FingerWorks TouchStream. That was an amazing gesture-touch input device which was excellent for everything except typing.

For typing, you really want the tactile feedback of buttons so after a few years I replaced the FingerWorks with a Truly Ergonomic Keyboard which I really loved. This was during the period when do-it-yourself keyboard community was coming together, and when new formats became more common starting with the venerable ErgoDox. I switched to an EZ, wrote a custom four-layer layout for myself, and came to really appreciate that design. I've used it for over a decade now.

Recently the folks at TEK sent me their new Cleave keyboard to review. I spent time using it and I'll compare it to the ErgoDox and to the original TEK.

Switches

The Cleave ships with high end infrared mechanical keyswitches. Instead of making an electrical contact at the bottom of the keystroke, the mechanism interrupts an infrared LED to actuate the keystroke. They claim these will last longer but for me the takeaway is that the sensation of producing a button press is very smooth and consistent. I never miss a letter by slightly underpressing the key. They feel great. They are tactile keyswitches which is what most people prefer, although myself I prefer linear. The keyswitches can be swapped out easily but most people won't bother because these are very good.

Baseplate

A keyboard should sit heavily and steadily on a desk so the baseplate is important. This one is stiff and heavy, made of aluminum. It feels nice, it is heavier and sturdier than my ErgoDox EZ. The whole thing feels right, you can pick it up without flexing, it can clunk down without worry.

Keycaps

Some keyboard nerds like unmarked keycaps because that's elite, but I like keycaps marked with their glyphs. Some people point out that unmarked caps can be remapped without mismatching the cap marking, but my retort is that keyboards only need to be mapped once and then used forever. I'm not rearranging the base layer of my keyboard very often, or ever.

The Cleave has nice cylindrical keycaps, either OEM or DCS or similar shape. The glyph font is nice and the shint-through is pretty. The sound they produce is satisfying, a light click on my version.

Backlighting

My main ErgoDox is the original unlit version. I also own the underlit Shine version and the backlit Glow version but I don't use them because the lighting is unsatisfying. I don't care for underlit at all, and the EZ Shine's backlighting is weak, mushy-colored, and doesn't cover the whole board. I think the folks selling the EZ were aiming for the gamer boi l33t h4x0r RGB crowd.

By contrast, the Cleave's backlighting seems to be targeted at professionals who want an attractive useful keyboard used often in low light. That's me. The lights are clear white, not mushy, they don't flash, and they'll never impress middle schoolers. 10/10

Key Arrangement

I use qwerty layout which is preset on the Cleave. Many ErgoDox users remap to a different layout but not me, I set up mine with as ordinary of a layout as possible on the main layers. Each of these keyboards has an appropriate columnar-staggered layout; that means the letter button placements on both keyboards are equal.

The Cleave has a dedicated Escape key in the proper location: separate from the other rows of keys, up to the left in the corner. That is where Escape belongs and the Cleave has it but the ErgoDox doesn't.

On the other hand, the Cleave puts arrow and nav keys in little clusters underneath the letter buttons whereas the ErgoDox has another row of buttons. I use the ErgoDox buttons for Command, Option, Hyper, Meh, and Control. The Cleave  lacks all of these and instead has two buttons for Control and Option on the far outside bottom corners under the Shift key. There are configuration options to move Command onto the caps lock key, or one of the spacebars, which a lot of people like.

Thumbs

Proper ergo keyboards move more functionality from pinky to thumb. Both Cleave and ErgoDox do this but the Dox does it a little better. The Cleave has basically two buttons per thumb but the Dox has quite a few depending on how far you reach; I commonly use my thumb for all three lower buttons in the thumb cluster plus three more of the command buttons.

But let me say one thing, which is that the Cleave has nice wide horizontal space bars, like they should be. ErgoDox really requires you to hit an exact spot for the space bar and it took adjustment not required by the Cleave.

Division

Both keyboards are split into left hand and right hand sections but the Cleave is on a single board whereas the ErgoDox is divided into two parts. Most people are comforted by a single unit keyboard but I've found over a decade of use my hands have drifted farther and farther apart, now at the maximum allowed by the connector cable. In my opinion, having a split-not-divided board like the Cleave robs users of the opportunity to evolve their typing toward greater comfort.

Programmability

I'm not aware of deep firmware customizability on the Cleave. If it has it, it's not QMK which is the nerd's choice for keyboard firmware. My ErgoDox has not only a custom layout but some of the layer setup has custom C code. Almost all users won't do that but I did and you can't do it on a Cleave.

Bottom Line

The reasons that I won't be giving up my ErgoDox are not reasons most keyboard users share: I want divided left and right with more thumb buttons and customizable firmware. My willingness to use unusual keyboards is already greater than the audience served by the Cleave, which is an audience I used to be in and to whom I would recommend the Cleave. People more like me can look at an ErgoDox or Iris. As for me, if I give up my ErgoDox it will likely be for something like a Manuform.

Wednesday, December 1, 2021

TEK Cleave keyboard: introduction

 My daily driver is an ErgoDox EZ. I like it so much I bought a second one, and I liked both of those so much that I acquired a third one.

The first keeb I ever bought myself with proper adult money was a FingerWorks TouchStream which, if you know you know.

In between the FingerWorks and the EZ I used, for several years, a Truly Ergonomic Keyboard. There were a few iterations of the first version and I think I had the very first iteration. It was overall a great keyboard which I used with success for quite a while.

During that time period, the international keyboard community came together during the design and release of the open source ErgoDox platform and the comeup of QMK firmware. I watched that and really wanted a Dox for advanced thumb usage, and also for programmability.

These days there are many options for professional keyboards and the Truly Ergonomic company has upgraded and updated their TEK with the new TEK Cleave. They sent me one, I'll review it here over a series of posts.

Wednesday, November 3, 2021

Monday, October 18, 2021

Decoding Failed -- System Halted

This weekend I dusted out my computer with some compressed air. When I was done I booted it up and it... just... wouldn't. The boot sequence was different, it offered some different options and they didn't work -- regular Ubuntu option didn't work and when I tried to run a memtest it would just stop at 35%. Eventually I selected an option which chugged for a while before producing

Decoding Failed-- System Halted

I had no idea what this meant and the internet suggested that either the disk was corrupted or the memory was bad. It's a solid state drive and I hadn't touched the RAM chips. I was ready to start pulling components but instead I went back and blew it all out again -- I got underneath, I sprayed up and down the memory chips and the SATA connectors.

When I tried again it booted like normal. So add "dust" to the list of things to check out.



Wednesday, March 22, 2017

FooBar Gearing Up For Destruction

I was pulled into Google FooBar. This is my solution to the third problem I received, Gearing Up For Destruction.

Given
R0 is radius of the zeroth element
Rn is any radius of element n
Rlast is the radius of the last element
Pn is the peg position (the input int) for element n

This is an induction problem, so I solved it using a base case and an induction case:

R0 = 2*Rlast
Rn+1 = Pn+1 - Pn - Rn

To get a feel for the resulting math, I then expanded out a few iterations and saw that it formed a predictable series (written with unreduced complexity to show patterns):

Two pegs:
R0 = (2/3) * (-P0 +P1)

Three pegs:
R0 = (2/1) * (-P0 +2P1 -P2)

Four pegs:
R0 = (2/3) * (-P0 +2P1 -2P2 +P3)

Five pegs:
R0 = (2/1) * (-P0 +2P1 -2P2 +2P3 -P4)

...and so on.

So, the pattern was two times each peg, except only one times the first and last peg, and the signs flipped for each peg. Then also there was a coefficient in front of all that: 2 for odd number of pegs and 2/3 for even number of pegs.

That's the basic solution, a simple math problem, but the description also demanded reduced fractions plus recognition of logically invalid cases, so there was a little more code.

    public static int[] answer(int[] pegs) {
        // do the inductive math
        int a = pegs[0];
        int flip = -1;
        for(int peg: pegs) {
            a += 2 * peg * flip;
            flip *= -1;
        }
        a += pegs[pegs.length-1] * flip;
        a *= 2;
        int b = (pegs.length%2==0) ? 3 : 1;

        // reduce

        if(a%b==0) {
            a /= b;
            b = 1;
        }

        // reject bad values

        float prevR = ((float)a) / ((float)b);
        for(int i = 0; i < pegs.length - 2; i++) {
            int width = pegs[i+1] - pegs[i];
            if(prevR < 0 || prevR > (width-1)) return new int[] {-1, -1};
            prevR = width - prevR;
        }

        return new int[] {a, b};

    }

I really enjoyed this problem, I had to puzzle it out on paper. Coding it was made more difficult by lack of access to the test cases so it wasn't clear where the algorithm was failing. The code to reject invalid values looks straightforward but it is the residue of many failed attempts.