Compare commits
No commits in common. "13545ac72536a22848af25fbc2d3a1bdf2e6ed1b" and "e0d919ed4a7d4d3d420f7afe7b4247b9f0c7bf87" have entirely different histories.
13545ac725
...
e0d919ed4a
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "creddy",
|
"name": "creddy",
|
||||||
"version": "0.4.1",
|
"version": "0.4.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "creddy"
|
name = "creddy"
|
||||||
version = "0.4.1"
|
version = "0.4.0"
|
||||||
description = "A friendly AWS credentials manager"
|
description = "A friendly AWS credentials manager"
|
||||||
authors = ["Joseph Montanaro"]
|
authors = ["Joseph Montanaro"]
|
||||||
license = ""
|
license = ""
|
||||||
|
@ -108,10 +108,6 @@ async fn setup(app: &mut App) -> Result<(), Box<dyn Error>> {
|
|||||||
setup_errors.push("Failed to register hotkeys. Hotkey settings have been disabled.".into());
|
setup_errors.push("Failed to register hotkeys. Hotkey settings have been disabled.".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let desktop_is_gnome = std::env::var("XDG_CURRENT_DESKTOP")
|
|
||||||
.map(|names| names.split(':').any(|n| n == "GNOME"))
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
// if session is empty, this is probably the first launch, so don't autohide
|
// if session is empty, this is probably the first launch, so don't autohide
|
||||||
if !conf.start_minimized || is_first_launch {
|
if !conf.start_minimized || is_first_launch {
|
||||||
app.get_window("main")
|
app.get_window("main")
|
||||||
@ -119,7 +115,7 @@ async fn setup(app: &mut App) -> Result<(), Box<dyn Error>> {
|
|||||||
.show()?;
|
.show()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = AppState::new(conf, session, pool, setup_errors, desktop_is_gnome);
|
let state = AppState::new(conf, session, pool, setup_errors);
|
||||||
app.manage(state);
|
app.manage(state);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -34,3 +34,59 @@ pub fn get_process_parent_info(pid: u32) -> Result<Client, ClientInfoError> {
|
|||||||
|
|
||||||
Ok(Client { pid: parent_pid_sys.as_u32(), exe })
|
Ok(Client { pid: parent_pid_sys.as_u32(), exe })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// async fn get_associated_pids(local_port: u16) -> Result<Vec<u32>, netstat2::error::Error> {
|
||||||
|
// let state = APP.get().unwrap().state::<AppState>();
|
||||||
|
// let AppConfig {
|
||||||
|
// listen_addr: app_listen_addr,
|
||||||
|
// listen_port: app_listen_port,
|
||||||
|
// ..
|
||||||
|
// } = *state.config.read().await;
|
||||||
|
|
||||||
|
// let sockets_iter = netstat2::iterate_sockets_info(
|
||||||
|
// AddressFamilyFlags::IPV4,
|
||||||
|
// ProtocolFlags::TCP
|
||||||
|
// )?;
|
||||||
|
// for item in sockets_iter {
|
||||||
|
// let sock_info = item?;
|
||||||
|
// let proto_info = match sock_info.protocol_socket_info {
|
||||||
|
// ProtocolSocketInfo::Tcp(tcp_info) => tcp_info,
|
||||||
|
// ProtocolSocketInfo::Udp(_) => {continue;}
|
||||||
|
// };
|
||||||
|
|
||||||
|
// if proto_info.local_port == local_port
|
||||||
|
// && proto_info.remote_port == app_listen_port
|
||||||
|
// && proto_info.local_addr == app_listen_addr
|
||||||
|
// && proto_info.remote_addr == app_listen_addr
|
||||||
|
// {
|
||||||
|
// return Ok(sock_info.associated_pids)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// Ok(vec![])
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// Theoretically, on some systems, multiple processes can share a socket
|
||||||
|
// pub async fn get_clients(local_port: u16) -> Result<Vec<Option<Client>>, ClientInfoError> {
|
||||||
|
// let mut clients = Vec::new();
|
||||||
|
// let mut sys = System::new();
|
||||||
|
// for p in get_associated_pids(local_port).await? {
|
||||||
|
// let pid = Pid::from_u32(p);
|
||||||
|
// sys.refresh_process(pid);
|
||||||
|
// let proc = sys.process(pid)
|
||||||
|
// .ok_or(ClientInfoError::ProcessNotFound)?;
|
||||||
|
|
||||||
|
// let client = Client {
|
||||||
|
// pid: p,
|
||||||
|
// exe: proc.exe().to_path_buf(),
|
||||||
|
// };
|
||||||
|
// clients.push(Some(client));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if clients.is_empty() {
|
||||||
|
// clients.push(None);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Ok(clients)
|
||||||
|
// }
|
||||||
|
@ -39,22 +39,13 @@ impl Visibility {
|
|||||||
.ok_or(WindowError::NoMainWindow)?;
|
.ok_or(WindowError::NoMainWindow)?;
|
||||||
|
|
||||||
self.leases += 1;
|
self.leases += 1;
|
||||||
// `original` represents the visibility of the window before any leases were acquired
|
|
||||||
// None means we don't know, Some(false) means it was previously hidden,
|
|
||||||
// Some(true) means it was previously visible
|
|
||||||
if self.original.is_none() {
|
if self.original.is_none() {
|
||||||
let is_visible = window.is_visible()?;
|
let is_visible = window.is_visible()?;
|
||||||
self.original = Some(is_visible);
|
self.original = Some(is_visible);
|
||||||
}
|
if !is_visible {
|
||||||
|
|
||||||
let state = app.state::<AppState>();
|
|
||||||
if matches!(self.original, Some(true)) && state.desktop_is_gnome {
|
|
||||||
// Gnome has a really annoying "focus-stealing prevention" behavior means we
|
|
||||||
// can't just pop up when the window is already visible, so to work around it
|
|
||||||
// we hide and then immediately unhide the window
|
|
||||||
window.hide()?;
|
|
||||||
}
|
|
||||||
window.show()?;
|
window.show()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
window.set_focus()?;
|
window.set_focus()?;
|
||||||
|
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
@ -104,9 +95,8 @@ pub struct AppState {
|
|||||||
pub request_count: RwLock<u64>,
|
pub request_count: RwLock<u64>,
|
||||||
pub waiting_requests: RwLock<HashMap<u64, Sender<Approval>>>,
|
pub waiting_requests: RwLock<HashMap<u64, Sender<Approval>>>,
|
||||||
pub pending_terminal_request: RwLock<bool>,
|
pub pending_terminal_request: RwLock<bool>,
|
||||||
// these are never modified and so don't need to be wrapped in RwLocks
|
// setup_errors is never modified and so doesn't need to be wrapped in RwLock
|
||||||
pub setup_errors: Vec<String>,
|
pub setup_errors: Vec<String>,
|
||||||
pub desktop_is_gnome: bool,
|
|
||||||
pool: sqlx::SqlitePool,
|
pool: sqlx::SqlitePool,
|
||||||
visibility: RwLock<Visibility>,
|
visibility: RwLock<Visibility>,
|
||||||
}
|
}
|
||||||
@ -117,7 +107,6 @@ impl AppState {
|
|||||||
session: Session,
|
session: Session,
|
||||||
pool: SqlitePool,
|
pool: SqlitePool,
|
||||||
setup_errors: Vec<String>,
|
setup_errors: Vec<String>,
|
||||||
desktop_is_gnome: bool,
|
|
||||||
) -> AppState {
|
) -> AppState {
|
||||||
AppState {
|
AppState {
|
||||||
config: RwLock::new(config),
|
config: RwLock::new(config),
|
||||||
@ -126,7 +115,6 @@ impl AppState {
|
|||||||
waiting_requests: RwLock::new(HashMap::new()),
|
waiting_requests: RwLock::new(HashMap::new()),
|
||||||
pending_terminal_request: RwLock::new(false),
|
pending_terminal_request: RwLock::new(false),
|
||||||
setup_errors,
|
setup_errors,
|
||||||
desktop_is_gnome,
|
|
||||||
pool,
|
pool,
|
||||||
visibility: RwLock::new(Visibility::new()),
|
visibility: RwLock::new(Visibility::new()),
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "creddy",
|
"productName": "creddy",
|
||||||
"version": "0.4.1"
|
"version": "0.4.0"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user