Initial commit
This commit is contained in:
commit
ab1edbf0f4
11 changed files with 752 additions and 0 deletions
3
.envrc
Normal file
3
.envrc
Normal file
|
@ -0,0 +1,3 @@
|
|||
dotenv_if_exists
|
||||
|
||||
use flake
|
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
### direnv ###
|
||||
.direnv
|
||||
|
||||
### nix ###
|
||||
/result
|
||||
|
||||
### zig ###
|
||||
# Zig programming language
|
||||
|
||||
zig-cache/
|
||||
zig-out/
|
||||
build/
|
||||
build-*/
|
||||
docgen_tmp/
|
127
build.zig
Normal file
127
build.zig
Normal file
|
@ -0,0 +1,127 @@
|
|||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const path = std.fs.path;
|
||||
|
||||
const Build = std.Build;
|
||||
|
||||
const Scanner = @import("zig-wayland").Scanner;
|
||||
|
||||
// Although this function looks imperative, note that its job is to
|
||||
// declaratively construct a build graph that will be executed by an external
|
||||
// runner.
|
||||
pub fn build(b: *std.Build) void {
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
// what target to build for. Here we do not override the defaults, which
|
||||
// means any target is allowed, and the default is native. Other options
|
||||
// for restricting supported target set are available.
|
||||
const target = b.standardTargetOptions(.{});
|
||||
|
||||
// Standard optimization options allow the person running `zig build` to select
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
||||
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const scanner = Scanner.create(b, .{});
|
||||
const wayland = b.createModule(.{ .root_source_file = scanner.result });
|
||||
|
||||
scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml");
|
||||
scanner.addSystemProtocol("unstable/idle-inhibit/idle-inhibit-unstable-v1.xml");
|
||||
|
||||
const wlr_protocols_path = blk: {
|
||||
const pc_output = b.run(&.{ "pkg-config", "--variable=pkgdatadir", "wlr-protocols" });
|
||||
break :blk mem.trim(u8, pc_output, &std.ascii.whitespace);
|
||||
};
|
||||
|
||||
scanner.addCustomProtocol(b.pathJoin(&.{ wlr_protocols_path, "unstable/wlr-layer-shell-unstable-v1.xml" }));
|
||||
scanner.addCustomProtocol(b.pathJoin(&.{ wlr_protocols_path, "unstable/wlr-foreign-toplevel-management-unstable-v1.xml" }));
|
||||
|
||||
scanner.generate("wl_compositor", 1);
|
||||
scanner.generate("wl_shm", 1);
|
||||
scanner.generate("wl_output", 4);
|
||||
scanner.generate("xdg_wm_base", 6);
|
||||
scanner.generate("zwp_idle_inhibit_manager_v1", 1);
|
||||
scanner.generate("zwlr_foreign_toplevel_manager_v1", 3);
|
||||
scanner.generate("zwlr_layer_shell_v1", 4);
|
||||
|
||||
// const lib = b.addStaticLibrary(.{
|
||||
// .name = "vegetable-hamper",
|
||||
// // In this case the main source file is merely a path, however, in more
|
||||
// // complicated build scripts, this could be a generated file.
|
||||
// .root_source_file = b.path("src/root.zig"),
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// });
|
||||
|
||||
// // This declares intent for the library to be installed into the standard
|
||||
// // location when the user invokes the "install" step (the default step when
|
||||
// // running `zig build`).
|
||||
// b.installArtifact(lib);
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "vegetable-hamper",
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// Add wayland module
|
||||
exe.root_module.addImport("wayland", wayland);
|
||||
exe.linkLibC();
|
||||
exe.linkSystemLibrary2("wayland-client", .{ .needed = true });
|
||||
exe.linkSystemLibrary2("wlroots", .{ .needed = true });
|
||||
|
||||
scanner.addCSource(exe);
|
||||
|
||||
// This declares intent for the executable to be installed into the
|
||||
// standard location when the user invokes the "install" step (the default
|
||||
// step when running `zig build`).
|
||||
b.installArtifact(exe);
|
||||
|
||||
// This *creates* a Run step in the build graph, to be executed when another
|
||||
// step is evaluated that depends on it. The next line below will establish
|
||||
// such a dependency.
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
|
||||
// By making the run step depend on the install step, it will be run from the
|
||||
// installation directory rather than directly from within the cache directory.
|
||||
// This is not necessary, however, if the application depends on other installed
|
||||
// files, this ensures they will be present and in the expected location.
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
// This allows the user to pass arguments to the application in the build
|
||||
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
// This creates a build step. It will be visible in the `zig build --help` menu,
|
||||
// and can be selected like this: `zig build run`
|
||||
// This will evaluate the `run` step rather than the default, which is "install".
|
||||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
// Creates a step for unit testing. This only builds the test executable
|
||||
// but does not run it.
|
||||
// const lib_unit_tests = b.addTest(.{
|
||||
// .root_source_file = b.path("src/root.zig"),
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// });
|
||||
|
||||
// const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||
|
||||
// const exe_unit_tests = b.addTest(.{
|
||||
// .root_source_file = b.path("src/main.zig"),
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// });
|
||||
|
||||
// const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||
|
||||
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||
// the `zig build --help` menu, providing a way for the user to request
|
||||
// running the unit tests.
|
||||
// const test_step = b.step("test", "Run unit tests");
|
||||
// test_step.dependOn(&run_lib_unit_tests.step);
|
||||
// test_step.dependOn(&run_exe_unit_tests.step);
|
||||
}
|
36
build.zig.zon
Normal file
36
build.zig.zon
Normal file
|
@ -0,0 +1,36 @@
|
|||
.{
|
||||
.name = "vegetable-hamper",
|
||||
// This is a [Semantic Version](https://semver.org/).
|
||||
// In a future version of Zig it will be used for package deduplication.
|
||||
.version = "0.1.0",
|
||||
|
||||
// This field is optional.
|
||||
// This is currently advisory only; Zig does not yet do anything
|
||||
// with this value.
|
||||
//.minimum_zig_version = "0.11.0",
|
||||
|
||||
// This field is optional.
|
||||
// Each dependency must either provide a `url` and `hash`, or a `path`.
|
||||
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
|
||||
// Once all dependencies are fetched, `zig build` no longer requires
|
||||
// internet connectivity.
|
||||
.dependencies = .{
|
||||
.@"zig-wayland" = .{
|
||||
.url = "https://codeberg.org/ifreund/zig-wayland/archive/fe04636c866c6289b74c0803e621c9cc1bc1d1a4.tar.gz",
|
||||
.hash = "12205b33855e3634201e6777a06d9d50ff8f4477b47ef95024009dd3e60df7b269d3",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
// This makes *all* files, recursively, included in this package. It is generally
|
||||
// better to explicitly list the files and directories instead, to insure that
|
||||
// fetching from tarballs, file system paths, and version control all result
|
||||
// in the same contents hash.
|
||||
"",
|
||||
// For example...
|
||||
//"build.zig",
|
||||
//"build.zig.zon",
|
||||
//"src",
|
||||
//"LICENSE",
|
||||
//"README.md",
|
||||
},
|
||||
}
|
196
flake.lock
Normal file
196
flake.lock
Normal file
|
@ -0,0 +1,196 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1712014858,
|
||||
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"git-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1714478972,
|
||||
"narHash": "sha256-q//cgb52vv81uOuwz1LaXElp3XAe1TqrABXODAEF6Sk=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "2849da033884f54822af194400f8dff435ada242",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"git-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1714562304,
|
||||
"narHash": "sha256-Mr3U37Rh6tH0FbaDFu0aZDwk9mPAe7ASaqDOGgLqqLU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bcd44e224fd68ce7d269b4f44d24c2220fd821e7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"lastModified": 1711703276,
|
||||
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"dir": "lib",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1710695816,
|
||||
"narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "614b4613980a522ba49f0d194531beddbb7220d3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-23.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"git-hooks": "git-hooks",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1714058656,
|
||||
"narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
71
flake.nix
Normal file
71
flake.nix
Normal file
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
|
||||
treefmt-nix = {
|
||||
url = "github:numtide/treefmt-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
git-hooks = {
|
||||
url = "github:cachix/git-hooks.nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ ... }@inputs:
|
||||
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
systems = [ "x86_64-linux" ];
|
||||
|
||||
imports = [
|
||||
inputs.git-hooks.flakeModule
|
||||
inputs.treefmt-nix.flakeModule
|
||||
|
||||
./nix/zls
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
treefmt = {
|
||||
projectRootFile = "flake.lock";
|
||||
|
||||
programs = {
|
||||
deadnix.enable = true;
|
||||
nixfmt = {
|
||||
enable = true;
|
||||
package = pkgs.nixfmt-rfc-style;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
devShells.default =
|
||||
with pkgs;
|
||||
mkShell {
|
||||
name = "zig-app";
|
||||
|
||||
packages = [
|
||||
zig_0_12
|
||||
config.packages.zls
|
||||
|
||||
wayland
|
||||
wayland-protocols
|
||||
wlroots_0_17
|
||||
wlr-protocols
|
||||
|
||||
swayidle
|
||||
|
||||
pkg-config
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
54
nix/zls/default.nix
Normal file
54
nix/zls/default.nix
Normal file
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
# { lib
|
||||
# , stdenv
|
||||
# , fetchFromGitHub
|
||||
# , zig_0_11
|
||||
# , callPackage
|
||||
# }:
|
||||
|
||||
perSystem =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
packages.zls =
|
||||
let
|
||||
in
|
||||
pkgs.stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "zls";
|
||||
version = "0.12.0";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "zigtools";
|
||||
repo = "zls";
|
||||
rev = finalAttrs.version;
|
||||
fetchSubmodules = true;
|
||||
hash = "sha256-2iVDPUj9ExgTooDQmCCtZs3wxBe2be9xjzAk9HedPNY=";
|
||||
};
|
||||
|
||||
langref = pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/ziglang/zig/a685ab1499d6560c523f0dbce2890dc140671e43/doc/langref.html.in";
|
||||
hash = "sha256-7lFSfkVLOrn42nYnYyDmBkkRfM903lUUJZ5Sg+eBUpE=";
|
||||
};
|
||||
|
||||
zigBuildFlags = [ "-Dversion_data_path=${finalAttrs.langref}" ];
|
||||
|
||||
nativeBuildInputs = [ pkgs.zig_0_12.hook ];
|
||||
|
||||
postPatch = ''
|
||||
ln -s ${pkgs.callPackage ./deps.nix { }} $ZIG_GLOBAL_CACHE_DIR/p
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Zig LSP implementation + Zig Language Server";
|
||||
mainProgram = "zls";
|
||||
changelog = "https://github.com/zigtools/zls/releases/tag/${finalAttrs.version}";
|
||||
homepage = "https://github.com/zigtools/zls";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [
|
||||
figsoda
|
||||
moni
|
||||
];
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
20
nix/zls/deps.nix
Normal file
20
nix/zls/deps.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
# generated by zon2nix (https://github.com/figsoda/zon2nix)
|
||||
|
||||
{ linkFarm, fetchzip }:
|
||||
|
||||
linkFarm "zig-packages" [
|
||||
{
|
||||
name = "12201314cffeb40c5e4e3da166217d2c74628c74486414aaf97422bcd2279915b9fd";
|
||||
path = fetchzip {
|
||||
url = "https://github.com/ziglibs/known-folders/archive/bf79988adcfce166f848e4b11e718c1966365329.tar.gz";
|
||||
hash = "sha256-Q7eMdyScqj8qEiAHg1BnGRTsWSQOKWWTc6hUYHNlgGg=";
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "12200d71e4b7029ea56a429e24260c6c0e85a3069b0d4ba85eace21a0fd75910aa64";
|
||||
path = fetchzip {
|
||||
url = "https://github.com/ziglibs/diffz/archive/e10bf15962e45affb3fcd7d9a950977a69c901b3.tar.gz";
|
||||
hash = "sha256-yVFPVn4jGfcoE2V4xdTqdThYPutshL6U4feDzetWgFw=";
|
||||
};
|
||||
}
|
||||
]
|
203
src/main.zig
Normal file
203
src/main.zig
Normal file
|
@ -0,0 +1,203 @@
|
|||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
|
||||
const wayland = @import("wayland");
|
||||
const wl = wayland.client.wl;
|
||||
const zwp = wayland.client.zwp;
|
||||
const zwlr = wayland.client.zwlr;
|
||||
|
||||
const version = @import("version.zig").getVersion();
|
||||
|
||||
const Context = struct {
|
||||
toplevel_mgr: ?*zwlr.ForeignToplevelManagerV1,
|
||||
idle_inhibit_mgr: ?*zwp.IdleInhibitManagerV1,
|
||||
handles: std.AutoHashMap(*zwlr.ForeignToplevelHandleV1, ToplevelFullscreen),
|
||||
idle_inhibitor: ?*zwp.IdleInhibitorV1,
|
||||
shm: ?*wl.Shm,
|
||||
compositor: ?*wl.Compositor,
|
||||
layer_shell: ?*zwlr.LayerShellV1,
|
||||
surface: ?*wl.Surface,
|
||||
};
|
||||
|
||||
const ToplevelFullscreen = enum { Fullscreen, NotFullscreen };
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
std.log.info("Vegetable Hamper v{}", .{version});
|
||||
|
||||
var context = Context{
|
||||
.toplevel_mgr = null,
|
||||
.idle_inhibit_mgr = null,
|
||||
.handles = std.AutoHashMap(*zwlr.ForeignToplevelHandleV1, ToplevelFullscreen).init(std.heap.page_allocator),
|
||||
.idle_inhibitor = null,
|
||||
.shm = null,
|
||||
.compositor = null,
|
||||
.layer_shell = null,
|
||||
.surface = null,
|
||||
};
|
||||
defer context.handles.deinit();
|
||||
|
||||
const display = try wl.Display.connect(null);
|
||||
const registry = try display.getRegistry();
|
||||
registry.setListener(*Context, registry_listener, &context);
|
||||
|
||||
if (display.roundtrip() != .SUCCESS) {
|
||||
print("Initial roundtrip failed", .{});
|
||||
return error.RoundTripFailed;
|
||||
}
|
||||
|
||||
const compositor = context.compositor orelse return error.NoWlCompositor;
|
||||
const shm = context.shm orelse return error.NoWlShm;
|
||||
const layer_shell = context.layer_shell orelse return error.NoLayerShell;
|
||||
const toplevel_mgr = context.toplevel_mgr orelse return error.NoTopLevelManager;
|
||||
_ = context.idle_inhibit_mgr orelse return error.NoIdleInhibitManager;
|
||||
|
||||
const buffer = blk: {
|
||||
const width = 1;
|
||||
const height = 1;
|
||||
const stride = width * 4;
|
||||
const size = stride * height;
|
||||
|
||||
const fd = try std.posix.memfd_create("vegetable-hamper", 0);
|
||||
try std.posix.ftruncate(fd, size);
|
||||
const data = try std.posix.mmap(null, size, std.posix.PROT.READ | std.posix.PROT.WRITE, .{ .TYPE = .SHARED }, fd, 0);
|
||||
// @memcpy(data, @embedFile("res/cat.bgra"));
|
||||
@memset(data, 0);
|
||||
|
||||
const pool = try shm.createPool(fd, size);
|
||||
defer pool.destroy();
|
||||
|
||||
break :blk try pool.createBuffer(0, width, height, stride, wl.Shm.Format.argb8888);
|
||||
};
|
||||
|
||||
context.surface = try compositor.createSurface();
|
||||
defer context.surface.?.destroy();
|
||||
|
||||
const wlr_surface = try layer_shell.getLayerSurface(context.surface.?, null, .background, "vegetable-hamper");
|
||||
defer wlr_surface.destroy();
|
||||
|
||||
wlr_surface.setSize(1, 1);
|
||||
|
||||
toplevel_mgr.setListener(*Context, toplevel_manager_listener, &context);
|
||||
|
||||
wlr_surface.setListener(*wl.Surface, wlr_surface_listener, context.surface.?);
|
||||
|
||||
context.surface.?.commit();
|
||||
|
||||
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
|
||||
|
||||
context.surface.?.attach(buffer, 0, 0);
|
||||
context.surface.?.commit();
|
||||
|
||||
while (true) {
|
||||
if (display.dispatch() != .SUCCESS) return error.DispatchFailed;
|
||||
}
|
||||
}
|
||||
|
||||
fn wlr_surface_listener(wlr_surface: *zwlr.LayerSurfaceV1, event: zwlr.LayerSurfaceV1.Event, surface: *wl.Surface) void {
|
||||
switch (event) {
|
||||
.configure => |configure| {
|
||||
wlr_surface.ackConfigure(configure.serial);
|
||||
surface.commit();
|
||||
},
|
||||
.closed => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn registry_listener(registry: *wl.Registry, event: wl.Registry.Event, ctx: *Context) void {
|
||||
switch (event) {
|
||||
.global => |global| {
|
||||
if (mem.orderZ(u8, global.interface, zwlr.ForeignToplevelManagerV1.getInterface().name) == .eq) {
|
||||
std.log.debug("Found zwlr_foreign_toplevel_manager_v1", .{});
|
||||
ctx.toplevel_mgr = registry.bind(global.name, zwlr.ForeignToplevelManagerV1, 1) catch return;
|
||||
} else if (mem.orderZ(u8, global.interface, zwp.IdleInhibitManagerV1.getInterface().name) == .eq) {
|
||||
std.log.debug("Found zwp_idle_inhibit_manager_v1", .{});
|
||||
ctx.idle_inhibit_mgr = registry.bind(global.name, zwp.IdleInhibitManagerV1, 1) catch @panic("Error binding idle inhibit manager");
|
||||
} else if (mem.orderZ(u8, global.interface, wl.Compositor.getInterface().name) == .eq) {
|
||||
std.log.debug("Found wl_compositor", .{});
|
||||
ctx.compositor = registry.bind(global.name, wl.Compositor, 1) catch return;
|
||||
} else if (mem.orderZ(u8, global.interface, wl.Shm.getInterface().name) == .eq) {
|
||||
std.log.debug("Found wl_shm", .{});
|
||||
ctx.shm = registry.bind(global.name, wl.Shm, 1) catch return;
|
||||
} else if (mem.orderZ(u8, global.interface, zwlr.LayerShellV1.getInterface().name) == .eq) {
|
||||
std.log.debug("Found wlr_layer_shell", .{});
|
||||
ctx.layer_shell = registry.bind(global.name, zwlr.LayerShellV1, 1) catch return;
|
||||
} else {
|
||||
std.log.debug("Unhandled interface: {s}", .{global.interface});
|
||||
}
|
||||
},
|
||||
.global_remove => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn toplevel_manager_listener(manager: *zwlr.ForeignToplevelManagerV1, event: zwlr.ForeignToplevelManagerV1.Event, ctx: *Context) void {
|
||||
_ = manager;
|
||||
var handles = &ctx.handles;
|
||||
|
||||
switch (event) {
|
||||
.toplevel => |toplevel| {
|
||||
std.log.debug("New toplevel", .{});
|
||||
handles.put(toplevel.toplevel, .NotFullscreen) catch return;
|
||||
|
||||
toplevel.toplevel.setListener(*Context, toplevel_listener, ctx);
|
||||
},
|
||||
.finished => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn toplevel_listener(handle: *zwlr.ForeignToplevelHandleV1, event: zwlr.ForeignToplevelHandleV1.Event, ctx: *Context) void {
|
||||
var handles = &ctx.handles;
|
||||
switch (event) {
|
||||
.state => |stateEvent| {
|
||||
const states = stateEvent.state.slice(c_int);
|
||||
std.log.debug("State: {x}", .{states});
|
||||
for (states) |s| {
|
||||
const state: zwlr.ForeignToplevelHandleV1.State = @enumFromInt(s);
|
||||
switch (state) {
|
||||
.fullscreen => {
|
||||
std.log.debug("Something went fullscreen", .{});
|
||||
ctx.handles.put(handle, .Fullscreen) catch return;
|
||||
if (ctx.idle_inhibitor == null) {
|
||||
ctx.idle_inhibitor = ctx.idle_inhibit_mgr.?.createInhibitor(ctx.surface.?) catch @panic("Error creating idle inhibitor");
|
||||
print("Now hampering vegetation", .{});
|
||||
}
|
||||
},
|
||||
else => {
|
||||
ctx.handles.put(handle, .NotFullscreen) catch return;
|
||||
var values = ctx.handles.valueIterator();
|
||||
const someFullscreen = while (values.next()) |fs| {
|
||||
if (fs.* == .Fullscreen) {
|
||||
break true;
|
||||
}
|
||||
} else false;
|
||||
|
||||
if (!someFullscreen and ctx.idle_inhibitor != null) {
|
||||
ctx.idle_inhibitor.?.destroy();
|
||||
ctx.idle_inhibitor = null;
|
||||
print("No more full screen applications, no more hampering", .{});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
.title => {},
|
||||
.app_id => {},
|
||||
.output_enter => {},
|
||||
.output_leave => {},
|
||||
.done => {},
|
||||
.closed => {
|
||||
std.log.debug("Closed", .{});
|
||||
_ = handles.remove(handle);
|
||||
},
|
||||
.parent => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn print(comptime format: []const u8, args: anytype) void {
|
||||
const stdout_file = std.io.getStdOut().writer();
|
||||
var bw = std.io.bufferedWriter(stdout_file);
|
||||
const stdout = bw.writer();
|
||||
|
||||
stdout.print(format ++ "\n", args) catch @panic("Could not write to stdout");
|
||||
|
||||
bw.flush() catch @panic("Could not flush stdout"); // don't forget to flush!
|
||||
}
|
10
src/root.zig
Normal file
10
src/root.zig
Normal file
|
@ -0,0 +1,10 @@
|
|||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
|
||||
export fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
test "basic add functionality" {
|
||||
try testing.expect(add(3, 7) == 10);
|
||||
}
|
18
src/version.zig
Normal file
18
src/version.zig
Normal file
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn getVersion() Version {
|
||||
return Version{};
|
||||
}
|
||||
const Version = struct {
|
||||
comptime major: u8 = 0,
|
||||
comptime minor: u8 = 1,
|
||||
comptime patch: u8 = 0,
|
||||
const Self = @This();
|
||||
|
||||
pub fn format(self: Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
|
||||
try writer.print("{}.{}.{}", .{ self.major, self.minor, self.patch });
|
||||
}
|
||||
};
|
Loading…
Reference in a new issue