parent
c2a29470c3
commit
cf85ec736f
|
|
@ -0,0 +1,28 @@
|
|||
name: Build Linux Bundle
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
|
||||
- name: Free disk space
|
||||
run: sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache
|
||||
|
||||
- name: Build Linux Bundle
|
||||
run: nix build .nix#graphite-bundle.tar.xz && cp ./result ./graphite-bundle.tar.xz
|
||||
|
||||
- name: Upload Linux Bundle
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: graphite-bundle.tar.xz
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
branding/
|
||||
target/
|
||||
result/
|
||||
.flatpak-builder/
|
||||
*.spv
|
||||
*.exrc
|
||||
perf.data*
|
||||
|
|
|
|||
|
|
@ -1,24 +1,26 @@
|
|||
{ pkgs, inputs, ... }:
|
||||
|
||||
let
|
||||
cef = pkgs.cef-binary.overrideAttrs (_: _: {
|
||||
cef = pkgs.cef-binary.overrideAttrs {
|
||||
postInstall = ''
|
||||
strip $out/Release/*.so*
|
||||
'';
|
||||
});
|
||||
};
|
||||
|
||||
cefPath = pkgs.runCommand "cef-path" {} ''
|
||||
cefPath = pkgs.runCommand "cef-path" { } ''
|
||||
mkdir -p $out
|
||||
|
||||
ln -s ${cef}/include $out/include
|
||||
find ${cef}/Release -name "*" -type f -exec ln -s {} $out/ \;
|
||||
find ${cef}/Resources -name "*" -maxdepth 1 -exec ln -s {} $out/ \;
|
||||
|
||||
echo '${builtins.toJSON {
|
||||
type = "minimal";
|
||||
name = builtins.baseNameOf cef.src.url;
|
||||
sha1 = "";
|
||||
}}' > $out/archive.json
|
||||
echo '${
|
||||
builtins.toJSON {
|
||||
type = "minimal";
|
||||
name = builtins.baseNameOf cef.src.url;
|
||||
sha1 = "";
|
||||
}
|
||||
}' > $out/archive.json
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,7 +33,10 @@
|
|||
info = {
|
||||
pname = "graphite";
|
||||
version = "unstable";
|
||||
src = ./..;
|
||||
src = pkgs.lib.cleanSourceWith {
|
||||
src = ./..;
|
||||
filter = path: type: !(type == "directory" && builtins.baseNameOf path == ".nix");
|
||||
};
|
||||
};
|
||||
|
||||
pkgs = import inputs.nixpkgs {
|
||||
|
|
@ -129,6 +132,13 @@
|
|||
embeddedResources = false;
|
||||
dev = true;
|
||||
};
|
||||
graphite-bundle = import ./pkgs/graphite-bundle.nix {
|
||||
inherit pkgs graphite;
|
||||
};
|
||||
graphite-flatpak-manifest = import ./pkgs/graphite-flatpak-manifest.nix {
|
||||
inherit pkgs;
|
||||
archive = graphite-bundle.tar;
|
||||
};
|
||||
#TODO: graphene-cli = import ./pkgs/graphene-cli.nix { inherit info pkgs inputs deps libs tools; };
|
||||
raster-nodes-shaders = import ./pkgs/raster-nodes-shaders.nix {
|
||||
inherit
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
pkgs,
|
||||
graphite,
|
||||
}:
|
||||
let
|
||||
bundle =
|
||||
{
|
||||
pkgs,
|
||||
graphite,
|
||||
archive ? false,
|
||||
compression ? null,
|
||||
passthru ? {},
|
||||
}:
|
||||
(
|
||||
let
|
||||
tar = if compression == null then archive else true;
|
||||
nameArchiveSuffix = if tar then ".tar" else "";
|
||||
nameCompressionSuffix = if compression == null then "" else "." + compression;
|
||||
name = "graphite-bundle${nameArchiveSuffix}${nameCompressionSuffix}";
|
||||
build = ''
|
||||
mkdir -p out
|
||||
mkdir -p out/bin
|
||||
cp ${graphite}/bin/.graphite-wrapped out/bin/graphite
|
||||
chmod -v +w out/bin/graphite
|
||||
patchelf --set-rpath '$ORIGIN/../lib:$ORIGIN/../lib/cef' --set-interpreter '/lib64/ld-linux-x86-64.so.2' out/bin/graphite
|
||||
mkdir -p out/lib/cef
|
||||
mkdir -p ./cef
|
||||
tar -xvf ${pkgs.cef-binary.src} -C ./cef --strip-components=1
|
||||
cp -r ./cef/Release/* out/lib/cef/
|
||||
cp -r ./cef/Resources/* out/lib/cef/
|
||||
find "out/lib/cef/locales" -type f ! -name 'en-US*' -delete
|
||||
${pkgs.bintools}/bin/strip out/lib/cef/*.so*
|
||||
cp -r ${graphite}/share out/share
|
||||
'';
|
||||
install =
|
||||
if tar then
|
||||
''
|
||||
cd out
|
||||
tar -c \
|
||||
--sort=name \
|
||||
--mtime='@1' --clamp-mtime \
|
||||
--owner=0 --group=0 --numeric-owner \
|
||||
--mode='u=rwX,go=rX' \
|
||||
--format=posix \
|
||||
--pax-option=delete=atime,delete=ctime \
|
||||
--no-acls --no-xattrs --no-selinux \
|
||||
* ${
|
||||
if compression == "xz" then
|
||||
"| xz "
|
||||
else if compression == "gz" then
|
||||
"| gzip -n "
|
||||
else
|
||||
""
|
||||
}> $out
|
||||
''
|
||||
else
|
||||
''
|
||||
mkdir -p $out
|
||||
cp -r out/* $out/
|
||||
'';
|
||||
in
|
||||
|
||||
pkgs.runCommand name
|
||||
{
|
||||
inherit passthru;
|
||||
}
|
||||
''
|
||||
${build}
|
||||
${install}
|
||||
''
|
||||
);
|
||||
in
|
||||
bundle {
|
||||
inherit pkgs graphite;
|
||||
passthru = {
|
||||
tar = bundle {
|
||||
inherit pkgs graphite;
|
||||
archive = true;
|
||||
passthru = {
|
||||
gz = bundle {
|
||||
inherit pkgs graphite;
|
||||
compression = "gz";
|
||||
};
|
||||
xz = bundle {
|
||||
inherit pkgs graphite;
|
||||
compression = "xz";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
pkgs,
|
||||
archive,
|
||||
}:
|
||||
|
||||
(pkgs.formats.json { }).generate "art.graphite.Graphite.json" {
|
||||
app-id = "art.graphite.Graphite";
|
||||
runtime = "org.freedesktop.Platform";
|
||||
runtime-version = "25.08";
|
||||
sdk = "org.freedesktop.Sdk";
|
||||
command = "graphite";
|
||||
finish-args = [
|
||||
"--device=dri"
|
||||
"--share=ipc"
|
||||
"--socket=wayland"
|
||||
"--socket=fallback-x11"
|
||||
"--share=network"
|
||||
];
|
||||
modules = [
|
||||
{
|
||||
name = "app";
|
||||
buildsystem = "simple";
|
||||
build-commands = [
|
||||
"mkdir -p /app"
|
||||
"cp -r ./* /app/"
|
||||
"chmod +x /app/bin/*"
|
||||
];
|
||||
sources = [
|
||||
{
|
||||
type = "archive";
|
||||
path = archive;
|
||||
strip-components = 0;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ deps.crane.lib.buildPackage (
|
|||
cp $src/desktop/assets/*.desktop $out/share/applications/
|
||||
|
||||
mkdir -p $out/share/icons/hicolor/scalable/apps
|
||||
cp ${branding}/app-icons/graphite.svg $out/share/icons/hicolor/scalable/apps/
|
||||
cp ${branding}/app-icons/graphite.svg $out/share/icons/hicolor/scalable/apps/art.graphite.Graphite.svg
|
||||
'';
|
||||
|
||||
postFixup = ''
|
||||
|
|
|
|||
|
|
@ -774,7 +774,7 @@ dependencies = [
|
|||
"thiserror 2.0.16",
|
||||
"tracing",
|
||||
"wgpu",
|
||||
"windows 0.58.0",
|
||||
"windows",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
|
|
@ -1685,6 +1685,17 @@ version = "2.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "fd-lock"
|
||||
version = "4.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"rustix",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.7"
|
||||
|
|
@ -1829,7 +1840,7 @@ dependencies = [
|
|||
"read-fonts 0.35.0",
|
||||
"roxmltree",
|
||||
"smallvec",
|
||||
"windows 0.58.0",
|
||||
"windows",
|
||||
"windows-core 0.58.0",
|
||||
"yeslogic-fontconfig-sys",
|
||||
]
|
||||
|
|
@ -2147,7 +2158,7 @@ dependencies = [
|
|||
"log",
|
||||
"presser",
|
||||
"thiserror 1.0.69",
|
||||
"windows 0.58.0",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2330,6 +2341,7 @@ dependencies = [
|
|||
"ctrlc",
|
||||
"derivative",
|
||||
"dirs",
|
||||
"fd-lock",
|
||||
"futures",
|
||||
"glam",
|
||||
"graphite-desktop-embedded-resources",
|
||||
|
|
@ -2339,7 +2351,6 @@ dependencies = [
|
|||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
"open",
|
||||
"pidlock",
|
||||
"rand 0.9.2",
|
||||
"rfd",
|
||||
"ron",
|
||||
|
|
@ -2350,7 +2361,7 @@ dependencies = [
|
|||
"vello",
|
||||
"wgpu",
|
||||
"window_clipboard",
|
||||
"windows 0.58.0",
|
||||
"windows",
|
||||
"winit",
|
||||
]
|
||||
|
||||
|
|
@ -4370,17 +4381,6 @@ version = "0.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
||||
|
||||
[[package]]
|
||||
name = "pidlock"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f837924d5368f9f35a1c404699de3c074311358035c77d7164f5948c08b31382"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"thiserror 1.0.69",
|
||||
"windows 0.62.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.10"
|
||||
|
|
@ -7224,7 +7224,7 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
"wgpu-types",
|
||||
"windows 0.58.0",
|
||||
"windows",
|
||||
"windows-core 0.58.0",
|
||||
]
|
||||
|
||||
|
|
@ -7297,27 +7297,6 @@ dependencies = [
|
|||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.62.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core 0.62.2",
|
||||
"windows-future",
|
||||
"windows-numerics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
|
||||
dependencies = [
|
||||
"windows-core 0.62.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.58.0"
|
||||
|
|
@ -7344,30 +7323,6 @@ dependencies = [
|
|||
"windows-strings 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||
dependencies = [
|
||||
"windows-implement 0.60.2",
|
||||
"windows-interface 0.59.3",
|
||||
"windows-link 0.2.1",
|
||||
"windows-result 0.4.1",
|
||||
"windows-strings 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
||||
dependencies = [
|
||||
"windows-core 0.62.2",
|
||||
"windows-link 0.2.1",
|
||||
"windows-threading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.58.0"
|
||||
|
|
@ -7424,16 +7379,6 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
|
||||
dependencies = [
|
||||
"windows-core 0.62.2",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.5.3"
|
||||
|
|
@ -7463,15 +7408,6 @@ dependencies = [
|
|||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||
dependencies = [
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.1.0"
|
||||
|
|
@ -7491,15 +7427,6 @@ dependencies = [
|
|||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||
dependencies = [
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
|
|
@ -7593,15 +7520,6 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
|
||||
dependencies = [
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ open = { workspace = true }
|
|||
rand = { workspace = true, features = ["thread_rng"] }
|
||||
serde = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
pidlock = "0.2.2"
|
||||
fd-lock = "4.0.4"
|
||||
ctrlc = "3.5.1"
|
||||
window_clipboard = "0.5"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Comment=Open-source vector & raster graphics editor. Featuring node based proced
|
|||
Exec=graphite
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=graphite
|
||||
Icon=art.graphite.Graphite
|
||||
Categories=Graphics;VectorGraphics;RasterGraphics;
|
||||
Keywords=graphite;editor;vector;raster;procedural;design;
|
||||
StartupWMClass=art.graphite.Graphite
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
|
|||
|
||||
let settings = Settings {
|
||||
multi_threaded_message_loop: 1,
|
||||
#[cfg(target_os = "linux")]
|
||||
no_sandbox: 1,
|
||||
..Self::common_settings(&instance_dir)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ impl<H: CefEventHandler> ImplApp for BrowserProcessAppImpl<H> {
|
|||
fn on_before_command_line_processing(&self, _process_type: Option<&cef::CefString>, command_line: Option<&mut cef::CommandLine>) {
|
||||
if let Some(cmd) = command_line {
|
||||
cmd.append_switch_with_value(Some(&CefString::from("renderer-process-limit")), Some(&CefString::from("1")));
|
||||
cmd.append_switch_with_value(Some(&CefString::from("password-store")), Some(&CefString::from("basic")));
|
||||
cmd.append_switch_with_value(Some(&CefString::from("disk-cache-size")), Some(&CefString::from("0")));
|
||||
cmd.append_switch(Some(&CefString::from("incognito")));
|
||||
cmd.append_switch(Some(&CefString::from("no-first-run")));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use clap::Parser;
|
||||
use std::io::Write;
|
||||
use std::process::exit;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
use winit::event_loop::EventLoop;
|
||||
|
|
@ -38,26 +39,35 @@ pub fn start() {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut lock = pidlock::Pidlock::new_validated(dirs::app_data_dir().join(APP_LOCK_FILE_NAME)).unwrap();
|
||||
match lock.acquire() {
|
||||
Ok(lock) => {
|
||||
let cli = Cli::parse();
|
||||
|
||||
let Ok(lock_file) = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(dirs::app_data_dir().join(APP_LOCK_FILE_NAME))
|
||||
else {
|
||||
tracing::error!("Failed to open lock file, Exiting.");
|
||||
exit(1);
|
||||
};
|
||||
let mut lock = fd_lock::RwLock::new(lock_file);
|
||||
let lock = match lock.try_write() {
|
||||
Ok(mut guard) => {
|
||||
tracing::info!("Acquired application lock");
|
||||
lock
|
||||
let _ = guard.set_len(0);
|
||||
let _ = write!(guard, "{}", std::process::id());
|
||||
let _ = guard.sync_all();
|
||||
guard
|
||||
}
|
||||
Err(pidlock::PidlockError::LockExists) => {
|
||||
Err(_) => {
|
||||
tracing::error!("Another instance is already running, Exiting.");
|
||||
exit(0);
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!("Failed to acquire application lock: {err}");
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
App::init();
|
||||
|
||||
let cli = Cli::parse();
|
||||
|
||||
let wgpu_context = futures::executor::block_on(gpu_context::create_wgpu_context());
|
||||
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
|
@ -94,6 +104,9 @@ pub fn start() {
|
|||
|
||||
event_loop.run_app(&mut app).unwrap();
|
||||
|
||||
// Explicitly drop the instance lock
|
||||
drop(lock);
|
||||
|
||||
// Workaround for a Windows-specific exception that occurs when `app` is dropped.
|
||||
// The issue causes the window to hang for a few seconds before closing.
|
||||
// Appears to be related to CEF object destruction order.
|
||||
|
|
|
|||
Loading…
Reference in New Issue