feat(home/runescape): add Alt1 toolkit

Package Arroquw's Alt1 Electron fork from source, configure its protocol and persistence, and add Hyprland rules for XWayland overlays. Patch the capture IPC so settings diagnostics and applets can use the detected RuneScape client.

Assisted-by: pi (openai-codex/gpt-5.6-sol)
This commit is contained in:
Gabriel Fontes
2026-07-15 23:35:50 -03:00
parent 8919726975
commit 9bb90362a7
5 changed files with 265 additions and 2 deletions
@@ -219,10 +219,11 @@ in {
steamGame = "match:class steam_app_[0-9]*";
wineTray = "match:class explorer.exe";
rsiLauncher = "match:class rsi launcher.exe";
runescape = "match:class Runescape";
runescape = "match:class (?i)^runescape$";
steamBigPicture = "match:title Steam Big Picture Mode";
firefoxPictureInPicture = "match:class firefox, match:title Picture-in-Picture";
floatingVlc = "match:float 1, match:class vlc";
alt1 = "match:class (?i)^alt1lite$, match:title ^(Alt1 Lite app|Alt1Lite overlay window)$";
in
[
"idle_inhibit focus, match:fullscreen_state_internal 2 *"
@@ -235,6 +236,15 @@ in {
"tile on, ${rsiLauncher}"
"suppress_event activate, ${runescape}"
"render_unfocused on, ${runescape}"
"float on, ${alt1}"
"pin on, ${alt1}"
"no_blur on, ${alt1}"
"no_shadow on, ${alt1}"
"no_anim on, ${alt1}"
"border_size 0, ${alt1}"
"rounding 0, ${alt1}"
"fullscreen on, ${steamBigPicture}"
@@ -7,14 +7,19 @@ in {
runelite
hdos
runescape
pkgs.alt1
pkgs.jagex-auth
];
xdg.mimeApps.defaultApplications."x-scheme-handler/jagex" = "jagex-auth-handler.desktop";
xdg.mimeApps.defaultApplications = {
"x-scheme-handler/alt1" = "alt1lite.desktop";
"x-scheme-handler/jagex" = "jagex-auth-handler.desktop";
};
home.persistence = {
"/persist".directories = [
".runelite"
".config/alt1"
".config/hdos"
".local/share/jagex-auth"
"Jagex"
+210
View File
@@ -0,0 +1,210 @@
{
alsa-lib,
at-spi2-atk,
atk,
cairo,
copyDesktopItems,
cups,
dbus,
dbus-glib,
electron,
expat,
fetchFromGitHub,
fetchNpmDeps,
gcc,
glib,
gnumake,
gtk2,
gtk3,
lib,
libappindicator-gtk2,
libappindicator-gtk3,
libdrm,
libgbm,
libglvnd,
libjpeg,
libpng,
libtiff,
libudev0-shim,
libva,
libxcb,
libxcb-wm,
libxcomposite,
libxdamage,
libxext,
libxfixes,
libxkbcommon,
libxrandr,
libx11,
makeDesktopItem,
makeWrapper,
mesa,
nodejs,
npmHooks,
nspr,
nss,
pango,
pipewire,
pkg-config,
python3,
stdenv,
vips,
}: let
version = "0.0.1-unstable-2026-06-25";
desktopItem = makeDesktopItem {
name = "alt1lite";
desktopName = "Alt1 Toolkit";
comment = "RuneScape toolkit and app host";
exec = "alt1 %U";
icon = "alt1";
categories = ["Game" "Utility"];
mimeTypes = ["x-scheme-handler/alt1"];
startupWMClass = "Alt1Lite";
};
in
stdenv.mkDerivation (finalAttrs: {
pname = "alt1";
inherit version;
src = fetchFromGitHub {
owner = "Arroquw";
repo = "alt1-electron";
rev = "a1e315490e4d7a64fd624ea3969deba36d81c39b";
hash = "sha256-h2r/N+R1z/f2V2KilXpafxNQJxiI4j1WsAaWKCLTTmU=";
};
patches = [./package.patch];
npmDeps = fetchNpmDeps {
inherit (finalAttrs) src;
hash = "sha256-Q1F30c6942/ZT9BocdYNmV1hXL+KRvtHSer2CS2nBI4=";
};
makeCacheWritable = true;
npmInstallFlags = ["--include=dev"];
env = {
ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
npm_config_nodedir = electron.headers;
npm_config_ignore_scripts = "true";
SHARP_IGNORE_GLOBAL_LIBVIPS = "1";
SHARP_LIBVIPS_VERSION = vips.version;
NIX_CFLAGS_COMPILE = toString [
"-I${glib.dev}/include/glib-2.0"
"-I${glib.out}/lib/glib-2.0/include"
"-I${vips.dev}/include"
"-lvips"
];
LD_LIBRARY_PATH = lib.makeLibraryPath [
vips
glib
libpng
libjpeg
libtiff
];
NODE_ENV = "production";
doDist = false;
};
nativeBuildInputs = [
copyDesktopItems
gcc
gnumake
makeWrapper
nodejs
npmHooks.npmConfigHook
npmHooks.npmBuildHook
npmHooks.npmInstallHook
pkg-config
python3
];
buildInputs = [
alsa-lib
at-spi2-atk
atk
cairo
cups
dbus
dbus-glib
electron
expat
glib
gtk2
gtk3
libappindicator-gtk2
libappindicator-gtk3
libdrm
libgbm
libglvnd
libudev0-shim
libva
libxcb
libxcb-wm
libxcomposite
libxdamage
libxext
libxfixes
libxkbcommon
libxrandr
libx11
mesa
nspr
nss
pango
pipewire
vips
];
desktopItems = [desktopItem];
buildPhase = ''
runHook preBuild
export npm_config_cache="$TMPDIR/npm-cache"
export npm_config_ignore_scripts=true
export npm_config_runtime=electron
export npm_config_target=${electron.version}
export npm_config_disturl=https://electronjs.org/headers
export npm_config_build_from_source=true
npx --offline electron-rebuild \
-f \
-w alt1lite \
-c.electronDist=${electron}/libexec/electron \
-c.electronVersion=${electron.version}
npm --offline run build -- --mode production
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p \
$out/lib/alt1/build/Release \
$out/lib/alt1/dist/tooltip \
$out/share/icons/hicolor/256x256/apps
cp -r dist $out/lib/alt1/
cp build/Release/addon.node $out/lib/alt1/build/Release/
cp config.json $out/lib/alt1/dist/tooltip/
ln -s tooltip/config.json $out/lib/alt1/dist/config.json
install -Dm644 src/imgs/alt1icon_large.png \
$out/share/icons/hicolor/256x256/apps/alt1.png
makeWrapper ${lib.getExe electron} $out/bin/alt1 \
--add-flags "--ozone-platform=x11" \
--add-flags "$out/lib/alt1/dist/alt1lite.bundle.js"
runHook postInstall
'';
meta = {
description = "Cross-platform client for Alt1 Toolkit apps";
homepage = "https://github.com/Arroquw/alt1-electron";
license = lib.licenses.gpl3Only;
mainProgram = "alt1";
platforms = ["x86_64-linux"];
};
})
+37
View File
@@ -0,0 +1,37 @@
--- a/src/ipcapi.ts
+++ b/src/ipcapi.ts
@@ -5,7 +5,7 @@
import { admins, fixTooltip, getManagedAppWindow, ManagedWindow, openApp } from "./main";
import { native } from "./native";
import { settings } from "./settings";
-import { FlatImageData, OverlayCommand, Rectangle, RsClientState, imageDataFrom } from "./shared";
+import { FlatImageData, OverlayCommand, Rectangle, RsClientState } from "./shared";
import { getRsInstanceFromWnd, rsInstances } from "./rsinstance";
import * as fs from 'fs';
@@ -252,13 +252,12 @@
? (((mx & 0xFFFF) << 16) | (my & 0xFFFF))
: -1;
- let wnd = expectAppWindow(e);
let state: RsClientState = {
- active: wnd.rsClient.isActive,
- clientRect: wnd.rsClient.window.getClientBounds(),
- lastActiveTime: wnd.rsClient.lastActiveTime,
+ active: client.isActive,
+ clientRect: client.window.getClientBounds(),
+ lastActiveTime: client.lastActiveTime,
ping: 10,//TODO
- scaling: wnd.rsClient.window.getScale(),
+ scaling: client.window.getScale(),
captureMode: settings.captureMode,
mousePosition: mousePosition
};
@@ -268,7 +267,6 @@
ipcMain.handle("capture", (e: any, x: any, y: any, width: any, height: any) => {
let client = expectPermittedRsClient(e);
let capt = native.captureWindowMulti(client.window.handle, settings.captureMode, { main: { x, y, width, height } });
- let data: ImageData = imageDataFrom(capt.main, width, height);
return capt.main;
});
+1
View File
@@ -2,6 +2,7 @@
# Packages with an actual source
lyrics = pkgs.python3Packages.callPackage ./lyrics {};
prefetcharr = pkgs.callPackage ./prefetcharr {};
alt1 = pkgs.callPackage ./alt1 {};
hyprbars = pkgs.callPackage ./hyprbars {};
jellysearch = pkgs.callPackage ./jellysearch {};
runescape = pkgs.callPackage ./runescape {};