asdfkkk
This commit is contained in:
parent
0c5413eb3a
commit
3da5c0de14
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
|||
[submodule "deps/zig-wayland"]
|
||||
path = deps/zig-wayland
|
||||
url = https://github.com/ifreund/zig-wayland.git
|
||||
[submodule "deps/zig-args"]
|
||||
path = deps/zig-args
|
||||
url = https://github.com/MasterQ32/zig-args.git
|
||||
|
|
46
build.zig
46
build.zig
|
@ -1,4 +1,5 @@
|
|||
const std = @import("std");
|
||||
const ScanProtocolsStep = @import("deps/zig-wayland/build.zig").ScanProtocolsStep;
|
||||
|
||||
pub fn build(b: *std.build.Builder) void {
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
|
@ -11,9 +12,49 @@ pub fn build(b: *std.build.Builder) void {
|
|||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
const exe = b.addExecutable("zlurp", "src/main.zig");
|
||||
const scanner = ScanProtocolsStep.create(b);
|
||||
scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml");
|
||||
scanner.addSystemProtocol("unstable/xdg-output/xdg-output-unstable-v1.xml");
|
||||
scanner.addProtocolPath("protocols/wlr-layer-shell-unstable-v1.xml");
|
||||
|
||||
// Pass the maximum version implemented by your wayland server or client.
|
||||
// Requests, events, enums, etc. from newer versions will not be generated,
|
||||
// ensuring forwards compatibility with newer protocol xml.
|
||||
// This will also generate code for interfaces created using the provided
|
||||
// global interface, in this example wl_keyboard, wl_pointer, xdg_surface,
|
||||
// xdg_toplevel, etc. would be generated.
|
||||
scanner.generate("wl_compositor", 4);
|
||||
scanner.generate("zxdg_output_manager_v1", 1);
|
||||
scanner.generate("zwlr_layer_shell_v1", 1);
|
||||
scanner.generate("wl_shm", 1);
|
||||
scanner.generate("wl_output", 3);
|
||||
scanner.generate("wl_seat", 2);
|
||||
scanner.generate("xdg_wm_base", 1);
|
||||
|
||||
const zig_args = std.build.Pkg{
|
||||
.name = "zig-args",
|
||||
.source = .{.path = "deps/zig-args/args.zig"},
|
||||
};
|
||||
|
||||
const wayland = std.build.Pkg{
|
||||
.name = "wayland",
|
||||
.source = .{ .generated = &scanner.result },
|
||||
};
|
||||
|
||||
const exe = b.addExecutable("zlurp", "main.zig");
|
||||
exe.setTarget(target);
|
||||
exe.setBuildMode(mode);
|
||||
|
||||
exe.step.dependOn(&scanner.step);
|
||||
exe.addPackage(wayland);
|
||||
exe.addPackage(zig_args);
|
||||
exe.linkLibC();
|
||||
exe.linkSystemLibrary("wayland-client");
|
||||
exe.linkSystemLibrary("xkbcommon");
|
||||
exe.linkSystemLibrary("cairo");
|
||||
|
||||
scanner.addCSource(exe);
|
||||
|
||||
exe.install();
|
||||
|
||||
const run_cmd = exe.run();
|
||||
|
@ -25,7 +66,8 @@ pub fn build(b: *std.build.Builder) void {
|
|||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
const exe_tests = b.addTest("src/main.zig");
|
||||
// TESTS
|
||||
const exe_tests = b.addTest("main.zig");
|
||||
exe_tests.setTarget(target);
|
||||
exe_tests.setBuildMode(mode);
|
||||
|
||||
|
|
1
deps/zig-args
vendored
Submodule
1
deps/zig-args
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit f272f2fb25ff86c00fa67051175b8db76b23e402
|
328
main.zig
Normal file
328
main.zig
Normal file
|
@ -0,0 +1,328 @@
|
|||
const std = @import("std");
|
||||
const wayland = @import("zig-wayland/wayland.zig");
|
||||
const zig_args = @import("zig-args");
|
||||
const wl = wayland.client.wl;
|
||||
const xdg = wayland.client.xdg;
|
||||
const zxdg = wayland.client.zxdg;
|
||||
const zwlr = wayland.client.zwlr;
|
||||
const list = wayland.server.wl.list;
|
||||
|
||||
const xkb = @cImport({
|
||||
@cInclude("xkbcommon/xkbcommon.h");
|
||||
});
|
||||
|
||||
const cairo = @cImport({
|
||||
@cInclude("cairo/cairo.h");
|
||||
});
|
||||
|
||||
const Point = struct {
|
||||
x: i32,
|
||||
y: i32,
|
||||
};
|
||||
|
||||
const Size = struct {
|
||||
const Self = @This();
|
||||
width: u32,
|
||||
height: u32,
|
||||
|
||||
|
||||
fn size(self: *Self) usize {
|
||||
return self.width * self.height;
|
||||
}
|
||||
};
|
||||
|
||||
const Box = struct {
|
||||
const Self = @This();
|
||||
|
||||
position: Point,
|
||||
extents: Size,
|
||||
|
||||
fn intersects(self: *const Self, other: *const Self) bool {
|
||||
const x1 = self.position.x;
|
||||
const y1 = self.position.y;
|
||||
const w1 = self.extents.width;
|
||||
const h1 = self.extents.height;
|
||||
|
||||
const x2 = other.position.x;
|
||||
const y2 = other.position.y;
|
||||
const w2 = other.extents.width;
|
||||
const h2 = other.extents.height;
|
||||
|
||||
// return self.x < other.x + other.width and
|
||||
// self.x + self.width > other.x and
|
||||
// self.y < other.y + other.height and
|
||||
// self.height + self.y > other.y;
|
||||
|
||||
return x1 < x2 + w2 and
|
||||
x1 + w1 > x2 and
|
||||
y1 < y1 + h2 and
|
||||
y1 + h1 > y2;
|
||||
}
|
||||
|
||||
fn contains(self: *Self, point: Point) bool {
|
||||
const x1 = self.position.x;
|
||||
const y1 = self.position.y;
|
||||
const w1 = self.extents.width;
|
||||
const h1 = self.extents.height;
|
||||
|
||||
const x2 = point.x;
|
||||
const y2 = point.y;
|
||||
|
||||
// return self.x <= point.x and self.x + self.width > point.x and
|
||||
// self.y <= point.y and self.y + self.height > point.y;
|
||||
|
||||
return x1 <= x2 and x1 + w1 > x2 and
|
||||
y1 <= y2 and y1 + h1 > y2;
|
||||
}
|
||||
|
||||
fn size(self: *Self) usize {
|
||||
return self.extents.size();
|
||||
}
|
||||
};
|
||||
|
||||
fn ListItem(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
link: list.Link,
|
||||
value: T,
|
||||
|
||||
fn Head() type {
|
||||
list.Head(Self, "link");
|
||||
}
|
||||
|
||||
fn fromLink(link: *list.Link) *Self {
|
||||
return @fieldParentPtr(Self, "link", link);
|
||||
}
|
||||
|
||||
fn remove(self: *Self) void {
|
||||
self.link.remove();
|
||||
}
|
||||
|
||||
fn next(self: *Self) ?*list.Link {
|
||||
self.link.next();
|
||||
}
|
||||
|
||||
fn prev(self: *Self) ?*list.Link {
|
||||
self.link.prev();
|
||||
}
|
||||
|
||||
fn getLink(self: *Self) *list.Link {
|
||||
return &self.link;
|
||||
}
|
||||
|
||||
fn get(self: *Self) *T {
|
||||
return &self.value;
|
||||
}
|
||||
|
||||
fn getConst(self: *const Self) *const T {
|
||||
return &self.value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const Options = struct {
|
||||
const Self = @This();
|
||||
|
||||
help: bool = false,
|
||||
@"display-dimensions": bool = false,
|
||||
background: ?u32 = null,
|
||||
border: ?u32 = null,
|
||||
selection: ?u32 = null,
|
||||
choice: ?u32 = null,
|
||||
format: ?[]const u8 = null,
|
||||
@"font-family": ?[]const u8 = null,
|
||||
@"border-weight": ?u32 = null,
|
||||
@"single-point": bool = false,
|
||||
@"output-boxes": bool = false,
|
||||
@"restrict-selection": bool = false,
|
||||
// TODO: parse this in the format of W:H instead of a fraction
|
||||
@"aspect-ratio": ?f64 = null,
|
||||
|
||||
pub const shorthands = .{
|
||||
.h = "help",
|
||||
.b = "background",
|
||||
.c = "border",
|
||||
.s = "selection",
|
||||
.B = "choice",
|
||||
.f = "format",
|
||||
.F = "font-family",
|
||||
.w = "border-weight",
|
||||
.p = "single-point",
|
||||
.o = "output-boxes",
|
||||
.r = "restrict-selection",
|
||||
.a = "aspect-ratio",
|
||||
};
|
||||
|
||||
const usage = @embedFile("usage");
|
||||
|
||||
fn parse() !zig_args.ParseArgsResult(Self, null) {
|
||||
const self = try zig_args.parseForCurrentProcess(Self, std.heap.page_allocator, .print);
|
||||
// TODO: print help
|
||||
|
||||
return self;
|
||||
}
|
||||
};
|
||||
|
||||
const State = struct {
|
||||
const Uninit = struct {
|
||||
const Self = @This();
|
||||
|
||||
ally: std.mem.Allocator = std.heap.c_allocator,
|
||||
|
||||
dpy: *wl.Display = undefined,
|
||||
registry: *wl.Registry = undefined,
|
||||
|
||||
shm: ?*wl.Shm = null,
|
||||
compositor: ?*wl.Compositor = null,
|
||||
layer_shell: ?*zwlr.LayerShellV1 = null,
|
||||
xdg_output_manager: ?*zxdg.OutputManagerV1 = null,
|
||||
|
||||
fn create() !*Self {
|
||||
const ally = std.heap.c_allocator;
|
||||
|
||||
const dpy = try wl.Display.connect(null);
|
||||
const registry = try dpy.getRegistry();
|
||||
|
||||
const self = try ally.create(Self);
|
||||
|
||||
self.* = .{
|
||||
.ally = ally,
|
||||
.dpy = dpy,
|
||||
.registry = registry,
|
||||
};
|
||||
|
||||
registry.setListener(*Self, registryListener, self);
|
||||
if (dpy.roundtrip() != .SUCCESS) return error.RoundtripFailed;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
fn deinit(self: *Self) !void {
|
||||
self.ally.destroy(self);
|
||||
}
|
||||
|
||||
fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, self: *Self) void {
|
||||
switch (event) {
|
||||
.global => |global| {
|
||||
if (std.cstr.cmp(global.interface, wl.Compositor.getInterface().name) == 0) {
|
||||
self.compositor = registry.bind(global.name, wl.Compositor, 4) catch return;
|
||||
} else if (std.cstr.cmp(global.interface, wl.Shm.getInterface().name) == 0) {
|
||||
self.shm = registry.bind(global.name, wl.Shm, 1) catch return;
|
||||
} else if (std.cstr.cmp(global.interface, zwlr.LayerShellV1.getInterface().name) == 0) {
|
||||
self.layer_shell = registry.bind(global.name, zwlr.LayerShellV1, 1) catch return;
|
||||
} else if (std.cstr.cmp(global.interface, zxdg.OutputManagerV1.getInterface().name) == 0) {
|
||||
self.xdg_output_manager = registry.bind(global.name, zxdg.OutputManagerV1, 2) catch
|
||||
return;
|
||||
}
|
||||
},
|
||||
.global_remove => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn intoInit(self: *Self) !*Init {
|
||||
// free self at end of this function
|
||||
defer self.ally.destroy(self);
|
||||
|
||||
const init = try self.ally.create(Init);
|
||||
// free allocated memory if not returning it
|
||||
errdefer self.ally.destroy(init);
|
||||
|
||||
const xkb_context = xkb.xkb_context_new(xkb.XKB_CONTEXT_NO_FLAGS) orelse
|
||||
return error.NoXkbContext;
|
||||
// free xkb_context if we fail to initialize the state
|
||||
errdefer xkb.xkb_context_unref(xkb_context);
|
||||
|
||||
const cursor_theme = std.process.getEnvVarOwned(self.ally, "XCURSOR_THEME") catch "";
|
||||
// only free cursor_theme if bailing
|
||||
errdefer self.ally.free(cursor_theme);
|
||||
|
||||
const buf = try std.process.getEnvVarOwned(self.ally, "XCURSOR_SIZE");
|
||||
defer self.ally.free(buf);
|
||||
|
||||
const cursor_size = std.fmt.parseInt(u32, buf, 10) catch return error.InvalidXCursorSize;
|
||||
|
||||
// i hope this is fine but appears to be requried to reset the listener on the registry
|
||||
self.registry.destroy();
|
||||
const registry = try self.dpy.getRegistry();
|
||||
|
||||
init.* = Init {
|
||||
.ally = self.ally,
|
||||
.dpy = self.dpy,
|
||||
.registry = registry,
|
||||
|
||||
// these 4 fields are set by the registry listener so they may be null at this point
|
||||
// treat that as a hard error tho.
|
||||
.shm = self.shm orelse return error.NoWlShm,
|
||||
.compositor = self.compositor orelse return error.NoWlCompositor,
|
||||
.layer_shell = self.layer_shell orelse return error.NoWlrLayerShell,
|
||||
.xdg_output_manager = self.xdg_output_manager orelse return error.NoXdgOutputManager,
|
||||
|
||||
// these 3 fields should never be null because init() will bail if these functions fail
|
||||
.xkb_context = xkb_context,
|
||||
.cursor_theme = cursor_theme,
|
||||
.cursor_size = cursor_size,
|
||||
};
|
||||
|
||||
init.registry.setListener(*Init, Init.registryListener, init);
|
||||
|
||||
return init;
|
||||
}
|
||||
};
|
||||
|
||||
const Init = struct {
|
||||
const Self = @This();
|
||||
|
||||
ally: std.mem.Allocator = std.heap.c_allocator,
|
||||
|
||||
dpy: *wl.Display = undefined,
|
||||
registry: *wl.Registry = undefined,
|
||||
|
||||
shm: *wl.Shm = undefined,
|
||||
compositor: *wl.Compositor = undefined,
|
||||
layer_shell: *zwlr.LayerShellV1 = undefined,
|
||||
xdg_output_manager: *zxdg.OutputManagerV1 = undefined,
|
||||
|
||||
xkb_context: *xkb.xkb_context = undefined,
|
||||
|
||||
cursor_theme: []const u8 = undefined,
|
||||
cursor_size: u32 = undefined,
|
||||
|
||||
fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, self: *Self) void {
|
||||
_ = registry;
|
||||
_ = self;
|
||||
std.debug.print("registryListener called after init", .{});
|
||||
switch (event) {
|
||||
.global => {},
|
||||
.global_remove => {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn deinit(self: *Self) void {
|
||||
defer self.ally.destroy(self);
|
||||
|
||||
self.shm.destroy();
|
||||
self.compositor.destroy();
|
||||
self.layer_shell.destroy();
|
||||
self.xdg_output_manager.destroy();
|
||||
xkb.xkb_context_unref(self.xkb_context);
|
||||
self.registry.destroy();
|
||||
|
||||
self.ally.free(self.cursor_theme);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
pub fn main() !void {
|
||||
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
|
||||
std.debug.print("All your {s} are belong to us.\n", .{"codebase"});
|
||||
|
||||
const state = try State.Uninit.create();
|
||||
const init = try state.intoInit();
|
||||
|
||||
_ = try std.io.getStdIn().reader().readByte();
|
||||
|
||||
defer init.deinit();
|
||||
}
|
285
protocols/wlr-layer-shell-unstable-v1.xml
Normal file
285
protocols/wlr-layer-shell-unstable-v1.xml
Normal file
|
@ -0,0 +1,285 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_layer_shell_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2017 Drew DeVault
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwlr_layer_shell_v1" version="1">
|
||||
<description summary="create surfaces that are layers of the desktop">
|
||||
Clients can use this interface to assign the surface_layer role to
|
||||
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
rendered with a defined z-depth respective to each other. They may also be
|
||||
anchored to the edges and corners of a screen and specify input handling
|
||||
semantics. This interface should be suitable for the implementation of
|
||||
many desktop shell components, and a broad number of other applications
|
||||
that interact with the desktop.
|
||||
</description>
|
||||
|
||||
<request name="get_layer_surface">
|
||||
<description summary="create a layer_surface from a surface">
|
||||
Create a layer surface for an existing surface. This assigns the role of
|
||||
layer_surface, or raises a protocol error if another role is already
|
||||
assigned.
|
||||
|
||||
Creating a layer surface from a wl_surface which has a buffer attached
|
||||
or committed is a client error, and any attempts by a client to attach
|
||||
or manipulate a buffer prior to the first layer_surface.configure call
|
||||
must also be treated as errors.
|
||||
|
||||
You may pass NULL for output to allow the compositor to decide which
|
||||
output to use. Generally this will be the one that the user most
|
||||
recently interacted with.
|
||||
|
||||
Clients can specify a namespace that defines the purpose of the layer
|
||||
surface.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
<arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
|
||||
<arg name="namespace" type="string" summary="namespace for the layer surface"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="role" value="0" summary="wl_surface has another role"/>
|
||||
<entry name="invalid_layer" value="1" summary="layer value is invalid"/>
|
||||
<entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/>
|
||||
</enum>
|
||||
|
||||
<enum name="layer">
|
||||
<description summary="available layers for surfaces">
|
||||
These values indicate which layers a surface can be rendered in. They
|
||||
are ordered by z depth, bottom-most first. Traditional shell surfaces
|
||||
will typically be rendered between the bottom and top layers.
|
||||
Fullscreen shell surfaces are typically rendered at the top layer.
|
||||
Multiple surfaces can share a single layer, and ordering within a
|
||||
single layer is undefined.
|
||||
</description>
|
||||
|
||||
<entry name="background" value="0"/>
|
||||
<entry name="bottom" value="1"/>
|
||||
<entry name="top" value="2"/>
|
||||
<entry name="overlay" value="3"/>
|
||||
</enum>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_layer_surface_v1" version="1">
|
||||
<description summary="layer metadata interface">
|
||||
An interface that may be implemented by a wl_surface, for surfaces that
|
||||
are designed to be rendered as a layer of a stacked desktop-like
|
||||
environment.
|
||||
|
||||
Layer surface state (size, anchor, exclusive zone, margin, interactivity)
|
||||
is double-buffered, and will be applied at the time wl_surface.commit of
|
||||
the corresponding wl_surface is called.
|
||||
</description>
|
||||
|
||||
<request name="set_size">
|
||||
<description summary="sets the size of the surface">
|
||||
Sets the size of the surface in surface-local coordinates. The
|
||||
compositor will display the surface centered with respect to its
|
||||
anchors.
|
||||
|
||||
If you pass 0 for either value, the compositor will assign it and
|
||||
inform you of the assignment in the configure event. You must set your
|
||||
anchor to opposite edges in the dimensions you omit; not doing so is a
|
||||
protocol error. Both values are 0 by default.
|
||||
|
||||
Size is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="set_anchor">
|
||||
<description summary="configures the anchor point of the surface">
|
||||
Requests that the compositor anchor the surface to the specified edges
|
||||
and corners. If two orthoginal edges are specified (e.g. 'top' and
|
||||
'left'), then the anchor point will be the intersection of the edges
|
||||
(e.g. the top left corner of the output); otherwise the anchor point
|
||||
will be centered on that edge, or in the center if none is specified.
|
||||
|
||||
Anchor is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="anchor" type="uint" enum="anchor"/>
|
||||
</request>
|
||||
|
||||
<request name="set_exclusive_zone">
|
||||
<description summary="configures the exclusive geometry of this surface">
|
||||
Requests that the compositor avoids occluding an area of the surface
|
||||
with other surfaces. The compositor's use of this information is
|
||||
implementation-dependent - do not assume that this region will not
|
||||
actually be occluded.
|
||||
|
||||
A positive value is only meaningful if the surface is anchored to an
|
||||
edge, rather than a corner. The zone is the number of surface-local
|
||||
coordinates from the edge that are considered exclusive.
|
||||
|
||||
Surfaces that do not wish to have an exclusive zone may instead specify
|
||||
how they should interact with surfaces that do. If set to zero, the
|
||||
surface indicates that it would like to be moved to avoid occluding
|
||||
surfaces with a positive excluzive zone. If set to -1, the surface
|
||||
indicates that it would not like to be moved to accomodate for other
|
||||
surfaces, and the compositor should extend it all the way to the edges
|
||||
it is anchored to.
|
||||
|
||||
For example, a panel might set its exclusive zone to 10, so that
|
||||
maximized shell surfaces are not shown on top of it. A notification
|
||||
might set its exclusive zone to 0, so that it is moved to avoid
|
||||
occluding the panel, but shell surfaces are shown underneath it. A
|
||||
wallpaper or lock screen might set their exclusive zone to -1, so that
|
||||
they stretch below or over the panel.
|
||||
|
||||
The default value is 0.
|
||||
|
||||
Exclusive zone is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="zone" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_margin">
|
||||
<description summary="sets a margin from the anchor point">
|
||||
Requests that the surface be placed some distance away from the anchor
|
||||
point on the output, in surface-local coordinates. Setting this value
|
||||
for edges you are not anchored to has no effect.
|
||||
|
||||
The exclusive zone includes the margin.
|
||||
|
||||
Margin is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="top" type="int"/>
|
||||
<arg name="right" type="int"/>
|
||||
<arg name="bottom" type="int"/>
|
||||
<arg name="left" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_keyboard_interactivity">
|
||||
<description summary="requests keyboard events">
|
||||
Set to 1 to request that the seat send keyboard events to this layer
|
||||
surface. For layers below the shell surface layer, the seat will use
|
||||
normal focus semantics. For layers above the shell surface layers, the
|
||||
seat will always give exclusive keyboard focus to the top-most layer
|
||||
which has keyboard interactivity set to true.
|
||||
|
||||
Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||
you do not want to receive them, set the input region on your surface
|
||||
to an empty region.
|
||||
|
||||
Events is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="keyboard_interactivity" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="get_popup">
|
||||
<description summary="assign this layer_surface as an xdg_popup parent">
|
||||
This assigns an xdg_popup's parent to this layer_surface. This popup
|
||||
should have been created via xdg_surface::get_popup with the parent set
|
||||
to NULL, and this request must be invoked before committing the popup's
|
||||
initial state.
|
||||
|
||||
See the documentation of xdg_popup for more details about what an
|
||||
xdg_popup is and how it is used.
|
||||
</description>
|
||||
<arg name="popup" type="object" interface="xdg_popup"/>
|
||||
</request>
|
||||
|
||||
<request name="ack_configure">
|
||||
<description summary="ack a configure event">
|
||||
When a configure event is received, if a client commits the
|
||||
surface in response to the configure event, then the client
|
||||
must make an ack_configure request sometime before the commit
|
||||
request, passing along the serial of the configure event.
|
||||
|
||||
If the client receives multiple configure events before it
|
||||
can respond to one, it only has to ack the last configure event.
|
||||
|
||||
A client is not required to commit immediately after sending
|
||||
an ack_configure request - it may even ack_configure several times
|
||||
before its next surface commit.
|
||||
|
||||
A client may send multiple ack_configure requests before committing, but
|
||||
only the last request sent before a commit indicates which configure
|
||||
event the client really is responding to.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the layer_surface">
|
||||
This request destroys the layer surface.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="configure">
|
||||
<description summary="suggest a surface change">
|
||||
The configure event asks the client to resize its surface.
|
||||
|
||||
Clients should arrange their surface for the new states, and then send
|
||||
an ack_configure request with the serial sent in this configure event at
|
||||
some point before committing the new surface.
|
||||
|
||||
The client is free to dismiss all but the last configure event it
|
||||
received.
|
||||
|
||||
The width and height arguments specify the size of the window in
|
||||
surface-local coordinates.
|
||||
|
||||
The size is a hint, in the sense that the client is free to ignore it if
|
||||
it doesn't resize, pick a smaller size (to satisfy aspect ratio or
|
||||
resize in steps of NxM pixels). If the client picks a smaller size and
|
||||
is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
|
||||
surface will be centered on this axis.
|
||||
|
||||
If the width or height arguments are zero, it means the client should
|
||||
decide its own window dimension.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="closed">
|
||||
<description summary="surface should be closed">
|
||||
The closed event is sent by the compositor when the surface will no
|
||||
longer be shown. The output may have been destroyed or the user may
|
||||
have asked for it to be removed. Further changes to the surface will be
|
||||
ignored. The client should destroy the resource after receiving this
|
||||
event, and create a new surface if they so choose.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
|
||||
<entry name="invalid_size" value="1" summary="size is invalid"/>
|
||||
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
|
||||
</enum>
|
||||
|
||||
<enum name="anchor" bitfield="true">
|
||||
<entry name="top" value="1" summary="the top edge of the anchor rectangle"/>
|
||||
<entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/>
|
||||
<entry name="left" value="4" summary="the left edge of the anchor rectangle"/>
|
||||
<entry name="right" value="8" summary="the right edge of the anchor rectangle"/>
|
||||
</enum>
|
||||
</interface>
|
||||
</protocol>
|
57
src/main.zig
57
src/main.zig
|
@ -1,57 +0,0 @@
|
|||
const std = @import("std");
|
||||
|
||||
const VecN = std.meta.Vector;
|
||||
|
||||
const Rgba32 = union {
|
||||
comps: struct { r: u32, g: u32, b: u32, a: u32 },
|
||||
rgba: u64,
|
||||
};
|
||||
|
||||
const State = struct {
|
||||
colors: struct { background: Rgba32, border: Rgba32, selection: Rgba32, choice: Rgba32 },
|
||||
border_weight: u8,
|
||||
display_dimensions: bool,
|
||||
restrict_selection: bool,
|
||||
fixed_aspect_ratio: bool,
|
||||
aspect_ratio: f32,
|
||||
// font_family
|
||||
};
|
||||
|
||||
fn defaultState() State {
|
||||
return State{
|
||||
.colors = .{
|
||||
.background = .{ .rgba = 0xFFFFFF40 },
|
||||
.border = .{ .rgba = 0x000000FF },
|
||||
.selection = .{ .rgba = 0x00000000 },
|
||||
.choice = .{ .rgba = 0xFFFFFF40 },
|
||||
},
|
||||
.border_weight = 2,
|
||||
.display_dimensions = false,
|
||||
.restrict_selection = false,
|
||||
.fixed_aspect_ratio = false,
|
||||
.aspect_ratio = 0,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
|
||||
std.debug.print("All your {s} are belong to us.\n", .{"codebase"});
|
||||
|
||||
// stdout is for the actual output of your application, for example if you
|
||||
// are implementing gzip, then only the compressed bytes should be sent to
|
||||
// stdout, not any debugging messages.
|
||||
const stdout_file = std.io.getStdOut().writer();
|
||||
var bw = std.io.bufferedWriter(stdout_file);
|
||||
const stdout = bw.writer();
|
||||
|
||||
try stdout.print("Run `zig build test` to run the tests.\n", .{});
|
||||
|
||||
try bw.flush(); // don't forget to flush!
|
||||
}
|
||||
|
||||
test "simple test" {
|
||||
var list = std.ArrayList(i32).init(std.testing.allocator);
|
||||
defer list.deinit(); // try commenting this out and see if zig detects the memory leak!
|
||||
try list.append(42);
|
||||
try std.testing.expectEqual(@as(i32, 42), list.pop());
|
||||
}
|
15
usage
Normal file
15
usage
Normal file
|
@ -0,0 +1,15 @@
|
|||
Usage: slurp [options...]
|
||||
|
||||
--help -h Show help message and quit.
|
||||
--display-dimensions -d Display dimensions of selection.
|
||||
--background -b #rrggbbaa Set background color.
|
||||
--border -c #rrggbbaa Set border color.
|
||||
--selection -s #rrggbbaa Set selection color.
|
||||
--choice -B #rrggbbaa Set option box color.
|
||||
--font-family -F s Set the font family for the dimensions.
|
||||
--border-weight -w n Set border weight.
|
||||
--format -f s Set output format.
|
||||
--output-boxes -o Select a display output.
|
||||
--single-point -p Select a single point.
|
||||
--restrict-selection -r Restrict selection to predefined boxes.
|
||||
--aspect-ratio -a w:h Force aspect ratio.
|
1
zig-wayland
Symbolic link
1
zig-wayland
Symbolic link
|
@ -0,0 +1 @@
|
|||
zig-cache/zig-wayland
|
Loading…
Reference in a new issue