mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
Add terminal support for *nix
This commit is contained in:
parent
d2f818fad2
commit
b250a2f724
3 changed files with 87 additions and 27 deletions
|
@ -1,9 +1,15 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This script currently only supports universal builds on x86_64.
|
||||||
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Add Linux cross-compilation target
|
# Add Linux cross-compilation target
|
||||||
rustup target add aarch64-unknown-linux-gnu
|
rustup target add aarch64-unknown-linux-gnu
|
||||||
|
# Detect host architecture
|
||||||
|
HOST_ARCH=$(uname -m)
|
||||||
|
|
||||||
|
|
||||||
# Define output paths
|
# Define output paths
|
||||||
OUTPUT_DIR="../../../out/launcher"
|
OUTPUT_DIR="../../../out/launcher"
|
||||||
|
@ -12,11 +18,18 @@ LAUNCHER_DIR="$OUTPUT_DIR/anki-launcher"
|
||||||
# Clean existing output directory
|
# Clean existing output directory
|
||||||
rm -rf "$LAUNCHER_DIR"
|
rm -rf "$LAUNCHER_DIR"
|
||||||
|
|
||||||
# Build binaries for both Linux architectures
|
# Build binaries based on host architecture
|
||||||
cargo build -p launcher --release --target x86_64-unknown-linux-gnu
|
if [ "$HOST_ARCH" = "aarch64" ]; then
|
||||||
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
|
# On aarch64 host, only build for aarch64
|
||||||
cargo build -p launcher --release --target aarch64-unknown-linux-gnu
|
cargo build -p launcher --release --target aarch64-unknown-linux-gnu
|
||||||
(cd ../../.. && ./ninja extract:uv_lin_arm)
|
else
|
||||||
|
# On other hosts, build for both architectures
|
||||||
|
cargo build -p launcher --release --target x86_64-unknown-linux-gnu
|
||||||
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
|
||||||
|
cargo build -p launcher --release --target aarch64-unknown-linux-gnu
|
||||||
|
# Extract uv_lin_arm for cross-compilation
|
||||||
|
(cd ../../.. && ./ninja extract:uv_lin_arm)
|
||||||
|
fi
|
||||||
|
|
||||||
# Create output directory
|
# Create output directory
|
||||||
mkdir -p "$LAUNCHER_DIR"
|
mkdir -p "$LAUNCHER_DIR"
|
||||||
|
@ -24,13 +37,21 @@ mkdir -p "$LAUNCHER_DIR"
|
||||||
# Copy binaries and support files
|
# Copy binaries and support files
|
||||||
TARGET_DIR=${CARGO_TARGET_DIR:-../../../target}
|
TARGET_DIR=${CARGO_TARGET_DIR:-../../../target}
|
||||||
|
|
||||||
# Copy launcher binaries with architecture suffixes
|
# Copy binaries with architecture suffixes
|
||||||
cp "$TARGET_DIR/x86_64-unknown-linux-gnu/release/launcher" "$LAUNCHER_DIR/launcher.amd64"
|
if [ "$HOST_ARCH" = "aarch64" ]; then
|
||||||
cp "$TARGET_DIR/aarch64-unknown-linux-gnu/release/launcher" "$LAUNCHER_DIR/launcher.arm64"
|
# On aarch64 host, copy arm64 binary to both locations
|
||||||
|
cp "$TARGET_DIR/aarch64-unknown-linux-gnu/release/launcher" "$LAUNCHER_DIR/launcher.amd64"
|
||||||
# Copy uv binaries with architecture suffixes
|
cp "$TARGET_DIR/aarch64-unknown-linux-gnu/release/launcher" "$LAUNCHER_DIR/launcher.arm64"
|
||||||
cp "../../../out/extracted/uv/uv" "$LAUNCHER_DIR/uv.amd64"
|
# Copy uv binary to both locations
|
||||||
cp "../../../out/extracted/uv_lin_arm/uv" "$LAUNCHER_DIR/uv.arm64"
|
cp "../../../out/extracted/uv/uv" "$LAUNCHER_DIR/uv.amd64"
|
||||||
|
cp "../../../out/extracted/uv/uv" "$LAUNCHER_DIR/uv.arm64"
|
||||||
|
else
|
||||||
|
# On other hosts, copy architecture-specific binaries
|
||||||
|
cp "$TARGET_DIR/x86_64-unknown-linux-gnu/release/launcher" "$LAUNCHER_DIR/launcher.amd64"
|
||||||
|
cp "$TARGET_DIR/aarch64-unknown-linux-gnu/release/launcher" "$LAUNCHER_DIR/launcher.arm64"
|
||||||
|
cp "../../../out/extracted/uv/uv" "$LAUNCHER_DIR/uv.amd64"
|
||||||
|
cp "../../../out/extracted/uv_lin_arm/uv" "$LAUNCHER_DIR/uv.arm64"
|
||||||
|
fi
|
||||||
|
|
||||||
# Copy support files from lin directory
|
# Copy support files from lin directory
|
||||||
for file in README.md anki.1 anki.desktop anki.png anki.xml anki.xpm install.sh uninstall.sh anki; do
|
for file in README.md anki.1 anki.desktop anki.png anki.xml anki.xpm install.sh uninstall.sh anki; do
|
||||||
|
|
|
@ -15,6 +15,7 @@ use anyhow::Result;
|
||||||
|
|
||||||
// Re-export Unix functions that macOS uses
|
// Re-export Unix functions that macOS uses
|
||||||
pub use super::unix::{
|
pub use super::unix::{
|
||||||
|
ensure_terminal_shown,
|
||||||
exec_anki,
|
exec_anki,
|
||||||
get_anki_binary_path,
|
get_anki_binary_path,
|
||||||
initial_terminal_setup,
|
initial_terminal_setup,
|
||||||
|
@ -36,20 +37,7 @@ pub fn launch_anki_detached(anki_bin: &std::path::Path, _config: &crate::Config)
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ensure_terminal_shown() -> Result<()> {
|
pub fn relaunch_in_terminal() -> Result<()> {
|
||||||
let stdout_is_terminal = std::io::IsTerminal::is_terminal(&std::io::stdout());
|
|
||||||
if !stdout_is_terminal {
|
|
||||||
// If launched from GUI, relaunch in Terminal.app
|
|
||||||
relaunch_in_terminal()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set terminal title to "Anki Launcher"
|
|
||||||
print!("\x1b]0;Anki Launcher\x07");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relaunch_in_terminal() -> Result<()> {
|
|
||||||
let current_exe = std::env::current_exe().context("Failed to get current executable path")?;
|
let current_exe = std::env::current_exe().context("Failed to get current executable path")?;
|
||||||
Command::new("open")
|
Command::new("open")
|
||||||
.args(["-a", "Terminal"])
|
.args(["-a", "Terminal"])
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::io::IsTerminal;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
@ -17,8 +18,58 @@ pub fn initial_terminal_setup(_config: &mut Config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ensure_terminal_shown() -> Result<()> {
|
pub fn ensure_terminal_shown() -> Result<()> {
|
||||||
// Skip terminal relaunch on non-macOS Unix systems as we don't know which
|
let stdout_is_terminal = IsTerminal::is_terminal(&std::io::stdout());
|
||||||
// terminal is installed
|
if !stdout_is_terminal {
|
||||||
|
// If launched from GUI, try to relaunch in a terminal
|
||||||
|
crate::platform::relaunch_in_terminal()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set terminal title to "Anki Launcher"
|
||||||
|
print!("\x1b]2;Anki Launcher\x07");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
pub fn relaunch_in_terminal() -> Result<()> {
|
||||||
|
let current_exe = std::env::current_exe().context("Failed to get current executable path")?;
|
||||||
|
|
||||||
|
// Try terminals in order of preference
|
||||||
|
let terminals = [
|
||||||
|
("x-terminal-emulator", vec!["-e"]),
|
||||||
|
("gnome-terminal", vec!["--"]),
|
||||||
|
("konsole", vec!["-e"]),
|
||||||
|
("xfce4-terminal", vec!["-e"]),
|
||||||
|
("alacritty", vec!["-e"]),
|
||||||
|
("kitty", vec![]),
|
||||||
|
("foot", vec![]),
|
||||||
|
("urxvt", vec!["-e"]),
|
||||||
|
("xterm", vec!["-e"]),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (terminal_cmd, args) in &terminals {
|
||||||
|
// Check if terminal exists
|
||||||
|
if Command::new("which")
|
||||||
|
.arg(terminal_cmd)
|
||||||
|
.output()
|
||||||
|
.map(|o| o.status.success())
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
// Try to launch the terminal
|
||||||
|
let mut cmd = Command::new(terminal_cmd);
|
||||||
|
if args.is_empty() {
|
||||||
|
cmd.arg(¤t_exe);
|
||||||
|
} else {
|
||||||
|
cmd.args(args).arg(¤t_exe);
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.spawn().is_ok() {
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no terminal worked, continue without relaunching
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue