diff --git a/docs/guide/bundling.md b/docs/guide/bundling.md
index 9b912ce3..a2482968 100644
--- a/docs/guide/bundling.md
+++ b/docs/guide/bundling.md
@@ -26,12 +26,80 @@ Flags:
Currently there are 3 builtin plugins.
- css: import `.css` will be inlined as a string
-- sass: importing `.scss` files will go through the sass transpiler and be inlined as a string that contains valid css
- - uses the `sass` executable found on $PATH
-- blp: importing `.blp` files will go through [blueprint](https://jwestman.pages.gitlab.gnome.org/blueprint-compiler/) and be inlined as a string that contains valid xml template definitions
+- sass: importing `.scss` files will go through the sass transpiler and be inlined as a string that contains valid css using the `sass` executable found on `$PATH`
+ :::code-group
+
+ ```scss [style.scss]
+ $color: white;
+
+ selector {
+ color: $color;
+ }
+ ```
+
+ :::
+ :::code-group
+
+ ```ts [ app.ts]
+ import style from "./style.scss"
+
+ print(style)
+ // selector {
+ // color: white;
+ // }
+ ```
+
+ :::
+
+- blp: importing `.blp` files will go through [blueprint](https://jwestman.pages.gitlab.gnome.org/blueprint-compiler/) and be inlined as a string that contains xml template definitions
+ :::code-group
+
+ ```blp [ ui.blp]
+ using Gtk 4.0;
+
+ Label {
+ label: _("hello");
+ }
+ ```
+
+ :::
+ :::code-group
+
+ ```ts [ app.ts]
+ import ui from "./ui.blp"
+
+ print(ui)
+ //
+ //
+ //
+ //
+ //
+ ```
+
+ :::
+
- inline: importing with `inline:/path/to/file` will inline the contents of the file as a string
+ :::code-group
+
+ ```txt [data.txt]
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do.
+ ```
-AGS defines `SRC` by default which by default will point to the directory of `entryfile`.
+ :::
+ :::code-group
+
+ ```ts [ app.ts]
+ import data from "inline:./data.txt"
+
+ print(ui)
+ // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do.
+ ```
+
+ :::
+
+AGS defines `SRC` which by default will point to the directory of `entryfile`.
It can be overriden with `-d "SRC='/path/to/source'"`
```js
@@ -118,14 +186,94 @@ and distribute its output JS file as an executable.
Optionally use a build tool like meson to also declare its runtime dependencies.
When you have data files that you cannot inline as a string, for example icons,
-a good practice would be to.
+a good practice would be to:
1. Install data files to a directory, usually `/usr/share/your-project`
2. Define it as `DATADIR` in `env.d.ts` and at bundle time with `--define`
3. In code you can refer to data files through this `DATADIR` variable
-Optionally you should use a build tool like meson or a makefile
-to let users decide where to install to.
+ :::code-group
-> [!NOTE]
-> On Nix you can use the [lib.bundle](./nix#bundle-and-devshell) function.
+ ```meson [meson.build]
+ prefix = get_option('prefix')
+ pkgdatadir = prefix / get_option('datadir') / meson.project_name()
+ bindir = prefix / get_option('bindir')
+
+ install_data(
+ files('data/data.txt'),
+ install_dir: pkgdatadir,
+ )
+
+ custom_target(
+ command: [
+ find_program('ags'),
+ 'bundle',
+ '--define', 'DATADIR="' + pkgdatadir + '"',
+ meson.project_source_root() / 'app.ts',
+ meson.project_name(),
+ ],
+ output: [meson.project_name()],
+ input: files('app.ts'),
+ install: true,
+ install_dir: bindir,
+ )
+ ```
+
+ ```ts [env.d.ts]
+ declare const DATADIR: string
+ ```
+
+ ```ts [app.ts]
+ const data = `${DATADIR}/data.txt`
+ ```
+
+ :::
+
+> [!TIP]
+> On Nix you can use the [lib.bundle](./nix#bundle-and-devshell) function as well as meson.
+
+## Notice for Gtk4
+
+[`gtk4-layer-shell` needs to be linked before wayland.](https://github.com/wmww/gtk4-layer-shell/issues/3#issuecomment-1502339477)
+When bundling a Gtk4 application you will have to use a wrapper to make it work.
+
+:::code-group
+
+```bash [wrapper.sh]
+#!/bin/bash
+LD_PRELOAD="@LAYER_SHELL_LIBDIR@/libgtk4-layer-shell.so" @MAIN_PROGRAM@ $@
+```
+
+:::
+:::code-group
+
+```meson [meson.build]
+pkgdatadir = get_option('prefix') / get_option('datadir') / meson.project_name()
+main = meson.project_name() + '.wrapped'
+
+custom_target(
+ command: [
+ find_program('ags'),
+ 'bundle',
+ meson.project_source_root() / 'app.ts',
+ main,
+ ],
+ output: [meson.project_name()],
+ input: files('app.ts'),
+ install: true,
+ install_dir: pkgdatadir,
+)
+
+configure_file(
+ input: files('wrapper.sh'),
+ output: meson.project_name(),
+ configuration: {
+ 'MAIN_PROGRAM': pkgdatadir / main,
+ 'LAYER_SHELL_LIBDIR': dependency('gtk4-layer-shell-0').get_variable('libdir'),
+ },
+ install: true,
+ install_dir: get_option('prefix') / get_option('bindir'),
+)
+```
+
+:::
diff --git a/docs/guide/example.md b/docs/guide/example.md
index 47805e16..ef46e9b2 100644
--- a/docs/guide/example.md
+++ b/docs/guide/example.md
@@ -106,5 +106,6 @@ fi
```
> [!TIP]
-> If you are happy with the script and don't plan to change it anymore [bundle](./bundling.md) it,
+> If you are happy with the script and don't
+> plan to change it anymore [bundle](./bundling.md) it,
> which will remove the dependency on AGS.
diff --git a/docs/guide/init.md b/docs/guide/init.md
index e96a7d7b..a817d018 100644
--- a/docs/guide/init.md
+++ b/docs/guide/init.md
@@ -26,43 +26,42 @@ It will generate the following files:
```txt
.
-├── .gitignore
-├── @girs/ # generated types
+├── @girs/
+├── node_modules/
+│ └── astal
├── widget/
│ └── Bar.tsx
-├── app.ts # entry proint
-├── env.d.ts # additional types
+├── app.ts
+├── env.d.ts
├── style.scss
-└── tsconfig.json # needed by LSPs
+├── package.json
+└── tsconfig.json
```
The `@girs` directory contains the generated types, which are
created when running the `init` command or the `types` command.
-Assuming this directory will be tracked with git,
-it generates a `.gitignore` file which is set to ignore `@girs` and `node_modules`.
-Initially `node_modules` doesn't exist, but if you decide to install any `npm`
-package it is not needed to track them with git. You can also add `tsconfig.json`
-and `env.d.ts` to this list, as they are only used for developing and can be
-regenerated with the `types` command. Only track `tsconfig.json` if you add
-anything additional to `compilerOptions.paths`.
-
-> [!NOTE]
-> Since the runtime is `gjs`, very few packages will run from `npm`.
+:::details Details on TypeScript.
+While `gjs` does not currently support Node.js project structures and its ecosystem
+the JavaScript tooling we are using relies on it. The `node_modules` directory
+contains the `astal` package, but its purpose is only to provide type information.
+The `package.json` is a file describing the project and `tsconfig.json` is a file
+containing settings for TypeScript.
+:::
-The `env.d.ts` will tell the LSP that `.css`, `.scss` and `.blp` files can be
-imported and will be inlined as a string. It also tells it that imports
-prefixed with `inline:` will be inlined as well as that a global `SRC` variable
-is available.
+> [!WARNING]
+> Since the runtime is `gjs`, very few packages will run from `npm`,
+since most depends on `node` features.
-The `tsconfig.json` file tells information to the LSP so that
-intellisense can do its thing and provide great DX.
+The `env.d.ts` let's the type checker in your editor know about additional
+[features](./bundling) the `ags` bundler provides, for example the ability to inline files.
+This can be also be expanded for variables defined with the `--define` flag at bundling.
-`app.ts` is the entry point of the project which usually contains only
-an `App.start` call where you define [main](https://aylur.github.io/astal/guide/typescript/cli-app#entry-point) and [requestHandler](https://aylur.github.io/astal/guide/typescript/cli-app#messaging-from-cli),
+`app.ts` is the entry point of the project which usually
+contains only an `App.start` call where you define [main](https://aylur.github.io/astal/guide/typescript/cli-app#entry-point) and [requestHandler](https://aylur.github.io/astal/guide/typescript/cli-app#messaging-from-cli),
but can contain any other code.
-> [!NOTE]
+> [!TIP]
> You could also name the entry file `app.tsx` and write any JSX there.
> [!TIP]
@@ -70,15 +69,14 @@ but can contain any other code.
> in `tsconfig.json` and optionally `"checkJs": true` will allow
> JavaScript, although it is very much recommended to TypeScript.
-You are not forced into a project structure. You can put
-`style.scss` and `widget/Bar.ts` anywhere you like, only the entry file matters.
-
## Running projects
`tsconfig.json`, `env.d.ts` and `@girs` are only significant for the LSP,
they are not needed to run the project.
-:::tip
-You can also use `ags run` as a shebang line for simple scripts.
-See an [simple dialog example](./example.md)
-:::
+> [!TIP]
+> You can also use `ags run` as a shebang line for simple scripts.
+> See an [simple dialog example](./example.md).
+
+> [!IMPORTANT]
+> When using Gtk4 you have to use `--gtk4` flag for [gtk4-layer-shell](https://github.com/wmww/gtk4-layer-shell/issues/3#issuecomment-1502339477).
diff --git a/docs/guide/nix.md b/docs/guide/nix.md
index 68936ee4..69ddff6c 100644
--- a/docs/guide/nix.md
+++ b/docs/guide/nix.md
@@ -29,6 +29,7 @@ Using nix, you'll technically never have to use the `ags` cli.
src = ./.;
name = "my-shell"; # name of executable
entry = "app.ts";
+ gtk4 = false;
# additional libraries and executables to add to gjs' runtime
extraPackages = [
diff --git a/docs/guide/quick-start.md b/docs/guide/quick-start.md
index 902ce779..eef6594d 100644
--- a/docs/guide/quick-start.md
+++ b/docs/guide/quick-start.md
@@ -16,16 +16,32 @@ nix shell github:aylur/ags # ags in a temporary shell
2. Initialize a project
-```sh
-ags init
+:::code-group
+
+```sh [Gtk3]
+ags init --gtk 3
+```
+
+```sh [Gtk4]
+ags init --gtk 3
```
+:::
+
3. Run the project
-```sh
+:::code-group
+
+```sh [Gtk3]
ags run
```
+```sh [Gtk4]
+ags run --gtk4
+```
+
+:::
+
4. Learn [TypeScript in Y minutes](https://learnxinyminutes.com/docs/typescript/)
5. Read the [Astal Documentation](https://aylur.github.io/astal/guide/typescript/first-widgets) to start developing
diff --git a/docs/vitepress.config.ts b/docs/vitepress.config.ts
index cd6bfea6..19a0296c 100644
--- a/docs/vitepress.config.ts
+++ b/docs/vitepress.config.ts
@@ -12,6 +12,13 @@ export default defineConfig({
["link", { rel: "icon", href: "https://aylur.github.io/astal/icon.svg" }],
],
+ markdown: {
+ languageAlias: {
+ meson: "ruby",
+ blp: "c", // TODO: find a better alternative
+ },
+ },
+
themeConfig: {
outline: "deep",
diff --git a/flake.nix b/flake.nix
index b518444d..5ba30ef1 100644
--- a/flake.nix
+++ b/flake.nix
@@ -55,7 +55,16 @@
};
devShells.${system}.default = pkgs.mkShell {
- packages = with pkgs; [go gopls gotools go-tools];
+ packages = with pkgs; [
+ markdownlint-cli2
+ marksman
+ vtsls
+ vscode-langservers-extracted
+ go
+ gopls
+ gotools
+ go-tools
+ ];
};
};
}
diff --git a/lib/esbuild.go b/lib/esbuild.go
index 7d89f8c0..af5bb5da 100644
--- a/lib/esbuild.go
+++ b/lib/esbuild.go
@@ -161,6 +161,11 @@ func Bundle(opts BundleOpts) {
Platform: api.PlatformNeutral,
TsconfigRaw: tsconfig,
Define: defines,
+ Target: api.ES2022,
+ Sourcemap: api.SourceMapInline,
+ Engines: []api.Engine{
+ {Name: api.EngineFirefox, Version: "115"},
+ },
Loader: map[string]api.Loader{
".js": api.LoaderJSX,
".css": api.LoaderText,
diff --git a/nix/bundle.nix b/nix/bundle.nix
index 75c96106..8896605e 100644
--- a/nix/bundle.nix
+++ b/nix/bundle.nix
@@ -7,6 +7,7 @@
src,
name,
extraPackages ? [],
+ gtk4 ? false,
}:
pkgs.stdenvNoCC.mkDerivation {
inherit src name;
@@ -29,6 +30,7 @@ pkgs.stdenvNoCC.mkDerivation {
preFixup = ''
gappsWrapperArgs+=(
+ --set LD_PRELOAD "${pkgs.gtk4-layer-shell}/lib/libgtk4-layer-shell.so"
--prefix PATH : ${with pkgs;
lib.makeBinPath (extraPackages
++ [