refactor: allow entering username
This commit is contained in:
parent
7aa41f6a16
commit
abc591db6d
5 changed files with 692 additions and 464 deletions
1068
Cargo.lock
generated
1068
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -45,13 +45,13 @@ xdg = "2.5.2"
|
|||
tokio = { workspace = true, features = ["full"] }
|
||||
wayland-client = "0.31.8"
|
||||
# For network status using networkmanager feature
|
||||
cosmic-dbus-networkmanager = { git = "https://github.com/pop-os/dbus-settings-bindings", rev = "badfc6a", optional = true }
|
||||
cosmic-dbus-networkmanager = { git = "https://github.com/pop-os/dbus-settings-bindings", optional = true }
|
||||
# For logind integration using logind feature
|
||||
logind-zbus = { version = "4", optional = true }
|
||||
logind-zbus = { version = "5", optional = true }
|
||||
# Fix zbus compilation by manually adding nix with user feature
|
||||
nix = { workspace = true, optional = true }
|
||||
# For power status with upower feature
|
||||
upower_dbus = { git = "https://github.com/pop-os/dbus-settings-bindings", rev = "badfc6a", optional = true }
|
||||
upower_dbus = { git = "https://github.com/pop-os/dbus-settings-bindings", optional = true }
|
||||
# Required for some features
|
||||
zbus = { workspace = true, optional = true }
|
||||
# CLI arguments
|
||||
|
|
@ -102,7 +102,7 @@ pwd = "1.4.0"
|
|||
ron = "0.10.1"
|
||||
serde = "1"
|
||||
tokio = "1.39.1"
|
||||
zbus = "4"
|
||||
zbus = "5"
|
||||
|
||||
[workspace.dependencies.cosmic-applets-config]
|
||||
git = "https://github.com/pop-os/cosmic-applets"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use cosmic_greeter_daemon::UserData;
|
||||
use std::{env, error::Error, future::pending, io, path::Path};
|
||||
use zbus::{ConnectionBuilder, DBusError};
|
||||
use zbus::{connection::Builder, DBusError};
|
||||
|
||||
//IMPORTANT: this function is critical to the security of this proxy. It must ensure that the
|
||||
// callback is executed with the permissions of the specified user id. A good test is to see if
|
||||
|
|
@ -101,7 +101,7 @@ impl GreeterProxy {
|
|||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
|
||||
|
||||
let _conn = ConnectionBuilder::system()?
|
||||
let _conn = Builder::system()?
|
||||
.name("com.system76.CosmicGreeter")?
|
||||
.serve_at("/com/system76/CosmicGreeter", GreeterProxy)?
|
||||
.build()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
cancel = Cancel
|
||||
caps-lock = Caps Lock is active.
|
||||
enter-user = Enter name manually...
|
||||
type-username = Username:
|
||||
keyboard-layout = Keyboard layout
|
||||
restart = Restart
|
||||
restart-now = Restart now?
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ use cosmic::{
|
|||
use cosmic_greeter_config::Config as CosmicGreeterConfig;
|
||||
use cosmic_greeter_daemon::UserData;
|
||||
use greetd_ipc::Request;
|
||||
use std::sync::LazyLock;
|
||||
use std::{
|
||||
collections::{HashMap, hash_map},
|
||||
error::Error,
|
||||
|
|
@ -49,6 +50,8 @@ use crate::{
|
|||
fl,
|
||||
};
|
||||
|
||||
static USERNAME_ID: LazyLock<iced::id::Id> = LazyLock::new(|| iced::id::Id::new("username-id"));
|
||||
|
||||
#[proxy(
|
||||
interface = "com.system76.CosmicGreeter",
|
||||
default_service = "com.system76.CosmicGreeter",
|
||||
|
|
@ -351,6 +354,7 @@ pub enum Message {
|
|||
Surface(surface::Action),
|
||||
Suspend,
|
||||
Username(String),
|
||||
EnterUser(bool, String),
|
||||
}
|
||||
|
||||
impl From<common::Message> for Message {
|
||||
|
|
@ -372,10 +376,12 @@ pub struct App {
|
|||
dialog_page_opt: Option<DialogPage>,
|
||||
dropdown_opt: Option<Dropdown>,
|
||||
heartbeat_handle: Option<cosmic::iced::task::Handle>,
|
||||
entering_name: bool,
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn menu(&self, id: SurfaceId) -> Element<Message> {
|
||||
const DEFAULT_MENU_ITEM_HEIGHT: f32 = 36.;
|
||||
let window_width = self
|
||||
.common
|
||||
.window_size
|
||||
|
|
@ -430,8 +436,20 @@ impl App {
|
|||
.on_press(message),
|
||||
)
|
||||
};
|
||||
let dropdown_menu = |items| {
|
||||
widget::container(widget::column::with_children(items))
|
||||
let dropdown_menu = |items: Vec<_>| {
|
||||
let item_cnt = items.len();
|
||||
|
||||
let items = widget::column::with_children(items);
|
||||
let items = if item_cnt > 7 {
|
||||
Element::from(
|
||||
widget::scrollable(items)
|
||||
.height(Length::Fixed(DEFAULT_MENU_ITEM_HEIGHT * 7.)),
|
||||
)
|
||||
} else {
|
||||
Element::from(items)
|
||||
};
|
||||
|
||||
widget::container(items)
|
||||
.padding(1)
|
||||
//TODO: move style to libcosmic
|
||||
.class(theme::Container::custom(|theme| {
|
||||
|
|
@ -485,7 +503,29 @@ impl App {
|
|||
Message::Username(name.clone()),
|
||||
));
|
||||
}
|
||||
user_button = user_button.popup(dropdown_menu(items));
|
||||
let item_cnt = items.len();
|
||||
let menu_button = widget::menu::menu_button(vec![
|
||||
Element::from(widget::Space::with_width(Length::Fixed(25.0))),
|
||||
widget::text(fl!("enter-user"))
|
||||
.align_x(iced::alignment::Horizontal::Left)
|
||||
.into(),
|
||||
])
|
||||
.on_press(Message::EnterUser(true, String::new()))
|
||||
.into();
|
||||
let items = if item_cnt >= 6 {
|
||||
dropdown_menu(vec![
|
||||
widget::scrollable(widget::column::with_children(items))
|
||||
.height(Length::Fixed(DEFAULT_MENU_ITEM_HEIGHT * 6.))
|
||||
.into(),
|
||||
widget::divider::horizontal::light().into(),
|
||||
menu_button,
|
||||
])
|
||||
} else {
|
||||
items.push(menu_button);
|
||||
dropdown_menu(items)
|
||||
};
|
||||
|
||||
user_button = user_button.popup(items);
|
||||
}
|
||||
|
||||
let mut session_button = widget::popover(
|
||||
|
|
@ -575,7 +615,8 @@ impl App {
|
|||
}
|
||||
SocketState::Open => {
|
||||
for user_data in &self.flags.user_datas {
|
||||
if user_data.name == self.selected_username.username {
|
||||
if !self.entering_name && user_data.name == self.selected_username.username
|
||||
{
|
||||
match &user_data.icon_opt {
|
||||
Some(icon) => {
|
||||
column = column.push(
|
||||
|
|
@ -600,6 +641,17 @@ impl App {
|
|||
);
|
||||
}
|
||||
}
|
||||
if self.entering_name {
|
||||
column = column.push(
|
||||
widget::text_input(
|
||||
fl!("type-username"),
|
||||
self.selected_username.username.as_str(),
|
||||
)
|
||||
.id(USERNAME_ID.clone())
|
||||
.on_input(|input| Message::EnterUser(false, input))
|
||||
.on_submit(|v| Message::Username(v)),
|
||||
)
|
||||
}
|
||||
match &self.common.prompt_opt {
|
||||
Some((prompt, secret, value_opt)) => match value_opt {
|
||||
Some(value) => {
|
||||
|
|
@ -875,6 +927,7 @@ impl cosmic::Application for App {
|
|||
dialog_page_opt: None,
|
||||
dropdown_opt: None,
|
||||
heartbeat_handle: None,
|
||||
entering_name: false,
|
||||
};
|
||||
(app, common_task)
|
||||
}
|
||||
|
|
@ -1035,11 +1088,22 @@ impl cosmic::Application for App {
|
|||
self.dropdown_opt = None;
|
||||
}
|
||||
}
|
||||
Message::EnterUser(focus_input, username) => {
|
||||
self.entering_name = true;
|
||||
self.selected_username = NameIndexPair {
|
||||
data_idx: Self::user_data_index(&self.flags.user_datas, &username),
|
||||
username,
|
||||
};
|
||||
if focus_input {
|
||||
return widget::text_input::focus(USERNAME_ID.clone());
|
||||
}
|
||||
}
|
||||
Message::Username(username) => {
|
||||
if self.dropdown_opt == Some(Dropdown::User) {
|
||||
self.dropdown_opt = None;
|
||||
}
|
||||
if username != self.selected_username.username {
|
||||
if self.entering_name || username != self.selected_username.username {
|
||||
self.entering_name = false;
|
||||
let data_idx = Self::user_data_index(&self.flags.user_datas, &username);
|
||||
self.selected_username = NameIndexPair { username, data_idx };
|
||||
self.common.surface_images.clear();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue