Fix text scaling in Bar
Before, we were missing the initial events from the wl_output, including the scale. This meant that we weren't scaling the bar clock correctly. To fix it, we just moved the wl_global binding into the .wl_output event We also got rid of the hashmap of outputs in Globals and Context.
This commit is contained in:
parent
a37f72f0d7
commit
9b0bac12ff
4 changed files with 22 additions and 52 deletions
|
|
@ -88,7 +88,9 @@ pub fn initSurface(bar: *Bar) !void {
|
||||||
|
|
||||||
// TODO: Add padding to config
|
// TODO: Add padding to config
|
||||||
const vertical_padding = 5;
|
const vertical_padding = 5;
|
||||||
const bar_height: u31 = @intCast(bar.fcft_fonts.height + 2 * vertical_padding);
|
// Set size wants logical pixels, so we have to scale the height
|
||||||
|
const logical_font_height = @divFloor(bar.fcft_fonts.height, @as(i32, bar.font_scale));
|
||||||
|
const bar_height: u31 = @intCast(logical_font_height + 2 * vertical_padding);
|
||||||
layer_surface.setSize(0, bar_height);
|
layer_surface.setSize(0, bar_height);
|
||||||
|
|
||||||
layer_surface.setAnchor(.{ .top = options.position == .top, .bottom = options.position == .bottom, .left = true, .right = true });
|
layer_surface.setAnchor(.{ .top = options.position == .top, .bottom = options.position == .bottom, .left = true, .right = true });
|
||||||
|
|
@ -366,7 +368,7 @@ fn getFcftFonts(fonts: []const u8, scale: u31) !*fcft.Font {
|
||||||
while (it.next()) |font| {
|
while (it.next()) |font| {
|
||||||
if (scale > 1) {
|
if (scale > 1) {
|
||||||
// If scale >1, we append :dpi so we can scale the font
|
// If scale >1, we append :dpi so we can scale the font
|
||||||
log.debug("bwbuhse {d} {d}", .{ base_dpi, scale });
|
log.debug("Scaling font DPI: base={d} scale={d}", .{ base_dpi, scale });
|
||||||
const scaled = try arena_alloc.dupeZ(
|
const scaled = try arena_alloc.dupeZ(
|
||||||
u8,
|
u8,
|
||||||
try std.fmt.allocPrint(arena_alloc, "{s}:dpi={}", .{ font, @as(u32, base_dpi) * scale }),
|
try std.fmt.allocPrint(arena_alloc, "{s}:dpi={}", .{ font, @as(u32, base_dpi) * scale }),
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ wl_compositor: *wl.Compositor,
|
||||||
wl_display: *wl.Display,
|
wl_display: *wl.Display,
|
||||||
wl_registry: *wl.Registry,
|
wl_registry: *wl.Registry,
|
||||||
wl_shm: *wl.Shm,
|
wl_shm: *wl.Shm,
|
||||||
wl_outputs: *std.AutoHashMapUnmanaged(u32, *wl.Output),
|
|
||||||
|
|
||||||
river_layer_shell_v1: *river.LayerShellV1,
|
river_layer_shell_v1: *river.LayerShellV1,
|
||||||
zwlr_layer_shell_v1: *zwlr.LayerShellV1,
|
zwlr_layer_shell_v1: *zwlr.LayerShellV1,
|
||||||
|
|
@ -52,7 +51,6 @@ pub const Options = struct {
|
||||||
wl_display: *wl.Display,
|
wl_display: *wl.Display,
|
||||||
wl_registry: *wl.Registry,
|
wl_registry: *wl.Registry,
|
||||||
wl_shm: *wl.Shm,
|
wl_shm: *wl.Shm,
|
||||||
wl_outputs: *std.AutoHashMapUnmanaged(u32, *wl.Output),
|
|
||||||
|
|
||||||
river_input_manager_v1: *river.InputManagerV1,
|
river_input_manager_v1: *river.InputManagerV1,
|
||||||
river_libinput_config_v1: *river.LibinputConfigV1,
|
river_libinput_config_v1: *river.LibinputConfigV1,
|
||||||
|
|
@ -93,7 +91,6 @@ pub fn create(options: Options) !*Context {
|
||||||
.wl_display = options.wl_display,
|
.wl_display = options.wl_display,
|
||||||
.wl_registry = options.wl_registry,
|
.wl_registry = options.wl_registry,
|
||||||
.wl_shm = options.wl_shm,
|
.wl_shm = options.wl_shm,
|
||||||
.wl_outputs = options.wl_outputs,
|
|
||||||
.river_layer_shell_v1 = options.river_layer_shell_v1,
|
.river_layer_shell_v1 = options.river_layer_shell_v1,
|
||||||
.zwlr_layer_shell_v1 = options.zwlr_layer_shell_v1,
|
.zwlr_layer_shell_v1 = options.zwlr_layer_shell_v1,
|
||||||
.wallpaper_image = loadWallpaperImage(options.config),
|
.wallpaper_image = loadWallpaperImage(options.config),
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ pub fn destroy(output: *Output) void {
|
||||||
|
|
||||||
output.tag_layout_overrides.deinit(utils.gpa);
|
output.tag_layout_overrides.deinit(utils.gpa);
|
||||||
output.deinitWallpaperLayerSurface();
|
output.deinitWallpaperLayerSurface();
|
||||||
|
if (output.wl_output) |wl_output| wl_output.release();
|
||||||
output.river_output_v1.destroy();
|
output.river_output_v1.destroy();
|
||||||
output.river_layer_shell_output_v1.destroy();
|
output.river_layer_shell_output_v1.destroy();
|
||||||
utils.gpa.destroy(output);
|
utils.gpa.destroy(output);
|
||||||
|
|
@ -217,26 +218,19 @@ fn riverOutputListener(river_output_v1: *river.OutputV1, event: river.OutputV1.E
|
||||||
output.destroy();
|
output.destroy();
|
||||||
},
|
},
|
||||||
.wl_output => |ev| {
|
.wl_output => |ev| {
|
||||||
// It's guaranteed for the wl_output global to advertised before this event happens
|
// Bind the wl_output here so that our listener is set before the server sends the
|
||||||
output.wl_output = output.context.wl_outputs.get(ev.name).?;
|
// initial events (.scale, .mode, .name, .done, etc.). The .done handler will init
|
||||||
output.wl_output.?.setListener(*Output, wlOutputListener, output);
|
// bar/wallpaper surfaces.
|
||||||
|
const wl_output = output.context.wl_registry.bind(
|
||||||
// The wl_output's initial events come during the initial roundtrip
|
ev.name,
|
||||||
// before we set our listener, so the .done event that triggers
|
wl.Output,
|
||||||
// wallpaper init was lost. Explicitly init the surfaces here.
|
4,
|
||||||
output.initWallpaperLayerSurface() catch |err| {
|
) catch |err| {
|
||||||
const output_name = output.name orelse "some output";
|
log.err("Failed to bind wl_output: {}", .{err});
|
||||||
log.err("failed to add a surface to {s}: {}", .{ output_name, err });
|
return;
|
||||||
};
|
};
|
||||||
if (output.bar) |*bar| {
|
wl_output.setListener(*Output, wlOutputListener, output);
|
||||||
bar.initSurface() catch |err| {
|
output.wl_output = wl_output;
|
||||||
const output_name = output.name orelse "some output";
|
|
||||||
log.err("failed to init bar for {s}: {}", .{ output_name, err });
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// Tag overlay surfaces are created on-demand when tags change,
|
|
||||||
// so we don't init them here.
|
|
||||||
},
|
},
|
||||||
.dimensions => |ev| {
|
.dimensions => |ev| {
|
||||||
// Protocol guarantees that width and height are strictly greater than zero
|
// Protocol guarantees that width and height are strictly greater than zero
|
||||||
|
|
|
||||||
33
src/main.zig
33
src/main.zig
|
|
@ -12,17 +12,8 @@ const Globals = struct {
|
||||||
|
|
||||||
wl_compositor: ?*wl.Compositor = null,
|
wl_compositor: ?*wl.Compositor = null,
|
||||||
wl_shm: ?*wl.Shm = null,
|
wl_shm: ?*wl.Shm = null,
|
||||||
wl_outputs: std.AutoHashMapUnmanaged(u32, *wl.Output) = .empty,
|
|
||||||
|
|
||||||
zwlr_layer_shell_v1: ?*zwlr.LayerShellV1 = null,
|
zwlr_layer_shell_v1: ?*zwlr.LayerShellV1 = null,
|
||||||
|
|
||||||
fn deinit(globals: *Globals) void {
|
|
||||||
var it = globals.wl_outputs.valueIterator();
|
|
||||||
while (it.next()) |output| {
|
|
||||||
output.*.release();
|
|
||||||
}
|
|
||||||
globals.wl_outputs.deinit(utils.gpa);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const usage: []const u8 =
|
const usage: []const u8 =
|
||||||
|
|
@ -62,7 +53,6 @@ pub fn main() !void {
|
||||||
const wl_registry = try wl_display.getRegistry();
|
const wl_registry = try wl_display.getRegistry();
|
||||||
|
|
||||||
var globals: Globals = .{};
|
var globals: Globals = .{};
|
||||||
defer globals.deinit();
|
|
||||||
wl_registry.setListener(*Globals, registryListener, &globals);
|
wl_registry.setListener(*Globals, registryListener, &globals);
|
||||||
|
|
||||||
const errno = wl_display.roundtrip();
|
const errno = wl_display.roundtrip();
|
||||||
|
|
@ -72,8 +62,6 @@ pub fn main() !void {
|
||||||
|
|
||||||
const wl_compositor = globals.wl_compositor orelse utils.interfaceNotAdvertised(wl.Compositor);
|
const wl_compositor = globals.wl_compositor orelse utils.interfaceNotAdvertised(wl.Compositor);
|
||||||
const wl_shm = globals.wl_shm orelse utils.interfaceNotAdvertised(wl.Shm);
|
const wl_shm = globals.wl_shm orelse utils.interfaceNotAdvertised(wl.Shm);
|
||||||
// We can theoretically start with zero wl_outputs; don't panic if it's empty.
|
|
||||||
const wl_outputs = &globals.wl_outputs;
|
|
||||||
|
|
||||||
const river_input_manager_v1 = globals.river_input_manager_v1 orelse utils.interfaceNotAdvertised(river.InputManagerV1);
|
const river_input_manager_v1 = globals.river_input_manager_v1 orelse utils.interfaceNotAdvertised(river.InputManagerV1);
|
||||||
const river_libinput_config_v1 = globals.river_libinput_config_v1 orelse utils.interfaceNotAdvertised(river.LibinputConfigV1);
|
const river_libinput_config_v1 = globals.river_libinput_config_v1 orelse utils.interfaceNotAdvertised(river.LibinputConfigV1);
|
||||||
|
|
@ -88,7 +76,6 @@ pub fn main() !void {
|
||||||
const context = try Context.create(.{
|
const context = try Context.create(.{
|
||||||
.wl_compositor = wl_compositor,
|
.wl_compositor = wl_compositor,
|
||||||
.wl_display = wl_display,
|
.wl_display = wl_display,
|
||||||
.wl_outputs = wl_outputs,
|
|
||||||
.wl_registry = wl_registry,
|
.wl_registry = wl_registry,
|
||||||
.wl_shm = wl_shm,
|
.wl_shm = wl_shm,
|
||||||
.river_input_manager_v1 = river_input_manager_v1,
|
.river_input_manager_v1 = river_input_manager_v1,
|
||||||
|
|
@ -268,16 +255,8 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: *
|
||||||
};
|
};
|
||||||
} else if (mem.orderZ(u8, ev.interface, wl.Output.interface.name) == .eq) {
|
} else if (mem.orderZ(u8, ev.interface, wl.Output.interface.name) == .eq) {
|
||||||
if (ev.version < 4) utils.versionNotSupported(wl.Output, ev.version, 4);
|
if (ev.version < 4) utils.versionNotSupported(wl.Output, ev.version, 4);
|
||||||
|
// We don't bind wl_output until the river_output send its .wl_output event
|
||||||
const wl_output = registry.bind(ev.name, wl.Output, 4) catch |e| {
|
// This way, we don't miss the initial configuration events
|
||||||
fatal("Failed to bind to wl_output: {any}", .{@errorName(e)});
|
|
||||||
};
|
|
||||||
|
|
||||||
// We can get multiple wl_outputs, so we have to try add them to our HashMap
|
|
||||||
// instead of just keeping the one
|
|
||||||
globals.wl_outputs.put(utils.gpa, ev.name, wl_output) catch |e| {
|
|
||||||
fatal("Failed to add wl_output to hashmap: {any}", .{@errorName(e)});
|
|
||||||
};
|
|
||||||
} else if (mem.orderZ(u8, ev.interface, wl.Shm.interface.name) == .eq) {
|
} else if (mem.orderZ(u8, ev.interface, wl.Shm.interface.name) == .eq) {
|
||||||
globals.wl_shm = registry.bind(ev.name, wl.Shm, 1) catch |e| {
|
globals.wl_shm = registry.bind(ev.name, wl.Shm, 1) catch |e| {
|
||||||
fatal("Failed to bind to wl_shm: {any}", .{@errorName(e)});
|
fatal("Failed to bind to wl_shm: {any}", .{@errorName(e)});
|
||||||
|
|
@ -309,11 +288,9 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: *
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.global_remove => |ev| {
|
.global_remove => |_| {
|
||||||
// The only remove we care about is for wl_outputs
|
// wl_output removal is handled by the river protocol's .removed
|
||||||
if (!globals.wl_outputs.remove(ev.name)) {
|
// event, and we don't care about any other globals being removed.
|
||||||
log.debug("Received a global_remove event for something other than a wl_output", .{});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue