Compare commits
136 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
730729b2f1 | ||
|
b5d2e7806f | ||
|
a48d234c56 | ||
|
34fbe9f018 | ||
|
dc0c931917 | ||
|
af32c09966 | ||
|
584b9e440e | ||
|
2a65be9e33 | ||
|
630dbb486f | ||
|
8ec88e697b | ||
|
987a9d4587 | ||
|
42c5e6c1d7 | ||
|
39f6eb9b51 | ||
|
156186b1c9 | ||
|
e97114eee2 | ||
|
0719075808 | ||
|
aa93296968 | ||
|
5506bf85f9 | ||
|
1b75996fab | ||
|
2057f39390 | ||
|
d9badbe19c | ||
|
6c173507a5 | ||
|
541572809a | ||
|
eafa99f771 | ||
|
48897f71d2 | ||
|
812895129f | ||
|
e5c077bd78 | ||
|
d79bc8c84a | ||
|
efb14d9961 | ||
|
2e4e318e17 | ||
|
26e63a11a5 | ||
|
dfb44ab923 | ||
|
7aa97b6cc7 | ||
|
d02b1d1eef | ||
|
020cfec21b | ||
|
154f5eaa82 | ||
|
2c1dad91de | ||
|
b66871f6bd | ||
|
6a1dd637ce | ||
|
3a8e52ceb0 | ||
|
bf5e999a00 | ||
|
2c0a46abf2 | ||
|
669d808c89 | ||
|
fa3f77ef51 | ||
|
05d6c3cf1a | ||
|
2d9b184bd5 | ||
|
60cfdb38fb | ||
|
f4eb0e604b | ||
|
2b13cf3ce2 | ||
|
afea0a5339 | ||
|
be55d5a675 | ||
|
bdf7bed717 | ||
|
78dbbfbc75 | ||
|
dd9a3e87a3 | ||
|
d4066fc32a | ||
|
5a29338cce | ||
|
ea18e429c9 | ||
|
b16fc2ddec | ||
|
d8f06f1b46 | ||
|
84f1bfa1cc | ||
|
17a8e4a6af | ||
|
e9748dd79f | ||
|
a4e1163e13 | ||
|
3a9c3338e0 | ||
|
b26fd1d381 | ||
|
d2c8150675 | ||
|
17e5377587 | ||
|
df4b1d4461 | ||
|
89a9f1b348 | ||
|
26d48f4fe1 | ||
|
0b0a0a283c | ||
|
b2dc1df6f3 | ||
|
563a316695 | ||
|
c65bdb49e2 | ||
|
3ae1c8c611 | ||
|
be124d22d8 | ||
|
d8584653ce | ||
|
16f4f12810 | ||
|
fae77d8ea1 | ||
|
d8c7992512 | ||
|
2b7a0aa6da | ||
|
1ebbe1e391 | ||
|
f511bc15ec | ||
|
16cda14d9a | ||
|
6ee084e1a0 | ||
|
4126d00920 | ||
|
ac5ec74787 | ||
|
185dfe415a | ||
|
4c2944e89c | ||
|
9f6af155b8 | ||
|
5d442dbe33 | ||
|
011d9d837f | ||
|
75ce9e32a6 | ||
|
13dccf5b30 | ||
|
984cc2c13c | ||
|
5e034880af | ||
|
fb6d55abe9 | ||
|
b60eac426d | ||
|
0df5033f1d | ||
|
749c7f3884 | ||
|
c145dd4a7c | ||
|
53f9d3c62b | ||
|
34b017b66d | ||
|
aaa8761e4d | ||
|
352d3b11e3 | ||
|
4f0c6ef5a5 | ||
|
6f201f9cf5 | ||
|
06cce1a912 | ||
|
eb3a1e099a | ||
|
4a398b0a50 | ||
|
1cec46533d | ||
|
64e5db0c06 | ||
|
774af5843a | ||
|
c4da728abc | ||
|
e8c4147fe7 | ||
|
b9727214a3 | ||
|
9206d0f1f9 | ||
|
45f0ba7e1a | ||
|
87936379fa | ||
|
259a61cb1c | ||
|
6db6825a61 | ||
|
e5132f05cc | ||
|
b134c81c86 | ||
|
99d35b78c5 | ||
|
2514485ca4 | ||
|
deb048d1b3 | ||
|
2af69259fa | ||
|
008877a07b | ||
|
cbe33d9fde | ||
|
f6fb4e7323 | ||
|
e53da83c00 | ||
|
2d1af689a5 | ||
|
a697b2fa25 | ||
|
a8eb24e9a5 | ||
|
02cb5ee3b8 | ||
|
5f322703c3 |
@ -4,11 +4,10 @@ env:
|
||||
parser: "@babel/eslint-parser"
|
||||
parserOptions:
|
||||
sourceType: module
|
||||
ecmaVersion: 2023
|
||||
requireConfigFile: false
|
||||
babelOptions:
|
||||
plugins:
|
||||
- "@babel/plugin-syntax-import-assertions"
|
||||
- "@babel/plugin-syntax-import-attributes"
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- plugin:import/errors
|
||||
|
4
.gitconfig
Normal file
@ -0,0 +1,4 @@
|
||||
[re.sonny.Commit]
|
||||
title-length-hint=72
|
||||
body-length-wrap=50
|
||||
auto-capitalize-title=true
|
2
.github/CODEOWNERS
vendored
@ -4,7 +4,7 @@
|
||||
/src/langs/vala/ @lw64
|
||||
*.vala @lw64
|
||||
|
||||
/src/langs/rust/ @lw64
|
||||
/src/langs/rust/ @Hofer-Julian
|
||||
*.rs @Hofer-Julian
|
||||
Cargo.toml @Hofer-Julian
|
||||
Cargo.lock @Hofer-Julian
|
||||
|
8
.github/workflows/CI.yaml
vendored
@ -5,10 +5,11 @@ name: CI
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
CI:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@ -16,13 +17,12 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
cache: "npm"
|
||||
|
||||
- name: Install host dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install flatpak flatpak-builder mutter
|
||||
sudo apt-get install flatpak mutter flatpak-builder
|
||||
|
||||
# Restore caches
|
||||
- name: Restore Flatpak dependencies
|
||||
|
32
.github/workflows/deploy.yaml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
flatpak:
|
||||
name: "Flatpak"
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-nightly
|
||||
options: --privileged
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
name: "Build"
|
||||
with:
|
||||
bundle: re.sonny.Workbench.Devel.flatpak
|
||||
manifest-path: build-aux/re.sonny.Workbench.Devel.json
|
||||
cache-key: flatpak-builder-${{ github.sha }}
|
||||
|
||||
- uses: flatpak/flatpak-github-actions/flat-manager@v6
|
||||
name: "Deploy"
|
||||
with:
|
||||
repository: nightly
|
||||
flat-manager-url: https://flat-manager.gnome.org/
|
||||
token: ${{ secrets.GNOME_NIGHTLY_TOKEN }}
|
3
.gitignore
vendored
@ -15,6 +15,9 @@ install
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.gresource
|
||||
.frun
|
||||
|
||||
# IDEs / editors
|
||||
.idea
|
||||
|
||||
target
|
||||
|
7
.gitmodules
vendored
@ -4,3 +4,10 @@
|
||||
[submodule "demos"]
|
||||
path = demos
|
||||
url = https://github.com/workbenchdev/demos.git
|
||||
[submodule "blueprint-compiler"]
|
||||
path = blueprint-compiler
|
||||
url = https://gitlab.gnome.org/jwestman/blueprint-compiler.git
|
||||
[submodule "src/langs/typescript/template/gi-types"]
|
||||
path = gi-types
|
||||
url = https://gitlab.gnome.org/BrainBlasted/gi-typescript-definitions.git
|
||||
branch = nightly
|
||||
|
2
.vscode/extensions.json
vendored
@ -9,6 +9,6 @@
|
||||
"prince781.vala",
|
||||
"bodil.blueprint-gtk",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"ms-python.black-formatter"
|
||||
"charliermarsh.ruff"
|
||||
]
|
||||
}
|
||||
|
21
.vscode/settings.json
vendored
@ -5,8 +5,8 @@
|
||||
"files.watcherExclude": {
|
||||
"**/.git/objects/**": true,
|
||||
"**/.git/subtree-cache/**": true,
|
||||
"**/node_modules/*/**": true,
|
||||
"**/.hg/store/**": true,
|
||||
"**/node_modules/*/**": true,
|
||||
"**/.flatpak": true,
|
||||
"**/src/lib": true,
|
||||
".flatpak": true,
|
||||
@ -14,17 +14,26 @@
|
||||
"_build/**": true
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"rust-analyzer.server.path": "${workspaceFolder}/.flatpak/rust-analyzer.sh",
|
||||
"rust-analyzer.runnables.command": "${workspaceFolder}/.flatpak/cargo.sh",
|
||||
"rust-analyzer.files.excludeDirs": [".flatpak"],
|
||||
"[yaml]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"rust-analyzer.server.path": "${workspaceFolder}/.flatpak/rust-analyzer.sh",
|
||||
"rust-analyzer.runnables.command": "${workspaceFolder}/.flatpak/cargo.sh",
|
||||
"rust-analyzer.files.excludeDirs": [
|
||||
".flatpak",
|
||||
".flatpak-builder",
|
||||
"_build",
|
||||
"build",
|
||||
"builddir"
|
||||
],
|
||||
"vala.languageServerPath": "${workspaceFolder}/.flatpak/vala-language-server.sh",
|
||||
"[meson]": {
|
||||
"editor.defaultFormatter": "mesonbuild.mesonbuild"
|
||||
},
|
||||
"mesonbuild.configureOnOpen": false,
|
||||
"mesonbuild.buildFolder": "_build",
|
||||
"mesonbuild.mesonPath": "${workspaceFolder}/.flatpak/meson.sh",
|
||||
"vala.languageServerPath": "${workspaceFolder}/.flatpak/vala-language-server.sh"
|
||||
"mesonbuild.mesonPath": "${workspaceFolder}/.flatpak/meson.sh"
|
||||
}
|
||||
|
@ -26,13 +26,13 @@ We provide a couple of tools to make the development process pleasant.
|
||||
|
||||
```sh
|
||||
# Ubuntu requirements
|
||||
# sudo apt install flatpak flatpak-builder nodejs make
|
||||
# sudo apt install flatpak flatpak-builder nodejs make gcc g++
|
||||
|
||||
# Fedora requirements
|
||||
# sudo dnf install flatpak flatpak-builder nodejs make
|
||||
# sudo dnf install flatpak flatpak-builder nodejs make gcc gcc-c++
|
||||
|
||||
cd Workbench
|
||||
make setup
|
||||
make
|
||||
```
|
||||
|
||||
Before submitting a PR, we recommend running tests locally with
|
||||
|
49
Makefile
@ -1,16 +1,28 @@
|
||||
SHELL:=/bin/bash -O globstar
|
||||
.PHONY: setup build lint unit test ci sandbox flatpak
|
||||
.DEFAULT_GOAL := test
|
||||
.DEFAULT_GOAL := setup
|
||||
|
||||
setup:
|
||||
flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install --or-update --user --noninteractive flathub org.gnome.Sdk//45 org.flatpak.Builder org.freedesktop.Sdk.Extension.rust-stable//23.08 org.freedesktop.Sdk.Extension.vala//23.08 org.freedesktop.Sdk.Extension.llvm16//23.08
|
||||
npm install
|
||||
make build
|
||||
flatpak install --or-update --user --noninteractive flathub org.gnome.Sdk//48 org.flatpak.Builder org.freedesktop.Sdk.Extension.rust-stable//24.08 org.freedesktop.Sdk.Extension.vala//24.08 org.freedesktop.Sdk.Extension.llvm18//24.08 org.freedesktop.Sdk.Extension.node20//24.08 org.freedesktop.Sdk.Extension.typescript//24.08
|
||||
# flatpak remote-add --user --if-not-exists flathub-beta https://flathub.org/beta-repo/flathub-beta.flatpakrepo
|
||||
# flatpak remote-add --user --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo
|
||||
# flatpak install --or-update --user --noninteractive gnome-nightly org.gnome.Sdk//master
|
||||
git submodule update --init
|
||||
npm install --no-fund
|
||||
@echo "✅ You can use "make build" to build Workbench"
|
||||
|
||||
build:
|
||||
stable:
|
||||
# flatpak --user run org.flatpak.Builder --delete-build-dirs --disable-updates --build-only --ccache --force-clean flatpak build-aux/re.sonny.Workbench.json
|
||||
flatpak-builder --delete-build-dirs --disable-updates --build-only --ccache --force-clean flatpak build-aux/re.sonny.Workbench.json
|
||||
|
||||
devel:
|
||||
# flatpak --user run org.flatpak.Builder --delete-build-dirs --disable-updates --build-only --ccache --force-clean flatpak build-aux/re.sonny.Workbench.Devel.json
|
||||
flatpak-builder --delete-build-dirs --disable-updates --build-only --ccache --force-clean flatpak build-aux/re.sonny.Workbench.Devel.json
|
||||
|
||||
|
||||
build: devel
|
||||
|
||||
cli:
|
||||
./troll/gjspack/bin/gjspack src/cli/main.js --appid=re.sonny.Workbench.cli --prefix=/re/sonny/Workbench --resource-root=src/ --no-executable flatpak/files/share/re.sonny.Workbench.cli/
|
||||
cp src/cli/bin.js flatpak/files/bin/workbench-cli
|
||||
@ -21,7 +33,8 @@ lint:
|
||||
# Rust
|
||||
./build-aux/fun rustfmt --check --edition 2021 src/**/*.rs
|
||||
# Python
|
||||
./build-aux/fun black --check src/**/*.py
|
||||
./build-aux/fun ruff check --config=src/langs/python/ruff.toml src/**/*.py
|
||||
./build-aux/fun ruff format --config=src/langs/python/ruff.toml --check src/**/*.py
|
||||
# Blueprint
|
||||
./build-aux/fun blueprint-compiler format src/**/*.blp
|
||||
./build-aux/fun workbench-cli check blueprint src/**/*.blp
|
||||
@ -30,11 +43,12 @@ lint:
|
||||
# CSS
|
||||
./build-aux/fun workbench-cli check css src/**/*.css
|
||||
# Flatpak manifests
|
||||
flatpak run --user --command=flatpak-builder-lint org.flatpak.Builder manifest --exceptions build-aux/re.sonny.Workbench.json
|
||||
flatpak run --user --command=flatpak-builder-lint org.flatpak.Builder manifest --exceptions build-aux/re.sonny.Workbench.Devel.json
|
||||
flatpak run --user --command=flatpak-builder-lint org.flatpak.Builder manifest --exceptions --user-exceptions ./build-aux/exceptions.json build-aux/re.sonny.Workbench.json
|
||||
flatpak run --user --command=flatpak-builder-lint org.flatpak.Builder manifest --exceptions --user-exceptions ./build-aux/exceptions.json build-aux/re.sonny.Workbench.Devel.json
|
||||
|
||||
unit:
|
||||
./build-aux/fun gjs -m ./troll/tst/bin.js test/*.test.js
|
||||
#./build-aux/wip/run.js build-aux/re.sonny.Workbench.Devel.json -- gjs -m ./troll/tst/bin.js test/*.test.js
|
||||
|
||||
# https://github.com/ximion/appstream/issues/398#issuecomment-1129454985
|
||||
# flatpak run org.freedesktop.appstream.cli validate --override=release-time-missing=info --no-net data/app.metainfo.xml
|
||||
@ -47,25 +61,28 @@ unit:
|
||||
# flatpak run --env=G_DEBUG=fatal-criticals --command=appstream-util org.flatpak.Builder validate data/app.metainfo.xml
|
||||
|
||||
test: unit lint
|
||||
./build-aux/fun workbench-cli ci demos/demos/Welcome
|
||||
./build-aux/fun workbench-cli ci demos/src/Welcome
|
||||
# ./build-aux/wip/run.js build-aux/re.sonny.Workbench.Devel.json -- workbench-cli ci demos/src/Welcome/
|
||||
|
||||
ci: setup test
|
||||
./build-aux/fun workbench-cli ci demos/demos/**
|
||||
ci: setup build test
|
||||
# See Permissions.js
|
||||
# flatpak override --user --share=network --socket=pulseaudio --device=input re.sonny.Workbench.Devel
|
||||
./build-aux/fun workbench-cli ci demos/src/*
|
||||
|
||||
# Note that if you have Sdk extensions installed they will be used
|
||||
# make sure to test without the sdk extensions installed
|
||||
sandbox: setup
|
||||
flatpak-builder --ccache --user --install --force-clean flatpak build-aux/re.sonny.Workbench.Devel.json
|
||||
# flatpak remove --noninteractive org.freedesktop.Sdk.Extension.rust-stable//23.08 org.freedesktop.Sdk.Extension.vala//23.08 org.freedesktop.Sdk.Extension.llvm16//23.08
|
||||
flatpak run org.flatpak.Builder --ccache --user --install --force-clean flatpak build-aux/re.sonny.Workbench.Devel.json
|
||||
# flatpak remove --noninteractive org.freedesktop.Sdk.Extension.rust-stable//24.08 org.freedesktop.Sdk.Extension.vala//24.08 org.freedesktop.Sdk.Extension.llvm18//24.08
|
||||
flatpak run --command="bash" re.sonny.Workbench.Devel
|
||||
|
||||
flatpak:
|
||||
flatpak-builder --ccache --force-clean flatpak build-aux/re.sonny.Workbench.Devel.json
|
||||
flatpak run org.flatpak.Builder --ccache --force-clean flatpak build-aux/re.sonny.Workbench.Devel.json
|
||||
# This is what Flathub does - consider moving to lint
|
||||
flatpak run --env=G_DEBUG=fatal-criticals --command=appstream-util org.flatpak.Builder validate flatpak/files/share/appdata/re.sonny.Workbench.Devel.appdata.xml
|
||||
flatpak run --command="desktop-file-validate" --filesystem=host:ro org.freedesktop.Sdk//23.08 flatpak/files/share/applications/re.sonny.Workbench.Devel.desktop
|
||||
flatpak run --command="desktop-file-validate" --filesystem=host:ro org.freedesktop.Sdk//24.08 flatpak/files/share/applications/re.sonny.Workbench.Devel.desktop
|
||||
# appstreamcli validate --override=release-time-missing=info /path/to/your/app.metainfo.xml
|
||||
flatpak-builder --run flatpak build-aux/re.sonny.Workbench.Devel.json bash
|
||||
flatpak run org.flatpak.Builder --run flatpak build-aux/re.sonny.Workbench.Devel.json bash
|
||||
|
||||
# Sync with .gitignore
|
||||
clean:
|
||||
|
18
README.md
@ -6,7 +6,7 @@ Learn and prototype with GNOME technologies
|
||||
|
||||

|
||||
|
||||
<a href='https://flathub.org/apps/re.sonny.Workbench'><img width='240' height='80' alt='Download on Flathub' src='https://dl.flathub.org/assets/badges/flathub-badge-en.svg'/></a>
|
||||
<a href='https://flathub.org/apps/re.sonny.Workbench'><img width='240' alt='Download on Flathub' src='https://flathub.org/api/badge?svg&locale=en'/></a>
|
||||
|
||||
Workbench lets you experiment with GNOME technologies, no matter if tinkering for the first time or building and testing a GTK user interface.
|
||||
|
||||
@ -14,12 +14,12 @@ Among other things, Workbench comes with
|
||||
|
||||
- Live GTK/CSS preview
|
||||
- Library of 100+ examples
|
||||
<!-- - JavaScript, TypeScript, Rust, Python and Vala support -->
|
||||
- JavaScript, Rust, Python and Vala support
|
||||
- Declarative user interface syntax
|
||||
- Autosave, sessions and projects
|
||||
- Code linter and formatter
|
||||
- Code diagnostics, completion and formatter
|
||||
- Terminal output
|
||||
- 1000+ icons
|
||||
|
||||
ℹ️ Workbench is made possible by Flatpak. Only Flathub Workbench is supported.
|
||||
|
||||
@ -31,21 +31,21 @@ Among other things, Workbench comes with
|
||||
|
||||
| | Formatter | Linter | Library demos[1] |
|
||||
| ---------- | --------- | ------ | ---------------- |
|
||||
| JavaScript | ✅ | ✅ | 94 |
|
||||
| Python | ✅ | | 64 |
|
||||
| Vala | ✅ | ✅ | 54 |
|
||||
| Rust | ✅ | | 45 |
|
||||
| JavaScript | ✅ | ✅ | 103 |
|
||||
| Python | ✅ | ✅ | 98 |
|
||||
| Vala | ✅ | ✅ | 92 |
|
||||
| Rust | ✅ | ✅ | 52 |
|
||||
| Blueprint | ✅ | ✅ | |
|
||||
| CSS | ✅ | ✅ | |
|
||||
|
||||
[1] As of 2024-01-14 <!--counted with `~/go/bin/scc demos/demos`-->
|
||||
[1] As of 2024-06-16 <!--counted with `~/go/bin/scc demos/src`-->
|
||||
|
||||
## Tips and tricks
|
||||
|
||||
<details>
|
||||
<summary>Disable code formatting</summary>
|
||||
|
||||
[JavaScript](https://docs.rome.tools/formatter/#ignoring-code)
|
||||
[JavaScript](https://biomejs.dev/formatter/#ignore-code)
|
||||
|
||||
[CSS](https://prettier.io/docs/en/ignore.html#css)
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
<shortdesc>Learn and prototype with GNOME technologies</shortdesc>
|
||||
<description>Workbench goal is to let you experiment with GNOME technologies, no matter if tinkering for the first time or building and testing a custom GTK widget.</description>
|
||||
|
||||
<homepage rdf:resource="https://apps.gnome.org/Workbench" />
|
||||
<bug-database rdf:resource="https://github.com/workbenchdev/Workbench/issues" />
|
||||
<homepage rdf:resource="https://workbench.sonny.re" />
|
||||
<bug-database rdf:resource="https://workbench.sonny.re/feedback" />
|
||||
<programming-language>JavaScript</programming-language>
|
||||
<programming-language>Vala</programming-language>
|
||||
<programming-language>C</programming-language>
|
||||
@ -38,8 +38,10 @@
|
||||
</foaf:OnlineAccount>
|
||||
</foaf:account>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>julianhofer</foaf:name>
|
||||
<foaf:name>Julian Hofer</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:julianhofer@gnome.org" />
|
||||
<gnome:userid>julianhofer</gnome:userid>
|
||||
<foaf:account>
|
||||
|
1
blueprint-compiler
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 04ef0944db56ab01307a29aaa7303df6067cb3c0
|
@ -4,34 +4,37 @@ This directory contains the Flatpak Manifest and other build utilities.
|
||||
|
||||
## Workbench Flatpak Manifests
|
||||
|
||||
### gst-plugin-gtk4
|
||||
### Python Modules
|
||||
|
||||
```sh
|
||||
wget https://crates.io/api/v1/crates/gst-plugin-gtk4/0.11.1/download
|
||||
tar-xf download
|
||||
cd gst-plugin-gtk4-0.11.1/
|
||||
~/Projects/flathub/flatpak-builder-tools/cargo/flatpak-cargo-generator.py Cargo.lock
|
||||
# cp generated-sources.json to gst-plugin-gtk4-sources.json
|
||||
```
|
||||
The `modules/python-*.json` files contain Flatpak modules to install Python dependencies.
|
||||
|
||||
### Python Black Dependency
|
||||
|
||||
`modules/python-black.json` contains the Flatpak modules to install [https://github.com/psf/black](black), the
|
||||
uncompromising Python code formatter.
|
||||
|
||||
This file is partially auto-generated. Here is how to generate it:
|
||||
These files are (sometimes partially, see below) auto-generated. Here is how to generate it:
|
||||
|
||||
1. Obtain an up-to-date copy of [flatpak-builder-tools](https://github.com/flatpak/flatpak-builder-tools).
|
||||
2. Make sure you have a Python virtualenv activated with the dependencies for the `pip` generator from the repo above.
|
||||
3. Run `python3 <...>/flatpak-builder-tools/pip/flatpak-pip-generator black -o modules/python-black --build-isolation`
|
||||
3. Run `python3 <...>/flatpak-builder-tools/pip/flatpak-pip-generator <package> -o modules/python-<package> --build-isolation`
|
||||
|
||||
You will notice that Workbench will now not build. This is due to these issues:
|
||||
You will notice that Workbench will not build after auto-generating these files as described above.
|
||||
This is due to these issues:
|
||||
|
||||
- https://github.com/flatpak/flatpak-builder-tools/issues/380
|
||||
- https://github.com/pypa/pip/issues/7863
|
||||
|
||||
This means that the generated JSON file now needs its build dependencies manually added. Check the build dependencies
|
||||
of black and their dependencies and add them to the JSON as well. Brute-forcing the build to obtain missing packages
|
||||
of the package and their dependencies and add them to the JSON as well. Brute-forcing the build to obtain missing packages
|
||||
may help as does referencing old commits of the file. You can also use the generator command to generate dependencies
|
||||
for them and then merge it into the file by hand, but note that you will also need to manually collect their build
|
||||
dependencies too.
|
||||
|
||||
In some cases you may also need to manually remove some packages the generator adds (such as `packaging` with `rope`,
|
||||
as the SDK and Runtime already contain a version of these packages that can not be replaced. Make sure the package
|
||||
you want to install is actually compatible with the version of that dependency in the SDK/Runtime.
|
||||
|
||||
#### Python packages with Maturin as build system
|
||||
|
||||
Python packages with Maturin as build system need some additional manual steps to get working. You will have to have
|
||||
Rust enabled for compilation and pull in additional dependencies. See `modules/python-ruff.json` for example.
|
||||
|
||||
You can generate Maturin's dependencies with another generator provided by the Flatpak Builder Tools. Clone
|
||||
the Maturin repo in the corresponding version you need and run:
|
||||
`python3 <...>/flatpak-builder-tools/cargo/flatpak-cargo-generator.py <...>/Cargo.lock -o modules/cargo-sources-maturin.json`
|
||||
|
4
build-aux/exceptions.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"re.sonny.Workbench": ["external-gitmodule-url-found"],
|
||||
"re.sonny.Workbench.Devel": ["external-gitmodule-url-found"]
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
#!/usr/bin/env -S gjs -m
|
||||
|
||||
import Gio from "gi://Gio";
|
||||
import GLib from "gi://GLib";
|
||||
|
||||
Gio._promisify(
|
||||
Gio.File.prototype,
|
||||
"enumerate_children_async",
|
||||
"enumerate_children_finish",
|
||||
);
|
||||
|
||||
Gio._promisify(
|
||||
Gio.File.prototype,
|
||||
"replace_contents_async",
|
||||
"replace_contents_finish",
|
||||
);
|
||||
|
||||
const demos_dir = Gio.File.new_for_path(
|
||||
GLib.getenv("MESON_SOURCE_ROOT"),
|
||||
).get_child("demos/demos");
|
||||
const demos = [];
|
||||
|
||||
for (const file_info of demos_dir.enumerate_children(
|
||||
"",
|
||||
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
|
||||
null,
|
||||
)) {
|
||||
if (file_info.get_file_type() !== Gio.FileType.DIRECTORY) continue;
|
||||
|
||||
const demo_name = file_info.get_name();
|
||||
const demo_dir = demos_dir.get_child(demo_name);
|
||||
|
||||
let str;
|
||||
try {
|
||||
str = new TextDecoder().decode(
|
||||
demo_dir.get_child("main.json").load_contents(null)[1],
|
||||
);
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
continue;
|
||||
}
|
||||
|
||||
const demo = JSON.parse(str);
|
||||
demo.name = file_info.get_name();
|
||||
|
||||
const languages = [];
|
||||
if (demo_dir.get_child("main.js").query_exists(null)) {
|
||||
languages.push("javascript");
|
||||
}
|
||||
if (demo_dir.get_child("main.vala").query_exists(null)) {
|
||||
languages.push("vala");
|
||||
}
|
||||
if (demo_dir.get_child("code.rs").query_exists(null)) {
|
||||
languages.push("rust");
|
||||
}
|
||||
if (demo_dir.get_child("main.py").query_exists(null)) {
|
||||
languages.push("python");
|
||||
}
|
||||
demo.languages = languages;
|
||||
|
||||
demos.push(demo);
|
||||
}
|
||||
|
||||
const [pkgdatadir] = ARGV;
|
||||
|
||||
GLib.mkdir_with_parents(pkgdatadir, 0o755);
|
||||
await Gio.File.new_for_path(pkgdatadir)
|
||||
.get_child("demos/index.json")
|
||||
.replace_contents_async(
|
||||
new TextEncoder().encode(JSON.stringify(demos)),
|
||||
null,
|
||||
false,
|
||||
Gio.FileCreateFlags.NONE,
|
||||
null,
|
||||
);
|
250
build-aux/library.js
Executable file
@ -0,0 +1,250 @@
|
||||
#!/usr/bin/env -S gjs -m
|
||||
|
||||
import Gio from "gi://Gio";
|
||||
import GLib from "gi://GLib";
|
||||
import { programArgs, exit } from "system";
|
||||
|
||||
Gio._promisify(
|
||||
Gio.File.prototype,
|
||||
"enumerate_children_async",
|
||||
"enumerate_children_finish",
|
||||
);
|
||||
|
||||
Gio._promisify(
|
||||
Gio.File.prototype,
|
||||
"replace_contents_async",
|
||||
"replace_contents_finish",
|
||||
);
|
||||
|
||||
Gio._promisify(
|
||||
Gio.File.prototype,
|
||||
"make_directory_async",
|
||||
"make_directory_finish",
|
||||
);
|
||||
|
||||
Gio._promisify(Gio.File.prototype, "copy_async", "copy_finish");
|
||||
|
||||
const loop = new GLib.MainLoop(null, false);
|
||||
|
||||
const [pkgdatadir] = programArgs;
|
||||
GLib.mkdir_with_parents(
|
||||
Gio.File.new_for_path(pkgdatadir).get_child("demos").get_path(),
|
||||
0o755,
|
||||
);
|
||||
|
||||
const demos_dir = Gio.File.new_for_path(
|
||||
GLib.getenv("MESON_SOURCE_ROOT"),
|
||||
).get_child("demos/src");
|
||||
const demos = [];
|
||||
|
||||
(async () => {
|
||||
const enumerator = await demos_dir.enumerate_children_async(
|
||||
`${Gio.FILE_ATTRIBUTE_STANDARD_NAME},${Gio.FILE_ATTRIBUTE_STANDARD_IS_HIDDEN}`,
|
||||
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
null,
|
||||
);
|
||||
for (const file_info of enumerator) {
|
||||
if (file_info.get_is_hidden()) continue;
|
||||
if (file_info.get_file_type() !== Gio.FileType.DIRECTORY) continue;
|
||||
|
||||
const demo_dir = enumerator.get_child(file_info);
|
||||
|
||||
let str;
|
||||
try {
|
||||
str = new TextDecoder().decode(
|
||||
demo_dir.get_child("main.json").load_contents(null)[1],
|
||||
);
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
continue;
|
||||
}
|
||||
|
||||
const demo = JSON.parse(str);
|
||||
demo.name = file_info.get_name();
|
||||
|
||||
if (!isDemoCompatible(demo)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const languages = [];
|
||||
if (demo_dir.get_child("main.js").query_exists(null)) {
|
||||
languages.push("javascript");
|
||||
}
|
||||
if (demo_dir.get_child("main.ts").query_exists(null)) {
|
||||
languages.push("typescript");
|
||||
}
|
||||
if (demo_dir.get_child("main.vala").query_exists(null)) {
|
||||
languages.push("vala");
|
||||
}
|
||||
if (demo_dir.get_child("code.rs").query_exists(null)) {
|
||||
languages.push("rust");
|
||||
}
|
||||
if (demo_dir.get_child("main.py").query_exists(null)) {
|
||||
languages.push("python");
|
||||
}
|
||||
demo.languages = languages;
|
||||
|
||||
await copyDemo(
|
||||
demo_dir,
|
||||
Gio.File.new_for_path(pkgdatadir)
|
||||
.get_child("demos")
|
||||
.get_child(demo_dir.get_basename()),
|
||||
);
|
||||
|
||||
demos.push(demo);
|
||||
}
|
||||
|
||||
demos.sort((a, b) => {
|
||||
if (a.name === "Welcome") return -1;
|
||||
if (b.name === "Welcome") return 1;
|
||||
if (a.name === "Platform Tools") return -1;
|
||||
if (b.name === "Platform Tools") return 1;
|
||||
else return a.name.localeCompare(b.name);
|
||||
});
|
||||
|
||||
await Gio.File.new_for_path(pkgdatadir)
|
||||
.get_child("demos/index.json")
|
||||
.replace_contents_async(
|
||||
new TextEncoder().encode(JSON.stringify(demos)),
|
||||
null,
|
||||
false,
|
||||
Gio.FileCreateFlags.NONE,
|
||||
null,
|
||||
);
|
||||
})()
|
||||
.catch((err) => {
|
||||
loop.quit();
|
||||
console.error(err);
|
||||
exit(1);
|
||||
})
|
||||
.then(() => {
|
||||
loop.quit();
|
||||
});
|
||||
|
||||
async function copyDemo(source, destination) {
|
||||
try {
|
||||
destination.make_directory_with_parents(null);
|
||||
} catch (err) {
|
||||
if (!err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const enumerator = await source.enumerate_children_async(
|
||||
`${Gio.FILE_ATTRIBUTE_STANDARD_NAME},${Gio.FILE_ATTRIBUTE_STANDARD_IS_HIDDEN}`,
|
||||
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
null,
|
||||
);
|
||||
|
||||
for await (const file_info of enumerator) {
|
||||
if (file_info.get_is_hidden()) continue;
|
||||
|
||||
const child = enumerator.get_child(file_info);
|
||||
if (
|
||||
// Sync with demos "make clean" and .gitignore
|
||||
[
|
||||
"Cargo.lock",
|
||||
"Cargo.toml",
|
||||
"lib.rs",
|
||||
"workbench.rs",
|
||||
"workbench.vala",
|
||||
"libworkbenchcode.so",
|
||||
"settings",
|
||||
"main.ui",
|
||||
"icons.gresource",
|
||||
"icons.gresource.xml",
|
||||
].includes(child.get_basename())
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const child_dest = destination.get_child(child.get_basename());
|
||||
|
||||
if (file_info.get_file_type() === Gio.FileType.DIRECTORY) {
|
||||
await copyDirectory(child, child_dest);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
await child.copy_async(
|
||||
child_dest, // destination
|
||||
Gio.FileCopyFlags.NONE, // flags
|
||||
GLib.PRIORITY_DEFAULT, // priority
|
||||
null, // cancellable
|
||||
null, // progress_callback
|
||||
);
|
||||
} catch (err) {
|
||||
if (!err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function copyDirectory(source, destination) {
|
||||
try {
|
||||
await destination.make_directory_async(GLib.PRIORITY_DEFAULT, null);
|
||||
} catch (err) {
|
||||
if (!err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const enumerator = await source.enumerate_children_async(
|
||||
`${Gio.FILE_ATTRIBUTE_STANDARD_NAME},${Gio.FILE_ATTRIBUTE_STANDARD_IS_HIDDEN}`,
|
||||
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
null,
|
||||
);
|
||||
|
||||
for await (const file_info of enumerator) {
|
||||
if (file_info.get_is_hidden()) continue;
|
||||
|
||||
const child = enumerator.get_child(file_info);
|
||||
const child_dest = destination.get_child(child.get_basename());
|
||||
|
||||
if (file_info.get_file_type() === Gio.FileType.DIRECTORY) {
|
||||
await copyDirectory(child, child_dest);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
await child.copy_async(
|
||||
child_dest, // destination
|
||||
Gio.FileCopyFlags.NONE, // flags
|
||||
GLib.PRIORITY_DEFAULT, // priority
|
||||
null, // cancellable
|
||||
null, // progress_callback
|
||||
);
|
||||
} catch (err) {
|
||||
if (!err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const key_file = new GLib.KeyFile();
|
||||
key_file.load_from_file("/.flatpak-info", GLib.KeyFileFlags.NONE);
|
||||
// runtime/org.gnome.Sdk/x86_64/master
|
||||
const [, , , runtime_version] = key_file
|
||||
.get_string("Application", "runtime")
|
||||
.split("/");
|
||||
|
||||
function isDemoCompatible(demo) {
|
||||
const demo_runtime_version = demo["runtime-version"];
|
||||
|
||||
if (demo_runtime_version === "master") {
|
||||
return runtime_version === "master";
|
||||
} else if (runtime_version === "master") {
|
||||
return true;
|
||||
} else if (!demo_runtime_version) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return +runtime_version >= +demo_runtime_version;
|
||||
}
|
||||
|
||||
loop.run();
|
@ -6,19 +6,23 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/JCWasmx86/GTKCssLanguageServer",
|
||||
"commit": "6475047e6d2632467838769332bc849941ab2aaa"
|
||||
"commit": "dcbe75012d2d26fbca2729cee014e4860e31fa53"
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "jsonrpc-glib",
|
||||
"config-opts": ["--buildtype=release", "-Denable_tests=false"],
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"--buildtype=release",
|
||||
"-Denable_tests=false"
|
||||
],
|
||||
"buildsystem": "meson",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://download.gnome.org/sources/jsonrpc-glib/3.44/jsonrpc-glib-3.44.0.tar.xz",
|
||||
"sha256": "69406a0250d0cc5175408cae7eca80c0c6bfaefc4ae1830b354c0433bcd5ce06"
|
||||
"url": "https://download.gnome.org/sources/jsonrpc-glib/3.44/jsonrpc-glib-3.44.1.tar.xz",
|
||||
"sha256": "1361d17e9c805646afe5102e59baf8ca450238600fcabd01586c654b78bb30df"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -7,15 +7,15 @@
|
||||
"type": "file",
|
||||
"dest-filename": "biome",
|
||||
"only-arches": ["aarch64"],
|
||||
"url": "https://github.com/biomejs/biome/releases/download/cli%2Fv1.4.1/biome-linux-arm64",
|
||||
"sha256": "8f2712e303877594a9401ce392724f8b8c94d533b6f5902d9cbdd149e4fbd794"
|
||||
"url": "https://github.com/biomejs/biome/releases/download/cli%2Fv1.9.4/biome-linux-arm64",
|
||||
"sha256": "f0f0f3e7cdec78420a600b05bfc364aa9b804811bd3bbae04e7bf090828ae970"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"dest-filename": "biome",
|
||||
"only-arches": ["x86_64"],
|
||||
"url": "https://github.com/biomejs/biome/releases/download/cli%2Fv1.4.1/biome-linux-x64",
|
||||
"sha256": "2995159aebcb7ddd116b098a1a0a459d1a8681aaa878623fb5390cc0dd0e414a"
|
||||
"url": "https://github.com/biomejs/biome/releases/download/cli%2Fv1.9.4/biome-linux-x64",
|
||||
"sha256": "ce247fb644999ef52e5111dd6fd6e471019669fc9c4a44b5699721e39b7032c3"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -3,9 +3,8 @@
|
||||
"buildsystem": "meson",
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/jwestman/blueprint-compiler.git",
|
||||
"commit": "80aaee374d332b0c7e04a132cce9c472d6427a1e"
|
||||
"type": "dir",
|
||||
"path": "../../blueprint-compiler"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
12
build-aux/modules/gom.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "gom",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": ["--libdir=/app/lib", "-Denable-gtk-doc=false"],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://download.gnome.org/sources/gom/0.5/gom-0.5.3.tar.xz",
|
||||
"sha256": "069d0909fbdc6b4d27edf7a879366194e3ab508b03548bf5b89ff63546d20177"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "gst-plugin-gtk4",
|
||||
"buildsystem": "simple",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://crates.io/api/v1/crates/gst-plugin-gtk4/0.11.2/download",
|
||||
"dest-filename": "gst-plugin-gtk4-0.11.2.tar.gz",
|
||||
"sha256": "33970273495544e54d5f486d761b09d402f0cf8760990e1ea508bd5141f8ebeb"
|
||||
},
|
||||
"gst-plugin-gtk4-sources.json"
|
||||
],
|
||||
"build-commands": [
|
||||
"cargo cinstall --offline --release --features=wayland,x11glx,x11egl --library-type=cdylib --prefix=/app"
|
||||
],
|
||||
"build-options": {
|
||||
"env": {
|
||||
"CARGO_HOME": "/run/build/gst-plugin-gtk4/cargo"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
{
|
||||
"name": "icon-development-kit",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"mkdir -p /app/share/icon-development-kit",
|
||||
"mkdir -p /app/share/icons/hicolor/scalable/actions/",
|
||||
"yq -o=json _data/icons.yaml > /app/share/icon-development-kit/icons.json",
|
||||
"cp -r img/symbolic/**/*.svg /app/share/icons/hicolor/scalable/actions/ || true"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/Teams/Design/icon-development-kit-www.git",
|
||||
"commit": "d6bc308bbf9dab29c719f09ddfd54088b58abf5f"
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "yq",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": ["chmod +x yq", "cp yq /app/bin/yq"],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"only-arches": ["x86_64"],
|
||||
"url": "https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_amd64",
|
||||
"sha256": "4ee662847c588c3ef2fec8bfb304e8739e3dbaba87ccb9a608d691c88f5b64dc",
|
||||
"dest-filename": "yq"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"only-arches": ["aarch64"],
|
||||
"url": "https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_arm64",
|
||||
"sha256": "15925a972d268bcb0a7aa2236c7e5925b7a3ba4b5569bb57e943db7e8c6f834f",
|
||||
"dest-filename": "yq"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
"name": "libportal",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbackend-gtk3=disabled",
|
||||
"-Dbackend-gtk4=enabled",
|
||||
@ -11,8 +12,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/flatpak/libportal/releases/download/0.7.1/libportal-0.7.1.tar.xz",
|
||||
"sha256": "297b90b263fad22190a26b8c7e8ea938fe6b18fb936265e588927179920d3805"
|
||||
"url": "https://github.com/flatpak/libportal/releases/download/0.9.1/libportal-0.9.1.tar.xz",
|
||||
"sha256": "de801ee349ed3c255a9af3c01b1a401fab5b3fc1c35eb2fd7dfb35d4b8194d7f"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,12 +1,38 @@
|
||||
{
|
||||
"name": "libshumate",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": ["-Dgtk_doc=false", "-Dlibsoup3=true"],
|
||||
"config-opts": ["--libdir=/app/lib", "-Ddemos=false", "-Dgtk_doc=false"],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://download.gnome.org/sources/libshumate/1.1/libshumate-1.1.2.tar.xz",
|
||||
"sha256": "8f094f6e7e256ab192800516ff96617abeec2363b054aad6aeb17e0088c1fb2c"
|
||||
"url": "https://download.gnome.org/sources/libshumate/1.4/libshumate-1.4.rc.tar.xz",
|
||||
"sha256": "a57b97dbbda55bcb07c6f0197ff006128518c2b2c88fbee8bea5168acbc9baee"
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "protobuf",
|
||||
"buildsystem": "autotools",
|
||||
"config-opts": ["DIST_LANG=cpp"],
|
||||
"cleanup": ["/bin/protoc*", "/lib/libprotoc*", "/lib/libprotobuf-lite*"],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-all-3.17.3.tar.gz",
|
||||
"sha256": "77ad26d3f65222fd96ccc18b055632b0bfedf295cb748b712a98ba1ac0b704b2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "protobuf-c",
|
||||
"buildsystem": "autotools",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/protobuf-c/protobuf-c/releases/download/v1.4.0/protobuf-c-1.4.0.tar.gz",
|
||||
"sha256": "26d98ee9bf18a6eba0d3f855ddec31dbe857667d269bc0b6017335572f85bbcb"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "libspelling",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": ["-Ddocs=false"],
|
||||
"config-opts": ["--libdir=/app/lib", "-Ddocs=false"],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://download.gnome.org/sources/libspelling/0.2/libspelling-0.2.0.tar.xz",
|
||||
"sha256": "fdc5609e02818eca6fc172ff164caa8e52dba638d7590130af3dfb1f28b53421"
|
||||
"url": "https://download.gnome.org/sources/libspelling/0.4/libspelling-0.4.6.tar.xz",
|
||||
"sha256": "3248a9b5336ea2f727d2db912d2f0083accc0505ce707679b3d9b8266c0101f5"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,104 +0,0 @@
|
||||
{
|
||||
"name": "python3-black",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"black\""
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/36/bf/a462f36723824c60dc3db10528c95656755964279a6a5c287b4f9fd0fa84/black-23.10.1.tar.gz",
|
||||
"sha256": "1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl",
|
||||
"sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl",
|
||||
"sha256": "4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl",
|
||||
"sha256": "8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/b4/2a/9b1be29146139ef459188f5e420a66e835dda921208db600b7037093891f/pathspec-0.11.2-py3-none-any.whl",
|
||||
"sha256": "1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/56/29/3ec311dc18804409ecf0d2b09caa976f3ae6215559306b5b530004e11156/platformdirs-3.11.0-py3-none-any.whl",
|
||||
"sha256": "e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/6b/be/0f2f4a5e8adc114a02b63d92bf8edbfa24db6fc602fca83c885af2479e0e/editables-0.5-py3-none-any.whl",
|
||||
"sha256": "61e5ffa82629e0d8bfe09bc44a07db3c1ab8ed1ce78a6980732870f19b5e7d4c"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/76/56/8ccca673e2c896931722f876bf040c0b6a7d8c1a128be60516a8a55bb27a/hatchling-1.18.0-py3-none-any.whl",
|
||||
"sha256": "b66dc254931ec42aa68b5febd1d342c58142cc5267b7ff3b12ba3fa5b4900c93"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl",
|
||||
"sha256": "8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/b4/2a/9b1be29146139ef459188f5e420a66e835dda921208db600b7037093891f/pathspec-0.11.2-py3-none-any.whl",
|
||||
"sha256": "1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/05/b8/42ed91898d4784546c5f06c60506400548db3f7a4b3fb441cba4e5c17952/pluggy-1.3.0-py3-none-any.whl",
|
||||
"sha256": "d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/ec/40/05cb2725ca7e6c844c66af626c5749efd254ec4506f17a1d01ba79ae9da6/trove_classifiers-2023.10.18-py3-none-any.whl",
|
||||
"sha256": "20a3da8e3cb65587cc9f5d5b837bf74edeb480bba9bd8cd4f03ab056d6b06c4c"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/00/b1/90cc7881c2e870333eeafa6afb7b27de53418aad1ba5409ad331c96608a1/hatch_vcs-0.3.0-py3-none-any.whl",
|
||||
"sha256": "60ce59a3fa4664057e4a858b6a96ab0b9dec21bf8f562f836139315bb361be8c"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/0e/a3/b9a8b0adfe672bf0df5901707aa929d30a97ee390ba651910186776746d2/setuptools_scm-8.0.4-py3-none-any.whl",
|
||||
"sha256": "b47844cd2a84b83b3187a5782c71128c28b4c94cad8bfb871da2784a5cb54c4f"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/24/21/7d397a4b7934ff4028987914ac1044d3b7d52712f30e2ac7a2ae5bc86dd0/typing_extensions-4.8.0-py3-none-any.whl",
|
||||
"sha256": "8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/6b/74/74a15619861065fa75f6170c649cd2fd5467726bb407ec2017d4a3f92d28/hatch_fancy_pypi_readme-23.1.0-py3-none-any.whl",
|
||||
"sha256": "9a2c0e5d527611701858083bfb355876f26e04a075342b7d4da725ba5a6dd6ea"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/ef/cc/93f7213b2ab5ed383f98ce8020e632ef256b406b8569606c3f160ed8e1c9/setuptools-68.2.2.tar.gz",
|
||||
"sha256": "4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/a4/99/78c4f3bd50619d772168bec6a0f34379b02c19c9cced0ed833ecd021fd0d/wheel-0.41.2.tar.gz",
|
||||
"sha256": "0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/c4/e6/c1ac50fe3eebb38a155155711e6e864e254ce4b6e17fe2429b4c4d5b9e80/flit_core-3.9.0.tar.gz",
|
||||
"sha256": "72ad266176c4a3fcfab5f2930d76896059851240570ce9a98733b658cb786eba"
|
||||
}
|
||||
]
|
||||
}
|
64
build-aux/modules/python-python-lsp-ruff.json
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "python3-python-lsp-ruff",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"python-lsp-ruff\""
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/e1/c7/247d04257d391251f32a7179cb74b418954022f1e9e276b5933e6ac1d3b1/python_lsp_ruff-2.2.0-py3-none-any.whl",
|
||||
"sha256": "fe0487c7997b38a59862c44e19cb815e24bb1b2f7cef4f1f32c61cf623a5ce94"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/b3/0d/cd4a4071c7f38385dc5ba91286723b4d1090b87815db48216212c6c6c30e/cattrs-23.2.3-py3-none-any.whl",
|
||||
"sha256": "0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/8d/37/2351e48cb3309673492d3a8c59d407b75fb6630e560eb27ecd4da03adc9a/lsprotocol-2023.0.1-py3-none-any.whl",
|
||||
"sha256": "c75223c9e4af2f24272b14c6375787438279369236cd568f596d4951052a60f2"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/91/f7/3b9c3a588e46bbdc2671d8fd07ecee118a672db50d72656b5726fbeffbcd/python_lsp_server-1.10.0-py3-none-any.whl",
|
||||
"sha256": "1a9f338bd7cf3cdde5ae85a2bd93fd5be9e55249f6482d88f99fb6227215424a"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl",
|
||||
"sha256": "99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/20/9f/bc63f0f0737ad7a60800bfd472a4836661adae21f9c2535f3957b1e54ceb/jedi-0.19.1-py2.py3-none-any.whl",
|
||||
"sha256": "e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/a5/5b/0cc789b59e8cc1bf288b38111d002d8c5917123194d45b29dcdac64723cc/pluggy-1.4.0-py3-none-any.whl",
|
||||
"sha256": "7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/cb/d9/656659d5b5d5f402b2b174cd0ba9bc827e07ce3c0bf88da65424baf64af8/python_lsp_jsonrpc-1.1.2-py3-none-any.whl",
|
||||
"sha256": "7339c2e9630ae98903fdaea1ace8c47fba0484983794d6aafd0bd8989be2b03c"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/6e/54/6f2bdac7117e89a47de4511c9f01732a283457ab1bf856e1e51aa861619e/ujson-5.9.0.tar.gz",
|
||||
"sha256": "89cc92e73d5501b8a7f48575eeb14ad27156ad092c2e9fc7e3cf949f07e75532"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/c1/cf/4eee59f6c4111b3e80cc32cf6bac483a90646f5c8693e84496c9855e8e38/docstring_to_markdown-0.15-py3-none-any.whl",
|
||||
"sha256": "27afb3faedba81e34c33521c32bbd258d7fbb79eedf7d29bc4e81080e854aec0"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/05/63/8011bd08a4111858f79d2b09aad86638490d62fbf881c44e434a6dfca87b/parso-0.8.3-py2.py3-none-any.whl",
|
||||
"sha256": "c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"
|
||||
}
|
||||
]
|
||||
}
|
69
build-aux/modules/python-python-lsp-server.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"name": "python3-python-lsp-server",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"python-lsp-server\""
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/be/4f/1b6eb5a6d92ae52f3798e9fdffd225f1bcd017172bb732743315390a9025/docstring_to_markdown-0.13-py3-none-any.whl",
|
||||
"sha256": "aa487059d0883e70e54da25c7b230e918d9e4d40f23d6dfaa2b73e4225b2d7dd"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/20/9f/bc63f0f0737ad7a60800bfd472a4836661adae21f9c2535f3957b1e54ceb/jedi-0.19.1-py2.py3-none-any.whl",
|
||||
"sha256": "e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/05/63/8011bd08a4111858f79d2b09aad86638490d62fbf881c44e434a6dfca87b/parso-0.8.3-py2.py3-none-any.whl",
|
||||
"sha256": "c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/05/b8/42ed91898d4784546c5f06c60506400548db3f7a4b3fb441cba4e5c17952/pluggy-1.3.0-py3-none-any.whl",
|
||||
"sha256": "d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/cb/d9/656659d5b5d5f402b2b174cd0ba9bc827e07ce3c0bf88da65424baf64af8/python_lsp_jsonrpc-1.1.2-py3-none-any.whl",
|
||||
"sha256": "7339c2e9630ae98903fdaea1ace8c47fba0484983794d6aafd0bd8989be2b03c"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/83/49/355783384945708c604f4ad4c773d4ec93bc609b691698e5d8ecfc51d01c/python_lsp_server-1.9.0-py3-none-any.whl",
|
||||
"sha256": "6b947cf9dc33d7bed9abc936bb173140fcf606b6eb50cf02e27d4cb09f10d3fb"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/6e/54/6f2bdac7117e89a47de4511c9f01732a283457ab1bf856e1e51aa861619e/ujson-5.9.0.tar.gz",
|
||||
"sha256": "89cc92e73d5501b8a7f48575eeb14ad27156ad092c2e9fc7e3cf949f07e75532"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl",
|
||||
"sha256": "8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/0e/a3/b9a8b0adfe672bf0df5901707aa929d30a97ee390ba651910186776746d2/setuptools_scm-8.0.4-py3-none-any.whl",
|
||||
"sha256": "b47844cd2a84b83b3187a5782c71128c28b4c94cad8bfb871da2784a5cb54c4f"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/b7/f4/6a90020cd2d93349b442bfcb657d0dc91eee65491600b2cb1d388bc98e6b/typing_extensions-4.9.0-py3-none-any.whl",
|
||||
"sha256": "af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/bb/e1/ed2dd0850446b8697ad28d118df885ad04140c64ace06c4bd559f7c8a94f/setuptools-69.0.2-py3-none-any.whl",
|
||||
"sha256": "1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/c7/c3/55076fc728723ef927521abaa1955213d094933dc36d4a2008d5101e1af5/wheel-0.42.0-py3-none-any.whl",
|
||||
"sha256": "177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d"
|
||||
}
|
||||
]
|
||||
}
|
48
build-aux/modules/python-ruff.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "python3-ruff",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
". /usr/lib/sdk/rust-stable/enable.sh && pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"ruff\""
|
||||
],
|
||||
"build-options": {
|
||||
"env": {
|
||||
"CARGO_HOME": "/run/build/python3-ruff/cargo",
|
||||
"CARGO_NET_OFFLINE": "true"
|
||||
}
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/20/90/43a3aa35f037e91582ec7516a92084a71f84e89e39ef580813bed072b154/maturin-1.4.0.tar.gz",
|
||||
"sha256": "ed12e1768094a7adeafc3a74ebdb8dc2201fa64c4e7e31f14cfc70378bf93790"
|
||||
},
|
||||
"sources/cargo-sources-maturin.json",
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/ef/cc/93f7213b2ab5ed383f98ce8020e632ef256b406b8569606c3f160ed8e1c9/setuptools-68.2.2.tar.gz",
|
||||
"sha256": "4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/c7/c3/55076fc728723ef927521abaa1955213d094933dc36d4a2008d5101e1af5/wheel-0.42.0-py3-none-any.whl",
|
||||
"sha256": "177f9c9b0d45c47873b619f5b650346d632cdc35fb5e4d25058e09c9e581433d"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/f7/7f/8b1c33598b03ad612b8ced223f9ca54076b789fabf5a66ce37cc096d9cf7/setuptools_rust-1.9.0-py3-none-any.whl",
|
||||
"sha256": "409caf49dcf7ad9bd510b4bf4011fbad504e745fae98f57fe1c06f3a97719638"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/6a/23/8146aad7d88f4fcb3a6218f41a60f6c2d4e3a72de72da1825dc7c8f7877c/semantic_version-2.10.0-py2.py3-none-any.whl",
|
||||
"sha256": "de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/61/b0/5fb64bc79464823ca94e566c9000143ddc11f9396c6e20202315059dd64f/ruff-0.3.0.tar.gz",
|
||||
"sha256": "0886184ba2618d815067cf43e005388967b67ab9c80df52b32ec1152ab49f53a"
|
||||
},
|
||||
"sources/cargo-sources-ruff.json"
|
||||
]
|
||||
}
|
3986
build-aux/modules/sources/cargo-sources-maturin.json
Normal file
4584
build-aux/modules/sources/cargo-sources-ruff.json
Normal file
@ -2,6 +2,7 @@
|
||||
"name": "vte",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Ddocs=false",
|
||||
"-Dgtk3=false",
|
||||
"-Dgtk4=true",
|
||||
@ -11,8 +12,21 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://download.gnome.org/sources/vte/0.74/vte-0.74.0.tar.xz",
|
||||
"sha256": "9ae08f777952ba793221152d360550451580f42d3b570e3341ebb6841984c76b"
|
||||
"url": "https://download.gnome.org/sources/vte/0.79/vte-0.79.91.tar.xz",
|
||||
"sha256": "adca667d40ae1839ba258b63701cd05fba249303d72258711cc69294b2cb8646"
|
||||
}
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "fast_float",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/fastfloat/fast_float/archive/refs/tags/v6.1.6.tar.gz",
|
||||
"sha256": "4458aae4b0eb55717968edda42987cabf5f7fc737aee8fede87a70035dba9ab0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "webp-pixbuf-loader",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Dgdk_pixbuf_moduledir=/app/lib/gdk-pixbuf-2.0/2.10.0/loaders/"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/aruiz/webp-pixbuf-loader.git",
|
||||
"tag": "0.2.4",
|
||||
"commit": "a35014104a226265e44fe30fcdb4df9305af3466"
|
||||
}
|
||||
],
|
||||
"post-install": [
|
||||
"GDK_PIXBUF_MODULEDIR=/app/lib/gdk-pixbuf-2.0/2.10.0/loaders/ gdk-pixbuf-query-loaders > /app/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache",
|
||||
"gdk-pixbuf-query-loaders >> /app/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
|
||||
]
|
||||
}
|
@ -1,28 +1,30 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/flatpak/flatpak-builder/main/data/flatpak-manifest.schema.json",
|
||||
"id": "re.sonny.Workbench.Devel",
|
||||
"runtime": "org.gnome.Sdk",
|
||||
"runtime-version": "45",
|
||||
"runtime-version": "48",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.vala",
|
||||
"org.freedesktop.Sdk.Extension.rust-stable",
|
||||
"org.freedesktop.Sdk.Extension.llvm16"
|
||||
"org.freedesktop.Sdk.Extension.llvm18",
|
||||
"org.freedesktop.Sdk.Extension.node20",
|
||||
"org.freedesktop.Sdk.Extension.typescript"
|
||||
],
|
||||
"build-options": {
|
||||
"append-path": "/usr/lib/sdk/vala/bin:/usr/lib/sdk/rust-stable/bin",
|
||||
"append-path": "/usr/lib/sdk/vala/bin:/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/node20/bin:/usr/lib/sdk/typescript/bin",
|
||||
"append-ld-library-path": "/usr/lib/sdk/vala/lib"
|
||||
},
|
||||
"command": "workbench",
|
||||
"separate-locales": false,
|
||||
"finish-args": [
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--device=dri",
|
||||
"--share=network",
|
||||
"--socket=pulseaudio"
|
||||
"--device=dri"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"#/include",
|
||||
"#/lib/pkgconfig",
|
||||
"/man",
|
||||
"/share/doc",
|
||||
@ -34,17 +36,17 @@
|
||||
"*.a"
|
||||
],
|
||||
"modules": [
|
||||
"modules/python-black.json",
|
||||
"modules/blueprint-compiler.json",
|
||||
"modules/biome.json",
|
||||
"modules/gst-plugin-gtk4.json",
|
||||
"modules/vte.json",
|
||||
"modules/libshumate.json",
|
||||
"modules/libportal.json",
|
||||
"modules/libspelling.json",
|
||||
"modules/gom.json",
|
||||
"modules/GTKCssLanguageServer.json",
|
||||
"modules/icon-development-kit.json",
|
||||
"modules/webp-pixbuf-loader.json",
|
||||
"modules/python-python-lsp-server.json",
|
||||
"modules/python-ruff.json",
|
||||
"modules/python-python-lsp-ruff.json",
|
||||
{
|
||||
"name": "Workbench",
|
||||
"buildsystem": "meson",
|
||||
|
@ -1,28 +1,30 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/flatpak/flatpak-builder/main/data/flatpak-manifest.schema.json",
|
||||
"id": "re.sonny.Workbench",
|
||||
"runtime": "org.gnome.Sdk",
|
||||
"runtime-version": "45",
|
||||
"runtime-version": "48",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.vala",
|
||||
"org.freedesktop.Sdk.Extension.rust-stable",
|
||||
"org.freedesktop.Sdk.Extension.llvm16"
|
||||
"org.freedesktop.Sdk.Extension.llvm18",
|
||||
"org.freedesktop.Sdk.Extension.node20",
|
||||
"org.freedesktop.Sdk.Extension.typescript"
|
||||
],
|
||||
"build-options": {
|
||||
"append-path": "/usr/lib/sdk/vala/bin:/usr/lib/sdk/rust-stable/bin",
|
||||
"append-path": "/usr/lib/sdk/vala/bin:/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/node20/bin:/usr/lib/sdk/typescript/bin",
|
||||
"append-ld-library-path": "/usr/lib/sdk/vala/lib"
|
||||
},
|
||||
"command": "workbench",
|
||||
"separate-locales": false,
|
||||
"finish-args": [
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--device=dri",
|
||||
"--share=network",
|
||||
"--socket=pulseaudio"
|
||||
"--device=dri"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"#/include",
|
||||
"#/lib/pkgconfig",
|
||||
"/man",
|
||||
"/share/doc",
|
||||
@ -34,17 +36,17 @@
|
||||
"*.a"
|
||||
],
|
||||
"modules": [
|
||||
"modules/python-black.json",
|
||||
"modules/blueprint-compiler.json",
|
||||
"modules/biome.json",
|
||||
"modules/gst-plugin-gtk4.json",
|
||||
"modules/vte.json",
|
||||
"modules/libshumate.json",
|
||||
"modules/libportal.json",
|
||||
"modules/libspelling.json",
|
||||
"modules/gom.json",
|
||||
"modules/GTKCssLanguageServer.json",
|
||||
"modules/icon-development-kit.json",
|
||||
"modules/webp-pixbuf-loader.json",
|
||||
"modules/python-python-lsp-server.json",
|
||||
"modules/python-ruff.json",
|
||||
"modules/python-python-lsp-ruff.json",
|
||||
{
|
||||
"name": "Workbench",
|
||||
"buildsystem": "meson",
|
||||
|
308
build-aux/wip/minimist.js
Normal file
@ -0,0 +1,308 @@
|
||||
/* eslint-disable */
|
||||
|
||||
// https://github.com/minimistjs/minimist/blob/bedaa8b9ab5a901fa342aad4494cbbf676b11a21/index.js
|
||||
|
||||
function hasKey(obj, keys) {
|
||||
var o = obj;
|
||||
keys.slice(0, -1).forEach(function (key) {
|
||||
o = o[key] || {};
|
||||
});
|
||||
|
||||
var key = keys[keys.length - 1];
|
||||
return key in o;
|
||||
}
|
||||
|
||||
function isNumber(x) {
|
||||
if (typeof x === "number") {
|
||||
return true;
|
||||
}
|
||||
if (/^0x[0-9a-f]+$/i.test(x)) {
|
||||
return true;
|
||||
}
|
||||
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
|
||||
}
|
||||
|
||||
function isConstructorOrProto(obj, key) {
|
||||
return (
|
||||
(key === "constructor" && typeof obj[key] === "function") ||
|
||||
key === "__proto__"
|
||||
);
|
||||
}
|
||||
|
||||
export default function minimist(args, opts) {
|
||||
if (!opts) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
var flags = {
|
||||
bools: {},
|
||||
strings: {},
|
||||
unknownFn: null,
|
||||
};
|
||||
|
||||
if (typeof opts.unknown === "function") {
|
||||
flags.unknownFn = opts.unknown;
|
||||
}
|
||||
|
||||
if (typeof opts.boolean === "boolean" && opts.boolean) {
|
||||
flags.allBools = true;
|
||||
} else {
|
||||
[]
|
||||
.concat(opts.boolean)
|
||||
.filter(Boolean)
|
||||
.forEach(function (key) {
|
||||
flags.bools[key] = true;
|
||||
});
|
||||
}
|
||||
|
||||
var aliases = {};
|
||||
|
||||
function isBooleanKey(key) {
|
||||
if (flags.bools[key]) {
|
||||
return true;
|
||||
}
|
||||
if (!aliases[key]) {
|
||||
return false;
|
||||
}
|
||||
return aliases[key].some(function (x) {
|
||||
return flags.bools[x];
|
||||
});
|
||||
}
|
||||
|
||||
Object.keys(opts.alias || {}).forEach(function (key) {
|
||||
aliases[key] = [].concat(opts.alias[key]);
|
||||
aliases[key].forEach(function (x) {
|
||||
aliases[x] = [key].concat(
|
||||
aliases[key].filter(function (y) {
|
||||
return x !== y;
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
[]
|
||||
.concat(opts.string)
|
||||
.filter(Boolean)
|
||||
.forEach(function (key) {
|
||||
flags.strings[key] = true;
|
||||
if (aliases[key]) {
|
||||
[].concat(aliases[key]).forEach(function (k) {
|
||||
flags.strings[k] = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var defaults = opts.default || {};
|
||||
|
||||
var argv = { _: [] };
|
||||
|
||||
function argDefined(key, arg) {
|
||||
return (
|
||||
(flags.allBools && /^--[^=]+$/.test(arg)) ||
|
||||
flags.strings[key] ||
|
||||
flags.bools[key] ||
|
||||
aliases[key]
|
||||
);
|
||||
}
|
||||
|
||||
function setKey(obj, keys, value) {
|
||||
var o = obj;
|
||||
for (var i = 0; i < keys.length - 1; i++) {
|
||||
var key = keys[i];
|
||||
if (isConstructorOrProto(o, key)) {
|
||||
return;
|
||||
}
|
||||
if (o[key] === undefined) {
|
||||
o[key] = {};
|
||||
}
|
||||
if (
|
||||
o[key] === Object.prototype ||
|
||||
o[key] === Number.prototype ||
|
||||
o[key] === String.prototype
|
||||
) {
|
||||
o[key] = {};
|
||||
}
|
||||
if (o[key] === Array.prototype) {
|
||||
o[key] = [];
|
||||
}
|
||||
o = o[key];
|
||||
}
|
||||
|
||||
var lastKey = keys[keys.length - 1];
|
||||
if (isConstructorOrProto(o, lastKey)) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
o === Object.prototype ||
|
||||
o === Number.prototype ||
|
||||
o === String.prototype
|
||||
) {
|
||||
o = {};
|
||||
}
|
||||
if (o === Array.prototype) {
|
||||
o = [];
|
||||
}
|
||||
if (
|
||||
o[lastKey] === undefined ||
|
||||
isBooleanKey(lastKey) ||
|
||||
typeof o[lastKey] === "boolean"
|
||||
) {
|
||||
o[lastKey] = value;
|
||||
} else if (Array.isArray(o[lastKey])) {
|
||||
o[lastKey].push(value);
|
||||
} else {
|
||||
o[lastKey] = [o[lastKey], value];
|
||||
}
|
||||
}
|
||||
|
||||
function setArg(key, val, arg) {
|
||||
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
||||
if (flags.unknownFn(arg) === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var value = !flags.strings[key] && isNumber(val) ? Number(val) : val;
|
||||
setKey(argv, key.split("."), value);
|
||||
|
||||
(aliases[key] || []).forEach(function (x) {
|
||||
setKey(argv, x.split("."), value);
|
||||
});
|
||||
}
|
||||
|
||||
// Set booleans to false by default.
|
||||
Object.keys(flags.bools).forEach(function (key) {
|
||||
setArg(key, false);
|
||||
});
|
||||
// Set booleans to user defined default if supplied.
|
||||
Object.keys(defaults)
|
||||
.filter(isBooleanKey)
|
||||
.forEach(function (key) {
|
||||
setArg(key, defaults[key]);
|
||||
});
|
||||
var notFlags = [];
|
||||
|
||||
if (args.indexOf("--") !== -1) {
|
||||
notFlags = args.slice(args.indexOf("--") + 1);
|
||||
args = args.slice(0, args.indexOf("--"));
|
||||
}
|
||||
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
var arg = args[i];
|
||||
var key;
|
||||
var next;
|
||||
|
||||
if (/^--.+=/.test(arg)) {
|
||||
// Using [\s\S] instead of . because js doesn't support the
|
||||
// 'dotall' regex modifier. See:
|
||||
// http://stackoverflow.com/a/1068308/13216
|
||||
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
||||
key = m[1];
|
||||
var value = m[2];
|
||||
if (isBooleanKey(key)) {
|
||||
value = value !== "false";
|
||||
}
|
||||
setArg(key, value, arg);
|
||||
} else if (/^--no-.+/.test(arg)) {
|
||||
key = arg.match(/^--no-(.+)/)[1];
|
||||
setArg(key, false, arg);
|
||||
} else if (/^--.+/.test(arg)) {
|
||||
key = arg.match(/^--(.+)/)[1];
|
||||
next = args[i + 1];
|
||||
if (
|
||||
next !== undefined &&
|
||||
!/^(-|--)[^-]/.test(next) &&
|
||||
!isBooleanKey(key) &&
|
||||
!flags.allBools
|
||||
) {
|
||||
setArg(key, next, arg);
|
||||
i += 1;
|
||||
} else if (/^(true|false)$/.test(next)) {
|
||||
setArg(key, next === "true", arg);
|
||||
i += 1;
|
||||
} else {
|
||||
setArg(key, flags.strings[key] ? "" : true, arg);
|
||||
}
|
||||
} else if (/^-[^-]+/.test(arg)) {
|
||||
var letters = arg.slice(1, -1).split("");
|
||||
|
||||
var broken = false;
|
||||
for (var j = 0; j < letters.length; j++) {
|
||||
next = arg.slice(j + 2);
|
||||
|
||||
if (next === "-") {
|
||||
setArg(letters[j], next, arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (/[A-Za-z]/.test(letters[j]) && next[0] === "=") {
|
||||
setArg(letters[j], next.slice(1), arg);
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
/[A-Za-z]/.test(letters[j]) &&
|
||||
/-?\d+(\.\d*)?(e-?\d+)?$/.test(next)
|
||||
) {
|
||||
setArg(letters[j], next, arg);
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (letters[j + 1] && letters[j + 1].match(/\W/)) {
|
||||
setArg(letters[j], arg.slice(j + 2), arg);
|
||||
broken = true;
|
||||
break;
|
||||
} else {
|
||||
setArg(letters[j], flags.strings[letters[j]] ? "" : true, arg);
|
||||
}
|
||||
}
|
||||
|
||||
key = arg.slice(-1)[0];
|
||||
if (!broken && key !== "-") {
|
||||
if (
|
||||
args[i + 1] &&
|
||||
!/^(-|--)[^-]/.test(args[i + 1]) &&
|
||||
!isBooleanKey(key)
|
||||
) {
|
||||
setArg(key, args[i + 1], arg);
|
||||
i += 1;
|
||||
} else if (args[i + 1] && /^(true|false)$/.test(args[i + 1])) {
|
||||
setArg(key, args[i + 1] === "true", arg);
|
||||
i += 1;
|
||||
} else {
|
||||
setArg(key, flags.strings[key] ? "" : true, arg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
||||
argv._.push(flags.strings._ || !isNumber(arg) ? arg : Number(arg));
|
||||
}
|
||||
if (opts.stopEarly) {
|
||||
argv._.push.apply(argv._, args.slice(i + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(defaults).forEach(function (k) {
|
||||
if (!hasKey(argv, k.split("."))) {
|
||||
setKey(argv, k.split("."), defaults[k]);
|
||||
|
||||
(aliases[k] || []).forEach(function (x) {
|
||||
setKey(argv, x.split("."), defaults[k]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (opts["--"]) {
|
||||
argv["--"] = notFlags.slice();
|
||||
} else {
|
||||
notFlags.forEach(function (k) {
|
||||
argv._.push(k);
|
||||
});
|
||||
}
|
||||
|
||||
return argv;
|
||||
}
|
264
build-aux/wip/run.js
Executable file
@ -0,0 +1,264 @@
|
||||
#!/usr/bin/env -S gjs -m
|
||||
|
||||
import Gio from "gi://Gio";
|
||||
import { exit, programArgs, programInvocationName } from "system";
|
||||
import GLib from "gi://GLib";
|
||||
import minimist from "./minimist.js";
|
||||
|
||||
// export G_MESSAGES_DEBUG=Gjs-Console && ./run.js
|
||||
|
||||
Gio._promisify(
|
||||
Gio.File.prototype,
|
||||
"load_contents_async",
|
||||
"load_contents_finish",
|
||||
);
|
||||
|
||||
Gio._promisify(
|
||||
Gio.Subprocess.prototype,
|
||||
"wait_check_async",
|
||||
"wait_check_finish",
|
||||
);
|
||||
|
||||
const path = GLib.get_current_dir();
|
||||
console.debug(programInvocationName, programArgs);
|
||||
const argv = minimist(programArgs, { boolean: true, "--": true });
|
||||
console.debug(argv);
|
||||
|
||||
const [manifest_path] = argv._;
|
||||
if (!manifest_path) {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
print(`${programInvocationName} [--verbose] [--debug] MANIFEST [-- command]`);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
const home = GLib.get_home_dir();
|
||||
|
||||
const manifest_file = Gio.File.new_for_path(manifest_path);
|
||||
const [contents] = await manifest_file.load_contents_async(null);
|
||||
const manifest = JSON.parse(new TextDecoder().decode(contents));
|
||||
|
||||
// console.log(JSON.parse(manifest));
|
||||
|
||||
const flatpak_id = manifest.id;
|
||||
// We assume the last module is the app itself
|
||||
const app_module = manifest.modules.at(-1);
|
||||
|
||||
function exists(path) {
|
||||
const result = Gio.File.new_for_path(path).query_exists(null);
|
||||
console.debug(`${path} ${result ? "exists" : "non existant"}`);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!exists(`${path}/.flatpak/repo`)) {
|
||||
const { runtime, sdk } = manifest;
|
||||
const runtime_version = manifest["runtime-version"];
|
||||
// initializes repo
|
||||
await run([
|
||||
"flatpak",
|
||||
"build-init",
|
||||
`${path}/.flatpak/repo`,
|
||||
flatpak_id,
|
||||
sdk,
|
||||
runtime,
|
||||
runtime_version,
|
||||
]);
|
||||
}
|
||||
|
||||
const prefix = [
|
||||
"flatpak-builder",
|
||||
"--ccache",
|
||||
"--force-clean",
|
||||
"--disable-updates",
|
||||
];
|
||||
const suffix = [
|
||||
`--state-dir=${path}/.flatpak/flatpak-builder`,
|
||||
`--stop-at=${app_module.name}`,
|
||||
`${path}/.flatpak/repo`,
|
||||
Gio.File.new_for_path(path).get_relative_path(manifest_file),
|
||||
];
|
||||
|
||||
// de-initializes
|
||||
async function downloadSources() {
|
||||
await run([...prefix, "--download-only", ...suffix]);
|
||||
}
|
||||
|
||||
// de-initializes
|
||||
async function buildModules() {
|
||||
await run([
|
||||
...prefix,
|
||||
"--disable-download",
|
||||
"--build-only",
|
||||
"--keep-build-dirs",
|
||||
...suffix,
|
||||
]);
|
||||
}
|
||||
|
||||
if (!exists(`${path}/.flatpak/flatpak-builder`)) {
|
||||
await downloadSources();
|
||||
await buildModules();
|
||||
}
|
||||
|
||||
// builds workbench
|
||||
if (!exists(`${path}/_build`)) {
|
||||
await buildModules();
|
||||
await buildCommand([
|
||||
"meson",
|
||||
"--prefix",
|
||||
"/app",
|
||||
"_build",
|
||||
"-Dprofile=development",
|
||||
]);
|
||||
}
|
||||
|
||||
await buildCommand(["meson", "install", "-C", "_build"]);
|
||||
// await buildCommand([
|
||||
// `troll/gjspack/bin/gjspack`,
|
||||
// `--appid=${flatpak_id}`,
|
||||
// "--prefix=/re/sonny/Workbench",
|
||||
// `--project-root=.`,
|
||||
// `--resource-root=./src`,
|
||||
// "--blueprint-compiler=/app/bin/blueprint-compiler",
|
||||
// "--no-executable",
|
||||
// `${path}/src/main.js`,
|
||||
// `/app/share/${flatpak_id}.src.gresource`,
|
||||
// ]);
|
||||
|
||||
// starts workbench
|
||||
const command = argv["--"].length ? argv["--"] : [manifest.command];
|
||||
await runCommand(command);
|
||||
|
||||
function buildCommand(argv) {
|
||||
let PATH =
|
||||
"/app/bin:/app/bin:/app/bin:/usr/bin:${home}/.var/app/com.visualstudio.code/data/node_modules/bin:/app/bin:/usr/bin";
|
||||
const append_path = manifest["build-options"]?.["append-path"];
|
||||
if (append_path) PATH += `:${append_path}`;
|
||||
|
||||
let LD_LIBRARY_PATH = "/app/lib:/app/lib";
|
||||
const append_ld_library_path =
|
||||
manifest["build-options"]?.["append-ls-library-path"];
|
||||
if (append_ld_library_path) LD_LIBRARY_PATH += `:${append_ld_library_path}`;
|
||||
|
||||
const PKG_CONFIG_PATH =
|
||||
"/usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib64/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig:/app/lib/pkgconfig:/app/share/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig";
|
||||
|
||||
return run([
|
||||
"flatpak",
|
||||
"build",
|
||||
"--share=network",
|
||||
`--filesystem=${path}`,
|
||||
`--filesystem=${path}/.flatpak/repo`,
|
||||
`--env=PATH=${PATH}`,
|
||||
`--env=LD_LIBRARY_PATH=${LD_LIBRARY_PATH}`,
|
||||
`--env=PKG_CONFIG_PATH=${PKG_CONFIG_PATH}`,
|
||||
`--filesystem=${path}/_build`,
|
||||
`${path}/.flatpak/repo`,
|
||||
...argv,
|
||||
]);
|
||||
}
|
||||
|
||||
async function runCommand(argv) {
|
||||
await exec(
|
||||
[
|
||||
"flatpak",
|
||||
"build",
|
||||
"--with-appdir",
|
||||
"--allow=devel",
|
||||
`--bind-mount=/run/user/1000/doc=/run/user/1000/doc/by-app/${flatpak_id}`,
|
||||
...manifest["finish-args"],
|
||||
|
||||
// Non default permissions, see Permissions.js
|
||||
// consider getting installed overrides instead with
|
||||
// flatpak override --user --show re.sonny.Workbench.Devel
|
||||
"--share=network",
|
||||
"--socket=pulseaudio",
|
||||
"--device=input",
|
||||
|
||||
"--talk-name=org.freedesktop.portal.*",
|
||||
"--talk-name=org.a11y.Bus",
|
||||
"--bind-mount=/run/flatpak/at-spi-bus=/run/user/1000/at-spi/bus",
|
||||
"--env=AT_SPI_BUS_ADDRESS=unix:path=/run/flatpak/at-spi-bus",
|
||||
...getHostEnv(),
|
||||
"--bind-mount=/run/host/fonts=/usr/share/fonts",
|
||||
"--bind-mount=/run/host/fonts-cache=/usr/lib/fontconfig/cache",
|
||||
`--filesystem=${home}/.local/share/fonts:ro`,
|
||||
`--filesystem=${home}/.cache/fontconfig:ro`,
|
||||
`--bind-mount=/run/host/user-fonts-cache=${home}/.cache/fontconfig`,
|
||||
`--bind-mount=/run/host/font-dirs.xml=${home}/.cache/font-dirs.xml`,
|
||||
`${path}/.flatpak/repo`,
|
||||
...argv,
|
||||
],
|
||||
{ verbose: true },
|
||||
);
|
||||
}
|
||||
|
||||
function getHostEnv() {
|
||||
// https://github.com/bilelmoussaoui/flatpak-vscode/blob/6424e7d8f53924faa33c9043153e08b0aedf6225/src/utils.ts#L88
|
||||
const forwarded_env_keys = [
|
||||
"COLORTERM",
|
||||
"DESKTOP_SESSION",
|
||||
"LANG",
|
||||
"WAYLAND_DISPLAY",
|
||||
"XDG_CURRENT_DESKTOP",
|
||||
"XDG_SEAT",
|
||||
"XDG_SESSION_DESKTOP",
|
||||
"XDG_SESSION_ID",
|
||||
"XDG_SESSION_TYPE",
|
||||
"XDG_VTNR",
|
||||
"AT_SPI_BUS_ADDRESS",
|
||||
];
|
||||
|
||||
const env_vars = [];
|
||||
forwarded_env_keys.forEach((key) => {
|
||||
const value = GLib.getenv(key);
|
||||
if (value === undefined) env_vars.push(key + "=" + value);
|
||||
});
|
||||
|
||||
return env_vars;
|
||||
}
|
||||
|
||||
async function run(_) {
|
||||
return exec(_, { verbose: argv.verbose });
|
||||
}
|
||||
|
||||
async function exec(argv, { cancellable = null /*, verbose = false*/ }) {
|
||||
argv = argv.map((arg) => {
|
||||
return arg.toString();
|
||||
});
|
||||
|
||||
console.debug(`$ ${argv.join(" ")}`);
|
||||
|
||||
let cancelId = 0;
|
||||
|
||||
// meson uses stdout for logs
|
||||
// const flags = verbose
|
||||
// ? Gio.SubprocessFlags.NONE
|
||||
// : Gio.SubprocessFlags.STDOUT_SILENCE;
|
||||
|
||||
const flags = Gio.SubprocessFlags.NONE;
|
||||
|
||||
const proc = new Gio.Subprocess({
|
||||
argv,
|
||||
flags,
|
||||
});
|
||||
proc.init(cancellable);
|
||||
|
||||
if (cancellable instanceof Gio.Cancellable)
|
||||
cancelId = cancellable.connect(() => proc.force_exit());
|
||||
|
||||
try {
|
||||
const success = await proc.wait_check_async(null);
|
||||
|
||||
if (!success) {
|
||||
const status = proc.get_exit_status();
|
||||
throw new Gio.IOErrorEnum({
|
||||
code: Gio.IOErrorEnum.FAILED,
|
||||
message: `Command '${argv}' failed with exit code ${status}`,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.debug(err);
|
||||
exit(1);
|
||||
} finally {
|
||||
if (cancelId > 0) cancellable.disconnect(cancelId);
|
||||
}
|
||||
}
|
34
build-aux/wip/run.sh
Executable file
@ -0,0 +1,34 @@
|
||||
set -eux
|
||||
|
||||
flatpak_id=re.sonny.Workbench.Devel
|
||||
path=/home/sonny/Projects/Workbench
|
||||
manifest=$path/build-aux/$flatpak_id.json
|
||||
module_name=Workbench
|
||||
command=workbench
|
||||
|
||||
function run_build_command {
|
||||
flatpak build --share=network --filesystem=$path --filesystem=$path/.flatpak/repo --env=PATH=/app/bin:/app/bin:/app/bin:/usr/bin:/home/sonny/.var/app/com.visualstudio.code/data/node_modules/bin:/app/bin:/usr/bin:/usr/lib/sdk/vala/bin:/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/node20/bin:/usr/lib/sdk/typescript/bin --env=LD_LIBRARY_PATH=/app/lib:/app/lib:/usr/lib/sdk/vala/lib --env=PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib64/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig:/app/lib/pkgconfig:/app/share/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig --filesystem=$path/_build $path/.flatpak/repo $1
|
||||
}
|
||||
|
||||
if [ ! -d "$path/.flatpak/repo" ]; then
|
||||
# initializes repo
|
||||
flatpak build-init $path/.flatpak/repo $flatpak_id org.gnome.Sdk org.gnome.Sdk 47
|
||||
fi
|
||||
|
||||
if [ ! -d "$path/.flatpak/flatpak-builder" ]; then
|
||||
# downloads sources (de-initializes)
|
||||
flatpak-builder --ccache --force-clean --disable-updates --download-only --state-dir=$path/.flatpak/flatpak-builder --stop-at=$module_name $path/.flatpak/repo $manifest
|
||||
# builds modules (de-initializes)
|
||||
flatpak-builder --ccache --force-clean --disable-updates --disable-download --build-only --keep-build-dirs --state-dir=$path/.flatpak/flatpak-builder --stop-at=$module_name $path/.flatpak/repo $manifest
|
||||
fi
|
||||
|
||||
# builds Workbench module
|
||||
if [ ! -d "$path/_build" ]; then
|
||||
run_build_command "meson --prefix /app _build -Dprofile=development"
|
||||
else
|
||||
time run_build_command "meson install -C _build"
|
||||
# time run_build_command "$path/troll/gjspack/bin/gjspack --appid=$flatpak_id --prefix=/re.sonny.Workbench --project-root=$path --resource-root=$path/src --blueprint-compiler=/app/bin/blueprint-compiler --no-executable $path/src/main.js /app/share/$flatpak_id.src.gresource"
|
||||
fi
|
||||
|
||||
# starts workbench
|
||||
flatpak build --with-appdir --allow=devel --bind-mount=/run/user/1000/doc=/run/user/1000/doc/by-app/$flatpak_id --share=ipc --socket=fallback-x11 --socket=wayland --device=dri --share=network --socket=pulseaudio --talk-name='org.freedesktop.portal.*' --talk-name=org.a11y.Bus --bind-mount=/run/flatpak/at-spi-bus=/run/user/1000/at-spi/bus --env=AT_SPI_BUS_ADDRESS=unix:path=/run/flatpak/at-spi-bus --env=AT_SPI_BUS_ADDRESS=unix:path=/run/flatpak/at-spi-bus --env=COLORTERM=truecolor --env=DESKTOP_SESSION=gnome --env=LANG=en_US.UTF-8 --env=WAYLAND_DISPLAY=wayland-0 --env=XDG_CURRENT_DESKTOP=GNOME --env=XDG_SESSION_DESKTOP=gnome --env=XDG_SESSION_TYPE=wayland --bind-mount=/run/host/fonts=/usr/share/fonts --bind-mount=/run/host/fonts-cache=/usr/lib/fontconfig/cache --filesystem=/home/sonny/.local/share/fonts:ro --filesystem=/home/sonny/.cache/fontconfig:ro --bind-mount=/run/host/user-fonts-cache=/home/sonny/.cache/fontconfig --bind-mount=/run/host/font-dirs.xml=/home/sonny/.cache/font-dirs.xml $path/.flatpak/repo $command
|
@ -8,6 +8,6 @@ Type=Application
|
||||
Categories=WebDevelopment;Development;IDE;GNOME;GTK;
|
||||
Icon=@app_id@
|
||||
# TRANSLATORS: Don't translate
|
||||
Keywords=CSS;JavaScript;GJS;Blueprint;builder;Vala;GTK;libadwaita;Python;PyGObject;Rust;doc;playground;code;
|
||||
Keywords=CSS;JavaScript;GJS;Blueprint;builder;Vala;GTK;libadwaita;Python;PyGObject;Rust;doc;playground;code;TypeScript;
|
||||
DBusActivatable=true
|
||||
StartupNotify=true
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<schemalist gettext-domain="@app_id@">
|
||||
<schemalist>
|
||||
<enum id="re.sonny.Workbench.UserInterfaceLanguage">
|
||||
<value nick="blueprint" value="0"/>
|
||||
<value nick="xml" value="1"/>
|
||||
@ -12,15 +12,15 @@
|
||||
<key name="recent-code-language" type="i">
|
||||
<default>0</default>
|
||||
</key>
|
||||
<key name="open-extensions" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
<key name="recent-projects" type="as">
|
||||
<default>[]</default>
|
||||
</key>
|
||||
<key name="first-run" type="b">
|
||||
<default>true</default>
|
||||
</key>
|
||||
<key name="typescript" type="b">
|
||||
<default>true</default>
|
||||
</key>
|
||||
</schema>
|
||||
<schema id="@app_id@.Session" path="/re/sonny/Workbench/">
|
||||
<key name="show-code" type="b">
|
||||
@ -59,5 +59,17 @@
|
||||
<key name="edited" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
<key name="window-width" type="i">
|
||||
<default>0</default>
|
||||
</key>
|
||||
<key name="window-height" type="i">
|
||||
<default>0</default>
|
||||
</key>
|
||||
<key name="window-maximized" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
<key name="window-fullscreened" type="b">
|
||||
<default>false</default>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
|
@ -3,17 +3,15 @@
|
||||
<id>@app_id@</id>
|
||||
<launchable type="desktop-id">@app_id@.desktop</launchable>
|
||||
<name translatable="no">Workbench</name>
|
||||
<!-- developer_name tag deprecated with Appstream 1.0 -->
|
||||
<developer_name translatable="no">Sonny Piers</developer_name>
|
||||
<developer>
|
||||
<developer id="re.sonny">
|
||||
<name translatable="no">Sonny Piers</name>
|
||||
</developer>
|
||||
<update_contact>sonnyp@gnome.org</update_contact>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0</project_license>
|
||||
<summary>Learn and prototype with GNOME technologies</summary>
|
||||
<summary>Prototype with GNOME technologies</summary>
|
||||
<description>
|
||||
<p>Workbench lets you experiment with GNOME technologies, no matter if tinkering for the first time or building and testing a GTK user interface.</p>
|
||||
<p>Workbench is for learning and prototyping with GNOME technologies, no matter if tinkering for the first time or building and testing a GTK user interface.</p>
|
||||
<p>Among other things, Workbench comes with</p>
|
||||
<ul>
|
||||
<li>Live GTK/CSS preview</li>
|
||||
@ -21,31 +19,215 @@
|
||||
<li>JavaScript, Rust, Python and Vala support</li>
|
||||
<li>Declarative user interface syntax</li>
|
||||
<li>Autosave, sessions and projects</li>
|
||||
<li>Code linter and formatter</li>
|
||||
<li>Code diagnostics, completion and formatter</li>
|
||||
<li>Terminal output</li>
|
||||
<li>1000+ icons</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url type="homepage">https://apps.gnome.org/Workbench</url>
|
||||
<url type="bugtracker">https://github.com/workbenchdev/Workbench/issues</url>
|
||||
<url type="donation">https://ko-fi.com/sonnyp</url>
|
||||
<url type="vcs-browser">https://github.com/workbenchdev/Workbench</url>
|
||||
<url type="homepage">https://workbench.sonny.re</url>
|
||||
<url type="bugtracker">https://workbench.sonny.re/feedback</url>
|
||||
<url type="donation">https://workbench.sonny.re/donate</url>
|
||||
<url type="vcs-browser">https://workbench.sonny.re/source</url>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://raw.githubusercontent.com/workbenchdev/Workbench/main/data/screenshot.png</image>
|
||||
<image>https://raw.githubusercontent.com/workbenchdev/Workbench/main/data/screenshots/welcome.png</image>
|
||||
<caption>Welcome screen</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://raw.githubusercontent.com/workbenchdev/Workbench/main/data/screenshot-code.png</image>
|
||||
<image>https://raw.githubusercontent.com/workbenchdev/Workbench/main/data/screenshots/code.png</image>
|
||||
<caption>Drawing Area demo</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://raw.githubusercontent.com/workbenchdev/Workbench/main/data/screenshot-library.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://raw.githubusercontent.com/workbenchdev/Workbench/main/data/screenshot-extensions.png</image>
|
||||
<image>https://raw.githubusercontent.com/workbenchdev/Workbench/main/data/screenshots/library.png</image>
|
||||
<caption>Library window</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<content_rating type="oars-1.1" />
|
||||
<releases>
|
||||
<release version="48.0" date="2025-04-xx">
|
||||
<description translatable="no">
|
||||
<ul>
|
||||
<li>Use GNOME 48</li>
|
||||
</ul>
|
||||
<p>Library:</p>
|
||||
<ul>
|
||||
<li>Add "Shortcuts Window" demo</li>
|
||||
</ul>
|
||||
<p>Dependencies:</p>
|
||||
<ul>
|
||||
<!-- <li>Update Jsonrpc-GLib to 3.44.1</li> -->
|
||||
<li>Update libportal to 0.9.1</li>
|
||||
<li>Update libshumate to 1.4</li>
|
||||
<li>Update libspelling to 0.4.6</li>
|
||||
<li>Update vte to 0.80.0</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
|
||||
<release version="47.1" date="2025-01-24">
|
||||
<description translatable="no">
|
||||
<ul>
|
||||
<li>Fix permissions dialog</li>
|
||||
<li>Update Blueprint to 0.16.0</li>
|
||||
<li>Update libportal to 0.9.0</li>
|
||||
</ul>
|
||||
<p>Library:</p>
|
||||
<ul>
|
||||
<li>Replace GTK syntax with CSS variables</li>
|
||||
<li>Fix year sorting in "Column View" Python</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
|
||||
<release version="47.0" date="2024-12-11">
|
||||
<description translatable="no">
|
||||
<ul>
|
||||
<li>Use GNOME 47</li>
|
||||
<li>Add code suggestions/completions support</li>
|
||||
<li>Add Language and Category filters to the Library</li>
|
||||
<li>Add action to create new blank project</li>
|
||||
<li>Add experimental TypeScript support</li>
|
||||
</ul>
|
||||
<p>Library:</p>
|
||||
<ul>
|
||||
<li>Add "Button Row" demo</li>
|
||||
<li>Add "Gamepad" demo</li>
|
||||
<li>Add "List View with Sections" demo</li>
|
||||
<li>Add "List View with a Tree" demo</li>
|
||||
<li>Add "Bottom Sheet" demo</li>
|
||||
<li>Add "Database" demo</li>
|
||||
<li>Update "Spinner" to use AdwSpinner</li>
|
||||
<li>Port "Dialog" to Python</li>
|
||||
<li>Port "List View" to Python</li>
|
||||
<li>Port "Grid View" to Python</li>
|
||||
<li>Port "Level Bars" to Rust</li>
|
||||
<li>Port "Text Fields" to Rust</li>
|
||||
<li>Port "Column View" to Rust</li>
|
||||
<li>Port "Clamp" to Rust</li>
|
||||
<li>Port "List View" to Rust</li>
|
||||
<li>Port "Frame" to Rust</li>
|
||||
<li>Port "Audio" to Rust</li>
|
||||
<li>Port "File Monitor" to Vala</li>
|
||||
<li>Port "Scrolled Window" to Vala</li>
|
||||
<li>Port "Menu" to Vala</li>
|
||||
<li>Port "HTTP Server" to Vala</li>
|
||||
<li>Port "Map" to Vala</li>
|
||||
<li>Port "Session Monitor and Inhibit" to Vala</li>
|
||||
<li>Port "Save File" to Vala</li>
|
||||
<li>Port "Spin Button" to Vala</li>
|
||||
<li>Port "Progress Bar" to Vala</li>
|
||||
<li>Port "Label" to Vala</li>
|
||||
<li>Port "Power Profile Monitor" to Vala</li>
|
||||
<li>Port "Drawing Area" to Vala</li>
|
||||
<li>Port "Font Dialog" to Vala</li>
|
||||
<li>Port "Select Folder" to Vala</li>
|
||||
<li>Port "Network Monitor" to Vala</li>
|
||||
<li>Port "Toggle Button" to Vala</li>
|
||||
<li>Port "Tooltip" to Vala</li>
|
||||
<li>Port "Spell Checker" to Vala</li>
|
||||
<li>Port "Popovers" to Vala</li>
|
||||
<li>Port "Menu Button" to Vala</li>
|
||||
<li>Port "Frame" to Vala</li>
|
||||
<li>Port "Actions" to Vala</li>
|
||||
<li>Port "Dialog" to Vala</li>
|
||||
<li>Port "CSS Gradients" to Vala</li>
|
||||
<li>Port "Snapshot" to Vala</li>
|
||||
</ul>
|
||||
<p>Dependencies:</p>
|
||||
<ul>
|
||||
<!-- <li>Replace Biome with TypeScript Language Server</li> -->
|
||||
<li>Add GOM dependency 0.5.3</li>
|
||||
<li>Update Biome to 1.9.4</li>
|
||||
<li>Update libshumate to 1.3</li>
|
||||
<li>Update Blueprint to 0.14.0</li>
|
||||
<li>Update vte to 0.78.2</li>
|
||||
<li>Update libspelling to 0.4.5</li>
|
||||
<li>Update libportal to 0.8.1</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
|
||||
<release version="46.1" date="2024-04-30">
|
||||
<description translatable="no">
|
||||
<ul>
|
||||
<li>Add "Find" to search for code in the current editor</li>
|
||||
<li>Save and restore the session window dimensions</li>
|
||||
<li>Add "Reveal in Folder" to browse project files</li>
|
||||
<li>Remove Icon Library, please refer to the "Using Icons" entry</li>
|
||||
<li>List editor shortcuts in Shortcuts</li>
|
||||
<li>Fix Vala and Rust extensions detection on "Run"</li>
|
||||
<li>Library: Add "Using Icons"</li>
|
||||
<li>Library: Add "SVG"</li>
|
||||
<li>Library: Split "List View Widget" into "List View" and "Grid View"</li>
|
||||
<li>Library: Port "Animation" to Python</li>
|
||||
<li>Library: Port "Radio Buttons" to Vala</li>
|
||||
<li>Library: Port "Switch" to Vala</li>
|
||||
<li>Library: Port "Revealer" to Vala</li>
|
||||
<li>Library: Port "Styling with CSS" to Vala</li>
|
||||
<li>Library: Port "Separator" to Vala</li>
|
||||
<li>Library: Port "Level Bars" to Vala</li>
|
||||
<li>Library: Port "Link Button" to Vala</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
|
||||
<release version="46" date="2024-03-20">
|
||||
<description translatable="no">
|
||||
<ul>
|
||||
<li>Use GNOME 46</li>
|
||||
<li>Add basic Rust diagnostics</li>
|
||||
<li>Add basic Python diagnostics</li>
|
||||
<li>Replace Python formatter Black with Ruff</li>
|
||||
<li>Support libadwaita dialogs</li>
|
||||
<li>Stop adding a superfluous newlines to end of files</li>
|
||||
<li>Optimize opening Library entries</li>
|
||||
<li>Open project windows maximized</li>
|
||||
<li>Fix dangling bwrap processes after quitting Workbench</li>
|
||||
<li>Modernize the Extensions window</li>
|
||||
<li>Update Biome to 1.6.0</li>
|
||||
<li>Update libspelling to 0.2.1</li>
|
||||
<li>Update gst-plugin-gtk4 to 0.12.1</li>
|
||||
<li>Update libshumate to 1.2</li>
|
||||
<li>Update VTE to 0.76</li>
|
||||
<li>Update Blueprint to 0.12.0</li>
|
||||
<li>Update GTKCssLanguageServer</li>
|
||||
<li>Update icon-development-kit</li>
|
||||
<li>Library: Adapt demos to use GNOME 46 features</li>
|
||||
<li>Library: Add FileFilter example to "Open File" demo</li>
|
||||
<li>Library: Add "Snapshot" demo</li>
|
||||
<li>Library: Port "Scrolled Window" demo to Python</li>
|
||||
<li>Library: Port "HTTP Image" demo to Python</li>
|
||||
<li>Library: Port "HTTP Request" demo to Python</li>
|
||||
<li>Library: Port "HTTP Server" demo to Python</li>
|
||||
<li>Library: Port "Font Dialog" demo to Python</li>
|
||||
<li>Library: Port "Box" demo to Python</li>
|
||||
<li>Library: Port "Frame" demo to Python</li>
|
||||
<li>Library: Port "Grid" demo to Python</li>
|
||||
<li>Library: Port "Web View" demo to Python</li>
|
||||
<li>Library: Port "Network Monitor" demo to Python</li>
|
||||
<li>Library: Port "Navigation View" demo to Python</li>
|
||||
<li>Library: Port "Launcher" demo to Python</li>
|
||||
<li>Library: Port "Audio" demo to Python</li>
|
||||
<li>Library: Port "Map" demo to Python</li>
|
||||
<li>Library: Port "File Monitor" demo to Python</li>
|
||||
<li>Library: Port "WebSocket Client" demo to Python</li>
|
||||
<li>Library: Port "Screencast" demo to Python</li>
|
||||
<li>Library: Port "Progress Bar" demo to Python</li>
|
||||
<li>Library: Port "Camera" demo to Python</li>
|
||||
<li>Library: Port "Location" demo to Python</li>
|
||||
<li>Library: Port "List Model" demo to Python</li>
|
||||
<li>Library: Port "Drop Down" demo to Python</li>
|
||||
<li>Library: Port "Drawing Area" demo to Python</li>
|
||||
<li>Library: Port "Session Monitor and Inhibit" demo to Python</li>
|
||||
<li>Library: Port "View Switcher" demo to Python</li>
|
||||
<li>Library: Port "View Switcher" demo to Python</li>
|
||||
<li>Library: Port "Checkboxes" demo to Vala</li>
|
||||
<li>Library: Port "Action Bar" demo to Vala</li>
|
||||
<li>Library: Port "Clamp" demo to Vala</li>
|
||||
<li>Library: Port "Banner" demo to Vala</li>
|
||||
<li>Library: Port "Emoji Chooser" demo to Vala</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="45.4" date="2024-01-14">
|
||||
<description translatable="no">
|
||||
<ul>
|
||||
@ -53,7 +235,6 @@
|
||||
<li>Open the Library on start if there are no sessions to restore</li>
|
||||
<li>Restore scroll and cusor positions on format and Run</li>
|
||||
<li>Add "Copy" and "Select All" to Console</li>
|
||||
<!-- <li>Add find text support</li> -->
|
||||
<li>Add Vala formatter support</li>
|
||||
<li>Add WebP image format support</li>
|
||||
<li>Use Biome instead of prettier as JavaScript formatter</li>
|
||||
@ -214,7 +395,7 @@
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="45" date="2023-09-22">
|
||||
<release version="45.0" date="2023-09-22">
|
||||
<description translatable="no">
|
||||
<ul>
|
||||
<li>Use GNOME 45</li>
|
||||
@ -511,9 +692,15 @@
|
||||
<kudo>ModernToolkit</kudo>
|
||||
</kudos>
|
||||
<branding>
|
||||
<color type="primary">#33d17a</color>
|
||||
<color type="primary" scheme_preference="light">#57e389</color>
|
||||
<color type="primary" scheme_preference="dark">#26a269</color>
|
||||
</branding>
|
||||
<custom>
|
||||
<value key="GnomeSoftware::key-colors">[(51, 209, 122)]</value>
|
||||
</custom>
|
||||
<requires>
|
||||
<display_length compare="ge">1024</display_length>
|
||||
</requires>
|
||||
<recommends>
|
||||
<control>keyboard</control>
|
||||
<control>pointing</control>
|
||||
<control>touch</control>
|
||||
</recommends>
|
||||
</component>
|
||||
|
@ -2,49 +2,45 @@ desktop_file = configure_file(
|
||||
input: 'app.desktop',
|
||||
output: '@0@.desktop'.format(app_id),
|
||||
configuration: { 'app_id': app_id },
|
||||
install_dir: join_paths(get_option('datadir'), 'applications')
|
||||
install_dir: get_option('datadir') / 'applications'
|
||||
)
|
||||
|
||||
desktop_utils = find_program('desktop-file-validate', required: false)
|
||||
if desktop_utils.found()
|
||||
desktop_utils = find_program('desktop-file-validate', required: true)
|
||||
test('Validate desktop file', desktop_utils,
|
||||
args: [desktop_file]
|
||||
)
|
||||
endif
|
||||
|
||||
configure_file(
|
||||
input: 'app.service',
|
||||
output: '@0@.service'.format(app_id),
|
||||
configuration: { 'app_id': app_id, 'bindir': bindir },
|
||||
install_dir: join_paths(get_option('datadir'), 'dbus-1/services')
|
||||
install_dir: get_option('datadir') / 'dbus-1/services'
|
||||
)
|
||||
|
||||
appstream_file = configure_file(
|
||||
input: 'app.metainfo.xml',
|
||||
output: '@0@.metainfo.xml'.format(app_id),
|
||||
configuration: { 'app_id': app_id },
|
||||
install_dir: join_paths(get_option('datadir'), 'metainfo')
|
||||
install_dir: get_option('datadir') / 'metainfo'
|
||||
)
|
||||
|
||||
appstream_cli = find_program('appstreamcli', required: false)
|
||||
if appstream_cli.found()
|
||||
test('Validate metainfo file', appstream_cli,
|
||||
args: ['validate', '--override=release-time-missing=info', '--no-net', '--explain', appstream_file]
|
||||
appstreamcli = find_program('appstreamcli', required: false)
|
||||
test(
|
||||
'Validate appstream file',
|
||||
appstreamcli,
|
||||
args: ['validate', '--no-net', '--explain', appstream_file],
|
||||
)
|
||||
endif
|
||||
|
||||
configure_file(
|
||||
input: 'app.gschema.xml',
|
||||
output: '@0@.gschema.xml'.format(app_id),
|
||||
configuration: { 'app_id': app_id },
|
||||
install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas')
|
||||
install_dir: get_option('datadir') / 'glib-2.0/schemas'
|
||||
)
|
||||
|
||||
compile_schemas = find_program('glib-compile-schemas', required: false)
|
||||
if compile_schemas.found()
|
||||
compile_schemas = find_program('glib-compile-schemas', required: true)
|
||||
test('Validate schema file', compile_schemas,
|
||||
args: ['--strict', '--dry-run', meson.current_source_dir()]
|
||||
)
|
||||
endif
|
||||
|
||||
install_subdir('icons/hicolor', install_dir : join_paths(get_option('datadir'), 'icons'))
|
||||
install_subdir('icons/hicolor', install_dir : get_option('datadir') / 'icons')
|
||||
|
Before Width: | Height: | Size: 560 KiB |
Before Width: | Height: | Size: 230 KiB |
Before Width: | Height: | Size: 165 KiB |
Before Width: | Height: | Size: 503 KiB |
BIN
data/screenshots/code-dark.png
Normal file
After Width: | Height: | Size: 125 KiB |
BIN
data/screenshots/code.png
Normal file
After Width: | Height: | Size: 124 KiB |
BIN
data/screenshots/library-dark.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
data/screenshots/library.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
data/screenshots/welcome-dark.png
Normal file
After Width: | Height: | Size: 115 KiB |
BIN
data/screenshots/welcome.png
Normal file
After Width: | Height: | Size: 118 KiB |
2
demos
@ -1 +1 @@
|
||||
Subproject commit c92f1b3d5a0b1ba616396e28280c755679a84a18
|
||||
Subproject commit cd8b209df99294c72a5846ead00797db0bafa862
|
1
gi-types
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 396fe147142e28a921f0745eff1a562c7a551843
|
23
meson.build
@ -1,7 +1,14 @@
|
||||
project('Workbench', ['vala', 'c', 'rust'],
|
||||
version: '45.4',
|
||||
meson_version: '>= 0.59.0',
|
||||
license: 'GPL-3.0-only'
|
||||
project(
|
||||
'Workbench',
|
||||
['vala', 'c', 'rust'],
|
||||
version: '48.0',
|
||||
meson_version: '>= 1.0.0',
|
||||
license: 'GPL-3.0-only',
|
||||
default_options: [
|
||||
'libdir=lib',
|
||||
'warning_level=2',
|
||||
'werror=false',
|
||||
],
|
||||
)
|
||||
|
||||
gnome = import('gnome')
|
||||
@ -20,9 +27,9 @@ else
|
||||
endif
|
||||
|
||||
prefix = get_option('prefix')
|
||||
bindir = join_paths(prefix, 'bin')
|
||||
datadir = join_paths(prefix, get_option('datadir'))
|
||||
pkgdatadir = join_paths(datadir, app_id)
|
||||
bindir = prefix / 'bin'
|
||||
datadir = prefix / get_option('datadir')
|
||||
pkgdatadir = datadir / app_id
|
||||
|
||||
subdir('data')
|
||||
subdir('src')
|
||||
@ -30,5 +37,5 @@ subdir('src')
|
||||
gnome.post_install(
|
||||
glib_compile_schemas: true,
|
||||
gtk_update_icon_cache: true,
|
||||
update_desktop_database: true
|
||||
update_desktop_database: true,
|
||||
)
|
1026
package-lock.json
generated
13
package.json
@ -1,8 +1,9 @@
|
||||
{
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.22.11",
|
||||
"@babel/plugin-syntax-import-assertions": "^7.22.5",
|
||||
"@babel/core": "^7.25.7",
|
||||
"@babel/eslint-parser": "^7.25.7",
|
||||
"@babel/plugin-syntax-import-attributes": "^7.25.7",
|
||||
"@rollup/plugin-commonjs": "^22.0.1",
|
||||
"@rollup/plugin-node-resolve": "^13.3.0",
|
||||
"eslint": "^8.48.0",
|
||||
@ -12,7 +13,7 @@
|
||||
"events": "^3.3.0",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^14.0.1",
|
||||
"ltx": "git://github.com/xmppjs/ltx.git#d351ffa26ef1c5f2fbee7888d0bcd5047eb8a988",
|
||||
"ltx": "git://github.com/xmppjs/ltx.git#072690a43a51254ddd17b082131a8b9115586e8a",
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "3.0.3",
|
||||
"rollup": "^2.76.0",
|
||||
@ -26,10 +27,10 @@
|
||||
"lint-staged": {
|
||||
"*.{json,md,yaml,yml}": "prettier --write",
|
||||
"*.{js,cjs,mjs}": "eslint --fix",
|
||||
"*.css": "./build-aux/fun workbench-cli format",
|
||||
"*.py": "./build-aux/fun black",
|
||||
"*.css": "./build-aux/fun workbench-cli format css",
|
||||
"*.py": "./build-aux/fun workbench-cli format python",
|
||||
"*.rs": "./build-aux/fun rustfmt --edition 2021",
|
||||
"*.blp": "./build-aux/fun workbench-cli format",
|
||||
"*.blp": "./build-aux/fun workbench-cli format blueprint",
|
||||
"*.vala": "./build-aux/fun workbench-cli format vala"
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ template $Extension: ListBoxRow {
|
||||
Label label_title {}
|
||||
|
||||
[end]
|
||||
Image image_enabled {
|
||||
icon-name: "test-pass-symbolic";
|
||||
Image image_available {
|
||||
icon-name: "re.sonny.Workbench-test-pass-symbolic";
|
||||
|
||||
styles [
|
||||
"success"
|
||||
"success",
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -33,12 +33,13 @@ template $Extension: ListBoxRow {
|
||||
margin-bottom: 14;
|
||||
orientation: vertical;
|
||||
|
||||
Label label_hint {
|
||||
Label {
|
||||
wrap: true;
|
||||
xalign: 0;
|
||||
label: _("Run the following command");
|
||||
|
||||
styles [
|
||||
"dim-label"
|
||||
"dim-label",
|
||||
]
|
||||
}
|
||||
|
||||
@ -51,7 +52,7 @@ template $Extension: ListBoxRow {
|
||||
xalign: 0;
|
||||
|
||||
styles [
|
||||
"command_snippet"
|
||||
"command_snippet",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,8 @@ export default GObject.registerClass(
|
||||
Template,
|
||||
InternalChildren: [
|
||||
"label_title",
|
||||
"image_enabled",
|
||||
"image_available",
|
||||
"installation_guide",
|
||||
"label_hint",
|
||||
"label_command",
|
||||
],
|
||||
Properties: {
|
||||
@ -22,20 +21,13 @@ export default GObject.registerClass(
|
||||
GObject.ParamFlags.READWRITE,
|
||||
"",
|
||||
),
|
||||
enabled: GObject.ParamSpec.boolean(
|
||||
"enabled",
|
||||
available: GObject.ParamSpec.boolean(
|
||||
"available",
|
||||
"",
|
||||
"",
|
||||
GObject.ParamFlags.READWRITE,
|
||||
false,
|
||||
),
|
||||
hint: GObject.ParamSpec.string(
|
||||
"hint",
|
||||
"",
|
||||
"",
|
||||
GObject.ParamFlags.READWRITE,
|
||||
"",
|
||||
),
|
||||
command: GObject.ParamSpec.string(
|
||||
"command",
|
||||
"",
|
||||
@ -57,26 +49,19 @@ export default GObject.registerClass(
|
||||
);
|
||||
|
||||
this.bind_property(
|
||||
"enabled",
|
||||
this._image_enabled,
|
||||
"available",
|
||||
this._image_available,
|
||||
"visible",
|
||||
GObject.BindingFlags.SYNC_CREATE,
|
||||
);
|
||||
|
||||
this.bind_property(
|
||||
"enabled",
|
||||
"available",
|
||||
this._installation_guide,
|
||||
"visible",
|
||||
GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN,
|
||||
);
|
||||
|
||||
this.bind_property(
|
||||
"hint",
|
||||
this._label_hint,
|
||||
"label",
|
||||
GObject.BindingFlags.SYNC_CREATE,
|
||||
);
|
||||
|
||||
this.bind_property(
|
||||
"command",
|
||||
this._label_command,
|
||||
|
@ -1,18 +1,14 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
Adw.Window window {
|
||||
hide-on-close: true;
|
||||
modal: false;
|
||||
default-height: 750;
|
||||
default-width: 600;
|
||||
title: _("Workbench — Extensions");
|
||||
Adw.Dialog dialog {
|
||||
content-height: 750;
|
||||
content-width: 600;
|
||||
title: _("Extensions");
|
||||
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
show-title: false;
|
||||
}
|
||||
Adw.HeaderBar {}
|
||||
|
||||
content: ScrolledWindow {
|
||||
hscrollbar-policy: never;
|
||||
@ -38,42 +34,33 @@ Adw.Window window {
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Extensions");
|
||||
margin-bottom: 36;
|
||||
|
||||
styles [
|
||||
"title-1"
|
||||
]
|
||||
}
|
||||
|
||||
ListBox {
|
||||
selection-mode: none;
|
||||
|
||||
styles [
|
||||
"boxed-list"
|
||||
"boxed-list",
|
||||
]
|
||||
|
||||
$Extension {
|
||||
title: _("JavaScript");
|
||||
enabled: true;
|
||||
available: true;
|
||||
}
|
||||
|
||||
$Extension {
|
||||
title: _("Python");
|
||||
enabled: true;
|
||||
available: true;
|
||||
}
|
||||
|
||||
$Extension extension_rust {
|
||||
title: _("Rust");
|
||||
hint: _("To enable Rust support, run the following command in your Console or Terminal");
|
||||
command: "flatpak install flathub org.freedesktop.Sdk.Extension.rust-stable//23.08 org.freedesktop.Sdk.Extension.llvm16//23.08";
|
||||
}
|
||||
|
||||
$Extension extension_vala {
|
||||
title: _("Vala");
|
||||
hint: _("To enable Vala support, run the following command in your Console or Terminal");
|
||||
command: "flatpak install flathub org.freedesktop.Sdk.Extension.vala//23.08";
|
||||
}
|
||||
|
||||
$Extension extension_typescript {
|
||||
title: _("TypeScript");
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +72,7 @@ Adw.Window window {
|
||||
wrap: true;
|
||||
|
||||
styles [
|
||||
"dim-label"
|
||||
"dim-label",
|
||||
]
|
||||
}
|
||||
|
||||
@ -96,7 +83,7 @@ Adw.Window window {
|
||||
wrap: true;
|
||||
|
||||
styles [
|
||||
"dim-label"
|
||||
"dim-label",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -1,74 +1,89 @@
|
||||
import Gio from "gi://Gio";
|
||||
import GLib from "gi://GLib";
|
||||
|
||||
import { build } from "../../troll/src/main.js";
|
||||
|
||||
import Interface from "./Extensions.blp" with { type: "uri" };
|
||||
import illustration from "./extensions.svg";
|
||||
import { settings } from "../util.js";
|
||||
|
||||
import "./Extension.js";
|
||||
|
||||
const extensions = (() => {
|
||||
const keyfile = new GLib.KeyFile();
|
||||
|
||||
keyfile.load_from_file("/.flatpak-info", GLib.KeyFileFlags.NONE);
|
||||
|
||||
return keyfile
|
||||
.get_string_list("Instance", "runtime-extensions")
|
||||
.map((extension) => extension.split("=")[0]);
|
||||
})();
|
||||
import { settings } from "../util.js";
|
||||
import { getFlatpakInfo } from "../flatpak.js";
|
||||
|
||||
export const action_extensions = new Gio.SimpleAction({
|
||||
name: "extensions",
|
||||
parameter_type: null,
|
||||
});
|
||||
|
||||
export default function Extensions({ application }) {
|
||||
export function Extensions({ window }) {
|
||||
const {
|
||||
window,
|
||||
dialog,
|
||||
picture_illustration,
|
||||
extension_rust,
|
||||
extension_vala,
|
||||
extension_typescript,
|
||||
restart_hint,
|
||||
all_set_hint,
|
||||
} = build(Interface);
|
||||
|
||||
picture_illustration.set_resource(illustration);
|
||||
|
||||
extension_rust.enabled = isRustEnabled();
|
||||
extension_vala.enabled = isValaEnabled();
|
||||
extension_rust.available = isRustAvailable();
|
||||
extension_rust.command = `flatpak install flathub org.freedesktop.Sdk.Extension.rust-stable//${freedesktop_version} org.freedesktop.Sdk.Extension.${llvm}//${freedesktop_version}`;
|
||||
|
||||
for (const extension of [extension_rust, extension_vala]) {
|
||||
if (!extension.enabled) {
|
||||
extension_vala.available = isValaAvailable();
|
||||
extension_vala.command = `flatpak install flathub org.freedesktop.Sdk.Extension.vala//${freedesktop_version}`;
|
||||
|
||||
extension_typescript.available = isTypeScriptAvailable();
|
||||
extension_typescript.command = `flatpak install flathub org.freedesktop.Sdk.Extension.${node}//${freedesktop_version} org.freedesktop.Sdk.Extension.typescript//${freedesktop_version}`;
|
||||
extension_typescript.visible = isTypeScriptEnabled();
|
||||
|
||||
for (const extension of [
|
||||
extension_rust,
|
||||
extension_vala,
|
||||
extension_typescript,
|
||||
]) {
|
||||
if (!extension.available) {
|
||||
all_set_hint.set_visible(false);
|
||||
restart_hint.set_visible(true);
|
||||
}
|
||||
}
|
||||
|
||||
action_extensions.connect("activate", () => {
|
||||
settings.set_boolean("open-extensions", true);
|
||||
window.present();
|
||||
dialog.present(window);
|
||||
});
|
||||
|
||||
window.connect("close-request", () => {
|
||||
settings.set_boolean("open-extensions", false);
|
||||
});
|
||||
|
||||
if (settings.get_boolean("open-extensions")) {
|
||||
window.present();
|
||||
window.add_action(action_extensions);
|
||||
}
|
||||
|
||||
application.add_action(action_extensions);
|
||||
let rust_available = null;
|
||||
export function isRustAvailable() {
|
||||
rust_available ??=
|
||||
Gio.File.new_for_path("/usr/lib/sdk/rust-stable").query_exists(null) &&
|
||||
Gio.File.new_for_path(`/usr/lib/sdk/${llvm}`).query_exists(null);
|
||||
return rust_available;
|
||||
}
|
||||
|
||||
export function isRustEnabled() {
|
||||
return (
|
||||
extensions.includes("org.freedesktop.Sdk.Extension.rust-stable") &&
|
||||
extensions.includes("org.freedesktop.Sdk.Extension.llvm16")
|
||||
);
|
||||
let vala_available = null;
|
||||
export function isValaAvailable() {
|
||||
vala_available ??=
|
||||
Gio.File.new_for_path("/usr/lib/sdk/vala").query_exists(null);
|
||||
return vala_available;
|
||||
}
|
||||
|
||||
export function isValaEnabled() {
|
||||
return extensions.includes("org.freedesktop.Sdk.Extension.vala");
|
||||
let typescript_available = null;
|
||||
export function isTypeScriptAvailable() {
|
||||
typescript_available ??=
|
||||
isTypeScriptEnabled() &&
|
||||
Gio.File.new_for_path("/usr/lib/sdk/typescript").query_exists(null) &&
|
||||
Gio.File.new_for_path(`/usr/lib/sdk/${node}`).query_exists(null);
|
||||
return typescript_available;
|
||||
}
|
||||
|
||||
const llvm = "llvm18";
|
||||
const node = "node20";
|
||||
const runtime = getFlatpakInfo().get_string("Application", "runtime");
|
||||
const freedesktop_version = runtime.endsWith("master") ? "24.08" : "24.08";
|
||||
|
||||
export function isTypeScriptEnabled() {
|
||||
return settings.get_boolean("typescript");
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
using Gtk 4.0;
|
||||
|
||||
template $IconWidget: FlowBoxChild {
|
||||
focusable: false;
|
||||
halign: start;
|
||||
|
||||
Button button {
|
||||
clicked => $onClicked();
|
||||
width-request: 48;
|
||||
height-request: 48;
|
||||
|
||||
Image image {
|
||||
icon-name: "applications-science-symbolic";
|
||||
// preview only
|
||||
pixel-size: 32;
|
||||
halign: center;
|
||||
valign: center;
|
||||
}
|
||||
|
||||
styles [
|
||||
"flat"
|
||||
]
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import Gtk from "gi://Gtk";
|
||||
import GObject from "gi://GObject";
|
||||
|
||||
import Template from "./IconWidget.blp" with { type: "uri" };
|
||||
import { registerClass } from "../overrides.js";
|
||||
|
||||
class IconWidget extends Gtk.FlowBoxChild {
|
||||
constructor(params = {}) {
|
||||
super(params);
|
||||
this.bind_property(
|
||||
"icon_name",
|
||||
this._image,
|
||||
"icon-name",
|
||||
GObject.BindingFlags.SYNC_CREATE,
|
||||
);
|
||||
this.bind_property(
|
||||
"icon_name",
|
||||
this,
|
||||
"tooltip_text",
|
||||
GObject.BindingFlags.SYNC_CREATE,
|
||||
);
|
||||
}
|
||||
onClicked() {
|
||||
this.emit("clicked");
|
||||
}
|
||||
}
|
||||
|
||||
export default registerClass(
|
||||
{
|
||||
GTypeName: "IconWidget",
|
||||
Template,
|
||||
InternalChildren: ["image"],
|
||||
Properties: {
|
||||
icon_name: GObject.ParamSpec.string(
|
||||
"icon_name", // Name
|
||||
"icon_name", // Nick
|
||||
"", // Blurb
|
||||
GObject.ParamFlags.READWRITE, // Flags
|
||||
null, // Default value
|
||||
),
|
||||
},
|
||||
Signals: {
|
||||
clicked: {},
|
||||
},
|
||||
},
|
||||
IconWidget,
|
||||
);
|
@ -1,81 +0,0 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
Adw.Window window {
|
||||
width-request: 800;
|
||||
height-request: 600;
|
||||
hide-on-close: true;
|
||||
title: _("Workbench — Icon Library");
|
||||
|
||||
Adw.ToastOverlay overlay {
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {
|
||||
[title]
|
||||
Adw.Clamp {
|
||||
maximum-size: 800;
|
||||
|
||||
SearchEntry search_entry {
|
||||
hexpand: true;
|
||||
placeholder-text: _("Search for icons by name, category or tag");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrolledWindow {
|
||||
hexpand: true;
|
||||
vexpand: true;
|
||||
|
||||
Adw.Clamp {
|
||||
maximum-size: 800;
|
||||
|
||||
Box {
|
||||
orientation: vertical;
|
||||
|
||||
Label {
|
||||
styles [
|
||||
"title-4"
|
||||
]
|
||||
|
||||
label: "Icon Development Kit";
|
||||
margin-bottom: 6;
|
||||
margin-top: 12;
|
||||
halign: start;
|
||||
}
|
||||
|
||||
FlowBox flow_box_devkit {
|
||||
visible: false;
|
||||
valign: start;
|
||||
min-children-per-line: 5;
|
||||
max-children-per-line: 18;
|
||||
activate-on-single-click: true;
|
||||
selection-mode: none;
|
||||
margin-bottom: 12;
|
||||
}
|
||||
|
||||
Label {
|
||||
styles [
|
||||
"title-4"
|
||||
]
|
||||
|
||||
label: "Platform icons";
|
||||
margin-bottom: 6;
|
||||
margin-top: 12;
|
||||
halign: start;
|
||||
}
|
||||
|
||||
FlowBox flow_box_platform {
|
||||
visible: false;
|
||||
valign: start;
|
||||
min-children-per-line: 5;
|
||||
max-children-per-line: 18;
|
||||
activate-on-single-click: true;
|
||||
selection-mode: none;
|
||||
margin-bottom: 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
import Gtk from "gi://Gtk?version=4.0";
|
||||
import Gdk from "gi://Gdk";
|
||||
import Adw from "gi://Adw";
|
||||
import Gio from "gi://Gio";
|
||||
|
||||
import { build } from "../../troll/src/builder.js";
|
||||
|
||||
import IconWidget from "./IconWidget.js";
|
||||
import resource from "./main.blp" with { type: "uri" };
|
||||
|
||||
const toasts = new Set();
|
||||
|
||||
export default function IconLibrary() {
|
||||
const display = Gdk.Display.get_default();
|
||||
const clipboard = display.get_clipboard();
|
||||
|
||||
const dev_kit_icons = getDevKitIcons();
|
||||
const platform_icons = getPlatformIcons(dev_kit_icons);
|
||||
const icons = Object.assign(
|
||||
Object.create(null),
|
||||
platform_icons,
|
||||
dev_kit_icons,
|
||||
);
|
||||
|
||||
const { window, overlay, search_entry, flow_box_devkit, flow_box_platform } =
|
||||
build(resource);
|
||||
|
||||
function selectIcon(icon_name) {
|
||||
clipboard.set(icon_name);
|
||||
|
||||
for (const toast of toasts) {
|
||||
toast.dismiss();
|
||||
}
|
||||
const toast = new Adw.Toast({
|
||||
title: `“${icon_name}” copied to clipboard`,
|
||||
priority: Adw.ToastPriority.HIGH,
|
||||
});
|
||||
toast.connect("dismissed", onToastDismissed);
|
||||
toasts.add(toast);
|
||||
overlay.add_toast(toast);
|
||||
}
|
||||
|
||||
function filter_func({ icon_name }) {
|
||||
return icons[icon_name]?.some((tag) => tag.includes(search_entry.text));
|
||||
}
|
||||
flow_box_devkit.set_filter_func(filter_func);
|
||||
flow_box_platform.set_filter_func(filter_func);
|
||||
|
||||
search_entry.connect("search-changed", () => {
|
||||
flow_box_devkit.invalidate_filter();
|
||||
flow_box_platform.invalidate_filter();
|
||||
});
|
||||
|
||||
function populateIconDevKit() {
|
||||
for (const icon_name of Object.keys(dev_kit_icons).sort((a, b) =>
|
||||
a.localeCompare(b),
|
||||
)) {
|
||||
const icon = new IconWidget({
|
||||
icon_name,
|
||||
});
|
||||
icon.connect("clicked", () => selectIcon(icon_name));
|
||||
flow_box_devkit.append(icon);
|
||||
}
|
||||
flow_box_devkit.visible = true;
|
||||
}
|
||||
|
||||
function populatePlatformIcons() {
|
||||
for (const icon_name of Object.keys(platform_icons).sort((a, b) =>
|
||||
a.localeCompare(b),
|
||||
)) {
|
||||
const icon = new IconWidget({
|
||||
icon_name,
|
||||
});
|
||||
icon.connect("clicked", () => selectIcon(icon_name));
|
||||
flow_box_platform.append(icon);
|
||||
}
|
||||
flow_box_platform.visible = true;
|
||||
}
|
||||
|
||||
populateIconDevKit();
|
||||
populatePlatformIcons();
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
function onToastDismissed(toast) {
|
||||
toasts.delete(toast);
|
||||
}
|
||||
|
||||
function getDevKitIcons() {
|
||||
const icons = Object.create(null);
|
||||
|
||||
const [bytes] = Gio.File.new_for_path(
|
||||
"/app/share/icon-development-kit/icons.json",
|
||||
).load_bytes(null);
|
||||
|
||||
const icons_dev_kit = JSON.parse(new TextDecoder().decode(bytes.get_data()));
|
||||
for (const icon of icons_dev_kit) {
|
||||
// https://gitlab.gnome.org/Teams/Design/icon-development-kit/-/issues/62
|
||||
if (icon.context === "noexport-bits") continue;
|
||||
|
||||
icons[`${icon.filename}-symbolic`] = [
|
||||
icon.filename,
|
||||
icon.context,
|
||||
...icon.tags,
|
||||
];
|
||||
}
|
||||
|
||||
return icons;
|
||||
}
|
||||
|
||||
function getPlatformIcons(dev_kit_icons) {
|
||||
const display = Gdk.Display.get_default();
|
||||
const icons = Object.create(null);
|
||||
|
||||
const icon_theme = Gtk.IconTheme.get_for_display(display);
|
||||
const icons_theme = icon_theme.get_icon_names();
|
||||
|
||||
for (const icon of icons_theme) {
|
||||
if (
|
||||
icon.startsWith("re.sonny.Workbench") ||
|
||||
!icon.endsWith("-symbolic") ||
|
||||
icon in dev_kit_icons
|
||||
)
|
||||
continue;
|
||||
|
||||
if (!(icon in icons)) icons[icon] = [icon.split("-symbolic")[0]];
|
||||
}
|
||||
|
||||
return icons;
|
||||
}
|
@ -1,20 +1,20 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
template $EntryRow: Adw.PreferencesRow {
|
||||
template $EntryRow: Adw.ActionRow {
|
||||
activatable: true;
|
||||
|
||||
accessibility {
|
||||
labelled-by: title_label;
|
||||
described-by: description_label;
|
||||
}
|
||||
|
||||
title: bind title_label.label;
|
||||
|
||||
[prefix]
|
||||
Box contents {
|
||||
orientation: horizontal;
|
||||
|
||||
Box labels_box {
|
||||
margin-top: 6;
|
||||
margin-start: 12;
|
||||
margin-bottom: 6;
|
||||
spacing: 3;
|
||||
orientation: vertical;
|
||||
@ -28,7 +28,7 @@ template $EntryRow: Adw.PreferencesRow {
|
||||
Label description_label {
|
||||
styles [
|
||||
"dim-label",
|
||||
"caption"
|
||||
"caption",
|
||||
]
|
||||
|
||||
xalign: 0;
|
||||
@ -43,13 +43,13 @@ template $EntryRow: Adw.PreferencesRow {
|
||||
margin-top: 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[suffix]
|
||||
Image {
|
||||
icon-name: "go-next-symbolic";
|
||||
margin-end: 12;
|
||||
margin-start: 6;
|
||||
hexpand: true;
|
||||
halign: end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import GObject from "gi://GObject";
|
||||
import { getLanguage } from "../util.js";
|
||||
import Template from "./EntryRow.blp" with { type: "uri" };
|
||||
|
||||
class EntryRow extends Adw.PreferencesRow {
|
||||
class EntryRow extends Adw.ActionRow {
|
||||
constructor({ demo, ...params } = {}) {
|
||||
super(params);
|
||||
|
||||
@ -22,7 +22,7 @@ class EntryRow extends Adw.PreferencesRow {
|
||||
});
|
||||
|
||||
activate_action.connect("activate", () => {
|
||||
this.emit("activated", null);
|
||||
this.emit("triggered", null);
|
||||
});
|
||||
action_group.add_action(activate_action);
|
||||
|
||||
@ -47,7 +47,7 @@ class EntryRow extends Adw.PreferencesRow {
|
||||
});
|
||||
|
||||
button.connect("clicked", () => {
|
||||
this.emit("activated", language);
|
||||
this.emit("triggered", language);
|
||||
});
|
||||
|
||||
return button;
|
||||
@ -68,7 +68,7 @@ export default GObject.registerClass(
|
||||
),
|
||||
},
|
||||
Signals: {
|
||||
activated: {
|
||||
triggered: {
|
||||
param_types: [GObject.TYPE_JSOBJECT],
|
||||
},
|
||||
},
|
||||
|
@ -1,75 +1,130 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
Adw.PreferencesWindow window {
|
||||
Adw.Window window {
|
||||
hide-on-close: true;
|
||||
modal: false;
|
||||
title: _("Workbench — Library");
|
||||
default-height: 700;
|
||||
default-width: 700;
|
||||
|
||||
Adw.PreferencesPage {
|
||||
Adw.PreferencesGroup {
|
||||
Adw.ToolbarView toolbar_view {
|
||||
[top]
|
||||
Adw.HeaderBar header_bar {
|
||||
title-widget: Adw.WindowTitle {
|
||||
title: _("Workbench — Library");
|
||||
};
|
||||
}
|
||||
|
||||
content: ScrolledWindow scrolled_window {
|
||||
hscrollbar-policy: never;
|
||||
|
||||
child: Adw.Clamp {
|
||||
maximum-size: 576;
|
||||
margin-end: 12;
|
||||
margin-start: 12;
|
||||
|
||||
child: Box {
|
||||
orientation: vertical;
|
||||
spacing: 12;
|
||||
|
||||
Box {
|
||||
orientation: vertical;
|
||||
|
||||
Box {
|
||||
halign: center;
|
||||
vexpand: false;
|
||||
|
||||
Picture picture_illustration {
|
||||
can-shrink: false;
|
||||
margin-bottom: 32;
|
||||
margin-top: 24;
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Learn, Test, Remix");
|
||||
|
||||
styles [
|
||||
"title-1"
|
||||
"title-1",
|
||||
]
|
||||
}
|
||||
|
||||
Box {
|
||||
spacing: 6;
|
||||
|
||||
SearchEntry search_entry {
|
||||
search-delay: 100;
|
||||
placeholder-text: _("Search demos");
|
||||
activates-default: true;
|
||||
hexpand: true;
|
||||
margin-top: 32;
|
||||
}
|
||||
|
||||
DropDown dropdown_language {
|
||||
valign: end;
|
||||
|
||||
model: Gtk.StringList {};
|
||||
}
|
||||
|
||||
DropDown dropdown_category {
|
||||
valign: end;
|
||||
|
||||
model: Gtk.StringList {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListBox listbox {
|
||||
selection-mode: none;
|
||||
|
||||
styles [
|
||||
"boxed-list",
|
||||
]
|
||||
}
|
||||
|
||||
Box {
|
||||
halign: center;
|
||||
margin-bottom: 24;
|
||||
margin-top: 12;
|
||||
orientation: vertical;
|
||||
|
||||
Box results_empty {
|
||||
orientation: vertical;
|
||||
visible: false;
|
||||
margin-top: 46;
|
||||
margin-bottom: 70;
|
||||
spacing: 6;
|
||||
|
||||
Label {
|
||||
label: _("No results");
|
||||
|
||||
styles [
|
||||
"title-3",
|
||||
]
|
||||
}
|
||||
|
||||
Button button_reset {
|
||||
label: _("Reset filters");
|
||||
halign: center;
|
||||
|
||||
styles [
|
||||
"pill",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup library_uncategorized {}
|
||||
|
||||
Adw.PreferencesGroup library_tools {
|
||||
title: _("Tools");
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup library_network {
|
||||
title: _("Network");
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup library_controls {
|
||||
title: _("Controls");
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup library_layout {
|
||||
title: _("Layout");
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup library_feedback {
|
||||
title: _("Feedback");
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup library_navigation {
|
||||
title: _("Navigation");
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup library_user_interface {
|
||||
title: _("User Interface");
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup library_platform {
|
||||
title: _("Platform APIs");
|
||||
}
|
||||
|
||||
Adw.PreferencesGroup {
|
||||
vexpand: true;
|
||||
valign: end;
|
||||
|
||||
Label {
|
||||
label: _('All examples are dedicated to the public domain\nand <b>can be used freely</b> under the terms of <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0 1.0</a>.');
|
||||
label: _("All examples are dedicated to the public domain\nand <b>can be used freely</b> under the terms of <a href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0 1.0</a>");
|
||||
use-markup: true;
|
||||
|
||||
styles [
|
||||
"caption"
|
||||
"caption",
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,28 @@ import { createSessionFromDemo } from "../sessions.js";
|
||||
import EntryRow from "./EntryRow.js";
|
||||
|
||||
import illustration from "./library.svg";
|
||||
import { gettext as _ } from "gettext";
|
||||
|
||||
import { build } from "../../troll/src/builder.js";
|
||||
import {
|
||||
needsAdditionalPermissions,
|
||||
showPermissionsDialog,
|
||||
} from "../Permissions/Permissions.js";
|
||||
import { isTypeScriptEnabled } from "../Extensions/Extensions.js";
|
||||
|
||||
export default function Library({ application }) {
|
||||
const objects = build(resource);
|
||||
const { window, picture_illustration } = objects;
|
||||
const {
|
||||
window,
|
||||
picture_illustration,
|
||||
search_entry,
|
||||
dropdown_category,
|
||||
dropdown_language,
|
||||
results_empty,
|
||||
button_reset,
|
||||
listbox,
|
||||
scrolled_window,
|
||||
} = objects;
|
||||
window.application = application;
|
||||
picture_illustration.set_resource(illustration);
|
||||
|
||||
@ -27,17 +43,60 @@ export default function Library({ application }) {
|
||||
window.add_css_class("devel");
|
||||
}
|
||||
|
||||
let last_selected;
|
||||
let last_triggered;
|
||||
|
||||
window.connect("close-request", quitOnLastWindowClose);
|
||||
|
||||
const demos = getDemos();
|
||||
demos.forEach((demo) => {
|
||||
const widget = new EntryRow({ demo: demo });
|
||||
if (demo.name === "Welcome") last_selected = widget;
|
||||
const categories = [
|
||||
{ id: "all", name: _("Any Category"), index: 0 },
|
||||
{ id: "tools", name: _("Tools"), index: 1 },
|
||||
{ id: "network", name: _("Network"), index: 2 },
|
||||
{ id: "controls", name: _("Controls"), index: 3 },
|
||||
{ id: "layout", name: _("Layout"), index: 4 },
|
||||
{ id: "feedback", name: _("Feedback"), index: 5 },
|
||||
{ id: "navigation", name: _("Navigation"), index: 6 },
|
||||
{ id: "user_interface", name: _("User Interface"), index: 7 },
|
||||
{ id: "platform", name: _("Platform APIs"), index: 8 },
|
||||
];
|
||||
const categories_by_id = Object.fromEntries(
|
||||
categories.map((category) => [category.id, category]),
|
||||
);
|
||||
const categories_by_index = Object.fromEntries(
|
||||
categories.map((category) => [category.index, category]),
|
||||
);
|
||||
const category_all = categories_by_id["all"];
|
||||
|
||||
widget.connect("activated", (_self, language) => {
|
||||
last_selected = widget;
|
||||
categories.forEach((category) => {
|
||||
dropdown_category.model.append(category.name);
|
||||
});
|
||||
|
||||
const languages = [
|
||||
{ id: "all", name: _("Any Language"), index: 0 },
|
||||
{ id: "javascript", name: _("JavaScript"), index: 1 },
|
||||
{ id: "python", name: _("Python"), index: 2 },
|
||||
{ id: "rust", name: _("Rust"), index: 3 },
|
||||
{ id: "vala", name: _("Vala"), index: 4 },
|
||||
];
|
||||
if (isTypeScriptEnabled()) {
|
||||
languages.push({ id: "typescript", name: _("TypeScript"), index: 5 });
|
||||
}
|
||||
const languages_by_id = Object.fromEntries(
|
||||
languages.map((language) => [language.id, language]),
|
||||
);
|
||||
const languages_by_index = Object.fromEntries(
|
||||
languages.map((language) => [language.index, language]),
|
||||
);
|
||||
languages.forEach((language) => {
|
||||
dropdown_language.model.append(language.name);
|
||||
});
|
||||
|
||||
const demos = getDemos();
|
||||
const entries = demos.map((demo) => {
|
||||
const entry_row = new EntryRow({ demo });
|
||||
if (demo.name === "Welcome") last_triggered = entry_row;
|
||||
|
||||
entry_row.connect("triggered", (_self, language) => {
|
||||
last_triggered = entry_row;
|
||||
|
||||
openDemo({
|
||||
application,
|
||||
@ -45,17 +104,66 @@ export default function Library({ application }) {
|
||||
language,
|
||||
}).catch(console.error);
|
||||
});
|
||||
listbox.append(entry_row);
|
||||
|
||||
objects[`library_${demo.category}`].add(widget);
|
||||
const category = categories_by_id[demo.category];
|
||||
const widget = entry_row;
|
||||
const languages = demo.languages.map((lang) => languages_by_id[lang]);
|
||||
|
||||
return { ...demo, category, widget, languages };
|
||||
});
|
||||
|
||||
const language_all = languages_by_id["all"];
|
||||
|
||||
function updateList() {
|
||||
const current_category =
|
||||
categories_by_index[dropdown_category.get_selected()];
|
||||
const current_language =
|
||||
languages_by_index[dropdown_language.get_selected()];
|
||||
|
||||
const search_term = search_entry.get_text().toLowerCase();
|
||||
let results_found = false;
|
||||
entries.forEach(({ name, description, category, languages, widget }) => {
|
||||
const category_match =
|
||||
current_category === category_all || category === current_category;
|
||||
const language_match =
|
||||
current_language === language_all ||
|
||||
languages.includes(current_language);
|
||||
const search_match =
|
||||
search_term === "" ||
|
||||
name.toLowerCase().includes(search_term) ||
|
||||
description.toLowerCase().includes(search_term) ||
|
||||
category.name.toLowerCase().includes(search_term);
|
||||
const is_match = category_match && language_match && search_match;
|
||||
widget.visible = is_match;
|
||||
if (is_match) {
|
||||
results_found = true;
|
||||
}
|
||||
});
|
||||
|
||||
results_empty.visible = !results_found;
|
||||
}
|
||||
|
||||
search_entry.connect("search-changed", updateList);
|
||||
dropdown_category.connect("notify::selected", updateList);
|
||||
dropdown_language.connect("notify::selected", updateList);
|
||||
|
||||
function reset() {
|
||||
scrolled_window.vadjustment = null;
|
||||
search_entry.text = "";
|
||||
dropdown_category.selected = category_all.index;
|
||||
dropdown_language.selected = language_all.index;
|
||||
}
|
||||
button_reset.connect("clicked", reset);
|
||||
window.connect("show", reset);
|
||||
|
||||
const action_library = new Gio.SimpleAction({
|
||||
name: "library",
|
||||
parameter_type: null,
|
||||
});
|
||||
action_library.connect("activate", () => {
|
||||
window.present();
|
||||
last_selected?.grab_focus();
|
||||
last_triggered?.grab_focus();
|
||||
});
|
||||
application.add_action(action_library);
|
||||
application.set_accels_for_action("app.library", ["<Control><Shift>O"]);
|
||||
@ -80,15 +188,15 @@ export function getDemo(name) {
|
||||
|
||||
async function openDemo({ application, demo_name, language }) {
|
||||
const demo = getDemo(demo_name);
|
||||
const session = createSessionFromDemo(demo);
|
||||
const session = await createSessionFromDemo(demo);
|
||||
|
||||
if (language) {
|
||||
session.settings.set_int("code-language", language.index);
|
||||
global_settings.set_int("recent-code-language", language.index);
|
||||
|
||||
// If the user explictely requested to open the demo
|
||||
// If the user explicitly requested to open the demo
|
||||
// in a specific language then that's probably what they are interested in
|
||||
// therefor override the demo default and force show the code panel
|
||||
// therefore override the demo default and force show the code panel
|
||||
session.settings.set_boolean("show-code", true);
|
||||
}
|
||||
|
||||
@ -103,9 +211,17 @@ async function openDemo({ application, demo_name, language }) {
|
||||
);
|
||||
}
|
||||
|
||||
const { load, runCode } = Window({ application, session });
|
||||
const { load, runCode, window } = Window({
|
||||
application,
|
||||
session,
|
||||
});
|
||||
await load();
|
||||
|
||||
if (needsAdditionalPermissions({ demo })) {
|
||||
showPermissionsDialog({ window });
|
||||
return;
|
||||
}
|
||||
|
||||
const code_language = session.getCodeLanguage();
|
||||
const run = autorun && code_language.id === "javascript";
|
||||
if (run) {
|
||||
|
@ -1,9 +1,17 @@
|
||||
import Gio from "gi://Gio";
|
||||
import GObject from "gi://GObject";
|
||||
|
||||
import { settings as global_settings, makeDropdownFlat } from "./util.js";
|
||||
import { makeDropdownFlat, settings as global_settings } from "./util.js";
|
||||
import { setupRustProject } from "./langs/rust/rust.js";
|
||||
import { setupTypeScriptProject } from "./langs/typescript/typescript.js";
|
||||
import { setupJavascriptProject } from "./langs/javascript/javascript.js";
|
||||
|
||||
export default function PanelCode({ builder, previewer, settings }) {
|
||||
export default function PanelCode({
|
||||
builder,
|
||||
previewer,
|
||||
session: { settings, file },
|
||||
langs,
|
||||
}) {
|
||||
const panel_code = builder.get_object("panel_code");
|
||||
const button_code = builder.get_object("button_code");
|
||||
const stack_code = builder.get_object("stack_code");
|
||||
@ -47,6 +55,22 @@ export default function PanelCode({ builder, previewer, settings }) {
|
||||
panel.language = dropdown_code_lang.selected_item?.string;
|
||||
stack_code.visible_child_name = panel.language;
|
||||
previewer.useInternal().catch(console.error);
|
||||
|
||||
if (panel.language.toLowerCase() === "javascript") {
|
||||
setupJavascriptProject(file, langs.javascript.document).catch(
|
||||
console.error,
|
||||
);
|
||||
}
|
||||
|
||||
if (panel.language.toLowerCase() === "rust") {
|
||||
setupRustProject(file).catch(console.error);
|
||||
}
|
||||
|
||||
if (panel.language.toLowerCase() === "typescript") {
|
||||
setupTypeScriptProject(file, langs.typescript.document).catch(
|
||||
console.error,
|
||||
);
|
||||
}
|
||||
}
|
||||
switchLanguage();
|
||||
|
||||
|
@ -76,19 +76,18 @@ export default function PanelUI({
|
||||
"button_ui_experimental_blueprint",
|
||||
);
|
||||
button_ui_experimental_blueprint.connect("clicked", () => {
|
||||
const modal = builder.get_object("modal_blueprint_experimental");
|
||||
modal.set_transient_for(application.get_active_window());
|
||||
modal.present();
|
||||
const dialog = builder.get_object("dialog_blueprint_experimental");
|
||||
dialog.present(application.get_active_window());
|
||||
});
|
||||
const button_blueprint_documentation = builder.get_object(
|
||||
"button_blueprint_documentation",
|
||||
);
|
||||
button_blueprint_documentation.connect("clicked", () => {
|
||||
Gtk.show_uri(
|
||||
null,
|
||||
"https://jwestman.pages.gitlab.gnome.org/blueprint-compiler/",
|
||||
null,
|
||||
);
|
||||
new Gtk.UriLauncher({
|
||||
uri: "https://jwestman.pages.gitlab.gnome.org/blueprint-compiler/",
|
||||
})
|
||||
.launch(application.get_active_window(), null)
|
||||
.catch(console.error);
|
||||
});
|
||||
|
||||
let handler_id_xml = null;
|
||||
|
155
src/Permissions/Permissions.blp
Normal file
@ -0,0 +1,155 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
Adw.Dialog dialog {
|
||||
content-height: 750;
|
||||
content-width: 600;
|
||||
|
||||
Adw.ToolbarView {
|
||||
[top]
|
||||
Adw.HeaderBar {}
|
||||
|
||||
content: ScrolledWindow {
|
||||
hscrollbar-policy: never;
|
||||
|
||||
Adw.Clamp {
|
||||
maximum-size: 520;
|
||||
tightening-threshold: 400;
|
||||
margin-start: 12;
|
||||
margin-end: 12;
|
||||
margin-bottom: 24;
|
||||
|
||||
Box {
|
||||
orientation: vertical;
|
||||
halign: fill;
|
||||
spacing: 24;
|
||||
// Gtk.Picture needs to be wrapped in a box to behave properly
|
||||
Box {
|
||||
halign: center;
|
||||
|
||||
Picture picture_illustration {
|
||||
can-shrink: false;
|
||||
margin-bottom: 24;
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Permissions Needed");
|
||||
|
||||
styles [
|
||||
"title-1",
|
||||
]
|
||||
}
|
||||
|
||||
Label {
|
||||
label: _("Workbench needs additional permissions. Please run the following command in a terminal and restart Workbench.");
|
||||
wrap: true;
|
||||
justify: center;
|
||||
}
|
||||
|
||||
Label label_command {
|
||||
use-markup: true;
|
||||
wrap: true;
|
||||
wrap-mode: word_char;
|
||||
selectable: true;
|
||||
xalign: 0;
|
||||
|
||||
styles [
|
||||
"command_snippet",
|
||||
]
|
||||
}
|
||||
|
||||
Box {
|
||||
orientation: vertical;
|
||||
|
||||
Box {
|
||||
margin-bottom: 6;
|
||||
|
||||
Label {
|
||||
label: _("What it does");
|
||||
halign: start;
|
||||
hexpand: true;
|
||||
|
||||
styles [
|
||||
"heading",
|
||||
]
|
||||
}
|
||||
|
||||
Button button_info {
|
||||
icon-name: "re.sonny.Workbench-external-link-symbolic";
|
||||
|
||||
styles [
|
||||
"flat",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ListBox {
|
||||
selection-mode: none;
|
||||
|
||||
styles [
|
||||
"boxed-list",
|
||||
]
|
||||
|
||||
Adw.ActionRow {
|
||||
[prefix]
|
||||
Image {
|
||||
icon-name: "re.sonny.Workbench-person-symbolic";
|
||||
}
|
||||
|
||||
title: _("--user");
|
||||
subtitle: _("Grant for your account only");
|
||||
|
||||
styles [
|
||||
"property",
|
||||
]
|
||||
}
|
||||
|
||||
Adw.ActionRow {
|
||||
[prefix]
|
||||
Image {
|
||||
icon-name: "re.sonny.Workbench-network-wireless-symbolic";
|
||||
}
|
||||
|
||||
title: _("--share-network");
|
||||
subtitle: _("Network access");
|
||||
|
||||
styles [
|
||||
"property",
|
||||
]
|
||||
}
|
||||
|
||||
Adw.ActionRow {
|
||||
[prefix]
|
||||
Image {
|
||||
icon-name: "re.sonny.Workbench-speakers-symbolic";
|
||||
}
|
||||
|
||||
title: _("--socket=pulseaudio");
|
||||
subtitle: _("Record and play audio");
|
||||
|
||||
styles [
|
||||
"property",
|
||||
]
|
||||
}
|
||||
|
||||
Adw.ActionRow action_row_device {
|
||||
[prefix]
|
||||
Image {
|
||||
icon-name: "re.sonny.Workbench-gamepad-symbolic";
|
||||
}
|
||||
|
||||
// title: _("--device=input");
|
||||
subtitle: _("Access to input device such as gamepads");
|
||||
|
||||
styles [
|
||||
"property",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
72
src/Permissions/Permissions.js
Normal file
@ -0,0 +1,72 @@
|
||||
import Gio from "gi://Gio";
|
||||
import Gtk from "gi://Gtk";
|
||||
|
||||
import { build } from "../../troll/src/main.js";
|
||||
|
||||
import Interface from "./Permissions.blp" with { type: "uri" };
|
||||
|
||||
import illustration from "./permissions.svg";
|
||||
|
||||
import {
|
||||
getFlatpakId,
|
||||
getFlatpakInfo,
|
||||
isDeviceInputOverrideAvailable,
|
||||
} from "../flatpak.js";
|
||||
|
||||
const device = isDeviceInputOverrideAvailable() ? "input" : "all";
|
||||
|
||||
const action_permissions = new Gio.SimpleAction({
|
||||
name: "permissions",
|
||||
parameter_type: null,
|
||||
});
|
||||
|
||||
export function Permissions({ window }) {
|
||||
const {
|
||||
dialog,
|
||||
picture_illustration,
|
||||
label_command,
|
||||
button_info,
|
||||
action_row_device,
|
||||
} = build(Interface);
|
||||
|
||||
picture_illustration.set_resource(illustration);
|
||||
|
||||
label_command.label = `flatpak override --user --share=network --socket=pulseaudio --device=${device} ${getFlatpakId()}`;
|
||||
action_row_device.title = `--input=${device}`;
|
||||
|
||||
button_info.connect("clicked", () => {
|
||||
new Gtk.UriLauncher({
|
||||
uri: "https://docs.flatpak.org/en/latest/sandbox-permissions.html",
|
||||
})
|
||||
.launch(window, null)
|
||||
.catch(console.error);
|
||||
});
|
||||
|
||||
action_permissions.connect("activate", () => {
|
||||
dialog.present(window);
|
||||
});
|
||||
|
||||
window.add_action(action_permissions);
|
||||
}
|
||||
|
||||
const missing_permissions = (() => {
|
||||
const flatpak_info = getFlatpakInfo();
|
||||
const shared = flatpak_info.get_string_list("Context", "shared");
|
||||
const sockets = flatpak_info.get_string_list("Context", "sockets");
|
||||
const devices = flatpak_info.get_string_list("Context", "devices");
|
||||
|
||||
return (
|
||||
!shared.includes("network") ||
|
||||
!sockets.includes("pulseaudio") ||
|
||||
!devices.includes(device)
|
||||
);
|
||||
})();
|
||||
|
||||
export function needsAdditionalPermissions({ demo }) {
|
||||
if (!demo["flatpak-finish-args"]) return false;
|
||||
return missing_permissions;
|
||||
}
|
||||
|
||||
export function showPermissionsDialog({ window }) {
|
||||
window.activate_action("permissions", null);
|
||||
}
|
568
src/Permissions/permissions.svg
Normal file
@ -0,0 +1,568 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="332"
|
||||
height="200"
|
||||
viewBox="0 0 332 200"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||
sodipodi:docname="permissions.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="false"
|
||||
inkscape:deskcolor="#ffffff"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.099784977"
|
||||
inkscape:cx="-661.42221"
|
||||
inkscape:cy="-65.140066"
|
||||
inkscape:current-layer="layer1"
|
||||
showguides="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
id="grid1"
|
||||
units="px"
|
||||
originx="0"
|
||||
originy="0"
|
||||
spacingx="1"
|
||||
spacingy="1"
|
||||
empcolor="#0099e5"
|
||||
empopacity="0.30196078"
|
||||
color="#0099e5"
|
||||
opacity="0.14901961"
|
||||
empspacing="4"
|
||||
dotted="false"
|
||||
gridanglex="30"
|
||||
gridanglez="30"
|
||||
visible="false" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect65"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,21.13606,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,9.1490264,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<linearGradient
|
||||
id="linearGradient63"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#fbe47c;stop-opacity:0.6635828;"
|
||||
offset="0"
|
||||
id="stop63" />
|
||||
<stop
|
||||
style="stop-color:#87e8b5;stop-opacity:0.7638889;"
|
||||
offset="1"
|
||||
id="stop64" />
|
||||
</linearGradient>
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect62"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,1,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect60"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,2,0,1 @ F,0,1,1,0,2,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect58"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,6,0,1 @ F,0,1,1,0,6,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect56"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,1,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<linearGradient
|
||||
id="linearGradient26"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#2177df;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop26" />
|
||||
<stop
|
||||
style="stop-color:#1a5fb4;stop-opacity:1;"
|
||||
offset="0.09090688"
|
||||
id="stop28" />
|
||||
<stop
|
||||
style="stop-color:#1a5fb4;stop-opacity:1;"
|
||||
offset="0.9090907"
|
||||
id="stop29" />
|
||||
<stop
|
||||
style="stop-color:#15498a;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop27" />
|
||||
</linearGradient>
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect23"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,1,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,4,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<linearGradient
|
||||
id="linearGradient5"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#5e5c64;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5" />
|
||||
<stop
|
||||
style="stop-color:#4d4c50;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop6" />
|
||||
</linearGradient>
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect5"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,2,0,1 @ F,0,1,1,0,2,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect3"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,6,0,1 @ F,0,1,1,0,6,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect2"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,8,0,1 @ F,0,0,1,0,8.2101528,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect211"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect157"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect102"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1 @ F,0,1,1,0,12.476317,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect39"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,3.414062,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath31">
|
||||
<path
|
||||
style="opacity:1;fill:#865e3c;fill-opacity:1;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:3.57621, 3.57621"
|
||||
d="m 104.57142,32 c -2.53257,0 -4.571424,1.784002 -4.571424,4 V 82 H 227.99999 V 36 c 0,-2.215998 -2.03886,-4 -4.57143,-4 z"
|
||||
id="path32" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath33">
|
||||
<path
|
||||
style="opacity:1;fill:#865e3c;fill-opacity:1;stroke-width:1.99999;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:3.57621, 3.57621"
|
||||
d="m 99.999997,90 v 46 c 0,2.216 2.102573,4 4.714283,4 h 122.57143 c 2.61171,0 4.71428,-1.784 4.71428,-4 V 90 Z"
|
||||
id="path34" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5"
|
||||
id="linearGradient6"
|
||||
x1="176.92285"
|
||||
y1="156"
|
||||
x2="176.92285"
|
||||
y2="164"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.4984166,0,0,1.4984166,-49.616298,-72.451818)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient26"
|
||||
id="linearGradient27"
|
||||
x1="100"
|
||||
y1="120.00011"
|
||||
x2="100"
|
||||
y2="164"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.4984166,0,0,1.4984166,-49.616298,-72.451818)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient63"
|
||||
id="linearGradient65"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-35.382733,-4.2152026)"
|
||||
x1="248.07971"
|
||||
y1="113.07767"
|
||||
x2="85.016251"
|
||||
y2="113.07767" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
id="circle65"
|
||||
style="fill:url(#linearGradient65);stroke:none;stroke-width:1.46117;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 131.16602,27.330078 c -45.029881,-8.12e-4 -81.534017,36.503321 -81.533208,81.533202 2.7e-4,45.02912 36.504089,81.53206 81.533208,81.53125 8.38262,-0.006 16.67054,-1.30441 24.58233,-3.81292 11.09609,-3.51812 26.47255,-2.63586 37.20566,1.85535 9.07487,3.79734 18.86926,5.80785 28.84287,5.84038 41.61705,-7.5e-4 75.35384,-33.73841 75.35351,-75.35546 -7.4e-4,-41.616289 -33.73722,-75.352772 -75.35351,-75.353521 -8.35948,0.02724 -16.6344,1.44503 -24.49097,4.175374 -4.76994,1.657664 -11.30579,0.572701 -15.25124,-2.579772 -14.3779,-11.488134 -32.30568,-17.832988 -50.88865,-17.833883 z"
|
||||
transform="matrix(-1.0569476,0,0,1.0569476,354.87042,-13.797304)" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#1a5fb4;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 85.947825,152 H 64 a 4,4 135 0 0 -4,4 4,4 45 0 0 4,4 h 4 a 4,4 45 0 1 4,4 4,4 135 0 1 -4,4 H 56 a 4,4 135 0 0 -4,4 4,4 45 0 0 4,4 l 28,0 a 4,4 135 0 0 4,-4 4,4 135 0 1 4,-4 h 20"
|
||||
id="path23"
|
||||
sodipodi:nodetypes="cccccccccc"
|
||||
transform="matrix(1.4984165,0,0,1.4984165,-49.616294,-72.451812)" />
|
||||
<g
|
||||
id="g21"
|
||||
transform="matrix(1.4984165,0,0,1.4984165,-291.25069,-41.061959)"
|
||||
style="fill:#5e5c64">
|
||||
<path
|
||||
id="path16"
|
||||
style="color:#000000;fill:#5e5c64;stroke-linecap:square;-inkscape-stroke:none"
|
||||
d="m 296.00007,60.838426 -15.15429,45.460934 a 1.0001,1.0001 0 0 0 -0.002,0.008 l -10.51757,31.55664 -0.72461,2.16992 -0.31641,0.94726 1.89844,0.63282 0.3164,-0.94922 0.61719,-1.85156 23.88281,-19.40625 23.88282,19.40625 0.18554,0.55468 0.5,-0.16601 a 1,1 0 0 0 0.86328,-0.28906 l 0.53321,-0.17774 -0.31446,-0.94726 -10.49414,-31.48047 v -0.004 a 1.0001,1.0001 0 0 0 -0.004,-0.008 l -0.006,-0.0195 a 1,1 0 0 0 -0.004,-0.008 z m 0,6.326172 6.58204,19.748047 h -13.16407 z m -5.23046,21.748047 h 10.46093 l -5.23047,4.40625 z m -2.25586,0.712891 5.93359,5 -10.56836,8.902344 z m 14.97461,0 4.63281,13.904294 -10.56836,-8.904294 z m -7.48829,6.308593 11.45704,9.650391 h -22.91407 z m -11.3789,11.650391 h 22.75781 l -11.37891,9.24609 z m -2.32422,0.6875 12.11719,9.84766 -21.11914,17.16015 z m 27.40625,0 9.00195,27.00781 -21.11914,-17.16015 z" />
|
||||
</g>
|
||||
<circle
|
||||
style="fill:#deddda;fill-opacity:1;stroke:none;stroke-width:1.49841;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle82"
|
||||
cx="152.28058"
|
||||
cy="56.836697"
|
||||
r="15.564472" />
|
||||
<path
|
||||
id="path1"
|
||||
style="fill:#3d3846;stroke-width:2;stroke-dasharray:2, 2"
|
||||
d="m 278,104 h 55.8457 l 8.80509,-38.153666 A 4.7730278,4.7730278 51.497589 0 0 338,60 l -44,0 a 7.5166441,7.5166441 141.40213 0 0 -7.32973,5.850797 z"
|
||||
transform="matrix(1.4984165,0,0,1.4984165,-217.43895,5.4658483)" />
|
||||
<path
|
||||
id="path2"
|
||||
style="fill:url(#linearGradient6);stroke-width:2.99683;stroke-dasharray:2.99683, 2.99683"
|
||||
d="m 148.1747,161.30117 c 0,6.62041 5.3669,11.98733 11.98733,11.98733 h 107.57109 c 7.20105,0 13.44901,-4.9706 15.06784,-11.98733 z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
id="path3"
|
||||
style="fill:#77767b;stroke-width:2.99683;stroke-dasharray:2.99683, 2.99683"
|
||||
d="m 232.08602,161.30117 c 0,6.62041 5.3669,11.98733 11.98733,11.98733 h 23.65977 c 7.20105,0 13.44901,-4.9706 15.06784,-11.98733 z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
id="path4"
|
||||
style="fill:#99c1f1;stroke-width:2;stroke-dasharray:2, 2"
|
||||
d="m 282,104 h 47.8457 l 8.70812,-38.050404 A 1.5939923,1.5939923 51.445289 0 0 337,64 h -44 a 2.5,2.5 141.34019 0 0 -2.43902,1.95122 z"
|
||||
sodipodi:nodetypes="ccccc"
|
||||
transform="matrix(1.4984165,0,0,1.4984165,-217.43895,5.4658483)" />
|
||||
<rect
|
||||
style="fill:url(#linearGradient27);stroke:none;stroke-width:2.99683;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="rect7"
|
||||
width="59.936661"
|
||||
height="65.930313"
|
||||
x="70.257019"
|
||||
y="107.35817"
|
||||
ry="6.3252244"
|
||||
rx="6.3252244" />
|
||||
<rect
|
||||
style="fill:#62a0ea;fill-opacity:1;stroke:none;stroke-width:2.99683;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="rect6"
|
||||
width="47.949329"
|
||||
height="65.930313"
|
||||
x="88.238022"
|
||||
y="107.35818"
|
||||
ry="6.3252249"
|
||||
rx="6.3252244" />
|
||||
<circle
|
||||
style="fill:#1a5fb4;fill-opacity:1;stroke:none;stroke-width:2.99683;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="circle7"
|
||||
cx="112.21269"
|
||||
cy="155.30748"
|
||||
r="11.987332" />
|
||||
<circle
|
||||
style="fill:#1a5fb4;fill-opacity:1;stroke:none;stroke-width:2.99683;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="circle8"
|
||||
cx="112.21269"
|
||||
cy="125.33916"
|
||||
r="11.987332" />
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.99683;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="path8"
|
||||
cx="112.21269"
|
||||
cy="125.33916"
|
||||
r="4.4952497" />
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.99683;stroke-linecap:round;stroke-dasharray:none"
|
||||
id="circle9"
|
||||
cx="112.21269"
|
||||
cy="155.30748"
|
||||
r="4.4952497" />
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.49841;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path22"
|
||||
cx="152.28058"
|
||||
cy="54.836697"
|
||||
r="15.564472" />
|
||||
<circle
|
||||
style="fill:#77767b;fill-opacity:1;stroke:none;stroke-width:2.99683;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle22"
|
||||
cx="152.28058"
|
||||
cy="54.836697"
|
||||
r="3.1248076" />
|
||||
<rect
|
||||
style="fill:#f6f5f4;fill-opacity:1;stroke:none;stroke-width:1.49841;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect24"
|
||||
width="14.984165"
|
||||
height="2.9968331"
|
||||
x="115.20953"
|
||||
y="177.78374"
|
||||
ry="1.4984165"
|
||||
rx="1.4984165" />
|
||||
<rect
|
||||
style="fill:#1a5fb4;fill-opacity:1;stroke:none;stroke-width:1.49841;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect23"
|
||||
width="13.485737"
|
||||
height="5.9936943"
|
||||
x="106.21901"
|
||||
y="176.28529"
|
||||
ry="2.9968472" />
|
||||
<rect
|
||||
style="fill:#c0bfbc;fill-opacity:1;stroke:none;stroke-width:1.49841;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect25"
|
||||
width="1.4984146"
|
||||
height="2.9968281"
|
||||
x="122.70161"
|
||||
y="177.78374" />
|
||||
<rect
|
||||
style="fill:#c0bfbc;fill-opacity:1;stroke:none;stroke-width:1.49841;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect26"
|
||||
width="1.4984146"
|
||||
height="2.9968281"
|
||||
x="125.69843"
|
||||
y="177.78374" />
|
||||
<circle
|
||||
style="fill:#bf61ca;fill-opacity:0.48627451;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.443622"
|
||||
id="path71"
|
||||
cx="150.07011"
|
||||
cy="33.371632"
|
||||
r="1.7915844" />
|
||||
<circle
|
||||
style="fill:#bf61ca;fill-opacity:0.48627451;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.443622"
|
||||
id="circle71"
|
||||
cx="150.07011"
|
||||
cy="26.488079"
|
||||
r="1.7915844" />
|
||||
<circle
|
||||
style="fill:#bf61ca;fill-opacity:0.48627451;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.443622"
|
||||
id="circle72"
|
||||
cx="150.07011"
|
||||
cy="19.604527"
|
||||
r="1.7915844" />
|
||||
<circle
|
||||
style="fill:#bf61ca;fill-opacity:0.48627451;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.443622"
|
||||
id="circle77"
|
||||
cx="150.07011"
|
||||
cy="12.720974"
|
||||
r="1.7915844" />
|
||||
<circle
|
||||
style="fill:#c061cb;fill-opacity:0.484565;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.443622"
|
||||
id="circle78"
|
||||
cx="154.56282"
|
||||
cy="30.071247"
|
||||
r="1.7915844" />
|
||||
<circle
|
||||
style="fill:#c061cb;fill-opacity:0.484565;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.443622"
|
||||
id="circle79"
|
||||
cx="154.56282"
|
||||
cy="23.187695"
|
||||
r="1.7915844" />
|
||||
<circle
|
||||
style="fill:#c061cb;fill-opacity:0.484565;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.443622"
|
||||
id="circle80"
|
||||
cx="154.56282"
|
||||
cy="16.304142"
|
||||
r="1.7915844" />
|
||||
<circle
|
||||
style="fill:#c061cb;fill-opacity:0.484565;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:0.443622"
|
||||
id="circle81"
|
||||
cx="154.56282"
|
||||
cy="9.4205904"
|
||||
r="1.7915844" />
|
||||
<g
|
||||
fill="#222222"
|
||||
id="g2"
|
||||
transform="matrix(1.7236266,0,-0.3679857,1.7236266,234.34039,117.54652)"
|
||||
style="fill:#62a0ea;stroke-width:0.580172">
|
||||
<path
|
||||
d="M 9.492188,0.140625 C 8.640625,-0.0234375 7.769531,-0.0429688 6.917969,0.0742188 5.21875,0.304688 3.589844,1.082031 2.316406,2.367188 -0.230469,4.933594 -0.734375,8.90625 1.085938,12.03125 c 1.824218,3.121094 5.53125,4.636719 9.019531,3.683594 3.488281,-0.949219 5.90625,-4.132813 5.890625,-7.75 0,-0.550782 -0.453125,-1 -1.003906,-0.996094 -0.550782,0.00391 -0.996094,0.453125 -0.996094,1.003906 0.01563,2.722656 -1.792969,5.097656 -4.417969,5.816406 C 6.953125,14.503906 4.1875,13.371094 2.816406,11.023438 1.445312,8.671875 1.820312,5.707031 3.738281,3.773438 5.652344,1.84375 8.613281,1.4375 10.976562,2.789062 11.453125,3.0625 12.066406,2.898438 12.339844,2.417969 12.613281,1.9375 12.449219,1.328125 11.96875,1.050781 11.183594,0.605469 10.347656,0.300781 9.492188,0.140625 Z m 0,0"
|
||||
id="path1-6"
|
||||
style="fill:#62a0ea;stroke-width:0.580172" />
|
||||
<path
|
||||
d="M 15.753906,3.65625 C 15.929688,3.457031 16.015625,3.195312 16,2.933594 15.980469,2.667969 15.859375,2.421875 15.660156,2.246094 15.460938,2.070312 15.199219,1.980469 14.933594,2 14.667969,2.015625 14.421875,2.140625 14.246094,2.339844 L 7.949219,9.535156 5.707031,7.289062 C 5.316406,6.898438 4.683594,6.898438 4.292969,7.289062 4.105469,7.476562 4,7.734375 4,8 4,8.265625 4.105469,8.519531 4.292969,8.707031 l 3,3 C 7.488281,11.902344 7.757812,12.007812 8.035156,12 8.3125,11.988281 8.570312,11.867188 8.753906,11.65625 Z m 0,0"
|
||||
id="path2-7"
|
||||
style="fill:#62a0ea;stroke-width:0.580172" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 24 KiB |
@ -30,10 +30,7 @@ export default function External({ output, builder, onWindowChange }) {
|
||||
updateColorScheme();
|
||||
stack.set_visible_child_name("close_window");
|
||||
try {
|
||||
await dbus_proxy.OpenWindowAsync(
|
||||
output.get_allocated_width(),
|
||||
output.get_allocated_height(),
|
||||
);
|
||||
await dbus_proxy.OpenWindowAsync(output.get_width(), output.get_height());
|
||||
} catch (err) {
|
||||
console.debug(err);
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ export default function Internal({
|
||||
const prop_name = prop.get_name();
|
||||
// AdwWindow and AdwApplicationWindow have child and titlebar properties but do not support setting them
|
||||
// "Using gtk_window_get_titlebar() and gtk_window_set_titlebar() is not supported and will result in a crash."
|
||||
// https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1.4/class.Window.html
|
||||
// https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1.6/class.Window.html
|
||||
// https://github.com/workbenchdev/Workbench/issues/130
|
||||
if (
|
||||
(object_preview instanceof Adw.Window ||
|
||||
@ -219,7 +219,7 @@ export default function Internal({
|
||||
}
|
||||
|
||||
css_provider = new Gtk.CssProvider();
|
||||
css_provider.load_from_data(style, -1);
|
||||
css_provider.load_from_string(style);
|
||||
Gtk.StyleContext.add_provider_for_display(
|
||||
output.get_display(),
|
||||
css_provider,
|
||||
@ -257,7 +257,7 @@ function scopeStylesheet(style, id) {
|
||||
for (const node of ast.nodes) {
|
||||
if (node.selector === "window") {
|
||||
node.selector = `#${id}`;
|
||||
} else if (node.selector) {
|
||||
} else if (!node.selector.startsWith(":")) {
|
||||
node.selector = `#${id} ${node.selector}`;
|
||||
}
|
||||
}
|
||||
@ -272,8 +272,8 @@ function scopeStylesheet(style, id) {
|
||||
|
||||
function screenshot({ widget, path }) {
|
||||
const paintable = new Gtk.WidgetPaintable({ widget });
|
||||
const width = widget.get_allocated_width();
|
||||
const height = widget.get_allocated_height();
|
||||
const width = widget.get_width();
|
||||
const height = widget.get_height();
|
||||
|
||||
const snapshot = Gtk.Snapshot.new();
|
||||
paintable.snapshot(snapshot, width, height);
|
||||
|
@ -147,9 +147,7 @@ export default function Previewer({
|
||||
panel_code.language === "JavaScript" &&
|
||||
flags & Gtk.BuilderClosureFlags.SWAPPED
|
||||
) {
|
||||
console.warning(
|
||||
'Signal flag "swapped" is unsupported in JavaScript.',
|
||||
);
|
||||
console.warn('Signal flag "swapped" is unsupported in JavaScript.');
|
||||
}
|
||||
return this[function_name] || this.noop;
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
executable('workbench-previewer-module',
|
||||
'previewer.vala',
|
||||
dependencies: [ dependency('gio-2.0'), dependency('gmodule-2.0'), dependency('libadwaita-1'), dependency('shumate-1.0'), dependency('webkitgtk-6.0') ],
|
||||
dependencies: [ dependency('gtksourceview-5'), dependency('gmodule-2.0'), dependency('libadwaita-1'), dependency('shumate-1.0'), dependency('webkitgtk-6.0'), libworkbench_vapi ],
|
||||
# vala_args: [ '--gresourcesdir=' + meson.current_build_dir() ],
|
||||
install: true,
|
||||
link_with: libworkbench,
|
||||
)
|
||||
|
||||
executable('workbench-crasher',
|
||||
|
@ -6,19 +6,20 @@ namespace Workbench {
|
||||
this.notify["ColorScheme"].connect (() => {
|
||||
this.style_manager.color_scheme = this.ColorScheme;
|
||||
});
|
||||
|
||||
// See application.js
|
||||
var icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default());
|
||||
string[] resource_path = {"/org/gtk/libgtk/icons/", "/org/gnome/Adwaita/icons/", "/re/sonny/Workbench/icons/"};
|
||||
icon_theme.resource_path = resource_path;
|
||||
string [] search_path = {"/usr/share/icons", "/app/share/icons"};
|
||||
icon_theme.search_path = search_path;
|
||||
}
|
||||
|
||||
private void ensure_window () {
|
||||
if (this.window != null) {
|
||||
return;
|
||||
}
|
||||
var window = new Gtk.Window () {
|
||||
// Ensure the header bar has the same height as the one on Workbench main window
|
||||
titlebar = new Gtk.HeaderBar (),
|
||||
title = "Preview",
|
||||
default_width = 600,
|
||||
default_height = 800
|
||||
};
|
||||
var window = new Workbench.PreviewWindow ();
|
||||
this.set_window (window);
|
||||
}
|
||||
|
||||
@ -37,8 +38,8 @@ namespace Workbench {
|
||||
public bool screenshot (string path) {
|
||||
Gtk.Widget widget = this.target;
|
||||
var paintable = new Gtk.WidgetPaintable (widget);
|
||||
int width = widget.get_allocated_width ();
|
||||
int height = widget.get_allocated_height ();
|
||||
int width = widget.get_width ();
|
||||
int height = widget.get_height ();
|
||||
var snapshot = new Gtk.Snapshot ();
|
||||
paintable.snapshot (snapshot, width, height);
|
||||
Gsk.RenderNode? node = snapshot.to_node ();
|
||||
@ -83,7 +84,7 @@ namespace Workbench {
|
||||
// Not a Root/Window
|
||||
if (!(target is Gtk.Root)) {
|
||||
this.ensure_window ();
|
||||
this.window.child = target;
|
||||
((Workbench.PreviewWindow) this.window).set_content (target);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -124,7 +125,7 @@ namespace Workbench {
|
||||
var end = section.get_end_location ();
|
||||
this.css_parser_error (error.message, (int) start.lines, (int) start.line_chars, (int) end.lines, (int) end.line_chars);
|
||||
});
|
||||
this.css.load_from_data (content.data);
|
||||
this.css.load_from_string (content);
|
||||
Gtk.StyleContext.add_provider_for_display (
|
||||
Gdk.Display.get_default (),
|
||||
this.css,
|
||||
@ -142,6 +143,8 @@ namespace Workbench {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reload_icons (uri);
|
||||
|
||||
void* function;
|
||||
|
||||
this.module.symbol ("set_base_uri", out function);
|
||||
@ -169,6 +172,17 @@ namespace Workbench {
|
||||
main_function ();
|
||||
}
|
||||
|
||||
public async void reload_icons (string uri) {
|
||||
if (this.resource_icons != null) {
|
||||
this.resource_icons._unregister ();
|
||||
this.resource_icons = null;
|
||||
}
|
||||
try {
|
||||
this.resource_icons = Resource.load (File.new_for_uri(uri).get_child("icons.gresource").get_path());
|
||||
this.resource_icons._register ();
|
||||
} catch {}
|
||||
}
|
||||
|
||||
public void close_window () {
|
||||
if (this.window == null) {
|
||||
return;
|
||||
@ -211,6 +225,7 @@ namespace Workbench {
|
||||
private Module module;
|
||||
private Gtk.Builder? builder = null;
|
||||
private Adw.StyleManager style_manager = Adw.StyleManager.get_default ();
|
||||
private GLib.Resource? resource_icons = null;
|
||||
}
|
||||
|
||||
void main (string[] args) {
|
||||
@ -219,6 +234,11 @@ namespace Workbench {
|
||||
Process.exit (1);
|
||||
}
|
||||
|
||||
var app_id = GLib.Environment.get_variable("FLATPAK_ID");
|
||||
var resource = Resource.load (@"/app/share/$app_id/re.sonny.Workbench.libworkbench.gresource");
|
||||
GLib.resources_register (resource);
|
||||
|
||||
|
||||
var loop = new MainLoop ();
|
||||
|
||||
Adw.init ();
|
||||
|
@ -28,6 +28,8 @@ export function isPreviewable(class_name) {
|
||||
const klass = getObjectClass(class_name);
|
||||
if (!klass) return false;
|
||||
|
||||
if (GObject.type_is_a(klass, Adw.Dialog)) return false;
|
||||
|
||||
// GLib-GObject-ERROR: cannot create instance of abstract (non-instantiatable) type 'GtkWidget'
|
||||
if (GObject.type_test_flags(klass, GObject.TypeFlags.ABSTRACT)) return false;
|
||||
|
||||
@ -56,7 +58,7 @@ function getKlass(el) {
|
||||
return getObjectClass(class_name);
|
||||
}
|
||||
|
||||
function assertObjectBuildable(el_object, root) {
|
||||
function assertObjectBuildable(el_object, is_root) {
|
||||
const klass = getKlass(el_object);
|
||||
if (klass) {
|
||||
// GLib-GObject-ERROR: cannot create instance of abstract (non-instantiatable) type 'GtkWidget'
|
||||
@ -76,9 +78,16 @@ function assertObjectBuildable(el_object, root) {
|
||||
}
|
||||
|
||||
// Gtk:ERROR:../gtk/gtkwidget.c:2448:gtk_widget_root: assertion failed: (priv->root == NULL)
|
||||
if (!root && GObject.type_is_a(klass, Gtk.Root)) {
|
||||
if (!is_root && GObject.type_is_a(klass, Gtk.Root)) {
|
||||
throw new Error(
|
||||
`${klass.$gtype.name} is a GtkRoot. GtkRoot objects can only appear at the top-level.`,
|
||||
`${klass.$gtype.name} is a GtkRoot. GtkRoot objects can only be used at the top-level.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Adwaita-Trying to add AdwDialog 0x558667ff74d0 to GtkBox 0x558666bd17c0. Use adw_dialog_present() to show dialogs.
|
||||
if (!is_root && GObject.type_is_a(klass, Adw.Dialog)) {
|
||||
throw new Error(
|
||||
`${klass.$gtype.name} is a AdwDialog. AdwDialog objects can only be used at the top-level.`,
|
||||
);
|
||||
}
|
||||
|
||||
@ -101,7 +110,6 @@ function assertObjectBuildable(el_object, root) {
|
||||
`${klass.$gtype.name} does not support the child property.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Gtk-ERROR **: 23:19:54.204: GtkStackPage '<unnamed>' [0x55b094802eb0] is missing a child widget
|
||||
if (GObject.type_is_a(klass, Gtk.StackPage)) {
|
||||
@ -111,6 +119,7 @@ function assertObjectBuildable(el_object, root) {
|
||||
throw new Error(`${klass.$gtype.name} is missing a child widget.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const child_property = getChildProperty(el_object);
|
||||
if (child_property) {
|
||||
@ -164,7 +173,7 @@ function getNamespaces() {
|
||||
|
||||
function getSearchPathNamespaces(search_path) {
|
||||
const enumerator = Gio.File.new_for_path(search_path).enumerate_children(
|
||||
"standard::name",
|
||||
`${Gio.FILE_ATTRIBUTE_STANDARD_NAME},${Gio.FILE_ATTRIBUTE_STANDARD_IS_HIDDEN}`,
|
||||
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
|
||||
null,
|
||||
);
|
||||
@ -172,6 +181,7 @@ function getSearchPathNamespaces(search_path) {
|
||||
const namespaces = [];
|
||||
|
||||
for (const file_info of enumerator) {
|
||||
if (file_info.get_is_hidden()) continue;
|
||||
const name = file_info.get_name();
|
||||
if (!name.endsWith(".typelib")) continue;
|
||||
const [namespace] = name.split("-");
|
||||
|
@ -12,8 +12,7 @@ class WorkbenchHoverProvider extends GObject.Object {
|
||||
}
|
||||
|
||||
findDiagnostics(context) {
|
||||
const iter = new Gtk.TextIter();
|
||||
context.get_iter(iter);
|
||||
const [, iter] = context.get_iter();
|
||||
|
||||
const line = iter.get_line();
|
||||
// Looks like line_offset starts at 0
|
||||
|
18
src/about.js
@ -8,7 +8,7 @@ import {
|
||||
getGjsVersion,
|
||||
getGLibVersion,
|
||||
} from "../troll/src/util.js";
|
||||
import { getFlatpakInfo } from "./util.js";
|
||||
import { getFlatpakInfo } from "./flatpak.js";
|
||||
|
||||
export default function About({ application }) {
|
||||
const flatpak_info = getFlatpakInfo();
|
||||
@ -26,16 +26,15 @@ ${getValaVersion()}
|
||||
${getBlueprintVersion()}
|
||||
`.trim();
|
||||
|
||||
const dialog = new Adw.AboutWindow({
|
||||
transient_for: application.get_active_window(),
|
||||
const dialog = new Adw.AboutDialog({
|
||||
application_name: "Workbench",
|
||||
developer_name: "Sonny Piers",
|
||||
copyright: "© 2022 Sonny Piers",
|
||||
license_type: Gtk.License.GPL_3_0_ONLY,
|
||||
version: pkg.version,
|
||||
website: "https://apps.gnome.org/Workbench",
|
||||
website: "https://workbench.sonny.re",
|
||||
application_icon: pkg.name,
|
||||
issue_url: "https://github.com/workbenchdev/Workbench/issues",
|
||||
issue_url: "https://workbench.sonny.re/feedback",
|
||||
debug_info,
|
||||
developers: [
|
||||
"Sonny Piers https://sonny.re",
|
||||
@ -82,6 +81,11 @@ ${getBlueprintVersion()}
|
||||
"Urtsi Santsi <urtsi.santsi@proton.me>",
|
||||
"Roland Lötscher https://github.com/rolandlo",
|
||||
"Gregor Niehl https://fosstodon.org/@gregorni",
|
||||
"Jamie Gravendeel https://jamie.garden",
|
||||
"Bharat Tyagi https://github.com/BharatAtbrat",
|
||||
"Jan Fooken https://git.janvhs.com",
|
||||
"Vladimir Vaskov https://github.com/Rirusha",
|
||||
"Nokse https://github.com/Nokse22",
|
||||
// Add yourself as
|
||||
// "John Doe",
|
||||
// or
|
||||
@ -89,7 +93,7 @@ ${getBlueprintVersion()}
|
||||
// or
|
||||
// "John Doe https://john.com",
|
||||
]);
|
||||
dialog.present();
|
||||
dialog.present(application.active_window);
|
||||
|
||||
return { dialog };
|
||||
}
|
||||
@ -100,5 +104,5 @@ function getValaVersion() {
|
||||
}
|
||||
|
||||
function getBlueprintVersion() {
|
||||
return "Blueprint 80aaee37";
|
||||
return "Blueprint 0.16.0";
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
import Gtk from "gi://Gtk";
|
||||
import Gio from "gi://Gio";
|
||||
import GLib from "gi://GLib";
|
||||
import Gdk from "gi://Gdk";
|
||||
import Xdp from "gi://Xdp";
|
||||
import XdpGtk from "gi://XdpGtk4";
|
||||
|
||||
import About from "./about.js";
|
||||
import Window from "./window.js";
|
||||
import { portal, settings } from "./util.js";
|
||||
|
||||
import IconLibrary from "./IconLibrary/main.js";
|
||||
import { createSession } from "./sessions.js";
|
||||
|
||||
export default function Actions({ application }) {
|
||||
const quit = new Gio.SimpleAction({
|
||||
@ -30,38 +29,16 @@ export default function Actions({ application }) {
|
||||
});
|
||||
application.add_action(showAboutDialog);
|
||||
|
||||
const action_icon_library = new Gio.SimpleAction({
|
||||
name: "icon_library",
|
||||
});
|
||||
let window_icon_browser;
|
||||
action_icon_library.connect("activate", (_self, _target) => {
|
||||
window_icon_browser ??= IconLibrary();
|
||||
window_icon_browser.present();
|
||||
});
|
||||
application.add_action(action_icon_library);
|
||||
|
||||
const action_open_uri = new Gio.SimpleAction({
|
||||
name: "open_uri",
|
||||
parameter_type: new GLib.VariantType("s"),
|
||||
});
|
||||
action_open_uri.connect("activate", (_self, target) => {
|
||||
// This is not using the portal but we silence the GVFS warnings
|
||||
// in `log_handler.js`
|
||||
Gtk.show_uri(
|
||||
application.get_active_window(),
|
||||
target.unpack(),
|
||||
Gdk.CURRENT_TIME,
|
||||
);
|
||||
// an other option is to use libportal:
|
||||
// const parent = XdpGtk.parent_new_gtk(application.get_active_window());
|
||||
// portal
|
||||
// .open_uri(
|
||||
// parent,
|
||||
// target.unpack(),
|
||||
// Xdp.OpenUriFlags.NONE,
|
||||
// null, // cancellable
|
||||
// )
|
||||
// .catch(console.error);
|
||||
new Gtk.UriLauncher({
|
||||
uri: target.unpack(),
|
||||
})
|
||||
.launch(application.get_active_window(), null)
|
||||
.catch(console.error);
|
||||
});
|
||||
application.add_action(action_open_uri);
|
||||
|
||||
@ -90,6 +67,15 @@ export default function Actions({ application }) {
|
||||
// application.add_action(settings.create_action("safe-mode"));
|
||||
// application.add_action(settings.create_action("auto-preview"));
|
||||
|
||||
const action_new_project = new Gio.SimpleAction({
|
||||
name: "new",
|
||||
});
|
||||
action_new_project.connect("activate", (_self, _target) => {
|
||||
newProject({ application }).catch(console.error);
|
||||
});
|
||||
application.add_action(action_new_project);
|
||||
application.set_accels_for_action("app.new", ["<Control>N"]);
|
||||
|
||||
const action_open_file = new Gio.SimpleAction({
|
||||
name: "open",
|
||||
parameter_type: new GLib.VariantType("s"),
|
||||
@ -122,6 +108,12 @@ async function showScreenshot({ application, uri }) {
|
||||
);
|
||||
}
|
||||
|
||||
async function newProject({ application }) {
|
||||
const session = createSession();
|
||||
const { load } = Window({ application, session });
|
||||
await load();
|
||||
}
|
||||
|
||||
async function open({ application, hint }) {
|
||||
const file_dialog = new Gtk.FileDialog();
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
import Adw from "gi://Adw";
|
||||
import Gio from "gi://Gio";
|
||||
import Gtk from "gi://Gtk";
|
||||
import Gdk from "gi://Gdk";
|
||||
|
||||
import Window from "./window.js";
|
||||
import Actions from "./actions.js";
|
||||
import { settings, data_dir, ensureDir } from "./util.js";
|
||||
import { overrides } from "./overrides.js";
|
||||
import Library, { getDemo } from "./Library/Library.js";
|
||||
import Extensions from "./Extensions/Extensions.js";
|
||||
import {
|
||||
Session,
|
||||
addToRecentProjects,
|
||||
@ -15,6 +16,35 @@ import {
|
||||
} from "./sessions.js";
|
||||
import ShortcutsWindow from "./shortcutsWindow.js";
|
||||
|
||||
import "./icons/re.sonny.Workbench-beaker.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-code-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-placeholder-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-preview-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-ui-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-screenshot-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-multitasking-windows-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-down-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-eraser4-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-larger-brush-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-terminal-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-test-pass-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-up-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-library-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-gamepad-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-network-wireless-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-person-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-speakers-symbolic.svg" with { type: "icon" };
|
||||
import "./icons/re.sonny.Workbench-external-link-symbolic.svg" with { type: "icon" };
|
||||
|
||||
const icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default());
|
||||
icon_theme.resource_path = [
|
||||
"/org/gtk/libgtk/icons/",
|
||||
"/org/gnome/Adwaita/icons/",
|
||||
"/re/sonny/Workbench/icons/",
|
||||
];
|
||||
// Remove hosts and useless search paths
|
||||
icon_theme.search_path = ["/usr/share/icons", "/app/share/icons"];
|
||||
|
||||
ensureDir(data_dir);
|
||||
|
||||
const application = new Adw.Application({
|
||||
@ -39,23 +69,39 @@ application.connect("open", (_self, files, hint) => {
|
||||
load().catch(console.error);
|
||||
});
|
||||
|
||||
application.connect("startup", () => {
|
||||
Library({
|
||||
application,
|
||||
});
|
||||
let proc_biome;
|
||||
|
||||
Extensions({
|
||||
application.connect("startup", () => {
|
||||
// biome lsp-proxy starts a background server
|
||||
// it does not get stopped and leaves a process hanging
|
||||
// so manage it manually instead
|
||||
// See https://github.com/workbenchdev/Workbench/issues/828
|
||||
const subprocess_launcher = Gio.SubprocessLauncher.new(
|
||||
Gio.SubprocessFlags.STDERR_SILENCE,
|
||||
);
|
||||
proc_biome = subprocess_launcher.spawnv([
|
||||
"biome",
|
||||
"__run_server",
|
||||
"--config-path",
|
||||
pkg.pkgdatadir,
|
||||
]);
|
||||
|
||||
Library({
|
||||
application,
|
||||
});
|
||||
|
||||
ShortcutsWindow({ application });
|
||||
|
||||
restoreSessions();
|
||||
restoreSessions().catch(console.error);
|
||||
});
|
||||
|
||||
application.connect("shutdown", () => {
|
||||
proc_biome?.force_exit();
|
||||
});
|
||||
|
||||
application.connect("activate", () => {
|
||||
if (application.is_remote) {
|
||||
bootstrap();
|
||||
bootstrap().catch(console.error);
|
||||
}
|
||||
});
|
||||
|
||||
@ -75,14 +121,11 @@ function setColorScheme() {
|
||||
setColorScheme();
|
||||
settings.connect("changed::color-scheme", setColorScheme);
|
||||
|
||||
// We are not using async otherwise the app segfaults
|
||||
// does not like opening a window in a promise
|
||||
// TODO: make a reproducer and file a GJS bug
|
||||
function restoreSessions() {
|
||||
const sessions = getSessions();
|
||||
async function restoreSessions() {
|
||||
const sessions = await getSessions();
|
||||
|
||||
if (sessions.length < 1) {
|
||||
bootstrap();
|
||||
bootstrap().catch(console.error);
|
||||
} else {
|
||||
sessions.forEach((session) => {
|
||||
const { load } = Window({
|
||||
@ -94,7 +137,7 @@ function restoreSessions() {
|
||||
}
|
||||
}
|
||||
|
||||
function bootstrap() {
|
||||
async function bootstrap() {
|
||||
const first_run = settings.get_boolean("first-run");
|
||||
if (!first_run) {
|
||||
application.activate_action("library", null);
|
||||
@ -102,7 +145,7 @@ function bootstrap() {
|
||||
}
|
||||
|
||||
const demo = getDemo("Welcome");
|
||||
const session = createSessionFromDemo(demo);
|
||||
const session = await createSessionFromDemo(demo);
|
||||
const { load, window } = Window({
|
||||
application,
|
||||
session,
|
||||
|
@ -1,7 +1,6 @@
|
||||
#!@GJS@ -m
|
||||
|
||||
import { exit, programArgs } from "system";
|
||||
import GLib from "gi://GLib";
|
||||
import { setConsoleLogDomain } from "console";
|
||||
import Xdp from "gi://Xdp";
|
||||
|
||||
@ -14,7 +13,6 @@ imports.package.init({
|
||||
datadir: "@datadir@",
|
||||
});
|
||||
setConsoleLogDomain(pkg.name);
|
||||
GLib.set_application_name("Workbench");
|
||||
|
||||
if (!Xdp.Portal.running_under_flatpak()) {
|
||||
console.error(
|
||||
|
@ -8,5 +8,5 @@ It exposes the formatter and linter used in Workbench for the different language
|
||||
|
||||
```sh
|
||||
make cli
|
||||
./build-aux/fun workbench-cli ci demos/demos/*
|
||||
./build-aux/fun workbench-cli ci demos/src/*
|
||||
```
|
||||
|
97
src/cli/blueprint.js
Normal file
@ -0,0 +1,97 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import Gtk from "gi://Gtk";
|
||||
|
||||
import { getLanguage } from "../common.js";
|
||||
import { parse } from "../langs/xml/xml.js";
|
||||
import { LSPError } from "../lsp/LSP.js";
|
||||
import { checkFile, diagnose } from "./util.js";
|
||||
|
||||
const languageId = "blueprint";
|
||||
|
||||
export default async function blueprint({ file, lspc }) {
|
||||
print(` ${file.get_path()}`);
|
||||
|
||||
await diagnose({
|
||||
file,
|
||||
lspc,
|
||||
languageId,
|
||||
filter(diagnostic) {
|
||||
// No replacements yet
|
||||
return ![
|
||||
"Gtk.ShortcutsShortcut is deprecated\nhint: This widget will be removed in GTK 5",
|
||||
"Gtk.ShortcutLabel is deprecated\nhint: This widget will be removed in GTK 5",
|
||||
"Gtk.ShortcutsWindow is deprecated\nhint: This widget will be removed in GTK 5",
|
||||
"Gtk.ShortcutsGroup is deprecated\nhint: This widget will be removed in GTK 5",
|
||||
"Gtk.ShortcutsSection is deprecated\nhint: This widget will be removed in GTK 5",
|
||||
].includes(diagnostic.message);
|
||||
},
|
||||
});
|
||||
|
||||
const { xml } = await lspc._request("textDocument/x-blueprint-compile", {
|
||||
textDocument: {
|
||||
uri: file.get_uri(),
|
||||
},
|
||||
});
|
||||
|
||||
print(` ✅ compiles`);
|
||||
|
||||
try {
|
||||
await lspc._request("x-blueprint/decompile", {
|
||||
text: xml,
|
||||
});
|
||||
print(" ✅ decompiles");
|
||||
} catch (err) {
|
||||
if (!(err instanceof LSPError)) throw err;
|
||||
if (
|
||||
![
|
||||
// https://gitlab.gnome.org/jwestman/blueprint-compiler/-/issues/128
|
||||
"unsupported XML tag: <condition>",
|
||||
// https://gitlab.gnome.org/jwestman/blueprint-compiler/-/issues/139
|
||||
"unsupported XML tag: <items>",
|
||||
].includes(err.message)
|
||||
) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
await checkFile({
|
||||
lspc,
|
||||
file,
|
||||
lang: getLanguage(languageId),
|
||||
uri: file.get_uri(),
|
||||
});
|
||||
|
||||
await lspc._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri: file.get_uri(),
|
||||
},
|
||||
});
|
||||
|
||||
const tree = parse(xml);
|
||||
const template_el = tree.getChild("template");
|
||||
|
||||
let template;
|
||||
const builder = new Gtk.Builder();
|
||||
const blueprint_object_ids = [];
|
||||
|
||||
if (template_el) {
|
||||
template = tree.toString();
|
||||
} else {
|
||||
builder.add_from_string(xml, -1);
|
||||
print(` ✅ instantiates`);
|
||||
getXMLObjectIds(tree, blueprint_object_ids);
|
||||
}
|
||||
|
||||
return { template, builder, blueprint_object_ids };
|
||||
}
|
||||
|
||||
function getXMLObjectIds(tree, object_ids) {
|
||||
for (const object of tree.getChildren("object")) {
|
||||
if (object.attrs.id) object_ids.push(object.attrs.id);
|
||||
// <child> or <property name="child">
|
||||
for (const child of object.getChildElements()) {
|
||||
getXMLObjectIds(child, object_ids);
|
||||
}
|
||||
}
|
||||
}
|
25
src/cli/css.js
Normal file
@ -0,0 +1,25 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import { getLanguage } from "../common.js";
|
||||
import { checkFile, diagnose } from "./util.js";
|
||||
|
||||
const languageId = "css";
|
||||
|
||||
export default async function css({ file, lspc }) {
|
||||
print(` ${file.get_path()}`);
|
||||
|
||||
await diagnose({ file, lspc, languageId });
|
||||
|
||||
await checkFile({
|
||||
lspc,
|
||||
file,
|
||||
lang: getLanguage(languageId),
|
||||
uri: file.get_uri(),
|
||||
});
|
||||
|
||||
await lspc._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri: file.get_uri(),
|
||||
},
|
||||
});
|
||||
}
|
56
src/cli/javascript.js
Normal file
@ -0,0 +1,56 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import { getLanguage } from "../common.js";
|
||||
import { checkFile, getCodeObjectIds, diagnose, Interrupt } from "./util.js";
|
||||
|
||||
const languageId = "javascript";
|
||||
|
||||
export default async function javascript({
|
||||
file,
|
||||
lspc,
|
||||
blueprint_object_ids,
|
||||
demo_dir,
|
||||
application,
|
||||
builder,
|
||||
template,
|
||||
window,
|
||||
}) {
|
||||
print(` ${file.get_path()}`);
|
||||
|
||||
const text = await diagnose({ file, lspc, languageId });
|
||||
|
||||
await checkFile({
|
||||
lspc: lspc,
|
||||
file: file,
|
||||
lang: getLanguage("javascript"),
|
||||
uri: file.get_uri(),
|
||||
});
|
||||
|
||||
const js_object_ids = getCodeObjectIds(text);
|
||||
for (const object_id of js_object_ids) {
|
||||
if (!blueprint_object_ids.includes(object_id)) {
|
||||
print(` ❌ Reference to inexistant object id "${object_id}"`);
|
||||
throw new Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.workbench = {
|
||||
window,
|
||||
application,
|
||||
builder,
|
||||
template,
|
||||
resolve(path) {
|
||||
return demo_dir.resolve_relative_path(path).get_uri();
|
||||
},
|
||||
preview() {},
|
||||
};
|
||||
|
||||
await import(`file://${file.get_path()}`);
|
||||
print(" ✅ runs");
|
||||
|
||||
await lspc._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri: file.get_uri(),
|
||||
},
|
||||
});
|
||||
}
|
@ -4,6 +4,7 @@ import Gio from "gi://Gio";
|
||||
|
||||
import { formatting } from "./format.js";
|
||||
import { diagnostic_severities } from "../lsp/LSP.js";
|
||||
import { waitForDiagnostics } from "./util.js";
|
||||
|
||||
export default async function lint({ filenames, lang, lspc, ci }) {
|
||||
let success = true;
|
||||
@ -47,19 +48,6 @@ export default async function lint({ filenames, lang, lspc, ci }) {
|
||||
return success;
|
||||
}
|
||||
|
||||
export function waitForDiagnostics({ uri, lspc }) {
|
||||
return new Promise((resolve) => {
|
||||
const handler_id = lspc.connect(
|
||||
"notification::textDocument/publishDiagnostics",
|
||||
(_self, params) => {
|
||||
if (uri !== params.uri) return;
|
||||
lspc.disconnect(handler_id);
|
||||
resolve(params.diagnostics);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function serializeDiagnostics({ file, diagnostics }) {
|
||||
return (
|
||||
`\n${file.get_path()}\n` +
|
||||
|
463
src/cli/main.js
@ -5,22 +5,42 @@ import "../init.js";
|
||||
|
||||
import GLib from "gi://GLib";
|
||||
import Gio from "gi://Gio";
|
||||
import Gtk from "gi://Gtk";
|
||||
import Adw from "gi://Adw";
|
||||
import GObject from "gi://GObject";
|
||||
import Shumate from "gi://Shumate";
|
||||
import WebKit from "gi://WebKit";
|
||||
|
||||
import { createLSPClient, languages, getLanguage } from "../common.js";
|
||||
import lint, { waitForDiagnostics } from "./lint.js";
|
||||
import format, { formatting } from "./format.js";
|
||||
import { createLSPClient, languages, PYTHON_LSP_CONFIG } from "../common.js";
|
||||
import lint from "./lint.js";
|
||||
import format from "./format.js";
|
||||
|
||||
Gtk.init();
|
||||
import blueprint from "./blueprint.js";
|
||||
import css from "./css.js";
|
||||
import javascript from "./javascript.js";
|
||||
import typescript from "./typescript.js";
|
||||
import vala from "./vala.js";
|
||||
import python from "./python.js";
|
||||
import rust from "./rust.js";
|
||||
import { Interrupt } from "./util.js";
|
||||
|
||||
GObject.type_ensure(Shumate.SimpleMap);
|
||||
GObject.type_ensure(WebKit.WebView);
|
||||
|
||||
export async function main([action, ...args]) {
|
||||
const current_dir = Gio.File.new_for_path(GLib.get_current_dir());
|
||||
|
||||
if (action === "ci") {
|
||||
const filenames = args;
|
||||
const success = await ci({ filenames, current_dir });
|
||||
return success ? 0 : 1;
|
||||
try {
|
||||
await ci({ filenames });
|
||||
return 0;
|
||||
} catch (err) {
|
||||
if (err instanceof Interrupt) {
|
||||
return 1;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const [language_id, ...filenames] = args;
|
||||
@ -31,12 +51,10 @@ export async function main([action, ...args]) {
|
||||
}
|
||||
|
||||
if (lang.id === "vala") {
|
||||
const api_file = (
|
||||
GLib.getenv("FLATPAK_ID")
|
||||
? Gio.File.new_for_path(pkg.pkgdatadir)
|
||||
: current_dir.resolve_relative_path("src/langs/vala")
|
||||
).get_child("workbench.vala");
|
||||
api_file.copy(
|
||||
const file_api = Gio.File.new_for_path(pkg.pkgdatadir).get_child(
|
||||
"workbench.vala",
|
||||
);
|
||||
file_api.copy(
|
||||
current_dir.get_child("workbench.vala"),
|
||||
Gio.FileCopyFlags.OVERWRITE,
|
||||
null,
|
||||
@ -51,34 +69,49 @@ export async function main([action, ...args]) {
|
||||
lspc._start_process();
|
||||
await lspc._initialize();
|
||||
|
||||
let success = false;
|
||||
if (lang.id === "python") {
|
||||
await lspc._request("workspace/didChangeConfiguration", {
|
||||
settings: PYTHON_LSP_CONFIG,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
if (action === "lint") {
|
||||
success = await lint({ filenames, lang, lspc, ci: false });
|
||||
await lint({ filenames, lang, lspc, ci: false });
|
||||
return 0;
|
||||
} else if (action === "check") {
|
||||
success = await lint({ filenames, lang, lspc, ci: true });
|
||||
await lint({ filenames, lang, lspc, ci: true });
|
||||
return 0;
|
||||
} else if (action === "format") {
|
||||
success = await format({ filenames, lang, lspc });
|
||||
await format({ filenames, lang, lspc });
|
||||
return 0;
|
||||
} else {
|
||||
printerr(`Unknown action "${action}"}`);
|
||||
return 1;
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof Interrupt) {
|
||||
return 1;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
return success ? 0 : 1;
|
||||
}
|
||||
|
||||
import { parse } from "../langs/xml/xml.js";
|
||||
import Shumate from "gi://Shumate";
|
||||
import { LSPError, diagnostic_severities } from "../lsp/LSP.js";
|
||||
|
||||
// Why?
|
||||
new Shumate.Map();
|
||||
|
||||
const application = new Adw.Application();
|
||||
const window = new Adw.ApplicationWindow();
|
||||
|
||||
function createLSPClients({ root_uri }) {
|
||||
return Object.fromEntries(
|
||||
["javascript", "blueprint", "css", "vala"].map((id) => {
|
||||
[
|
||||
"javascript",
|
||||
"blueprint",
|
||||
"css",
|
||||
"vala",
|
||||
"rust",
|
||||
"python",
|
||||
"typescript",
|
||||
].map((id) => {
|
||||
const lang = languages.find((language) => language.id === id);
|
||||
const lspc = createLSPClient({
|
||||
lang,
|
||||
@ -90,31 +123,20 @@ function createLSPClients({ root_uri }) {
|
||||
);
|
||||
}
|
||||
|
||||
async function checkFile({ lspc, file, lang, uri }) {
|
||||
const [contents] = await file.load_contents_async(null);
|
||||
const text = new TextDecoder().decode(contents);
|
||||
const buffer = new Gtk.TextBuffer({ text });
|
||||
|
||||
const buffer_tmp = new Gtk.TextBuffer({ text: buffer.text });
|
||||
await formatting({ buffer: buffer_tmp, uri, lang, lspc });
|
||||
|
||||
if (buffer_tmp.text === buffer.text) {
|
||||
print(` ✅ checks`);
|
||||
return true;
|
||||
} else {
|
||||
printerr(
|
||||
` ❌ formatting differs - open and run ${file
|
||||
.get_parent()
|
||||
.get_basename()} with Workbench to fix`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function ci({ filenames, current_dir }) {
|
||||
async function ci({ filenames }) {
|
||||
for (const filename of filenames) {
|
||||
const demo_dir = Gio.File.new_for_path(filename);
|
||||
|
||||
print(`\n📂${demo_dir.get_path()}`);
|
||||
|
||||
const [compatible, required_runtime_version] = isDemoCompatible(demo_dir);
|
||||
if (!compatible) {
|
||||
print(
|
||||
` ⚠️ skipped - requires runtime version ${required_runtime_version}`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const lsp_clients = createLSPClients({ root_uri: demo_dir.get_uri() });
|
||||
await Promise.all(
|
||||
Object.entries(lsp_clients).map(([, lspc]) => {
|
||||
@ -122,282 +144,64 @@ async function ci({ filenames, current_dir }) {
|
||||
}),
|
||||
);
|
||||
|
||||
print(`\n📂${demo_dir.get_path()}`);
|
||||
|
||||
let template = null;
|
||||
const builder = new Gtk.Builder();
|
||||
const blueprint_object_ids = [];
|
||||
let xml = null;
|
||||
let builder = null;
|
||||
let blueprint_object_ids = null;
|
||||
|
||||
const file_blueprint = demo_dir.get_child("main.blp");
|
||||
if (file_blueprint.query_exists(null)) {
|
||||
print(` ${file_blueprint.get_path()}`);
|
||||
const uri = file_blueprint.get_uri();
|
||||
const languageId = "blueprint";
|
||||
let version = 0;
|
||||
|
||||
const [contents] = await file_blueprint.load_contents_async(null);
|
||||
const text = new TextDecoder().decode(contents);
|
||||
|
||||
await lsp_clients.blueprint._notify("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri,
|
||||
languageId,
|
||||
version: version++,
|
||||
text,
|
||||
},
|
||||
});
|
||||
|
||||
let diagnostics = await waitForDiagnostics({
|
||||
uri,
|
||||
lspc: lsp_clients.blueprint,
|
||||
});
|
||||
|
||||
diagnostics = diagnostics.filter((diagnostic) => {
|
||||
return !diagnostic.message.startsWith(
|
||||
// https://github.com/workbenchdev/demos/issues/42
|
||||
"Adw.ViewSwitcherTitle is deprecated",
|
||||
);
|
||||
});
|
||||
|
||||
if (diagnostics.length > 0) {
|
||||
printerr(serializeDiagnostics({ diagnostics }));
|
||||
return false;
|
||||
}
|
||||
|
||||
print(` ✅ lints`);
|
||||
|
||||
({ xml } = await lsp_clients.blueprint._request(
|
||||
"textDocument/x-blueprint-compile",
|
||||
{
|
||||
textDocument: {
|
||||
uri,
|
||||
},
|
||||
},
|
||||
));
|
||||
|
||||
print(` ✅ compiles`);
|
||||
|
||||
try {
|
||||
await lsp_clients.blueprint._request("x-blueprint/decompile", {
|
||||
text: xml,
|
||||
});
|
||||
print(" ✅ decompiles");
|
||||
} catch (err) {
|
||||
if (!(err instanceof LSPError)) throw err;
|
||||
if (
|
||||
![
|
||||
// https://gitlab.gnome.org/jwestman/blueprint-compiler/-/issues/128
|
||||
"unsupported XML tag: <condition>",
|
||||
// https://gitlab.gnome.org/jwestman/blueprint-compiler/-/issues/139
|
||||
"unsupported XML tag: <items>",
|
||||
].includes(err.message)
|
||||
) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const checks = await checkFile({
|
||||
lspc: lsp_clients.blueprint,
|
||||
({ template, builder, blueprint_object_ids } = await blueprint({
|
||||
file: file_blueprint,
|
||||
lang: getLanguage("blueprint"),
|
||||
uri,
|
||||
});
|
||||
if (!checks) return false;
|
||||
|
||||
await lsp_clients.blueprint._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri,
|
||||
},
|
||||
});
|
||||
|
||||
const tree = parse(xml);
|
||||
const template_el = tree.getChild("template");
|
||||
|
||||
if (template_el) {
|
||||
template = tree.toString();
|
||||
} else {
|
||||
builder.add_from_string(xml, -1);
|
||||
print(` ✅ instantiates`);
|
||||
getXMLObjectIds(tree, blueprint_object_ids);
|
||||
}
|
||||
lspc: lsp_clients.blueprint,
|
||||
}));
|
||||
}
|
||||
|
||||
const file_css = demo_dir.get_child("main.css");
|
||||
if (file_css.query_exists(null)) {
|
||||
print(` ${file_css.get_path()}`);
|
||||
|
||||
const uri = file_css.get_uri();
|
||||
const languageId = "css";
|
||||
let version = 0;
|
||||
|
||||
const [contents] = await file_css.load_contents_async(null);
|
||||
const text = new TextDecoder().decode(contents);
|
||||
|
||||
await lsp_clients.css._notify("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri,
|
||||
languageId,
|
||||
version: version++,
|
||||
text,
|
||||
},
|
||||
});
|
||||
|
||||
const diagnostics = await waitForDiagnostics({
|
||||
uri,
|
||||
lspc: lsp_clients.css,
|
||||
});
|
||||
if (diagnostics.length > 0) {
|
||||
printerr(serializeDiagnostics({ diagnostics }));
|
||||
return false;
|
||||
}
|
||||
print(` ✅ lints`);
|
||||
|
||||
const checks = await checkFile({
|
||||
lspc: lsp_clients.css,
|
||||
file: file_css,
|
||||
lang: getLanguage("css"),
|
||||
uri,
|
||||
});
|
||||
if (!checks) return false;
|
||||
|
||||
await lsp_clients.css._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri,
|
||||
},
|
||||
});
|
||||
await css({ file: file_css, lspc: lsp_clients.css });
|
||||
}
|
||||
|
||||
const file_javascript = demo_dir.get_child("main.js");
|
||||
if (file_javascript.query_exists(null)) {
|
||||
print(` ${file_javascript.get_path()}`);
|
||||
|
||||
const uri = file_javascript.get_uri();
|
||||
const languageId = "javascript";
|
||||
let version = 0;
|
||||
|
||||
const [contents] = await file_javascript.load_contents_async(null);
|
||||
const text = new TextDecoder().decode(contents);
|
||||
|
||||
await lsp_clients.javascript._notify("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri,
|
||||
languageId,
|
||||
version: version++,
|
||||
text,
|
||||
},
|
||||
});
|
||||
|
||||
const diagnostics = await waitForDiagnostics({
|
||||
uri,
|
||||
lspc: lsp_clients.javascript,
|
||||
});
|
||||
if (diagnostics.length > 0) {
|
||||
printerr(serializeDiagnostics({ diagnostics }));
|
||||
return false;
|
||||
}
|
||||
print(` ✅ lints`);
|
||||
|
||||
const checks = await checkFile({
|
||||
lspc: lsp_clients.javascript,
|
||||
await javascript({
|
||||
file: file_javascript,
|
||||
lang: getLanguage("javascript"),
|
||||
uri,
|
||||
});
|
||||
if (!checks) return false;
|
||||
|
||||
const js_object_ids = getCodeObjectIds(text);
|
||||
for (const object_id of js_object_ids) {
|
||||
if (!blueprint_object_ids.includes(object_id)) {
|
||||
print(` ❌ Reference to inexistant object id "${object_id}"`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.workbench = {
|
||||
window,
|
||||
lspc: lsp_clients.javascript,
|
||||
blueprint_object_ids,
|
||||
demo_dir,
|
||||
application,
|
||||
builder,
|
||||
template,
|
||||
resolve(path) {
|
||||
return demo_dir.resolve_relative_path(path).get_uri();
|
||||
},
|
||||
preview() {},
|
||||
};
|
||||
window,
|
||||
});
|
||||
}
|
||||
|
||||
await import(`file://${file_javascript.get_path()}`);
|
||||
print(" ✅ runs");
|
||||
|
||||
await lsp_clients.javascript._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri,
|
||||
},
|
||||
const file_typescript = demo_dir.get_child("main.ts");
|
||||
if (file_typescript.query_exists(null)) {
|
||||
await typescript({
|
||||
file: file_typescript,
|
||||
lspc: lsp_clients.typescript,
|
||||
blueprint_object_ids,
|
||||
demo_dir,
|
||||
application,
|
||||
builder,
|
||||
template,
|
||||
window,
|
||||
});
|
||||
}
|
||||
|
||||
const file_vala = demo_dir.get_child("main.vala");
|
||||
if (file_vala.query_exists(null)) {
|
||||
print(` ${file_vala.get_path()}`);
|
||||
|
||||
const uri = file_vala.get_uri();
|
||||
const languageId = "vala";
|
||||
let version = 0;
|
||||
|
||||
const api_file = (
|
||||
GLib.getenv("FLATPAK_ID")
|
||||
? Gio.File.new_for_path(`/app/share/${GLib.getenv("FLATPAK_ID")}`)
|
||||
: current_dir.resolve_relative_path("src/langs/vala")
|
||||
).get_child("workbench.vala");
|
||||
api_file.copy(
|
||||
demo_dir.get_child("workbench.vala"),
|
||||
Gio.FileCopyFlags.OVERWRITE,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
|
||||
const [contents] = await file_vala.load_contents_async(null);
|
||||
const text = new TextDecoder().decode(contents);
|
||||
|
||||
await lsp_clients.vala._notify("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri,
|
||||
languageId,
|
||||
version: version++,
|
||||
text,
|
||||
},
|
||||
});
|
||||
|
||||
const diagnostics = await waitForDiagnostics({
|
||||
uri,
|
||||
lspc: lsp_clients.vala,
|
||||
});
|
||||
if (
|
||||
![
|
||||
// FIXME: https://github.com/workbenchdev/demos/issues/43
|
||||
"List View Widgets",
|
||||
// FIXME: deprecated features, no replacement?
|
||||
"Text Fields",
|
||||
].includes(demo_dir.get_basename()) &&
|
||||
diagnostics.length > 0
|
||||
) {
|
||||
printerr(serializeDiagnostics({ diagnostics }));
|
||||
return false;
|
||||
await vala({ file: file_vala, lspc: lsp_clients.vala, demo_dir });
|
||||
}
|
||||
print(` ✅ lints`);
|
||||
|
||||
const checks = await checkFile({
|
||||
lspc: lsp_clients.vala,
|
||||
file: file_vala,
|
||||
lang: getLanguage("vala"),
|
||||
uri,
|
||||
});
|
||||
if (!checks) return false;
|
||||
const file_python = demo_dir.get_child("main.py");
|
||||
if (file_python.query_exists(null)) {
|
||||
await python({ file: file_python, lspc: lsp_clients.python });
|
||||
}
|
||||
|
||||
await lsp_clients.vala._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri,
|
||||
},
|
||||
});
|
||||
const file_rust = demo_dir.get_child("code.rs");
|
||||
if (file_rust.query_exists(null)) {
|
||||
await rust({ file: file_rust, lspc: lsp_clients.rust });
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
@ -406,43 +210,38 @@ async function ci({ filenames, current_dir }) {
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const key_file = new GLib.KeyFile();
|
||||
key_file.load_from_file("/.flatpak-info", GLib.KeyFileFlags.NONE);
|
||||
// runtime/org.gnome.Sdk/x86_64/master
|
||||
const [, , , runtime_version] = key_file
|
||||
.get_string("Application", "runtime")
|
||||
.split("/");
|
||||
|
||||
function isDemoCompatible(file) {
|
||||
let str;
|
||||
try {
|
||||
str = new TextDecoder().decode(
|
||||
file.get_child("main.json").load_contents(null)[1],
|
||||
);
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
return true;
|
||||
}
|
||||
|
||||
function getXMLObjectIds(tree, object_ids) {
|
||||
for (const object of tree.getChildren("object")) {
|
||||
if (object.attrs.id) object_ids.push(object.attrs.id);
|
||||
// <child> or <property name="child">
|
||||
for (const child of object.getChildElements()) {
|
||||
getXMLObjectIds(child, object_ids);
|
||||
}
|
||||
}
|
||||
const demo = JSON.parse(str);
|
||||
demo.name = file.get_basename();
|
||||
|
||||
const demo_runtime_version = demo["runtime-version"];
|
||||
|
||||
if (demo_runtime_version === "master") {
|
||||
return [runtime_version === "master", demo_runtime_version];
|
||||
} else if (runtime_version === "master") {
|
||||
return [true, demo_runtime_version];
|
||||
} else if (!demo_runtime_version) {
|
||||
return [true, demo_runtime_version];
|
||||
}
|
||||
|
||||
function getCodeObjectIds(text) {
|
||||
const object_ids = [];
|
||||
for (const match of text.matchAll(/get_object\("(.+)"\)/g)) {
|
||||
object_ids.push(match[1]);
|
||||
}
|
||||
return object_ids;
|
||||
}
|
||||
|
||||
function serializeDiagnostics({ diagnostics }) {
|
||||
return (
|
||||
diagnostics
|
||||
.map(({ severity, range, message }) => {
|
||||
return (
|
||||
" ❌ " +
|
||||
diagnostic_severities[severity] +
|
||||
" " +
|
||||
range.start.line +
|
||||
":" +
|
||||
range.start.character +
|
||||
" " +
|
||||
message.split("\n")[0]
|
||||
);
|
||||
})
|
||||
.join("\n") + "\n"
|
||||
);
|
||||
return [+runtime_version >= +demo_runtime_version, demo_runtime_version];
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ bin_conf.set('GJS', find_program('gjs').full_path())
|
||||
bin_conf.set('version', meson.project_version() + version_suffix)
|
||||
bin_conf.set('app_id', app_id)
|
||||
bin_conf.set('prefix', prefix)
|
||||
bin_conf.set('libdir', join_paths(get_option('prefix'), get_option('libdir')))
|
||||
bin_conf.set('libdir', get_option('prefix') / get_option('libdir'))
|
||||
bin_conf.set('datadir', datadir)
|
||||
bin_conf.set('pkgdatadir', pkgdatadir)
|
||||
bin_conf.set('sourcedir', meson.project_source_root())
|
||||
|
30
src/cli/python.js
Normal file
@ -0,0 +1,30 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import { PYTHON_LSP_CONFIG, getLanguage } from "../common.js";
|
||||
|
||||
import { checkFile, diagnose } from "./util.js";
|
||||
|
||||
const languageId = "python";
|
||||
|
||||
export default async function python({ file, lspc }) {
|
||||
print(` ${file.get_path()}`);
|
||||
|
||||
await lspc._request("workspace/didChangeConfiguration", {
|
||||
settings: PYTHON_LSP_CONFIG,
|
||||
});
|
||||
|
||||
await diagnose({ file, lspc, languageId });
|
||||
|
||||
await checkFile({
|
||||
lspc,
|
||||
file,
|
||||
lang: getLanguage(languageId),
|
||||
uri: file.get_uri(),
|
||||
});
|
||||
|
||||
await lspc._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri: file.get_uri(),
|
||||
},
|
||||
});
|
||||
}
|
48
src/cli/rust.js
Normal file
@ -0,0 +1,48 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import { getLanguage } from "../common.js";
|
||||
|
||||
import { checkFile } from "./util.js";
|
||||
|
||||
const languageId = "rust";
|
||||
|
||||
export default async function rust({ file, lspc }) {
|
||||
print(` ${file.get_path()}`);
|
||||
|
||||
const uri = file.get_uri();
|
||||
let version = 0;
|
||||
|
||||
const [contents] = await file.load_contents_async(null);
|
||||
const text = new TextDecoder().decode(contents);
|
||||
|
||||
await lspc._notify("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri,
|
||||
languageId,
|
||||
version: version++,
|
||||
text,
|
||||
},
|
||||
});
|
||||
|
||||
// FIXME: rust analyzer doesn't publish diagnostics if there are none
|
||||
// probably we should switch to pulling diagnostics but unknown if supported
|
||||
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#textDocument_pullDiagnostics
|
||||
// await diagnose({
|
||||
// file,
|
||||
// lspc,
|
||||
// languageId,
|
||||
// });
|
||||
|
||||
await checkFile({
|
||||
lspc,
|
||||
file,
|
||||
lang: getLanguage(languageId),
|
||||
uri,
|
||||
});
|
||||
|
||||
await lspc._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri,
|
||||
},
|
||||
});
|
||||
}
|
56
src/cli/typescript.js
Normal file
@ -0,0 +1,56 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import { getLanguage } from "../common.js";
|
||||
import { checkFile, getCodeObjectIds, diagnose, Interrupt } from "./util.js";
|
||||
|
||||
const languageId = "typescript";
|
||||
|
||||
export default async function typescript({
|
||||
file,
|
||||
lspc,
|
||||
blueprint_object_ids,
|
||||
demo_dir,
|
||||
application,
|
||||
builder,
|
||||
template,
|
||||
window,
|
||||
}) {
|
||||
print(` ${file.get_path()}`);
|
||||
|
||||
const text = await diagnose({ file, lspc, languageId });
|
||||
|
||||
await checkFile({
|
||||
lspc,
|
||||
file,
|
||||
lang: getLanguage(languageId),
|
||||
uri: file.get_uri(),
|
||||
});
|
||||
|
||||
const js_object_ids = getCodeObjectIds(text);
|
||||
for (const object_id of js_object_ids) {
|
||||
if (!blueprint_object_ids.includes(object_id)) {
|
||||
print(` ❌ Reference to inexistant object id "${object_id}"`);
|
||||
throw new Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.workbench = {
|
||||
window,
|
||||
application,
|
||||
builder,
|
||||
template,
|
||||
resolve(path) {
|
||||
return demo_dir.resolve_relative_path(path).get_uri();
|
||||
},
|
||||
preview() {},
|
||||
};
|
||||
|
||||
await import(`file://${file.get_path()}`);
|
||||
print(" ✅ runs");
|
||||
|
||||
await lspc._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri: file.get_uri(),
|
||||
},
|
||||
});
|
||||
}
|
111
src/cli/util.js
Normal file
@ -0,0 +1,111 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import Gtk from "gi://Gtk";
|
||||
|
||||
import { diagnostic_severities } from "../lsp/LSP.js";
|
||||
import { formatting } from "./format.js";
|
||||
|
||||
export class Interrupt extends Error {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
Error.captureStackTrace?.(this, Interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
export async function diagnose({
|
||||
file,
|
||||
lspc,
|
||||
languageId,
|
||||
filter = (_diagnostic) => {
|
||||
return true;
|
||||
},
|
||||
}) {
|
||||
const [contents] = await file.load_contents_async(null);
|
||||
const text = new TextDecoder().decode(contents);
|
||||
|
||||
const uri = file.get_uri();
|
||||
let version = 0;
|
||||
|
||||
await lspc._notify("textDocument/didOpen", {
|
||||
textDocument: {
|
||||
uri,
|
||||
languageId,
|
||||
version: version++,
|
||||
text,
|
||||
},
|
||||
});
|
||||
|
||||
let diagnostics = await waitForDiagnostics({
|
||||
uri,
|
||||
lspc,
|
||||
});
|
||||
diagnostics = diagnostics.filter(filter);
|
||||
if (diagnostics.length > 0) {
|
||||
printerr(serializeDiagnostics({ diagnostics }));
|
||||
throw new Interrupt();
|
||||
}
|
||||
|
||||
print(` ✅ lints`);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
export function serializeDiagnostics({ diagnostics }) {
|
||||
return (
|
||||
diagnostics
|
||||
.map(({ severity, range, message }) => {
|
||||
return (
|
||||
" ❌ " +
|
||||
diagnostic_severities[severity] +
|
||||
" " +
|
||||
range.start.line +
|
||||
":" +
|
||||
range.start.character +
|
||||
" " +
|
||||
message.split("\n")[0]
|
||||
);
|
||||
})
|
||||
.join("\n") + "\n"
|
||||
);
|
||||
}
|
||||
|
||||
export async function checkFile({ lspc, file, lang, uri }) {
|
||||
const [contents] = await file.load_contents_async(null);
|
||||
const text = new TextDecoder().decode(contents);
|
||||
const buffer = new Gtk.TextBuffer({ text });
|
||||
|
||||
const buffer_tmp = new Gtk.TextBuffer({ text: buffer.text });
|
||||
await formatting({ buffer: buffer_tmp, uri, lang, lspc });
|
||||
|
||||
if (buffer_tmp.text === buffer.text) {
|
||||
print(` ✅ checks`);
|
||||
} else {
|
||||
printerr(
|
||||
` ❌ formatting differs - open and run ${file
|
||||
.get_parent()
|
||||
.get_basename()} with Workbench to fix`,
|
||||
);
|
||||
throw new Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
export function getCodeObjectIds(text) {
|
||||
const object_ids = [];
|
||||
for (const match of text.matchAll(/get_object\("(.+)"\)/g)) {
|
||||
object_ids.push(match[1]);
|
||||
}
|
||||
return object_ids;
|
||||
}
|
||||
|
||||
export function waitForDiagnostics({ uri, lspc }) {
|
||||
return new Promise((resolve) => {
|
||||
const handler_id = lspc.connect(
|
||||
"notification::textDocument/publishDiagnostics",
|
||||
(_self, params) => {
|
||||
if (uri !== params.uri) return;
|
||||
lspc.disconnect(handler_id);
|
||||
resolve(params.diagnostics);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
62
src/cli/vala.js
Normal file
@ -0,0 +1,62 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import Gio from "gi://Gio";
|
||||
|
||||
import { getLanguage } from "../common.js";
|
||||
import { checkFile, diagnose } from "./util.js";
|
||||
|
||||
const languageId = "vala";
|
||||
|
||||
export default async function vala({ file, lspc, demo_dir }) {
|
||||
print(` ${file.get_path()}`);
|
||||
|
||||
const file_api = Gio.File.new_for_path(pkg.pkgdatadir).get_child(
|
||||
"workbench.vala",
|
||||
);
|
||||
file_api.copy(
|
||||
demo_dir.get_child("workbench.vala"),
|
||||
Gio.FileCopyFlags.OVERWRITE,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
|
||||
await diagnose({
|
||||
file,
|
||||
lspc,
|
||||
languageId,
|
||||
filter(diagnostic) {
|
||||
// FIXME: deprecated features, no replacement?
|
||||
if (demo_dir.get_basename() === "Text Fields") {
|
||||
const ignore_for_text_fields = [
|
||||
"`Gtk.EntryCompletion' has been deprecated since 4.10",
|
||||
"`Gtk.Entry.completion' has been deprecated since 4.10",
|
||||
"`Gtk.ListStore' has been deprecated since 4.10",
|
||||
"`Gtk.TreeIter' has been deprecated since 4.10",
|
||||
];
|
||||
return !ignore_for_text_fields.includes(diagnostic.message);
|
||||
// Gtk.StyleContext class is deprecated but not the following methods
|
||||
// gtk_style_context_add_provider_for_display
|
||||
// gtk_style_context_remove_provider_for_display
|
||||
} else if (demo_dir.get_basename() === "CSS Gradients") {
|
||||
return (
|
||||
diagnostic.message !==
|
||||
"`Gtk.StyleContext' has been deprecated since 4.10"
|
||||
);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
await checkFile({
|
||||
lspc,
|
||||
file,
|
||||
lang: getLanguage("vala"),
|
||||
uri: file.get_uri(),
|
||||
});
|
||||
|
||||
await lspc._notify("textDocument/didClose", {
|
||||
textDocument: {
|
||||
uri: file.get_uri(),
|
||||
},
|
||||
});
|
||||
}
|