Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 27 additions & 40 deletions crates/openlogi-overlay/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@ mod session;
use std::sync::Arc;

use anyhow::Result;
use gpui::AppContext as _;
use tracing::warn;
use tracing_subscriber::EnvFilter;

use openlogi_core::action_ring::DISPLAY_LIFETIME;

use crate::agent::{Ipc, OverlayCommand, spawn_ipc};
use crate::platform::RingPlacement;
use crate::ring::RingView;
use crate::ring::open_ring;
use crate::session::{ClickAwaySession, claim_the_role, spawn_click_away_dismissal};

fn main() -> Result<()> {
Expand Down Expand Up @@ -73,48 +71,37 @@ fn main() -> Result<()> {
for handle in cx.windows() {
let _ = handle.update(cx, |_, window, _| window.remove_window());
}
let placement = match RingPlacement::capture(cx) {
Ok(placement) => placement,
Err(error) => {
warn!(%error, "could not locate Actions Ring display");
let _ = commands.send(OverlayCommand::Cancel {
session_id: invocation.session_id,
});
return;
}
};
let commands = commands.clone();
let timeout_commands = commands.clone();
let session_id = invocation.session_id;
match cx.open_window(placement.window_options(), |_, cx| {
cx.new(|_| RingView::new(invocation, commands, &live_session))
}) {
Ok(handle) => {
if let Err(error) = handle
.update(cx, |_, window, _| placement.show(window))
.and_then(std::convert::identity)
});
let commands = commands.clone();
let timeout_commands = commands.clone();
let session_id = invocation.session_id;
// Awaited, not wrapped in `cx.update`: on Linux/Wayland this
// opens the ring's layer-shell host and then genuinely waits
// on the compositor's first pointer-motion delivery to it
// before placing the ring — see `ring::linux_wayland_ring_host`.
match open_ring(cx, invocation, commands, Arc::clone(&live_session)).await {
Ok((handle, host)) => {
cx.spawn(async move |cx| {
cx.background_executor().timer(DISPLAY_LIFETIME).await;
if handle
.update(cx, |_, window, _| window.remove_window())
.is_ok()
{
warn!(%error, "could not position Actions Ring window");
let _ = handle.update(cx, |_, window, _| window.remove_window());
let _ =
timeout_commands.send(OverlayCommand::Cancel { session_id });
return;
}
cx.spawn(async move |cx| {
cx.background_executor().timer(DISPLAY_LIFETIME).await;
if handle
.update(cx, |_, window, _| window.remove_window())
.is_ok()
{
let _ = timeout_commands
.send(OverlayCommand::Cancel { session_id });
}
})
.detach();
}
Err(error) => warn!(%error, "could not open Actions Ring window"),
// The ring's own dismissal paths (slot/cancel/root click,
// click-away) already close the host alongside it — this
// timeout path is the one exit that doesn't run through any
// of those, so it must close the host itself.
if let Some(host) = host {
let _ = host.update(cx, |_, window, _| window.remove_window());
}
})
.detach();
}
});
Err(error) => warn!(%error, "could not open Actions Ring window"),
}
}
})
.detach();
Expand Down
Loading
Loading