Compare commits

...
13 Commits
Author SHA1 Message Date
Lucas Oskorep cde5a4d58f feat: upgrade to gnome 51
Build and Test / build (push) Successful in 26s
Build and Test / release (push) Successful in 3s
Adds GNOME Shell 51 to shell-version and moves the build onto the
GNOME 51 type packages.

- tabBar: pass orientation instead of vertical to St.BoxLayout. The vertical
  property was removed from St widgets in 51 (deprecated in 48); orientation
  exists in 48 and later, so this keeps 48-51 working. Verified against the
  installed St-51 typelib
- switch to @girs/gjs 5.5.0 and the -51 namespace packages (shell/st/meta/
  clutter plus gio/glib/gobject/gtk/gdk/adw/pango)
- drop @girs/gnome-shell 50 and the stale @girs/mtk-17 dependency. The
  umbrella is GNOME 50 only and pulls St-18 and Meta-18 types that clash
  with the -51 packages
- types/: hand-written declarations for the Shell JS modules imported here
  (extension.js, prefs.js, main.js). Upstream 51 types (51.0.0-alpha.1) are
  not published to npm yet
- TypeScript 6.0.3 rather than 7: typescript-eslint requires <6.1.0 and
  ts-jest requires <7
- eslint 10.12, @eslint/js 10.0.1, eslint-plugin-jsdoc 65.3.4,
  typescript-eslint 8.71.2 and jest 30.5.2 / ts-jest 29.4.14
2026-10-15 01:54:51 -04:00
Lucas Oskorep 6729cb118e fix: typo
Build and Test / build (push) Successful in 48s
Build and Test / release (push) Successful in 3s
2026-09-08 21:50:13 -04:00
Lucas Oskorep c3d98b7b48 deps: update all dependencies to latest compatible versions
Build and Test / build (push) Failing after 12s
Build and Test / release (push) Skipped
2026-09-07 15:39:07 -04:00
Lucas Oskorep 02c66359d9 build: switch from fnm to mise for node and pnpm management
Build and Test / build (push) Successful in 23s
Build and Test / release (push) Successful in 3s
2026-09-07 15:28:22 -04:00
Lucas Oskorep 00263f6b81 build: only use npx corepack in packages recipe, use pnpm directly elsewhere
Build and Test / build (push) Successful in 27s
Build and Test / release (push) Successful in 3s
2026-09-07 15:14:58 -04:00
Lucas Oskorep 55e06d4f60 build: pin pnpm 12.3.4 in package.json and route just recipes through corepack
Build and Test / build (push) Successful in 27s
Build and Test / release (push) Successful in 4s
2026-09-07 15:05:53 -04:00
Lucas Oskorep 4c994943cd docs: move fnm setup after clone, add shell-hook PATH note
Build and Test / build (push) Successful in 24s
Build and Test / release (push) Successful in 3s
2026-09-07 14:46:52 -04:00
Lucas Oskorep c9ef3f404a docs: add source install + dev instructions, bump Node to 26
Build and Test / build (push) Successful in 44s
Build and Test / release (push) Successful in 4s
2026-09-07 14:16:28 -04:00
Lucas Oskorep 2fa02eac85 fix: build
Build and Test / build (push) Successful in 25s
Build and Test / release (push) Successful in 3s
2026-06-15 15:39:02 -04:00
Lucas Oskorep 6dfb107ad9 feat: ver-bump
Build and Test / build (push) Failing after 1m13s
Build and Test / release (push) Has been skipped
2026-06-15 15:32:52 -04:00
Lucas Oskorep e2fc4e7127 feat: update all packages 2026-06-15 15:31:41 -04:00
Lucas Oskorep bf7fe98b05 fix: ci
Build and Test / build (push) Successful in 25s
Build and Test / release (push) Successful in 13s
2026-06-15 15:22:36 -04:00
Lucas Oskorep 4a2067811c fix: ci
Build and Test / build (push) Failing after 17s
Build and Test / release (push) Has been skipped
2026-06-15 11:53:49 -04:00
15 changed files with 2407 additions and 1719 deletions

No files matched your search

+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
apt-get install -y libglib2.0-dev glib-networking zip apt-get install -y libglib2.0-dev glib-networking zip
- name: Install project dependencies - name: Install project dependencies
run: pnpm install run: pnpm install --ignore-scripts
- name: Run unit tests - name: Run unit tests
run: just test run: just test
+3
View File
@@ -0,0 +1,3 @@
[tools]
node = "26"
pnpm = "12.3.4"
-1
View File
@@ -1 +0,0 @@
25
+62
View File
@@ -28,3 +28,65 @@ MacOS tiling WMs, mainly [Aerospace](https://github.com/nikitabobko/AeroSpace) (
- complicated window dragging features and uis - complicated window dragging features and uis
- Aerospace supports control + drag to combine windows while moving with the mouse, and normal window dragging. - Aerospace supports control + drag to combine windows while moving with the mouse, and normal window dragging.
## Installation
Aerospike isn't on the GNOME extension store yet, so install it from source.
This builds the extension locally and drops it into your user's extension dir.
Requires [just](https://github.com/casey/just) as the command runner, plus the
same build toolchain used for development (see [Development](#development)):
[mise](https://mise.jdx.dev/) for managing tool versions (`node` and `pnpm`),
and `glib2` for `glib-compile-schemas`.
Arch Linux:
```bash
sudo pacman -S git just mise glib2 # mise needs its shell hook: https://mise.jdx.dev/getting-started.html#shells
```
Clone and install:
```bash
git clone https://github.com/lucasoskorep/aerospike-gnome
cd aerospike-gnome
mise install
just install
```
After installing from source, enable it (toggle in the Extensions app, or):
```bash
gnome-extensions enable aerospike@lucaso.io
```
Re-login or restart the shell (`Alt+F2` → `r` on X11) to pick it up.
## Development
Building and debugging locally needs a few extra tools:
- `just` — the command runner
- `mise` — runtime & tool manager (pins `node` and `pnpm` in `.mise.toml`)
- `glib2` — provides `glib-compile-schemas` for compiling the settings schema
Arch Linux:
```bash
sudo pacman -S just mise glib2
```
Install the pinned tools with mise (defined in `.mise.toml`):
```bash
mise install
```
Then:
```bash
just install # install deps + build + drop into the extension dir
just lint # lint
just test # run the test suite
just test-watch # run tests in watch mode
just live-debug # tail gnome-shell logs while you poke at it
```
+12 -10
View File
@@ -1,11 +1,13 @@
import "@girs/gjs"; import "@girs/gjs/ambient";
import "@girs/gjs/dom"; import "@girs/gjs/dom";
import "@girs/gnome-shell/ambient"; import "@girs/glib-2.0/ambient";
import "@girs/gnome-shell/extensions/global"; import "@girs/gio-2.0/ambient";
import "@girs/gobject-2.0/ambient";
// Extend Meta.Window with our custom property import "@girs/gtk-4.0/ambient";
declare namespace Meta { import "@girs/gdk-4.0/ambient";
interface Window { import "@girs/adw-1/ambient";
_aerospikeData?: any; import "@girs/pango-1.0/ambient";
} import "@girs/clutter-51/ambient";
} import "@girs/st-51/ambient";
import "@girs/meta-51/ambient";
import "@girs/shell-51/ambient";
+30
View File
@@ -0,0 +1,30 @@
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import jsdoc from "eslint-plugin-jsdoc";
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
jsdoc.configs["flat/recommended-typescript"],
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
"jsdoc/require-jsdoc": "off",
"jsdoc/require-param-description": "off",
"jsdoc/require-returns-description": "off",
"jsdoc/require-returns": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
],
},
},
{
ignores: ["dist/", "node_modules/", "*.js"],
},
);
+4 -3
View File
@@ -1,13 +1,14 @@
{ {
"name": "aerospike", "name": "Aerospike WM",
"description": "I3 Like Tiling Window Manager for Gnome", "description": "I3 Like Tiling Window Manager for Gnome",
"uuid": "aerospike@lucaso.io", "uuid": "aerospike@lucaso.io",
"settings-schema": "org.gnome.shell.extensions.aerospike", "settings-schema": "org.gnome.shell.extensions.aerospike",
"shell-version": [ "shell-version": [
"48", "48",
"49", "49",
"50" "50",
"51"
], ],
"gettext-domain": "aerospike@lucaso.io", "gettext-domain": "aerospike@lucaso.io",
"url": "https://gitea.chaosdev.gay/lucasoskorep/aerospike@lucaso.io" "url": "https://github.com/lucasoskorep/aerospike-gnome"
} }
+22 -32
View File
@@ -1,7 +1,8 @@
{ {
"name": "aerospike", "name": "aerospike",
"version": "0.2.3", "version": "0.2.5",
"description": "Simple, Opinionated Tiling Window Manager for Gnome written in Typescript", "description": "Simple, Opinionated Tiling Window Manager for Gnome written in Typescript",
"packageManager": "pnpm@12.3.4",
"type": "module", "type": "module",
"private": true, "private": true,
"repository": { "repository": {
@@ -24,37 +25,26 @@
"test:coverage": "jest --coverage" "test:coverage": "jest --coverage"
}, },
"devDependencies": { "devDependencies": {
"@girs/gjs": "4.0.0-beta.38", "@eslint/js": "^10.0.1",
"@girs/gnome-shell": "49.1.0", "@girs/adw-1": "^5.5.0",
"@jest/globals": "^30.0.0", "@girs/clutter-51": "^5.5.0",
"@girs/gio-2.0": "^5.5.0",
"@girs/gjs": "^5.5.0",
"@girs/glib-2.0": "^5.5.0",
"@girs/gobject-2.0": "^5.5.0",
"@girs/gdk-4.0": "^5.5.0",
"@girs/gtk-4.0": "^5.5.0",
"@girs/meta-51": "^5.5.0",
"@girs/pango-1.0": "^5.5.0",
"@girs/shell-51": "^5.5.0",
"@girs/st-51": "^5.5.0",
"@jest/globals": "^30.5.2",
"@types/jest": "^30.0.0", "@types/jest": "^30.0.0",
"eslint": "^10.0.0", "eslint": "^10.12.0",
"eslint-plugin-jsdoc": "^62.0.0", "eslint-plugin-jsdoc": "^65.3.4",
"jest": "^30.0.0", "jest": "^30.5.2",
"ts-jest": "^29.1.2", "ts-jest": "^29.4.14",
"typescript": "^5.9.2" "typescript": "^6.0.3",
}, "typescript-eslint": "^8.71.2"
"dependencies": {
"@girs/mtk-17": "17.0.0-4.0.0-beta.38"
},
"pnpm": {
"overrides": {
"@girs/cairo-1.0": "1.0.0-4.0.0-beta.38",
"@girs/freetype2-2.0": "2.0.0-4.0.0-beta.38",
"@girs/gdk-4.0": "4.0.0-4.0.0-beta.38",
"@girs/gdkpixbuf-2.0": "2.0.0-4.0.0-beta.38",
"@girs/gio-2.0": "2.86.0-4.0.0-beta.38",
"@girs/gjs": "4.0.0-beta.38",
"@girs/glib-2.0": "2.86.0-4.0.0-beta.38",
"@girs/gmodule-2.0": "2.0.0-4.0.0-beta.38",
"@girs/gobject-2.0": "2.86.0-4.0.0-beta.38",
"@girs/graphene-1.0": "1.0.0-4.0.0-beta.38",
"@girs/gsk-4.0": "4.0.0-4.0.0-beta.38",
"@girs/gtk-4.0": "4.20.1-4.0.0-beta.38",
"@girs/harfbuzz-0.0": "11.5.0-4.0.0-beta.38",
"@girs/mtk-17": "17.0.0-4.0.0-beta.38",
"@girs/pango-1.0": "1.57.0-4.0.0-beta.38",
"@girs/pangocairo-1.0": "1.0.0-4.0.0-beta.38"
}
} }
} }
+2110 -1669
View File
File diff suppressed because it is too large. Load diff
+5
View File
@@ -0,0 +1,5 @@
allowBuilds:
'@parcel/watcher': true
unrs-resolver: true
minimumReleaseAgeExclude:
- eslint-plugin-jsdoc@65.3.4
+1
View File
@@ -173,6 +173,7 @@ export default class AerospikeExtensions extends ExtensionPreferences {
if (!!value) { if (!!value) {
const mappings = value.split(',').map((x) => { const mappings = value.split(',').map((x) => {
const [, key, mods] = Gtk.accelerator_parse(x); const [, key, mods] = Gtk.accelerator_parse(x);
if (mods === null) return false;
return Gtk.accelerator_valid(key, mods) && Gtk.accelerator_name(key, mods); return Gtk.accelerator_valid(key, mods) && Gtk.accelerator_name(key, mods);
}); });
// Filter out any false values to ensure we only have strings // Filter out any false values to ensure we only have strings
+3 -1
View File
@@ -21,7 +21,9 @@ export class TabBar {
this._onTabClicked = onTabClicked; this._onTabClicked = onTabClicked;
this._bar = new St.BoxLayout({ this._bar = new St.BoxLayout({
style_class: 'aerospike-tab-bar', style_class: 'aerospike-tab-bar',
vertical: false, // `vertical` was removed from St widgets in GNOME Shell 51 (deprecated
// in 48); `orientation` is its replacement and exists in 48 and later.
orientation: Clutter.Orientation.HORIZONTAL,
reactive: true, reactive: true,
can_focus: false, can_focus: false,
track_hover: false, track_hover: false,
+3 -2
View File
@@ -10,14 +10,15 @@
"target": "ES2022", "target": "ES2022",
"lib": [ "lib": [
"ES2022" "ES2022"
], ]
}, },
"include": [ "include": [
"ambient.d.ts", "ambient.d.ts",
"types/**/*.d.ts",
"prefs.ts", "prefs.ts",
"src/**/*" "src/**/*"
], ],
"files": [ "files": [
"extension.ts" "extension.ts"
], ]
} }
+20
View File
@@ -0,0 +1,20 @@
/**
* GNOME Shell runtime globals.
*
* The `global` object is created by the shell before an extension is loaded and
* has no `.gir`, so it is not covered by the generated `@girs/*-51` packages.
* Upstream ships these in `@girs/gnome-shell`, but its GNOME 51 build
* (51.0.0-alpha.1) is unpublished, and v50 pulls St-18/Meta-18 types that
* collide with the -51 packages. Declaring the few symbols we use keeps the
* project on GNOME 51 types and installable from the registry.
*
* @see https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/environment.js
*/
import type Shell from "@girs/shell-51";
declare global {
/** Global shell object created by GNOME Shell on startup. */
const global: Shell.Global;
}
export {};
+131
View File
@@ -0,0 +1,131 @@
/**
* Ambient declarations for the GNOME Shell JavaScript modules this extension
* imports.
*
* Shell's JavaScript API has no `.gir`, so generated `@girs/*` types do not
* cover it. Upstream maintains those types in `@girs/gnome-shell`, but its
* GNOME 51 support (51.0.0-alpha.1) is unpublished on npm, and v50 depends on
* St-18/Meta-18 types that conflict with the -51 packages this project uses.
* Only the symbols actually imported here are declared; extend as needed.
*
* @see https://gitlab.gnome.org/GNOME/gnome-shell/-/tree/main/js/ui
*/
declare module "resource:///org/gnome/shell/extensions/extension.js" {
import type Gio from "@girs/gio-2.0";
/** Parsed contents of the extension's `metadata.json`. */
export interface ExtensionMetadata {
uuid: string;
name: string;
description: string;
"shell-version"?: string[];
"settings-schema"?: string;
"gettext-domain"?: string;
url?: string;
[key: string]: unknown;
}
/**
* Base class for an extension's `extension.js` default export.
*
* GNOME Shell 51 requires `disable()` to stay synchronous; returning a
* promise now throws.
*/
export class Extension {
constructor(metadata: ExtensionMetadata);
readonly metadata: ExtensionMetadata;
readonly uuid: string;
readonly path: string;
/** Returns a {@link Gio.Settings} for the extension's schema. */
getSettings(schema?: string | null, subdir?: string | null): Gio.Settings;
/** Marks the extension's settings as translatable. */
translateConfig(): void;
/** Opens the extension's preferences dialog, if it has one. */
openPreferences(): void;
enable(): void;
disable(): void;
}
}
declare module "resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js" {
import type Gio from "@girs/gio-2.0";
import type Adw from "@girs/adw-1";
/** Marks a string for translation and returns the translation. */
export function gettext(str: string): string;
/** Pluralised form of {@link gettext}. */
export function ngettext(fid: string, fidPlural: string, n: number): string;
/** Context-sensitive form of {@link gettext}. */
export function pgettext(context: string, str: string): string;
/** Base class for an extension's `prefs.js` default export. */
export class ExtensionPreferences {
readonly metadata: Record<string, unknown>;
readonly uuid: string;
readonly path: string;
/** Returns a {@link Gio.Settings} for the extension's schema. */
getSettings(schema?: string | null, subdir?: string | null): Gio.Settings;
/** Marks the extension's settings as translatable. */
translateConfig(): void;
/** Called by the shell to populate the preferences window. */
fillPreferencesWindow(window: Adw.PreferencesWindow): Promise<void> | void;
}
}
declare module "resource:///org/gnome/shell/ui/main.js" {
import type Gio from "@girs/gio-2.0";
import type Meta from "@girs/meta-51";
import type Shell from "@girs/shell-51";
import type St from "@girs/st-51";
/** Window management helpers exposed to extensions. */
export interface ShellWM {
/**
* Registers a keybinding from an extension's schema and returns its id.
*/
addKeybinding(
name: string,
settings: Gio.Settings,
flags: Meta.KeyBindingFlags,
mode: Shell.ActionMode,
handler: () => void,
): number;
/** Removes a keybinding previously added by this extension. */
removeKeybinding(name: string): boolean;
}
/** The shell's layout manager. */
export interface LayoutManager {
/** Actor holding all non-window UI. */
readonly uiGroup: St.Widget;
/** Actor holding the window group. */
readonly windowGroup: St.Widget;
readonly panelBox: St.BoxLayout;
readonly monitorManager: Meta.MonitorManager;
readonly nMonitors: number;
}
/** The overview (window overview + search). */
export interface Overview extends St.Widget {
connect(signal: "showing" | "hiding" | "show-overview", callback: () => void): number;
}
export const wm: ShellWM;
export const layoutManager: LayoutManager;
export const overview: Overview;
/** Shows a notification in the message tray. */
export function notify(message: string): void;
}