generated from eblume/project-template
Compare commits
4 commits
feature/cl
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b34371af87 | ||
| 17dab0e281 | |||
| 470ef1de0e | |||
| aec807fd28 |
5 changed files with 63 additions and 2 deletions
|
|
@ -12,6 +12,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
<!-- towncrier release notes start -->
|
||||
|
||||
## [v1.4.1] - 2026-06-08
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- The `heph` CLI and `heph-tui` now survive a daemon restart. Previously the unix-socket client connected once and never reconnected, so an opt-in self-update or `heph daemon restart` left every subsequent call failing — `heph-tui` would sit on errors until relaunched. The client now reconnects on a dropped socket: a request that never went out is retried transparently, while a reply lost mid-request is surfaced (not silently retried) so a mutation is never double-applied. A long-running TUI self-heals on its next refresh tick.
|
||||
- Quick-add popover (⌘'): hand keyboard focus back to the previously active app when it hides, and stop the (now invisible) overlay from intercepting clicks where it used to sit.
|
||||
|
||||
|
||||
## [v1.4.0] - 2026-06-08
|
||||
|
||||
### Features
|
||||
|
|
|
|||
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -2237,6 +2237,8 @@ dependencies = [
|
|||
"heph-core",
|
||||
"hephd",
|
||||
"libc",
|
||||
"objc2 0.6.4",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"serde_json",
|
||||
"winit",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -19,7 +19,16 @@ global-hotkey = "0.8"
|
|||
|
||||
# macOS-only: winit for the accessory-mode activation policy (no Dock icon),
|
||||
# pinned to the same minor eframe carries so cargo unifies to one winit; libc
|
||||
# for getppid() (orphan detection — self-exit when the supervising daemon dies).
|
||||
# for getppid() (orphan detection — self-exit when the supervising daemon dies);
|
||||
# objc2 + objc2-app-kit to hand keyboard focus back to the previously active app
|
||||
# when the popover hides (NSApplication.hide:/unhide:). Pinned to the 0.6/0.3
|
||||
# line global-hotkey already pulls in, so cargo unifies to one copy.
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
winit = "0.30"
|
||||
libc = "0.2"
|
||||
objc2 = "0.6"
|
||||
objc2-app-kit = { version = "0.3", default-features = false, features = [
|
||||
"std",
|
||||
"NSApplication",
|
||||
"NSResponder",
|
||||
] }
|
||||
|
|
|
|||
|
|
@ -226,6 +226,9 @@ impl QuickAdd {
|
|||
}
|
||||
|
||||
fn show(&mut self, ctx: &egui::Context) {
|
||||
// Undo the app-level hide from the previous `hide()` so we can take focus
|
||||
// again (no-op the first time / off macOS).
|
||||
app_take_focus();
|
||||
self.visible = true;
|
||||
self.focus_pending = true;
|
||||
self.current_hint = random_hint(self.current_hint);
|
||||
|
|
@ -256,6 +259,13 @@ impl QuickAdd {
|
|||
ctx.send_viewport_cmd(egui::ViewportCommand::InnerSize(egui::vec2(WIN_W, BASE_H)));
|
||||
self.win_h_applied = BASE_H;
|
||||
}
|
||||
// Hand keyboard focus back to the app underneath us. winit's
|
||||
// `Visible(false)` alone leaves *us* the active application, so focus
|
||||
// never returns and the borderless always-on-top overlay can keep eating
|
||||
// clicks where it used to sit. `NSApplication.hide:` orders our windows
|
||||
// fully out and activates the next app in line — exactly the one the user
|
||||
// was in (no-op off macOS).
|
||||
app_yield_focus();
|
||||
}
|
||||
|
||||
/// Optimistic submit: hide now, create in the background.
|
||||
|
|
@ -596,6 +606,39 @@ impl QuickAdd {
|
|||
}
|
||||
}
|
||||
|
||||
/// Hide the popover at the *application* level so macOS hands keyboard focus
|
||||
/// back to the previously active app. `NSApplication.hide:` orders all our
|
||||
/// windows out and activates the next app in line — the one the user was in —
|
||||
/// which a plain winit `Visible(false)` does not do. No-op off macOS.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn app_yield_focus() {
|
||||
use objc2::MainThreadMarker;
|
||||
use objc2_app_kit::NSApplication;
|
||||
// eframe's `update` runs on the main thread, so this marker is always Some.
|
||||
if let Some(mtm) = MainThreadMarker::new() {
|
||||
NSApplication::sharedApplication(mtm).hide(None);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn app_yield_focus() {}
|
||||
|
||||
/// Undo [`app_yield_focus`]: clear the app-level hidden flag before re-showing,
|
||||
/// so the window the viewport `Focus` command then makes key actually appears.
|
||||
/// (`unhide:` also re-activates us; the per-window `Focus`/`Visible` viewport
|
||||
/// commands do the rest.) No-op off macOS.
|
||||
#[cfg(target_os = "macos")]
|
||||
fn app_take_focus() {
|
||||
use objc2::MainThreadMarker;
|
||||
use objc2_app_kit::NSApplication;
|
||||
if let Some(mtm) = MainThreadMarker::new() {
|
||||
NSApplication::sharedApplication(mtm).unhide(None);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn app_take_focus() {}
|
||||
|
||||
/// The current parent process id, for orphan detection. `None` off macOS (where
|
||||
/// hephd does not supervise a helper — there is no Aqua session to inherit).
|
||||
fn current_parent_pid() -> Option<i32> {
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
The `heph` CLI and `heph-tui` now survive a daemon restart. Previously the unix-socket client connected once and never reconnected, so an opt-in self-update or `heph daemon restart` left every subsequent call failing — `heph-tui` would sit on errors until relaunched. The client now reconnects on a dropped socket: a request that never went out is retried transparently, while a reply lost mid-request is surfaced (not silently retried) so a mutation is never double-applied. A long-running TUI self-heals on its next refresh tick.
|
||||
Loading…
Add table
Add a link
Reference in a new issue