complete-computing-environment/gpd-pocket-3.org

8.4 KiB
Raw Permalink Blame History

GPD Pocket 3

These small 7-8 inch display laptops have been the most promising mobile Linux devices for me, each with some fatal flaw that made it unlikely to survive a long time. But maybe this one is different. I own the GPD Pocket which could not go in to deep sleep in linux, so it would always have a dead battery when I wanted to use it and the touchscreen did not function on it. I own the GPD Pocket 2 which runs NixOS but has a soldered in eMMC chip that is just slightly too small to be useful for me. The GPD Pocket 3 is a convertable touch screen laptop which is maybe versatile enough and full of upgradable storage with m.2 nvme.

The lads at GPD are at it again. This one has a 360° rotating screen and active stylus support. It has a proprietary IO port at the back of the device that can have an extra USB port, or an HDMI capture card and USB gadget hub, or an RS232 serial device. Maybe even a 4G cell card?? one can hope…

Having a performant Emacs environment in a light form-factor is a thing I've been chasing for a decade or more, and this is the latest step. It fits in my 8" camera messenger bag and my bike basket. It's an ebook reader and a programming environment and a shitposting machine.

NixOS on the GPD Pocket 3

This thing has kind of been a pain to run Linux on, especially after I had a real deep roam:Brain-o moment where I had to wipe the disk. I'd rather not talk about it lol.

Things were working well before then, like the thing worked quite nicely, but installing the very same system build I had just deployed early in the week would cause the machine to panick when modesetting occurred. I had to downgrade the kernel to 5.15 to get it to boot reliably but there was a bunch of weird display behavior, this was a bit worrying. 6.2 works but ZFS support is still labeled "unstable" so I'll have to be careful to not jog this thing too hard until 6.2 stabilizes lol.

{ lib, pkgs, ... }:

{

Keeping ZFS and Linux playing well together on NixOS stable is sometimes a pain in the ass; for now, it works, but sometimes I have to enableUnstable or pull in a nixpkgs-unstable patch to enable a version of ZFS which works with a kernel that isn't EOL and works with my device.

  # === gpd pocket 3 specific hax
  boot.zfs.enableUnstable = false;
  boot.kernelPackages = lib.mkForce pkgs.zfs.latestCompatibleLinuxPackages;

The display, as with all GPD Pockets is an 8 inch tablet display rotated 90° counter-clockwise, and so some work has to be done to rotate all of this, and the stylus coordinates and the accelerometer and whatnot. I had some real problems getting X11 to look decently without fractional scaling and I was having trouble getting the X11 config working, so this is my first machine running Wayland. I have a few things commented here for if upgrading my kernel or whatever breaks the display again during modesetting or whatever..

  boot.kernelParams = [
    "mem_sleep_default=deep"
    "fbcon=rotate:1"
    "video=DSI-1:panel_orientation=right_side_up"
  ];
  
  services.udev.extraRules = ''
    ACTION=="add|change", KERNEL=="event[0-9]*", ATTRS{name}=="GXTP7380:00 27C6:0113", ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0"
    ACTION=="add|change", KERNEL=="event[0-9]*", ATTRS{name}=="GXTP7380:00 27C6:0113 Stylus", ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0"
  '';
  services.udev.extraHwdb = ''
    sensor:modalias:*
      ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 1, 0, 0
  '';
  hardware.sensor.iio.enable = true;
  
  services.xserver.videoDrivers = ["modesetting" "intel"];
  
  services.xserver.displayManager.defaultSession = lib.mkForce "plasmawayland";
  # services.xserver.displayManager.lightdm.enable = lib.mkForce false;
  # services.xserver.displayManager.lightdm.enable = true;
  # services.xserver.displayManager.autoLogin.enable = lib.mkForce false;
  # systemd.defaultUnit = lib.mkForce "multi-user.target";

Make the sound work and the console legible.

  boot.extraModprobeConfig = ''
    options snd-intel-dspcfg dsp_driver=1
  '';
  hardware.enableRedistributableFirmware = true;
  
  console.font = "solar24x32.psfu";
  console.earlySetup = true;

Gotta have the soft keyboard since I'm actually goign to use this as a tablet for light web browsing. It still has to be enabled in System Settings, I need to automate the declarative setup of KDE and Plasma…

  environment.systemPackages = [
    pkgs.maliit-framework
    pkgs.maliit-keyboard
    pkgs.wl-clipboard
  ];
  
  services.xserver.desktopManager.plasma5 = {
    kwinrc = {
      "Wayland" = {
        "InputMethod[$e]" = "/run/current-system/sw/share/applications/com.github.maliit.keyboard.desktop";
        "VirtualKeyboardEnabled" = "true";
      };
    };
  };

Include the rotate script below:

  imports = [ <arroyo/nixos/gpd-pocket-3-rotate.nix> ];
}

Rotate Script

One of the side-effects of moving to Wayland is that the "Custom Shortcuts" system in KDE is not functional. There is a limited version of it in the main Shortcuts UI which lets you choose a .desktop file or shell script to run without arguments, so here I am writing a .desktop file.

I don't do a full rotation, and i use a neat little KDE command lie utility called kscreen-doctor to handle rotating the display on kwin_wayland: These numbers that come out of the first CUR_ROT pipeline are probably a bitfield or something, they're all base-2 even maybe? Who can say? They also differ depending on which KScreen backend you use…

STATUS_KSKB=QScreen
CUR_ROT=$(KSCREEN_BACKEND=$STATUS_KSKB kscreen-doctor --json | jq '.outputs[]|select(.name == "DSI-1").rotation')

# KWayland and QScreen don't return the same bitfield lol

case $STATUS_KSKB in
    QScreen)
        case $CUR_ROT in
            8) # normal
                kscreen-doctor output.DSI-1.rotation.right
                ;;
            1) # 90 ccw
                kscreen-doctor output.DSI-1.rotation.inverted
                ;;
            # 8) # normal
            #     kscreen-doctor output.DSI-1.rotation.inverted
            #     ;;
            # 4) # 90 ccw
            #     kscreen-doctor output.DSI-1.rotation.right
            #     ;;
        esac
        ;;
    KWayland)
        case $CUR_ROT in
            8) # normal
                kscreen-doctor output.DSI-1.rotation.inverted
                ;;
            4) # 90 ccw
                kscreen-doctor output.DSI-1.rotation.right
                ;;
        esac
        ;;
esac

Packaging this up is kind of ugly, i'm sure there is a more idiomatic way to ship a shell script with a desktop file. I should at least move this to rixpkgs eventually…

{ pkgs, ... }:

let
  gpd-rotate-display = pkgs.writeShellApplication {
    name = "gpd-rotate-display";
    runtimeInputs = with pkgs; [ plasma5Packages.libkscreen jq ];

    text = builtins.readFile <arroyo/files/gpd-pocket-3-rotate.sh>;
  };
  desktopItem = pkgs.makeDesktopItem {
    name = "gpd-rotate-display";
    desktopName = "Rotate Display";
    categories = ["Utility"];
    exec = "gpd-rotate-display";
  };
  gpd-rotate-display' = pkgs.stdenv.mkDerivation {
    name = "gpd-rotate-display";
    src = gpd-rotate-display;

    installPhase = ''
      mkdir -p $out/bin
      cp $src/bin/gpd-rotate-display $out/bin/
      cp --recursive "${desktopItem}/share" "$out/"
    '';
  };
in {
  environment.systemPackages = [
    gpd-rotate-display'
  ];
}

NEXT consider swap back to Xorg

scaling the touch and wacom when i run xinput scale command