mirror of https://github.com/fairyglade/ly.git
## What are the changes about? Add an option to allow user manually input username, instead of selecting from a list of discovered users. I have not tested the changes yet since I wasnt able to get it build locally. Will try to resolve this asap. ## What existing issue does this resolve? #891 ## Pre-requisites - [ ] I have tested & confirmed the changes work locally - [x] I have run `zig fmt` throughout my changes Co-authored-by: HigherOrderLogic <73709188+HigherOrderLogic@users.noreply.github.com> Co-authored-by: AnErrupTion <anerruption@disroot.org> Reviewed-on: https://codeberg.org/fairyglade/ly/pulls/1012 Reviewed-by: AnErrupTion <anerruption+codeberg@disroot.org>
This commit is contained in:
parent
006749b2ec
commit
25fad28c34
|
|
@ -144,6 +144,10 @@ pub fn handle(self: *Text, maybe_key: ?keyboard.Key) !void {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn writeText(self: *Text, str: []const u8) !void {
|
||||||
|
for (str) |c| try self.write(c);
|
||||||
|
}
|
||||||
|
|
||||||
fn draw(self: *Text) void {
|
fn draw(self: *Text) void {
|
||||||
if (self.masked) {
|
if (self.masked) {
|
||||||
if (self.maybe_mask) |mask| {
|
if (self.maybe_mask) |mask| {
|
||||||
|
|
|
||||||
|
|
@ -375,6 +375,10 @@ start_cmd = $CONFIG_DIRECTORY/ly/startup.sh
|
||||||
# Center the session name.
|
# Center the session name.
|
||||||
text_in_center = false
|
text_in_center = false
|
||||||
|
|
||||||
|
# If true, user will need to manually type username instead of selecting from the list
|
||||||
|
# of discovered users
|
||||||
|
type_username = false
|
||||||
|
|
||||||
# Default vi mode
|
# Default vi mode
|
||||||
# normal -> normal mode
|
# normal -> normal mode
|
||||||
# insert -> insert mode
|
# insert -> insert mode
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,19 @@ const Env = struct {
|
||||||
environment: Environment,
|
environment: Environment,
|
||||||
index: usize,
|
index: usize,
|
||||||
};
|
};
|
||||||
const EnvironmentLabel = CyclableLabel(Env, *UserList);
|
const EnvironmentLabel = CyclableLabel(Env, *?UserList);
|
||||||
|
|
||||||
const Session = @This();
|
const Session = @This();
|
||||||
|
|
||||||
instance: ?Widget = null,
|
instance: ?Widget = null,
|
||||||
label: *EnvironmentLabel,
|
label: *EnvironmentLabel,
|
||||||
user_list: *UserList,
|
user_list: *?UserList,
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
io: std.Io,
|
io: std.Io,
|
||||||
buffer: *TerminalBuffer,
|
buffer: *TerminalBuffer,
|
||||||
user_list: *UserList,
|
user_list: *?UserList,
|
||||||
width: usize,
|
width: usize,
|
||||||
text_in_center: bool,
|
text_in_center: bool,
|
||||||
fg: u32,
|
fg: u32,
|
||||||
|
|
@ -79,7 +79,7 @@ pub fn addEnvironment(self: *Session, environment: Environment) !void {
|
||||||
const env = Env{ .environment = environment, .index = self.label.list.items.len };
|
const env = Env{ .environment = environment, .index = self.label.list.items.len };
|
||||||
|
|
||||||
try self.label.addItem(env);
|
try self.label.addItem(env);
|
||||||
addedSession(env, self.user_list);
|
if (self.user_list.*) |w| addedSession(env, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(self: *Session) void {
|
fn draw(self: *Session) void {
|
||||||
|
|
@ -90,16 +90,16 @@ fn handle(self: *Session, maybe_key: ?keyboard.Key) !void {
|
||||||
try self.label.handle(maybe_key);
|
try self.label.handle(maybe_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addedSession(env: Env, user_list: *UserList) void {
|
fn addedSession(env: Env, user_list: UserList) void {
|
||||||
const user = user_list.label.list.items[user_list.label.current];
|
const user = user_list.label.list.items[user_list.label.current];
|
||||||
if (!user.first_run) return;
|
if (!user.first_run) return;
|
||||||
|
|
||||||
user.session_index.* = env.index;
|
user.session_index.* = env.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sessionChanged(env: Env, maybe_user_list: ?*UserList) void {
|
fn sessionChanged(env: Env, maybe_user_list: ?*?UserList) void {
|
||||||
if (maybe_user_list) |user_list| {
|
if (maybe_user_list) |user_list| {
|
||||||
user_list.label.list.items[user_list.label.current].session_index.* = env.index;
|
if (user_list.*) |w| w.label.list.items[w.label.current].session_index.* = env.index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ sleep_cmd: ?[]const u8 = null,
|
||||||
sleep_key: []const u8 = "F3",
|
sleep_key: []const u8 = "F3",
|
||||||
start_cmd: ?[]const u8 = null,
|
start_cmd: ?[]const u8 = null,
|
||||||
text_in_center: bool = false,
|
text_in_center: bool = false,
|
||||||
|
type_username: bool = false,
|
||||||
vi_default_mode: ViMode = .normal,
|
vi_default_mode: ViMode = .normal,
|
||||||
vi_mode: bool = false,
|
vi_mode: bool = false,
|
||||||
waylandsessions: ?[]const u8 = build_options.prefix_directory ++ "/share/wayland-sessions",
|
waylandsessions: ?[]const u8 = build_options.prefix_directory ++ "/share/wayland-sessions",
|
||||||
|
|
|
||||||
137
src/main.zig
137
src/main.zig
|
|
@ -107,8 +107,10 @@ const UiState = struct {
|
||||||
info_line: InfoLine,
|
info_line: InfoLine,
|
||||||
animate: bool,
|
animate: bool,
|
||||||
session: Session,
|
session: Session,
|
||||||
|
saved_username: ?[]const u8,
|
||||||
saved_users: SavedUsers,
|
saved_users: SavedUsers,
|
||||||
login: UserList,
|
login: ?UserList,
|
||||||
|
login_text: ?*Text,
|
||||||
password: *Text,
|
password: *Text,
|
||||||
password_widget: *Widget,
|
password_widget: *Widget,
|
||||||
insert_mode: bool,
|
insert_mode: bool,
|
||||||
|
|
@ -295,6 +297,7 @@ pub fn main(init: std.process.Init) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
state.has_old_save = false;
|
state.has_old_save = false;
|
||||||
|
state.saved_username = null;
|
||||||
|
|
||||||
if (state.config.save) read_save_file: {
|
if (state.config.save) read_save_file: {
|
||||||
old_save_parser = migrator.tryMigrateIniSaveFile(state.allocator, state.io, state.old_save_path, &state.saved_users, usernames.items) catch break :read_save_file;
|
old_save_parser = migrator.tryMigrateIniSaveFile(state.allocator, state.io, state.old_save_path, &state.saved_users, usernames.items) catch break :read_save_file;
|
||||||
|
|
@ -312,8 +315,19 @@ pub fn main(init: std.process.Init) !void {
|
||||||
var file_reader = save_file.reader(state.io, &file_buffer);
|
var file_reader = save_file.reader(state.io, &file_buffer);
|
||||||
var reader = &file_reader.interface;
|
var reader = &file_reader.interface;
|
||||||
|
|
||||||
const last_username_index_str = reader.takeDelimiterInclusive('\n') catch break :read_save_file;
|
const username_line = reader.takeDelimiterInclusive('\n') catch break :read_save_file;
|
||||||
state.saved_users.last_username_index = std.fmt.parseInt(usize, last_username_index_str[0..(last_username_index_str.len - 1)], 10) catch break :read_save_file;
|
|
||||||
|
if (std.mem.containsAtLeastScalar2(u8, username_line, '-', 1)) read_username: {
|
||||||
|
var iterator = std.mem.splitScalar(u8, username_line[0..(username_line.len - 1)], '-');
|
||||||
|
if (iterator.next() == null) break :read_username; // Would be index
|
||||||
|
|
||||||
|
const maybe_username = iterator.next();
|
||||||
|
if (maybe_username) |username| {
|
||||||
|
state.saved_username = try state.allocator.dupe(u8, username);
|
||||||
|
}
|
||||||
|
} else if (!state.config.type_username) {
|
||||||
|
state.saved_users.last_username_index = std.fmt.parseInt(usize, username_line[0..(username_line.len - 1)], 10) catch break :read_save_file;
|
||||||
|
}
|
||||||
|
|
||||||
while (reader.seek < reader.buffer.len) {
|
while (reader.seek < reader.buffer.len) {
|
||||||
const line = reader.takeDelimiterInclusive('\n') catch break;
|
const line = reader.takeDelimiterInclusive('\n') catch break;
|
||||||
|
|
@ -763,22 +777,25 @@ pub fn main(init: std.process.Init) !void {
|
||||||
);
|
);
|
||||||
defer state.login_label.deinit();
|
defer state.login_label.deinit();
|
||||||
|
|
||||||
state.login = try UserList.init(
|
state.login = null;
|
||||||
state.allocator,
|
if (!state.config.type_username) {
|
||||||
state.io,
|
state.login = try UserList.init(
|
||||||
&state.buffer,
|
state.allocator,
|
||||||
usernames,
|
state.io,
|
||||||
&state.saved_users,
|
&state.buffer,
|
||||||
&state.session,
|
usernames,
|
||||||
state.box.width - 2 * state.box.horizontal_margin - state.labels_max_length - 1,
|
&state.saved_users,
|
||||||
state.config.text_in_center,
|
&state.session,
|
||||||
state.buffer.fg,
|
state.box.width - 2 * state.box.horizontal_margin - state.labels_max_length - 1,
|
||||||
state.buffer.bg,
|
state.config.text_in_center,
|
||||||
);
|
state.buffer.fg,
|
||||||
defer state.login.deinit();
|
state.buffer.bg,
|
||||||
|
);
|
||||||
|
|
||||||
try state.buffer.registerKeybind(state.io, &state.login.label.keybinds, "H", &viGoLeft, &state);
|
try state.buffer.registerKeybind(state.io, &state.login.?.label.keybinds, "H", &viGoLeft, &state);
|
||||||
try state.buffer.registerKeybind(state.io, &state.login.label.keybinds, "L", &viGoRight, &state);
|
try state.buffer.registerKeybind(state.io, &state.login.?.label.keybinds, "L", &viGoRight, &state);
|
||||||
|
}
|
||||||
|
defer if (state.login) |*w| w.deinit();
|
||||||
|
|
||||||
if (state.config.shell) {
|
if (state.config.shell) {
|
||||||
addOtherEnvironment(&state.session, state.lang, .shell, null) catch |err| {
|
addOtherEnvironment(&state.session, state.lang, .shell, null) catch |err| {
|
||||||
|
|
@ -887,7 +904,7 @@ pub fn main(init: std.process.Init) !void {
|
||||||
// This effectively means you can't login, since there would be no local
|
// This effectively means you can't login, since there would be no local
|
||||||
// accounts *and* no root account...but at this point, if that's the
|
// accounts *and* no root account...but at this point, if that's the
|
||||||
// case, you have bigger problems to deal with in the first place. :D
|
// case, you have bigger problems to deal with in the first place. :D
|
||||||
try state.info_line.addMessage(state.lang.err_no_users, state.config.error_bg, state.config.error_fg);
|
if (!state.config.type_username) try state.info_line.addMessage(state.lang.err_no_users, state.config.error_bg, state.config.error_fg);
|
||||||
try state.log_file.err(state.io, "sys", "no users found", .{});
|
try state.log_file.err(state.io, "sys", "no users found", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -920,6 +937,22 @@ pub fn main(init: std.process.Init) !void {
|
||||||
try state.buffer.registerKeybind(state.io, &state.password.keybinds, "L", &viGoRight, &state);
|
try state.buffer.registerKeybind(state.io, &state.password.keybinds, "L", &viGoRight, &state);
|
||||||
|
|
||||||
state.password_widget = state.password.widget();
|
state.password_widget = state.password.widget();
|
||||||
|
state.login_text = null;
|
||||||
|
|
||||||
|
if (state.config.type_username) {
|
||||||
|
state.login_text = try Text.init(
|
||||||
|
state.allocator,
|
||||||
|
state.io,
|
||||||
|
&state.buffer,
|
||||||
|
state.insert_mode,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
state.box.width - 2 * state.box.horizontal_margin - state.labels_max_length - 1,
|
||||||
|
state.buffer.fg,
|
||||||
|
state.buffer.bg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
defer if (state.login_text) |lt| lt.deinit();
|
||||||
|
|
||||||
state.version_label = Label.init(
|
state.version_label = Label.init(
|
||||||
ly_version_str,
|
ly_version_str,
|
||||||
|
|
@ -974,13 +1007,18 @@ pub fn main(init: std.process.Init) !void {
|
||||||
);
|
);
|
||||||
|
|
||||||
state.session.label.current = session_index;
|
state.session.label.current = session_index;
|
||||||
for (state.login.label.list.items, 0..) |username, i| {
|
state.is_autologin = true;
|
||||||
if (std.mem.eql(u8, username.name, auto_user)) {
|
|
||||||
state.login.label.current = i;
|
if (state.login_text) |box| {
|
||||||
break;
|
try box.writeText(auto_user);
|
||||||
|
} else {
|
||||||
|
for (state.login.?.label.list.items, 0..) |username, i| {
|
||||||
|
if (std.mem.eql(u8, username.name, auto_user)) {
|
||||||
|
state.login.?.label.current = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.is_autologin = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch to selected TTY
|
// Switch to selected TTY
|
||||||
|
|
@ -1133,7 +1171,22 @@ pub fn main(init: std.process.Init) !void {
|
||||||
var default_input = state.config.default_input;
|
var default_input = state.config.default_input;
|
||||||
|
|
||||||
if (state.config.save and !state.is_autologin) {
|
if (state.config.save and !state.is_autologin) {
|
||||||
if (state.saved_users.last_username_index) |index| load_last_user: {
|
if (state.login_text) |box| {
|
||||||
|
if (state.saved_username) |username| {
|
||||||
|
defer state.allocator.free(username);
|
||||||
|
|
||||||
|
try box.writeText(username);
|
||||||
|
|
||||||
|
default_input = .password;
|
||||||
|
|
||||||
|
for (state.saved_users.user_list.items) |user| {
|
||||||
|
if (std.mem.eql(u8, username, user.username)) {
|
||||||
|
state.session.label.current = @min(user.session_index, state.session.label.list.items.len - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (state.saved_users.last_username_index) |index| load_last_user: {
|
||||||
// If the saved index isn't valid, bail out
|
// If the saved index isn't valid, bail out
|
||||||
if (index >= state.saved_users.user_list.items.len) break :load_last_user;
|
if (index >= state.saved_users.user_list.items.len) break :load_last_user;
|
||||||
|
|
||||||
|
|
@ -1143,7 +1196,7 @@ pub fn main(init: std.process.Init) !void {
|
||||||
// If it doesn't exist (anymore), we don't change the value
|
// If it doesn't exist (anymore), we don't change the value
|
||||||
for (usernames.items, 0..) |username, i| {
|
for (usernames.items, 0..) |username, i| {
|
||||||
if (std.mem.eql(u8, username, user.username)) {
|
if (std.mem.eql(u8, username, user.username)) {
|
||||||
state.login.label.current = i;
|
state.login.?.label.current = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1156,7 +1209,7 @@ pub fn main(init: std.process.Init) !void {
|
||||||
|
|
||||||
const info_line_widget = state.info_line.widget();
|
const info_line_widget = state.info_line.widget();
|
||||||
const session_widget = state.session.widget();
|
const session_widget = state.session.widget();
|
||||||
const login_widget = state.login.widget();
|
const login_widget = if (state.config.type_username) state.login_text.?.widget() else state.login.?.widget();
|
||||||
|
|
||||||
var widgets: std.ArrayList([]*Widget) = .empty;
|
var widgets: std.ArrayList([]*Widget) = .empty;
|
||||||
defer widgets.deinit(state.allocator);
|
defer widgets.deinit(state.allocator);
|
||||||
|
|
@ -1400,6 +1453,7 @@ fn disableInsertMode(ptr: *anyopaque) !bool {
|
||||||
if (state.config.vi_mode and state.insert_mode) {
|
if (state.config.vi_mode and state.insert_mode) {
|
||||||
state.insert_mode = false;
|
state.insert_mode = false;
|
||||||
state.password.should_insert = false;
|
state.password.should_insert = false;
|
||||||
|
if (state.login_text) |lt| lt.should_insert = false;
|
||||||
state.buffer.drawNextFrame(true);
|
state.buffer.drawNextFrame(true);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1411,6 +1465,7 @@ fn enableInsertMode(ptr: *anyopaque) !bool {
|
||||||
|
|
||||||
state.insert_mode = true;
|
state.insert_mode = true;
|
||||||
state.password.should_insert = true;
|
state.password.should_insert = true;
|
||||||
|
if (state.login_text) |lt| lt.should_insert = true;
|
||||||
state.buffer.drawNextFrame(true);
|
state.buffer.drawNextFrame(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1552,7 +1607,11 @@ fn authenticate(ptr: *anyopaque) !bool {
|
||||||
var file_writer = file.writer(state.io, &file_buffer);
|
var file_writer = file.writer(state.io, &file_buffer);
|
||||||
var writer = &file_writer.interface;
|
var writer = &file_writer.interface;
|
||||||
|
|
||||||
try writer.print("{d}\n", .{state.login.label.current});
|
if (state.login_text) |box| {
|
||||||
|
try writer.print("0-{s}\n", .{box.text.items});
|
||||||
|
} else {
|
||||||
|
try writer.print("{d}\n", .{state.login.?.label.current});
|
||||||
|
}
|
||||||
for (state.saved_users.user_list.items) |user| {
|
for (state.saved_users.user_list.items) |user| {
|
||||||
try writer.print("{s}:{d}\n", .{ user.username, user.session_index });
|
try writer.print("{s}:{d}\n", .{ user.username, user.session_index });
|
||||||
}
|
}
|
||||||
|
|
@ -1610,7 +1669,7 @@ fn authenticate(ptr: *anyopaque) !bool {
|
||||||
&state.log_file,
|
&state.log_file,
|
||||||
auth_options,
|
auth_options,
|
||||||
current_environment,
|
current_environment,
|
||||||
state.login.getCurrentUsername(),
|
if (state.login_text) |box| box.text.items else state.login.?.getCurrentUsername(),
|
||||||
password_text,
|
password_text,
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
shared_err.writeError(err);
|
shared_err.writeError(err);
|
||||||
|
|
@ -2135,12 +2194,22 @@ fn positionWidgets(ptr: *anyopaque) !void {
|
||||||
.childrenPosition()
|
.childrenPosition()
|
||||||
.resetXFrom(state.info_line.label.childrenPosition())
|
.resetXFrom(state.info_line.label.childrenPosition())
|
||||||
.addY(1));
|
.addY(1));
|
||||||
state.login.label.positionY(state.login_label
|
if (state.login_text) |box| {
|
||||||
.childrenPosition()
|
box.positionY(state.login_label
|
||||||
.addX(state.labels_max_length - TerminalBuffer.strWidth(state.login_label.text) + 1));
|
.childrenPosition()
|
||||||
|
.addX(state.labels_max_length - TerminalBuffer.strWidth(state.login_label.text) + 1));
|
||||||
|
} else {
|
||||||
|
state.login.?.label.positionY(state.login_label
|
||||||
|
.childrenPosition()
|
||||||
|
.addX(state.labels_max_length - TerminalBuffer.strWidth(state.login_label.text) + 1));
|
||||||
|
}
|
||||||
|
|
||||||
state.password_label.positionX(state.login.label
|
const login_children_pos = if (state.login_text) |box|
|
||||||
.childrenPosition()
|
box.childrenPosition()
|
||||||
|
else
|
||||||
|
state.login.?.label.childrenPosition();
|
||||||
|
|
||||||
|
state.password_label.positionX(login_children_pos
|
||||||
.resetXFrom(state.info_line.label.childrenPosition())
|
.resetXFrom(state.info_line.label.childrenPosition())
|
||||||
.addY(1));
|
.addY(1));
|
||||||
state.password.positionY(state.password_label
|
state.password.positionY(state.password_label
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue