mirror of
https://github.com/flectar/mail.git
synced 2026-11-11 17:57:54 +00:00
Merge pull request #124 from flectar/iamdarkle/appimage-on-arch-clicking-links-does-nothing-cop
fix: open links from the AppImage
This commit is contained in:
5 files changed
+59
-48
No files matched your search
+3
-11
@@ -79,18 +79,10 @@ if [[ "${1:-}" == "--integrate" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# The mail shell has a small number of worker threads. One glibc allocation
|
||||
# arena is enough and prevents per-thread arenas from retaining render/sync
|
||||
# scratch memory after a burst of work. Respect an explicit user override.
|
||||
export MALLOC_ARENA_MAX="${MALLOC_ARENA_MAX:-1}"
|
||||
export MALLOC_TRIM_THRESHOLD_="${MALLOC_TRIM_THRESHOLD_:-65536}"
|
||||
# The executable finds the bundled libraries in usr/lib through its RUNPATH.
|
||||
# Do not export LD_LIBRARY_PATH: the browser and every other program the app
|
||||
# launches would inherit it and load those libraries instead of the host's.
|
||||
|
||||
# Preserve the host search path for external programs such as the browser.
|
||||
export FLECTAR_MAIL_HOST_LD_LIBRARY_PATH="${LD_LIBRARY_PATH-}"
|
||||
export FLECTAR_MAIL_BUNDLED=1
|
||||
|
||||
# linuxdeploy places any non-system ELF dependencies here.
|
||||
export LD_LIBRARY_PATH="$app_dir/usr/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
# The Linux binary supports Slint's Wayland and X11 winit integrations. Slint
|
||||
# paints every application control while the window system owns window chrome.
|
||||
export SLINT_BACKEND="${SLINT_BACKEND:-winit-software}"
|
||||
|
||||
@@ -108,7 +108,22 @@ for library in libxkbcommon-x11.so.0 libxkbcommon.so.0; do
|
||||
fi
|
||||
done
|
||||
|
||||
# Preserve the allocator tuning and stable process name from our launcher.
|
||||
# AppRun leaves LD_LIBRARY_PATH to the host, so the executable and bundled
|
||||
# libraries must find usr/lib through the RUNPATH linuxdeploy sets.
|
||||
require_runpath() {
|
||||
local dynamic
|
||||
dynamic="$(readelf -d "$1")"
|
||||
if [[ "$dynamic" != *"Library runpath: [$2]"* ]]; then
|
||||
printf '%s does not have RUNPATH %s.\n' "$1" "$2" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
require_runpath "$app_dir/usr/bin/flectar-mail" '$ORIGIN/../lib'
|
||||
for library in "$app_dir"/usr/lib/*.so*; do
|
||||
require_runpath "$library" '$ORIGIN'
|
||||
done
|
||||
|
||||
# Preserve the renderer default and stable process name from our launcher.
|
||||
cp "$project_dir/resources/AppRun" "$app_dir/AppRun"
|
||||
chmod +x "$app_dir/AppRun"
|
||||
|
||||
|
||||
@@ -406,6 +406,16 @@ class ReleaseTests(unittest.TestCase):
|
||||
f"print({str(libraries)!r})\n"
|
||||
)
|
||||
pkg_config.chmod(0o755)
|
||||
# The fixture ELFs carry no RUNPATH; report the one linuxdeploy sets.
|
||||
readelf = root / "bin/readelf"
|
||||
readelf.write_text(
|
||||
"#!/usr/bin/env python3\n"
|
||||
"import sys\n"
|
||||
"assert sys.argv[1] == '-d'\n"
|
||||
"runpath = '$ORIGIN/../lib' if sys.argv[2].endswith('/usr/bin/flectar-mail') else '$ORIGIN'\n"
|
||||
"print(f' 0x000000000000001d (RUNPATH) Library runpath: [{runpath}]')\n"
|
||||
)
|
||||
readelf.chmod(0o755)
|
||||
deploy = root / "bin/linuxdeploy"
|
||||
deploy.write_text('''#!/usr/bin/env python3
|
||||
import pathlib, shutil, sys
|
||||
|
||||
+6
-36
@@ -6,9 +6,9 @@ type OpenUrl = dyn Fn(&str) -> Result<(), String> + Send + Sync;
|
||||
|
||||
/// The URL service carried by [`crate::PlatformContext`].
|
||||
///
|
||||
/// The default uses the system browser, preserving Linux's portal and AppImage
|
||||
/// library-path handling for authorization. Hosts without desktop launchers
|
||||
/// supply a callback with [`Self::new`]. Clones share that callback's state.
|
||||
/// The default uses the system browser, preferring Linux's desktop portal for
|
||||
/// authorization. Hosts without desktop launchers supply a callback with
|
||||
/// [`Self::new`]. Clones share that callback's state.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ExternalUrlOpener {
|
||||
handler: Option<Arc<OpenUrl>>,
|
||||
@@ -51,13 +51,8 @@ impl ExternalUrlOpener {
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
#[cfg(linux_desktop)]
|
||||
fn host_command(program: &str) -> Command {
|
||||
fn quiet_command(program: &str) -> Command {
|
||||
let mut command = Command::new(program);
|
||||
restore_library_path(
|
||||
&mut command,
|
||||
std::env::var_os("FLECTAR_MAIL_BUNDLED").is_some(),
|
||||
std::env::var_os("FLECTAR_MAIL_HOST_LD_LIBRARY_PATH"),
|
||||
);
|
||||
command
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
@@ -65,21 +60,6 @@ fn host_command(program: &str) -> Command {
|
||||
command
|
||||
}
|
||||
|
||||
#[cfg(linux_desktop)]
|
||||
fn restore_library_path(command: &mut Command, bundled: bool, path: Option<std::ffi::OsString>) {
|
||||
if !bundled {
|
||||
return;
|
||||
}
|
||||
match path.filter(|p| !p.is_empty()) {
|
||||
Some(path) => {
|
||||
command.env("LD_LIBRARY_PATH", path);
|
||||
}
|
||||
None => {
|
||||
command.env_remove("LD_LIBRARY_PATH");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(linux_desktop)]
|
||||
fn launch(mut command: Command) -> Result<(), String> {
|
||||
let mut child = command.spawn().map_err(|e| e.to_string())?;
|
||||
@@ -132,12 +112,12 @@ fn open_system_authorization(address: &url::Url) -> Result<(), String> {
|
||||
if open_with_desktop_portal(address).is_ok() {
|
||||
return Ok(());
|
||||
}
|
||||
let mut xdg = host_command("xdg-open");
|
||||
let mut xdg = quiet_command("xdg-open");
|
||||
xdg.arg(url);
|
||||
if launch(xdg).is_ok() {
|
||||
return Ok(());
|
||||
}
|
||||
let mut gio = host_command("gio");
|
||||
let mut gio = quiet_command("gio");
|
||||
gio.args(["open", url]);
|
||||
launch(gio).map_err(|_| "Could not open the default browser".into())
|
||||
}
|
||||
@@ -266,16 +246,6 @@ mod tests {
|
||||
assert!(launch(command).is_ok());
|
||||
}
|
||||
#[test]
|
||||
fn restores_host_libraries_only_for_bundled_builds() {
|
||||
let mut command = Command::new("xdg-open");
|
||||
restore_library_path(&mut command, false, None);
|
||||
assert_eq!(command.get_envs().count(), 0);
|
||||
restore_library_path(&mut command, true, Some("/host/lib".into()));
|
||||
assert_eq!(command.get_envs().next().unwrap().1.unwrap(), "/host/lib");
|
||||
restore_library_path(&mut command, true, Some("".into()));
|
||||
assert_eq!(command.get_envs().next().unwrap().1, None);
|
||||
}
|
||||
#[test]
|
||||
fn foreground_browser_does_not_hold_up_authorization() {
|
||||
let mut command = Command::new("sh");
|
||||
command.args(["-c", "sleep 2"]);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
#[cfg(glibc)]
|
||||
tune_allocator();
|
||||
// Slint 1.18 keeps the native window and its rendering surface when
|
||||
// hidden on X11 and Windows. Use its window recreation path for tray mode,
|
||||
// as it already does on Wayland, so a hidden window holds no surface.
|
||||
@@ -18,3 +20,25 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
flectar_mail::run_desktop(flectar_mail::platform::launch_context()?)
|
||||
}
|
||||
|
||||
/// The mail shell has a small number of worker threads. One glibc allocation
|
||||
/// arena is enough and prevents per-thread arenas from retaining render/sync
|
||||
/// scratch memory after a burst of work. Set in-process rather than through
|
||||
/// the environment, which the browser and other launched programs would
|
||||
/// inherit. Explicit user tuning wins.
|
||||
#[cfg(glibc)]
|
||||
fn tune_allocator() {
|
||||
let tunables = std::env::var("GLIBC_TUNABLES").unwrap_or_default();
|
||||
let user_set = |variable: &str, tunable: &str| {
|
||||
std::env::var_os(variable).is_some() || tunables.contains(tunable)
|
||||
};
|
||||
// SAFETY: mallopt only adjusts allocator parameters; no pointers change.
|
||||
unsafe {
|
||||
if !user_set("MALLOC_ARENA_MAX", "glibc.malloc.arena_max") {
|
||||
libc::mallopt(libc::M_ARENA_MAX, 1);
|
||||
}
|
||||
if !user_set("MALLOC_TRIM_THRESHOLD_", "glibc.malloc.trim_threshold") {
|
||||
libc::mallopt(libc::M_TRIM_THRESHOLD, 64 * 1024);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user