주변기기

Charybdis

작성일 수정일

Sofle을 통해 스플릿 키보드에 입문한 나는 마침내 Charybdis를 사 버렸다. Charybdis는 Sofle과 같은 스플릿 키보드이지만 (1) 트랙볼이 존재하고, (2) 더 굴곡지다는 점에서 Sofle과 대비된다.

Charybdis는 원래 Bastard Keyboards에서 나온 키보드인데, 오픈소스라서 Bastardkb GitHub에 가면 기판 설계도와 3D 프린팅 파일들이 있다. 뿌리를 따라 올라가면 Dactyl keyboard의 포크이고, 형제 키보드로는 (당연히) Scylla와 Dilemma가 있는데, Scylla는 Charybdis의 우측 thumb cluster 자리에 있는 트랙볼을 없애고, 좌측과 똑같이 5개 키를 넣은 키보드고 Dilemma는 트랙패드를 붙여놓은 물건이다.

내가 구매한 키보드는 이를 바탕으로 타오바오에서 만든 키보드다. 웬만하면 그래도 원조인 곳에서 사고 싶은 생각은 있었지만 그러기엔 좀 과하게 비싼 감이 있고 (40만원이 넘어간다… 타오바오에서 사면 10만원 조금 넘는다.) 그렇게까지 큰 메리트는 없다고 생각했다. 오히려 마지막까지 고민했던 건 Dilemma로, 이것도 분명 오픈소스인데 타오바오에서는 안 팔더라. 트랙볼보다 트랙패드가 더 편할 것이라는 건 자명한 사실이라 고민하다가 결국 지갑 사정으로 Charybdis를 샀다. 이게 정식 버전과 차이가 있는 건 펌웨어가 ZMK라서 블루투스가 지원된다는 정도이다. 키캡은 Drop의 MiTo MT3 9009 키캡을 샀다.

Charybdis-top

이건 위에서 찍은 사진인데, 지금은 아래 사진처럼 받침대를 붙여둔 상태다보니, 각도가 커져서 위에서 찍은 사진으로는 모양이 잘 안 나온다.

Charybdis-stand

한쪽만 옆에서 제대로 보면 대충 다음과 같이 생겼다.

Charybdis-side

확실한 건 Sofle보다도 적응이 힘들다는 것이다. 그중 나를 제일 귀찮게 한 건, 세벌식에서 종성을 입력하는 [ 키가 이런 작은 레이아웃에 그 자체로 할당되는 건 불가능하니, 나는 오직 이 용도로만 89를 동시에 누르면 [가 입력되도록 해 두었는데 Charybdis에서는 중지와 약지의 길이 차이를 고려하여 이들 두 키가 다른 깊이에 있어서 동시에 누른다고 눌렀는데 따로따로 입력될 때가 있다는 것이었다. 이는 다른 키들에도 사실 마찬가지라, 아직도 그렇게 타자속도가 잘 나오는 편은 아니다.

그럼에도 불구하고 전체적인 키보드의 만족도는 Sofle보다도 높은데, 우선

  1. 트랙볼은 Sofle의 조이스틱과는 비교가 안 될만큼 편하다. 나는 예전에 Kensington에서 나온 트랙볼을 몇 번 써 봤는데 그때도 나쁘지 않았었는데, 그 정도까지 바랄 수는 없지만 별도의 트랙패드나 마우스 없이도 충분히 쓸만하다. 약간 아쉬운 점은 트랙볼이 잘 빠진다는 것이다.
  2. Thumb cluster가 많다. 솔직히 Sofle은 thumb cluster라고는 하지만, 해당 키들은 엄지가 닿는 부분이라기보다는 그냥 알파열 밑에 있는 키들에 가까웠다. Charybdis는 이 영역이 아예 분리되어 있어 손을 움직일 일이 진짜 거의 없다.
  3. Thumb cluster의 배열도 좋다. 결국 thumb cluster의 키들은 하나 이상의 기능들을 수행해야만 하는데, 3키+2키로 두 줄로 되어 있어서 한 번에 여러 키를 누르기 좋다.

다만 아쉬운 것은 내 사용처에서 약간 Charybdis의 입지가 애매해졌다는 것이다. 마우스와 키보드가 일체형으로 달려있는 키보드라면, 당연히 들고 다니면서 쓰기에 좋을 것이고 처음에 살 때도 그렇게 생각했다. 그런데 우선 트랙볼이 계속 빠지니 들고 다니기는 약간 귀찮은 감이 있기는 있고, 무엇보다 다리도 달고… 손목받침도 사고… 하다보니 갖고 다니기에는 부담스러운 사이즈가 되어버렸다. 결국 들고 다니는 걸 Sofle+Magic Trackpad 조합으로 쓰고, 집에서는 순수하게 Charybdis만 썼었는데 최근에 제스처가 그리워져서 집에서 사용할 용도의 Magic Trackpad를 또 들여왔다. 근데 또… 구 Magic Trackpad (검은색)는 8핀이고, 새로 들여온 Magic Trackpad (흰색)은 C타입인데, Sofle이 검은색, Charybdis가 흰색이다보니 당연히 구 Magic Trackpad를 Sofle과, 새 Magic Trackpad를 Charybdis와 쓰게 되는데, 아무래도 들고 다니는 용의 키보드와 트랙패드가 충전단자가 통일이 안 되어 있으니 약간 성가시긴 하다. 집에 있을 때야 케이블 하나 더 두는 건 일이 아닌데, 바깥에서 쓰려면 케이블 하나 더 챙기는 게 또 나름대로 일이다보니. 이래서 계획소비가 중요하다.

Charybdis의 현재 키맵은 다음과 같다.

#include <behaviors.dtsi>
#include <dt-bindings/zmk/bt.h>
#include <dt-bindings/zmk/keys.h>
#include <dt-bindings/zmk/pointing.h>
#include <dt-bindings/zmk/behaviors.h>
#include <dt-bindings/zmk/rgb.h>


&lt {
    tapping-term-ms = <200>;
    flavor = "balanced";
    quick-tap-ms = <150>;
};

/ {
    scroll_encoder: scroll_encoder {
        compatible = "zmk,behavior-sensor-rotate";
        #sensor-binding-cells = <0>;
        bindings = <&msc SCRL_DOWN>, <&msc SCRL_UP>;

        tap-ms = <100>;
    };

    macros {
        leader: snippet_leader {
            compatible = "zmk,behavior-macro";
            #binding-cells = <0>;
            tap-ms = <1>;
            wait-ms = <1>;
            bindings = <&macro_tap &kp LC(LG(LA(SPACE))) &kp LC(LG(LS(RBKT)))>;
        };
        leader_alt: snippet_leader_alternative {
            compatible = "zmk,behavior-macro";
            #binding-cells = <0>;
            tap-ms = <1>;
            wait-ms = <1>;
            bindings = <&macro_tap &kp LC(LG(LA(SPACE))) &kp LC(LG(LS(LA(RBKT))))>;
        };
    };

    combos {
        compatible = "zmk,combos";
        combo_enter {
            timeout-ms = <200>;
            key-positions = <48 52>;
            bindings = <&kp ENTER>;
        };
        combo_leader_alternative {
            timeout-ms = <200>;
            key-positions = <54 55>;
            bindings = <&leader_alt>;
        };
        combo_vivaldi_right {
            timeout-ms = <150>;
            key-positions = <51 52>;
            bindings = <&kp LG(LALT)>;
        };
        combo_rectangle_right {
            timeout-ms = <150>;
            key-positions = <51 54>;
            bindings = <&kp LC(LALT)>;
        };
        combo_lbkt {
            timeout-ms = <150>;
            key-positions = <8 9>;
            bindings = <&kp LBKT>;
        };
    };

    behaviors {
        as: auto_shift {
            compatible = "zmk,behavior-hold-tap";
            #binding-cells = <2>;
            tapping_term_ms = <275>;
            quick_tap_ms = <0>;
            flavor = "tap-preferred";
            bindings = <&kp>, <&kp>;
        };

        mta: mod_tap_alternative {
            compatible = "zmk,behavior-hold-tap";
            #binding-cells = <2>;
            tapping_term_ms = <250>;
            quick_tap_ms = <0>;
            flavor = "tap-preferred";
            bindings = <&kp>, <&kp>;
        };

        lt: layer_tap {
            compatible = "zmk,behavior-hold-tap";
            #binding-cells = <2>;
            flavor = "tap-preferred";
            tapping-term-ms = <200>;
            bindings = <&mo>, <&kp>;
            display-name = "Layer-Tap";
        };

        lta: layer_tap_alternative {
            compatible = "zmk,behavior-hold-tap";
            #binding-cells = <2>;
            flavor = "hold-preferred";
            tapping-term-ms = <200>;
            bindings = <&mo>, <&kp>;
            display-name = "Layer-Tap";
        };

        lts: layer_tap_sticky {
            compatible = "zmk,behavior-hold-tap";
            #binding-cells = <2>;
            flavor = "hold-preferred";
            tapping-term-ms = <200>;
            bindings = <&kp>, <&slq>;
            display-name = "Layer-Tap-sticky";
        };

        slq: sticky_layer_non_quick_release {
            compatible = "zmk,behavior-sticky-key";
            #binding-cells = <1>;
            bindings = <&mo>;
            release-after-ms = <1000>;
            ignore-modifiers;
          };

        gtesc: grave_tilde_escape {
            compatible = "zmk,behavior-mod-morph";
            #binding-cells = <0>;
            bindings = <&kp ESC>, <&kp GRAVE>;
            mods = <(MOD_LGUI|MOD_LALT|MOD_LSFT|MOD_RGUI|MOD_RALT|MOD_RSFT)>;
            keep-mods = <(MOD_LSFT|MOD_RSFT)>;
        };

        bspc_del: backspace_delete {
            compatible = "zmk,behavior-mod-morph";
            #binding-cells = <0>;
            bindings = <&kp BACKSPACE>, <&kp DELETE>;
            mods = <(MOD_LALT|MOD_LSFT|MOD_RALT|MOD_RSFT)>;
        };

        tog_on: toggle_layer_on_only {
            compatible = "zmk,behavior-toggle-layer";
            #binding-cells = <1>;
            display-name = "Toggle Layer On";
            toggle-mode = "on";
        };

        tog_off: toggle_layer_off_only {
            compatible = "zmk,behavior-toggle-layer";
            #binding-cells = <1>;
            display-name = "Toggle Layer Off";
            toggle-mode = "off";
        };
    };

    keymap {
        compatible = "zmk,keymap";

        Base {
            bindings = <
&gtesc          &kp N1   &kp N2   &kp N3     &kp N4    &kp N5     &kp N6   &kp N7      &kp N8      &kp N9    &kp N0     &kp MINUS
&kp TAB         &kp Q    &kp W    &kp E      &kp R     &kp T      &kp Y    &kp U       &kp I       &kp O     &kp P      &kp BSLH
&mta CAPS RALT  &kp A    &kp S    &kp D      &kp F     &kp G      &kp H    &kp J       &kp K       &kp L     &kp SEMI   &kp APOS
&lts LSFT 2     &kp Z    &kp X    &kp C      &kp V     &kp B      &kp N    &kp M       &kp COMMA   &kp DOT   &kp FSLH   &lta 3 ENTER
                                  &kp SPACE  &kp LALT  &kp LGUI   &mo 1    &kp SPACE
                                             &kp LCTL  &bspc_del  &leader  
            >;
        };

        Fn {
            bindings = <
&kp C_BRI_DEC  &kp C_BRI_INC  &kp LC(UP)  &kp LG(SPACE)      &kp LG(LS(N4))  &kp LG(LS(N5))     &kp C_PREV         &kp C_PP           &kp C_NEXT  &kp C_MUTE  &kp C_VOL_DN          &kp C_VOL_UP
&trans         &bt BT_NXT     &bt BT_CLR  &trans             &trans          &trans             &trans             &trans             &trans      &trans      &kp LC(LG(LA(P)))     &trans
&trans         &trans         &trans      &kp LC(LG(LA(D)))  &trans          &trans             &trans             &kp LC(LG(LA(J)))  &trans      &trans      &trans                &trans
&trans         &trans         &trans      &kp LC(LG(LA(C)))  &trans          &kp LC(LG(LA(B)))  &kp LC(LG(LA(N)))  &trans             &trans      &trans      &kp LC(LG(LA(FSLH)))  &trans
                                          &trans             &trans          &trans             &trans             &trans
                                                             &trans          &to 0              &trans
            >;
        };

        Symbol {
            bindings = <
&trans     &trans    &trans    &trans     &trans  &trans  &trans  &trans  &trans     &kp LBKT   &kp RBKT  &kp EQUAL
&trans     &trans    &kp UP    &trans     &trans  &trans  &trans  &trans  &trans     &trans     &trans    &trans
&trans     &kp LEFT  &kp DOWN  &kp RIGHT  &trans  &trans  &trans  &trans  &trans     &mkp RCLK  &trans    &trans
&kp LSHFT  &trans    &trans    &trans     &trans  &trans  &trans  &trans  &mkp LCLK  &trans     &trans    &trans
                               &trans     &trans  &trans  &trans  &trans
                                          &trans  &to 0   &trans
            >;
        };

        snipe-layers {
            bindings = <
&trans  &trans    &trans    &trans     &trans  &trans  &trans  &trans  &trans     &trans     &trans  &trans
&trans  &trans    &kp UP    &trans     &trans  &trans  &trans  &trans  &trans     &trans     &trans  &trans
&trans  &kp LEFT  &kp DOWN  &kp RIGHT  &trans  &trans  &trans  &trans  &trans     &mkp RCLK  &trans  &trans
&mo 4   &trans    &trans    &trans     &trans  &trans  &trans  &trans  &mkp LCLK  &trans     &trans  &trans
                            &trans     &trans  &trans  &trans  &trans
                                       &trans  &to 0   &trans
            >;
        };

        scroll-layers {
            bindings = <
&trans  &trans    &trans    &trans     &trans  &trans  &trans  &trans  &trans     &trans     &trans     &trans
&trans  &trans    &kp UP    &trans     &trans  &trans  &trans  &trans  &trans     &trans     &trans     &trans
&trans  &kp LEFT  &kp DOWN  &kp RIGHT  &trans  &trans  &trans  &trans  &trans     &mkp RCLK  &trans     &trans
&trans  &trans    &trans    &trans     &trans  &trans  &trans  &trans  &mkp LCLK  &trans     &kp QMARK  &trans
                            &trans     &trans  &trans  &trans  &trans
                                       &trans  &to 0   &trans
            >;
        };
    };
};

레이어는 다섯 개로, Sofle과 달리 macOS용과 Windows용 base를 따로 두지 않았다. 이는 어차피 쓰다보니 Windows에 이들을 연결할 일은 없다는 깨달음에 따른 것이다. Windows는 보통 게임할 때나 켤 테니…

아이디어는 대략 Sofle에서와 비슷하고, 다른 것은 마우스 제어용 snipe 레이어와 scroll 레이어다. 우선 snipe 레이어는 말 그대로 정밀 모드로, 켜져 있는 동안 CPI가 600에서 200으로 떨어져 마우스가 움직이는 속도가 \(1/3\)이 된다. 보통 클릭을 하기 전, 버튼 위치에 맞게 잘 조준할 때 쓰므로 이 레이어에 &mkp LCLK&mkp RCLK을 같이 붙여줬다. 이들의 위치는 별다른 건 아니고, 이 레이어로 들어오는 키가 우하단 Shift 자리인데, 이 키를 새끼손가락으로 눌렀을 때 자연스레 검지와 중지가 가는 곳으로 둔 것이다. 이 레이어에서 특기할만한 또 다른 것은 좌하단 Shift의 &mo 4다. 오른손 새끼손가락의 &lta 3 ENTER를 길게 눌러 snipe 레이어로 들어온 상태에서 이 버튼을 누르면 scroll 레이어로 가며 여기서는 트랙볼을 움직이면 스크롤이 된다. 말로 설명하면 긴데 실제로 사용해보면 꽤 직관적이고 편하다. scroll 레이어에 &kp QMARK는 왜 있는지 모르겠다. 아마 Sofle에서 키맵 복사해온 흔적인 것 같다. 그 외 나머지는 대충 Sofle에서의 경험을 바탕으로 그대로 옮겨온 것이다. 다만 이제 조이스틱이 없으므로 방향키 역할을 Symbol, snipe-layers, scroll-layers 세 레이어에 모두 같은 자리 W, A, S, D로 넣어준 정도가 차이다.

댓글남기기