output: add output_title default option
Outputs now have a default option, "output_title". If this changes, the outputs title is set to the option value. This title is currently only relevant when run nested in a wayland/X11 session. Co-authored-by: Isaac Freund <ifreund@ifreund.xyz>
This commit is contained in:
committed by
Isaac Freund
parent
5e09b853f7
commit
7029a5cd3e
@ -45,6 +45,9 @@ output: ?*Output,
|
||||
key: [*:0]const u8,
|
||||
value: Value = .unset,
|
||||
|
||||
/// Emitted whenever the value of the option changes.
|
||||
update: wl.Signal(*Self) = undefined,
|
||||
|
||||
handles: wl.list.Head(zriver.OptionHandleV1, null) = undefined,
|
||||
|
||||
pub fn create(options_manager: *OptionsManager, output: ?*Output, key: [*:0]const u8) !*Self {
|
||||
@ -57,6 +60,7 @@ pub fn create(options_manager: *OptionsManager, output: ?*Output, key: [*:0]cons
|
||||
.key = try util.gpa.dupeZ(u8, mem.span(key)),
|
||||
};
|
||||
self.handles.init();
|
||||
self.update.init();
|
||||
|
||||
options_manager.options.append(self);
|
||||
|
||||
@ -101,6 +105,9 @@ pub fn set(self: *Self, value: Value) !void {
|
||||
|
||||
var it = self.handles.iterator(.forward);
|
||||
while (it.next()) |handle| self.sendValue(handle);
|
||||
|
||||
// Call listeners, if any.
|
||||
self.update.emit(self);
|
||||
}
|
||||
|
||||
fn sendValue(self: Self, handle: *zriver.OptionHandleV1) void {
|
||||
|
@ -18,6 +18,8 @@
|
||||
const Self = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const fmt = std.fmt;
|
||||
const wlr = @import("wlroots");
|
||||
const wayland = @import("wayland");
|
||||
const wl = wayland.server.wl;
|
||||
@ -35,6 +37,7 @@ const View = @import("View.zig");
|
||||
const ViewStack = @import("view_stack.zig").ViewStack;
|
||||
const AttachMode = @import("view_stack.zig").AttachMode;
|
||||
const OutputStatus = @import("OutputStatus.zig");
|
||||
const Option = @import("Option.zig");
|
||||
|
||||
const State = struct {
|
||||
/// A bit field of focused tags
|
||||
@ -84,6 +87,9 @@ enable: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleEnable),
|
||||
frame: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleFrame),
|
||||
mode: wl.Listener(*wlr.Output) = wl.Listener(*wlr.Output).init(handleMode),
|
||||
|
||||
// Listeners for options
|
||||
output_title: wl.Listener(*Option) = wl.Listener(*Option).init(handleTitleChange),
|
||||
|
||||
pub fn init(self: *Self, root: *Root, wlr_output: *wlr.Output) !void {
|
||||
// Some backends don't have modes. DRM+KMS does, and we need to set a mode
|
||||
// before we can use the output. The mode is a tuple of (width, height,
|
||||
@ -138,6 +144,10 @@ pub fn init(self: *Self, root: *Root, wlr_output: *wlr.Output) !void {
|
||||
.height = effective_resolution.height,
|
||||
};
|
||||
}
|
||||
|
||||
var buf: ["river - ".len + wlr_output.name.len + 1]u8 = undefined;
|
||||
const default_title = fmt.bufPrintZ(&buf, "river - {}", .{mem.spanZ(&wlr_output.name)}) catch unreachable;
|
||||
try self.defaultOption("output_title", .{ .string = default_title.ptr }, &self.output_title);
|
||||
}
|
||||
|
||||
pub fn getLayer(self: *Self, layer: zwlr.LayerShellV1.Layer) *std.TailQueue(LayerSurface) {
|
||||
@ -545,3 +555,29 @@ pub fn getEffectiveResolution(self: *Self) struct { width: u32, height: u32 } {
|
||||
.height = @intCast(u32, height),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setTitle(self: *Self, title: [*:0]const u8) void {
|
||||
if (self.wlr_output.isWl()) {
|
||||
self.wlr_output.wlSetTitle(title);
|
||||
} else if (self.wlr_output.isX11()) {
|
||||
self.wlr_output.x11SetTitle(title);
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an option for this output, attach a listener which is called when
|
||||
/// the option changed and initialize with a default value. Note that the
|
||||
/// listener is called once through this function.
|
||||
fn defaultOption(
|
||||
self: *Self,
|
||||
key: [*:0]const u8,
|
||||
value: Option.Value,
|
||||
listener: *wl.Listener(*Option),
|
||||
) !void {
|
||||
const option = try Option.create(&self.root.server.options_manager, self, key);
|
||||
option.update.add(listener);
|
||||
try option.set(value);
|
||||
}
|
||||
|
||||
fn handleTitleChange(listener: *wl.Listener(*Option), option: *Option) void {
|
||||
if (option.value.string) |title| option.output.?.setTitle(title);
|
||||
}
|
||||
|
@ -112,12 +112,12 @@ pub fn init(self: *Self) !void {
|
||||
|
||||
self.config = try Config.init();
|
||||
try self.decoration_manager.init(self);
|
||||
try self.options_manager.init(self);
|
||||
try self.root.init(self);
|
||||
// Must be called after root is initialized
|
||||
try self.input_manager.init(self);
|
||||
try self.control.init(self);
|
||||
try self.status_manager.init(self);
|
||||
try self.options_manager.init(self);
|
||||
|
||||
// These all free themselves when the wl_server is destroyed
|
||||
_ = try wlr.DataDeviceManager.create(self.wl_server);
|
||||
|
Reference in New Issue
Block a user