Skip to content

Commit

Permalink
scrollable wip
Browse files Browse the repository at this point in the history
  • Loading branch information
psnszsn committed Apr 29, 2024
1 parent a5ea6df commit d6b2986
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 81 deletions.
10 changes: 7 additions & 3 deletions apps/fontviewer/fontviewer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const PopupHandler = struct {
const rect = data.layout.get(idx, .rect);
const popup = app.new_surface(.{ .xdg_popup = .{
.anchor = rect,
.parent = data.parent.wl.xdg_toplevel.xdg_surface,
.parent = data.parent.role.xdg_toplevel.xdg_surface,
} }, data.widget) catch unreachable;
data.wl_surface = popup.wl_surface;
},
Expand Down Expand Up @@ -111,6 +111,7 @@ pub fn main() !void {
.font = app.font,
};

var scrollable: WidgetIdx = undefined;
const main_widget = b: {
const flex = layout.add2(.flex, .{ .orientation = .vertical });
const menu_bar = c: {
Expand All @@ -130,8 +131,11 @@ pub fn main() !void {
.columns = 32,
.font = app.font,
});
scrollable = layout.add2(.scrollable, .{});
layout.set(scrollable, .flex, 1);

layout.set_handler2(font_map, &font_map_handler, &s);
layout.set(flex, .children, &.{ menu_bar, font_map, font_view });
layout.set(flex, .children, &.{ menu_bar, font_map, font_view, scrollable });

s.connect(.selected_range, font_map, FontMap, .selected_range);
s.connect(.selected_glyph, font_map, FontMap, .selected_code_point);
Expand Down Expand Up @@ -161,7 +165,7 @@ pub fn main() !void {
};
const btn = layout.add2(.button, .{});
const sub_w = try app.new_surface(.{ .wl_subsurface = .{ .parent = bar.wl_surface } }, btn);
_ = sub_w; // autofix
layout.set(scrollable, .subsurface, sub_w.wl_surface);

try app.client.recvEvents();
}
Expand Down
5 changes: 3 additions & 2 deletions src/client.zig
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,11 @@ pub const Client = struct {
}
}
pub fn bind(client: *Client, idx: wl.Registry, _name: u32, comptime T: type, _version: u32) T {
const v = @min(T.interface.version, _version);
var _args = [_]Argument{
.{ .uint = _name },
.{ .string = T.interface.name },
.{ .uint = _version },
.{ .uint = v },
.{ .new_id = 0 },
};
const proxy = Proxy{ .client = client, .id = @intFromEnum(idx) };
Expand All @@ -341,7 +342,7 @@ fn displayListener(client: *Client, _: wl.Display, event: wl.Display.Event, _: ?
},
.delete_id => |del| {
const id = del.id;
std.log.info("del id {}", .{id});
// std.log.info("del id {}", .{id});
std.debug.assert(client.objects.items(.is_free)[id] == false);
client.objects.items(.is_free)[id] = true;
},
Expand Down
28 changes: 16 additions & 12 deletions toolkit/App.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ cursor_shape: wp.CursorShapeDeviceV1.Shape = .default,

// surfaces: std.ArrayListUnmanaged(Surface) = .{},
surfaces: std.AutoHashMapUnmanaged(wl.Surface, Surface) = .{},
subsurfaces: std.AutoHashMapUnmanaged(wl.Subsurface, Surface) = .{},
active_surface: ?wl.Surface = null,

layout: Layout = .{},
Expand Down Expand Up @@ -56,10 +55,10 @@ pub fn deinit(app: *App) void {
alloc.destroy(app);
}

pub fn new_surface(app: *App, opts: Surface.SurfaceInitOpts, root_widget: WidgetIdx) !*Surface {
pub fn new_surface(app: *App, opts: Surface.SurfaceRoleInit, root_widget: WidgetIdx) !*Surface {
const surf = try new_common(app, root_widget);

surf.wl = Surface.init_wl(surf, opts);
surf.role = Surface.init_role(surf, opts);

app.client.request(surf.wl_surface, .commit, {});
return surf;
Expand All @@ -74,12 +73,13 @@ pub fn new_common(app: *App, root_widget: WidgetIdx) !*Surface {
const surf = result.value_ptr;

const size = app.layout.call(root_widget, .size, .{Size.Minmax.ZERO});
app.layout.set(root_widget, .rect, size.to_rect());
surf.* = .{
.app = app,
.wl_surface = wl_surface,
.wl = undefined,
.size = size,
.role = undefined,
.min_size = size,
.size = size,
.last_frame = 0,
.root = root_widget,
};
Expand All @@ -101,19 +101,19 @@ pub fn registry_listener(client: *wlnd.Client, registry: wl.Registry, event: wl.
switch (event) {
.global => |global| {
if (std.mem.orderZ(u8, global.interface, wl.Compositor.interface.name) == .eq) {
context.compositor = client.bind(registry, global.name, wl.Compositor, 1);
context.compositor = client.bind(registry, global.name, wl.Compositor, global.version);
} else if (std.mem.orderZ(u8, global.interface, wl.Shm.interface.name) == .eq) {
context.shm = client.bind(registry, global.name, wl.Shm, 1);
context.shm = client.bind(registry, global.name, wl.Shm, global.version);
} else if (std.mem.orderZ(u8, global.interface, xdg.WmBase.interface.name) == .eq) {
context.wm_base = client.bind(registry, global.name, xdg.WmBase, 1);
context.wm_base = client.bind(registry, global.name, xdg.WmBase, global.version);
} else if (std.mem.orderZ(u8, global.interface, zwlr.LayerShellV1.interface.name) == .eq) {
context.layer_shell = client.bind(registry, global.name, zwlr.LayerShellV1, 1);
context.layer_shell = client.bind(registry, global.name, zwlr.LayerShellV1, global.version);
} else if (std.mem.orderZ(u8, global.interface, wp.CursorShapeManagerV1.interface.name) == .eq) {
context.cursor_shape_manager = client.bind(registry, global.name, wp.CursorShapeManagerV1, 1);
context.cursor_shape_manager = client.bind(registry, global.name, wp.CursorShapeManagerV1, global.version);
} else if (std.mem.orderZ(u8, global.interface, wl.Subcompositor.interface.name) == .eq) {
context.subcompositor = client.bind(registry, global.name, wl.Subcompositor, 1);
context.subcompositor = client.bind(registry, global.name, wl.Subcompositor, global.version);
} else if (std.mem.orderZ(u8, global.interface, wl.Seat.interface.name) == .eq) {
context.seat = client.bind(registry, global.name, wl.Seat, 1);
context.seat = client.bind(registry, global.name, wl.Seat, global.version);
client.set_listener(context.seat.?, *App, seat_listener, context);
}
},
Expand Down Expand Up @@ -167,6 +167,10 @@ fn pointer_listener(client: *wlnd.Client, _: wl.Pointer, _event: wl.Pointer.Even
.button => |ev| blk: {
break :blk .{ .button = .{ .button = @enumFromInt(ev.button), .state = ev.state } };
},
.frame => |_| blk: {
// TODO
break :blk null;
},
else => |d| blk: {
std.log.info("pointer event: {}", .{d});
break :blk null;
Expand Down
114 changes: 63 additions & 51 deletions toolkit/Surface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ app: *App,
root: WidgetIdx = undefined,

wl_surface: wl.Surface,
wl: union(SurfaceType) {
role: union(SurfaceRole) {
const Role = @This();
xdg_toplevel: struct {
xdg_surface: xdg.Surface,
xdg_toplevel: xdg.Toplevel,
Expand All @@ -12,35 +13,45 @@ wl: union(SurfaceType) {
xdg_popup: xdg.Popup,
},
wlr_layer_surface: zwlr.LayerSurfaceV1,
wl_subsurface: wl.Subsurface,
wl_subsurface: struct {
wl_subsurface: wl.Subsurface,
pub fn set_position(self: *@This(), x: u32, y: u32) void {
const role: *Role = @fieldParentPtr("wl_subsurface", self);
const surface: *Surface = @alignCast(@fieldParentPtr("role", role));
const client = surface.app.client;

client.request(self.wl_subsurface, .set_position, .{ .x = @intCast(x), .y = @intCast(y) });
client.request(surface.wl_surface, .commit, {});
}
},
},
size: Size,
min_size: Size,
last_frame: u32,
frame_done: bool = true,
initial_draw: bool = false,

pub const SurfaceType = enum {
pub const SurfaceRole = enum {
xdg_toplevel,
xdg_popup,
wlr_layer_surface,
wl_subsurface,
};

pub const SurfaceInitOpts = union(SurfaceType) {
pub const SurfaceRoleInit = union(SurfaceRole) {
xdg_toplevel: void,
xdg_popup: struct { parent: xdg.Surface, anchor: Rect },
wlr_layer_surface: void,
wl_subsurface: struct { parent: wl.Surface },
};

pub fn init_wl(
pub fn init_role(
surface: *Surface,
stype: SurfaceInitOpts,
) std.meta.FieldType(Surface, .wl) {
role: SurfaceRoleInit,
) std.meta.FieldType(Surface, .role) {
const app = surface.app;
const client = app.client;
switch (stype) {
switch (role) {
.wlr_layer_surface => {
std.debug.assert(app.layer_shell != null);
const layer_surface = client.request(app.layer_shell.?, .get_layer_surface, .{
Expand All @@ -67,8 +78,8 @@ pub fn init_wl(
client.set_listener(xdg_toplevel, *Surface, Surface.xdg_toplevel_listener, surface);
client.request(xdg_toplevel, .set_title, .{ .title = "Demo" });
client.request(xdg_toplevel, .set_min_size, .{
.width = @intCast(surface.size.width),
.height = @intCast(surface.size.height),
.width = @intCast(surface.min_size.width),
.height = @intCast(surface.min_size.height),
});

return .{ .xdg_toplevel = .{
Expand All @@ -82,10 +93,12 @@ pub fn init_wl(
.parent = opts.parent,
});
// errdefer client.request(wl_subsurface), .destroy, {});
client.request(wl_subsurface, .set_sync, {});
client.request(wl_subsurface, .set_desync, {});
client.request(wl_subsurface, .set_position, .{ .x = 500, .y = 22 });

return .{ .wl_subsurface = wl_subsurface };
surface.draw();

return .{ .wl_subsurface = .{ .wl_subsurface = wl_subsurface } };
},
.xdg_popup => |opts| {
const xdg_surface = client.request(app.wm_base.?, .get_xdg_surface, .{ .surface = surface.wl_surface });
Expand All @@ -95,8 +108,8 @@ pub fn init_wl(
defer client.request(positioner, .destroy, {});

client.request(positioner, .set_size, .{
.width = @intCast(surface.size.width),
.height = @intCast(surface.size.height),
.width = @intCast(surface.min_size.width),
.height = @intCast(surface.min_size.height),
});
const anchor_rect = opts.anchor;
client.request(positioner, .set_anchor_rect, .{
Expand Down Expand Up @@ -129,20 +142,16 @@ pub fn destroy(self: *Surface) void {
const client = self.app.client;
// const index = (@intFromPtr(self) - @intFromPtr(self.app.surfaces.items.ptr)) / @sizeOf(Surface);
// std.log.info("index: {}", .{index});
switch (self.wl) {
switch (self.role) {
.xdg_popup => |x| {
client.request(x.xdg_popup, .destroy, {});
client.request(x.xdg_surface, .destroy, {});
},
.xdg_toplevel => |x| {
_ = x; // autofix
},
.xdg_toplevel => |_| {},

.wlr_layer_surface => |x| {
_ = x; // autofix
},
.wlr_layer_surface => |_| {},
.wl_subsurface => |x| {
client.request(x, .destroy, {});
client.request(x.wl_subsurface, .destroy, {});
},
}
client.request(self.wl_surface, .destroy, {});
Expand All @@ -159,10 +168,11 @@ pub fn schedule_redraw(self: *Surface) void {
}

pub fn draw(self: *Surface) void {
std.log.info("draw {}", .{std.meta.activeTag(self.wl)});
std.log.info("draw {}", .{std.meta.activeTag(self.role)});
const client = self.app.client;
const buf = Buffer.get(self.app.client, self.app.shm.?, self.size.width, self.size.height) catch unreachable;
if (self.size.contains(self.min_size)) {
const size = self.app.layout.get(self.root, .rect).get_size();
const buf = Buffer.get(self.app.client, self.app.shm.?, size.width, size.height) catch unreachable;
if (size.contains(self.min_size)) {
const ctx = PaintCtx{
.buffer = @ptrCast(std.mem.bytesAsSlice(u32, buf.pool.mmap)),
//TODO: use ptrCast directly when implemented in zig
Expand All @@ -176,7 +186,7 @@ pub fn draw(self: *Surface) void {
@memset(buf.pool.mmap, 200);
}
client.request(self.wl_surface, .attach, .{ .buffer = buf.wl_buffer, .x = 0, .y = 0 });
client.request(self.wl_surface, .damage, .{
client.request(self.wl_surface, .damage_buffer, .{
.x = 0,
.y = 0,
.width = std.math.maxInt(i32),
Expand Down Expand Up @@ -222,12 +232,14 @@ fn layer_suface_listener(client: *wlnd.Client, layer_suface: zwlr.LayerSurfaceV1
surf.initial_draw = true;
}

surf.size = .{
const size = Size{
.width = configure.width,
.height = configure.height,
};

std.log.info("w: {} h: {}", .{ surf.size.width, surf.size.height });
surf.app.layout.set(surf.root, .rect, size.to_rect());

// std.log.info("w: {} h: {}", .{ surf.size.width, surf.size.height });

// if (self.anchor.top and self.anchor.bottom) {
// self.size.height = @as(usize, @intCast(configure.height));
Expand Down Expand Up @@ -255,53 +267,53 @@ fn frame_listener(_: *wlnd.Client, _: wl.Callback, event: wl.Callback.Event, sur
}
}

fn xdg_surface_listener(client: *wlnd.Client, xdg_surface: xdg.Surface, event: xdg.Surface.Event, win: *Surface) void {
fn xdg_surface_listener(client: *wlnd.Client, xdg_surface: xdg.Surface, event: xdg.Surface.Event, surf: *Surface) void {
switch (event) {
.configure => |configure| {
std.log.info("configure={}", .{configure});
client.request(xdg_surface, .ack_configure, .{ .serial = configure.serial });
if (!win.initial_draw) {
win.draw();
var it = win.app.surfaces.valueIterator();
while (it.next()) |surface| {
if (surface.wl == .wl_subsurface) {
surface.draw();
}
}
win.initial_draw = true;
if (!surf.initial_draw) {
surf.draw();
// for (surf.subsurfaces.items) |wl_surface|{
// const subs = surf.app.surfaces.getPtr(wl_surface).?;
// subs.draw();
// }
surf.initial_draw = true;
}
},
}
}
fn xdg_toplevel_listener(_: *wlnd.Client, _: xdg.Toplevel, event: xdg.Toplevel.Event, win: *Surface) void {
fn xdg_toplevel_listener(_: *wlnd.Client, _: xdg.Toplevel, event: xdg.Toplevel.Event, surf: *Surface) void {
switch (event) {
.configure => |configure| {
std.log.info("configure_top={}", .{configure});
const configure_size = Size{
.width = @intCast(configure.width),
.height = @intCast(configure.height),
};
if (configure_size.is_zero()) return;

const new_size = configure_size.unite(win.min_size);
if (new_size.is_eql(win.size)) return;
const new_size = configure_size.unite(surf.min_size);
// const old_size = surf.app.layout.get(surf.root, .rect).get_size();
// if (new_size.is_eql(old_size)) {
// std.log.info("old_size={}", .{old_size});
// return;
// }

std.log.warn("configure event {}", .{configure});
// surf.size = new_size;

win.size = new_size;
win.schedule_redraw();
surf.app.layout.set_size(surf.root, Size.Minmax.tight(new_size));
surf.schedule_redraw();

_ = win.app.layout.call(win.root, .size, .{
Size.Minmax.tight(win.size),
});
std.log.info("w: {} h: {}", .{ win.size.width, win.size.height });
std.log.info("w: {} h: {}", .{ new_size.width, new_size.height });
},
.close => {
win.app.client.connection.is_running = false;
surf.app.client.connection.is_running = false;
},
else => {},
}
}
fn xdg_popup_listener(client: *wlnd.Client, xdg_popup: xdg.Popup, event: xdg.Popup.Event, win: *Surface) void {
_ = client; // autofix
fn xdg_popup_listener(_: *wlnd.Client, xdg_popup: xdg.Popup, event: xdg.Popup.Event, win: *Surface) void {
switch (event) {
.configure => |configure| {
std.log.info("popup configure :{}", .{configure});
Expand Down
Loading

0 comments on commit d6b2986

Please sign in to comment.