Add a bindable "Refresh Page" action to Settings > Behavior > Page Turner that triggers a deep e-ink full refresh (GC16) to clear screen ghosting, gated to e-ink mode on Android. It reuses the existing hardware page-turner key-binding machinery: a new 'refresh' slot in HardwarePageTurnerSettings, shown only when isAndroidApp and the e-ink view setting is on. Pressing the bound key calls a new native bridge command instead of paginating. The native side is device-agnostic: EinkRefreshController probes each vendor mechanism via reflection and stops at the first that works, covering Onyx BOOX (Qualcomm View.refreshScreen), Tolino/Nook (NTX postInvalidateDelayed) and Boyue-style Rockchip (requestEpdMode) without bundling any vendor SDK. A success:false result is a soft no-op on non-e-ink hardware. iOS gets a stub. Verified on an Onyx BOOX Leaf5: the Onyx path fires and performs a visible full GC16 refresh. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -273,3 +273,10 @@ pub(crate) async fn clear_secure_item<R: Runtime>(
|
||||
) -> Result<SecureItemResponse> {
|
||||
app.native_bridge().clear_secure_item(payload)
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub(crate) async fn refresh_eink_screen<R: Runtime>(
|
||||
app: AppHandle<R>,
|
||||
) -> Result<RefreshEinkScreenResponse> {
|
||||
app.native_bridge().refresh_eink_screen()
|
||||
}
|
||||
|
||||
@@ -345,6 +345,12 @@ impl<R: Runtime> NativeBridge<R> {
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// E-ink panels exist only on the mobile (Android) side. Desktop has no
|
||||
/// e-ink controller, so this is unsupported here.
|
||||
pub fn refresh_eink_screen(&self) -> crate::Result<RefreshEinkScreenResponse> {
|
||||
Err(crate::Error::UnsupportedPlatformError)
|
||||
}
|
||||
}
|
||||
|
||||
const KEYRING_SERVICE: &str = "Readest Safe Storage";
|
||||
|
||||
@@ -88,6 +88,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
commands::set_secure_item,
|
||||
commands::get_secure_item,
|
||||
commands::clear_secure_item,
|
||||
commands::refresh_eink_screen,
|
||||
])
|
||||
.setup(|app, api| {
|
||||
#[cfg(mobile)]
|
||||
|
||||
@@ -332,6 +332,14 @@ impl<R: Runtime> NativeBridge<R> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Runtime> NativeBridge<R> {
|
||||
pub fn refresh_eink_screen(&self) -> crate::Result<RefreshEinkScreenResponse> {
|
||||
self.0
|
||||
.run_mobile_plugin("refresh_eink_screen", ())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Runtime> NativeBridge<R> {
|
||||
/// Open a full-screen `WKWebView` / `WebView` over the main app,
|
||||
/// navigate to `payload.url` with a real Chrome UA, wait for load
|
||||
|
||||
@@ -395,3 +395,13 @@ pub struct GetSecureItemResponse {
|
||||
pub value: Option<String>,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
/// Result of a deep e-ink full screen refresh. `success: false` means no
|
||||
/// known e-ink controller responded on this device (e.g. a non-e-ink
|
||||
/// Android phone) — not a hard error.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RefreshEinkScreenResponse {
|
||||
pub success: bool,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user