Squibid's Blog My blog. en-us http://squi.bid/blog/rss.xml 'New Keyboard!' https://squi.bid/blog/New-Keyboard!/index.html https://squi.bid/blog/New-Keyboard!/index.html Tue, 12 Aug 2025 03:23:38 -0400 'New Keyboard!'

New Keyboard!

tl;dr show me the board

Throughout the past few years I've hopped from keyboard to keyboard initally as a need for something to type on, but eventually as an obession with the sound and feel which to this day I cannot shake.

Keyboard #1

I started on a Razer Cynosa Chroma which as far as I can tell is no longer for sale. But for the sake of context you should know that it's a 100% membrane keyboard with per key backlighting. For a starter keyboard it was fine, but looking back any old office keyboard would've worked and the $40(?) that I spent on it was not worth it. But who cares, lets go to the next keyboard!

Keyboard #2

After being pushed by a friend who was obsessed interested in keyboards I finally took the plunge and built my first custom keyboard. This keyboard was a what I thought would be best after using a membrane for over two years (I had very little clue what I was doing). I ended up choosing a TKL board called the NINJA87BT which came with gateron milky yellow switches. This may not sound custom, but then I went and ordered some very very expensive switches called Helios v2s which are very quiet and so soft to type on. I also bought some keycaps with legends printed on the side nothing too expensive, but very nice to look at. Because this was my first board I had no clue what I was doing and I ended up spending around $300...

Keyboard #3

I started thinking about the future and how I really needed to take care of the hands that I use every day for programming. Though I wanted to go fully ergonomic, like where I'm at now, I chose to pace myself and decided to go with a UHK 60v2. It was expensive, but it promised something spectacular: a split keyboard without the ortho keywells and qmk configuration of my current keyboard which would've been very hard to switch to coming from a normal TKL. Instead of sticking with the cherry reds it came with I put my Helios in (because they are still the best switches I've ever felt). While this board was not nearly as custom as my last I was able to enjoy it much more knowing I was not going to get carpel tunnel halfway through my life.

I ended up using this board for about a year and a half until around mid July of 2025 when I updated the firmware for the first time since getting the board and it caused the keyboard to start crashing every once in a while. I tried to roll back to the version I was using before, but my configuration wasn't able to migrate back. So I decided it was time to move on to the keyboard I'd been dreaming of making.

Keyboard #4 (my current one)

The keyboard I've been typing this post on is a dactyl manuform 4x5, and It's my first truly hand built keyboard. I 3d printed the case, sanded, primed, painted (although it did not hide the layer lines very well), and wired. Wiring was a bit tricky but thanks to the pictures in the github repo I was able to do it without too much trouble.

After finishing the wiring, which took around 12 hours, I tried to flash qmk to both halves. At which point realized that the right half had the rows wired to the arduino pro micro in reverse order. After fixing the slight hiccup I flashed and viola a working keyboard. I then put on some black legend-less keycaps, and here is the final(ish) result:

The ish in final(ish) is because I've yet to add a baseplate which would add some much needed weight so the halves doesn't slide across my desk, but for now I'm happy with it.

Build your own

Incase you're reading this in the hopes of some tips for building your own here they are:

  • get the model for the keyboard from ryanis.cool/dactyl/#manuform
  • when wiring your keyboard try and make the wires going from the rows/columns around 1.5-2x longer than they need to be that way you don't snap when you're fiddling around in there
  • if you want to get rid of layer lines look into acetone dipping your print, I only learned about this after showing my fully wired board to a friend otherwise I would've done it

When it comes to using my keyboard it's setup for typing as that's what I do on it it most of the time, however when I play games things get a bit tricky. For games where I can remap the keys I shift every key over by one except for the keys on the bottom row, and then I set the sprint key as a. For the games where I can't remap the keys... I just stop playing them. If I had more of an interest in gaming I would've gone with the 4x6 as 6 more keys it offeres could've been really nice.

For those curious about the specs: I decided on a rj9 port mainly because I like the look of them over the TRRS cables everyone seems to be using nowadays. For the pro micro I went with the cheapest one I could find with a usb-c port, you can't really go wrong here. As for the actual layout my qmk config is below incase you really wanna know how I type:

/*
This is the c configuration file for the keymap
Copyright 2012 Jun Wako 
Copyright 2015 Jack Humbert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.  If not, see .
*/
#include QMK_KEYBOARD_H
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
  switch (keycode) {
    case KC_BSPC: {
      static uint16_t registered_key = KC_NO;
      if (record->event.pressed) {  // On key press.
        const uint8_t mods = get_mods();
#ifndef NO_ACTION_ONESHOT
        uint8_t shift_mods = (mods | get_oneshot_mods()) & MOD_MASK_SHIFT;
#else
        uint8_t shift_mods = mods & MOD_MASK_SHIFT;
#endif  // NO_ACTION_ONESHOT
        if (shift_mods) {  // At least one shift key is held.
          registered_key = KC_DEL;
          // If one shift is held, clear it from the mods. But if both
          // shifts are held, leave as is to send Shift + Del.
          if (shift_mods != MOD_MASK_SHIFT) {
#ifndef NO_ACTION_ONESHOT
            del_oneshot_mods(MOD_MASK_SHIFT);
#endif  // NO_ACTION_ONESHOT
            unregister_mods(MOD_MASK_SHIFT);
          }
        } else {
          registered_key = KC_BSPC;
        }
        register_code(registered_key);
        set_mods(mods);
      } else {  // On key release.
        unregister_code(registered_key);
      }
    } return false;
  }
  return true;
}
#define _BASE 0
#define _RAISE 1
#define _LOWER 2
#define SFT_ESC  SFT_T(KC_ESC)
#define CTL_BSPC CTL_T(KC_BSPC)
#define ALT_SPC  ALT_T(KC_SPC)
#define SFT_ENT  SFT_T(KC_ENT)
#define KC_ML KC_MS_LEFT
#define KC_MR KC_MS_RIGHT
#define KC_MU KC_MS_UP
#define KC_MD KC_MS_DOWN
#define KC_MB1 KC_MS_BTN1
#define KC_MB2 KC_MS_BTN2
#define RAISE MO(_RAISE)
#define LOWER MO(_LOWER)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_BASE] = LAYOUT(
        KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,                                         KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,
        KC_A,    KC_S,    KC_D,    KC_F,    KC_G,                                         KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN,
        KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,                                         KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_QUOT,
                          KC_LBRC, KC_RBRC,                                                        KC_MINS, KC_EQL,
                                                     KC_LCTL, KC_LSFT, KC_TAB, RSFT_T(KC_ESC),
                                                     KC_SPC,  KC_LALT,  KC_ENT,  KC_BSPC,
                                                     LOWER,   KC_LGUI,   KC_RGUI, RAISE
    ),
    [_RAISE] = LAYOUT(
        QK_BOOT, KC_MPRV, KC_MSTP, KC_MPLY, KC_MNXT,                                      KC_PGDN, MS_BTN1, MS_BTN2, KC_PGUP, KC_VOLU,
        _______, MS_LEFT, MS_DOWN, MS_UP,   MS_RGHT,                                      KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT, KC_MUTE,
        _______, MS_WHLL, MS_WHLD, MS_WHLU, MS_WHLR,                                      KC_BSLS, KC_SLSH, KC_LBRC, KC_RBRC, KC_VOLD,
                 _______, _______,                                                                          _______,  _______,
                                   _______, _______,                                      _______, _______,
                                                     _______, _______,  _______, _______,
                                                     _______, _______,  _______, _______
    ),
    [_LOWER] = LAYOUT(
        KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC,                                      KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN,
        KC_1,    KC_2,    KC_3,    KC_4,    KC_5,                                         KC_6,    KC_7,    KC_8,    KC_9,    KC_0,
        KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,                                        KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,
                 KC_F11,  KC_F12,                                                                           KC_GRV,  _______,
                                   _______, _______,                                      _______, _______,
                                                     _______, _______,  _______, _______,
                                                     _______, _______,  _______, _______
    )
};
		
]]>
'Serializing data in C' https://squi.bid/blog/Serializing-data-in-C/index.html https://squi.bid/blog/Serializing-data-in-C/index.html Sat, 09 Aug 2025 08:50:12 -0400 Why "suckless" software is important https://squi.bid/blog/Why-"suckless"-software-is-important/index.html https://squi.bid/blog/Why-"suckless"-software-is-important/index.html Sun, 14 Jan 2024 20:22:27 -0500 'Why "suckless" software is important'

When it comes to learning how to program there are a few things you can do:

  1. Read a textbook
  2. Watch videos
  3. Read some source code

Of these options I find the best way to truly learn how to program is to read someone else's program and try and understand it. For example recently I've been working on my own dmenu clone for Wayland. Throughout working on it instead of looking for tutorials on how to render a square using pixman I decided to take a look at dtao which is a clone of dzen for Wayland. By just reading the code and messing around with the program I was able to get an understanding for how rendering is done in pixman.

Now you may be asking yourself something like: "But what does this have to do with suckless software?". The answer to that is in their philosophy which is about: "keeping things simple, minimal and usable". The idea of keeping things minimal and useable allows them to create wonderful programs that not only work, but also showcase how to do things without extra fluff that something like i3 might have.

Even if you don't like suckless software it still serves as a great place to learn how to do the bare minimum. And for those who do enjoy using it, it can serve as a great starting place to hack upon until you get the software of your dreams.

]]>
What is a squibid? https://squi.bid/blog/What-is-a-squibid/index.html https://squi.bid/blog/What-is-a-squibid/index.html Mon, 30 Oct 2023 12:47:05 -0400 'What is a squibid?'

Recently, a few people have been asking me: "what is a squibid?" or "where did your name come from?". In this blog post I will answer those questions.

A few years ago I came up with a drawing of an animal reason to do anything with it, but regardless I chose to name it a squibid. Eventually, when trying to find a good username I chose squibid because that would cover both the username and profile picture.

]]>
librex and dots https://squi.bid/blog/librex-and-dots https://squi.bid/blog/librex-and-dots Tue, 27 Jun 2023 12:17:35 -0400 Hello!

In my first post state of the site I talked about a searxng instance however I found something better! I am now running a librex instance @ https://librex.squi.bid. My only modification to the site is changing the theme to the mellow theme.

As for my dots. I have continued to update my Neovim dotfiles, and I am currently in the process of making some MPV dot files. After I am done with my MPV config I'll get to work on putting together a git repo with my dotfiles (using submodules for the bigger parts of the config like Neovim).

I will also soon be setting up a Matrix account (not instance) but for now feel free to email me.

]]>
It's Alive! https://squi.bid/blog/It's-Alive! https://squi.bid/blog/It's-Alive! Mon, 17 Apr 2023 13:22:03 +0000 Cloning via http(s) now works!

btw I will be posting my dotfiles soontm

]]>
state of the site https://squi.bid/blog/state-of-the-site https://squi.bid/blog/state-of-the-site Sat, 11 Mar 2023 15:00:32 -0500 Hello o/, and welcome to my website!
As of right now I am still setting things up, I have a git server running but I am still working on getting cloning to work via https. On top of the git server I also have a cgit instance which I have gotten close to perfect (for some reason the site is only sometimes in darkmode).

As of right now that is all I've got running but I might be setting up a SearXNG instance soon.

However somethings that I will never put on my server are:
- social media frontend's eg: invious, and mastadon
- probably some other things that I can't think about right now

]]>