From a946c439b51884b54842169ad6652d83c957d8e6 Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 16:31:09 +0800 Subject: [PATCH 1/9] Add scrolling via ctrl n and p --- src/app.rs | 2 +- src/app/tile.rs | 14 +++-- src/app/tile/update.rs | 130 +++++++++++++++++++++-------------------- 3 files changed, 78 insertions(+), 68 deletions(-) diff --git a/src/app.rs b/src/app.rs index 904b7d4..821c62d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -68,7 +68,7 @@ pub enum Message { SetSender(ExtSender), SwitchToPage(Page), ClipboardHistory(ClipBoardContentType), - ChangeFocus(ArrowKey), + ChangeFocus(ArrowKey, u32), } /// The window settings for rustcast diff --git a/src/app/tile.rs b/src/app/tile.rs index 504b0bd..14896c4 100644 --- a/src/app/tile.rs +++ b/src/app/tile.rs @@ -172,22 +172,26 @@ impl Tile { return Some(Message::KeyPressed(65598)); } keyboard::Key::Named(Named::ArrowUp) => { - return Some(Message::ChangeFocus(ArrowKey::Up)); + return Some(Message::ChangeFocus(ArrowKey::Up, 1)); } keyboard::Key::Named(Named::ArrowLeft) => { - return Some(Message::ChangeFocus(ArrowKey::Left)); + return Some(Message::ChangeFocus(ArrowKey::Left, 1)); } keyboard::Key::Named(Named::ArrowRight) => { - return Some(Message::ChangeFocus(ArrowKey::Right)); + return Some(Message::ChangeFocus(ArrowKey::Right, 1)); } keyboard::Key::Named(Named::ArrowDown) => { - return Some(Message::ChangeFocus(ArrowKey::Down)); + return Some(Message::ChangeFocus(ArrowKey::Down, 1)); } keyboard::Key::Character(chr) => { - if modifiers.command() && chr.to_string().to_lowercase() == "r" { + if modifiers.command() && chr.to_string() == "r" { return Some(Message::ReloadConfig); } else if modifiers.command() && chr.to_string() == "," { open_settings(); + } else if chr.to_string() == "p" && modifiers.control() { + return Some(Message::ChangeFocus(ArrowKey::Up, 3)); + } else if chr.to_string() == "n" && modifiers.control() { + return Some(Message::ChangeFocus(ArrowKey::Down, 3)); } else { return Some(Message::FocusTextInput(Move::Forwards( chr.to_string(), diff --git a/src/app/tile/update.rs b/src/app/tile/update.rs index 2d24448..7fc9dd3 100644 --- a/src/app/tile/update.rs +++ b/src/app/tile/update.rs @@ -107,74 +107,80 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { Task::none() } - Message::ChangeFocus(key) => { - let len = match tile.page { - Page::ClipboardHistory => tile.clipboard_content.len() as u32, - Page::EmojiSearch => tile.emoji_apps.search_prefix(&tile.query_lc).count() as u32, // or tile.results.len() - _ => tile.results.len() as u32, - }; + Message::ChangeFocus(key, amount) => { + let mut return_task = Task::none(); + for _ in 0..amount { + let len = match tile.page { + Page::ClipboardHistory => tile.clipboard_content.len() as u32, + Page::EmojiSearch => { + tile.emoji_apps.search_prefix(&tile.query_lc).count() as u32 + } // or tile.results.len() + _ => tile.results.len() as u32, + }; - let old_focus_id = tile.focus_id; + let old_focus_id = tile.focus_id; - if len == 0 { - return Task::none(); - } + if len == 0 { + return Task::none(); + } - let change_by = match tile.page { - Page::EmojiSearch => 6, - _ => 1, - }; + let change_by = match tile.page { + Page::EmojiSearch => 6, + _ => 1, + }; - let task = match (&key, &tile.page) { - (ArrowKey::Down, _) => { - tile.focus_id = (tile.focus_id + change_by) % len; - Task::none() - } - (ArrowKey::Up, _) => { - tile.focus_id = (tile.focus_id + len - change_by) % len; - Task::none() - } - (ArrowKey::Left, Page::EmojiSearch) => { - tile.focus_id = (tile.focus_id + len - 1) % len; - operation::focus("results") - } - (ArrowKey::Right, Page::EmojiSearch) => { - tile.focus_id = (tile.focus_id + 1) % len; - operation::focus("results") - } - _ => Task::none(), - }; + let task = match (&key, &tile.page) { + (ArrowKey::Down, _) => { + tile.focus_id = (tile.focus_id + change_by) % len; + Task::none() + } + (ArrowKey::Up, _) => { + tile.focus_id = (tile.focus_id + len - change_by) % len; + Task::none() + } + (ArrowKey::Left, Page::EmojiSearch) => { + tile.focus_id = (tile.focus_id + len - 1) % len; + operation::focus("results") + } + (ArrowKey::Right, Page::EmojiSearch) => { + tile.focus_id = (tile.focus_id + 1) % len; + operation::focus("results") + } + _ => Task::none(), + }; - let quantity = match tile.page { - Page::Main => 66.5, - Page::ClipboardHistory => 50., - Page::EmojiSearch => 5., - }; + let quantity = match tile.page { + Page::Main => 66.5, + Page::ClipboardHistory => 50., + Page::EmojiSearch => 5., + }; - let (wrapped_up, wrapped_down) = match &key { - ArrowKey::Up => (tile.focus_id > old_focus_id, false), - ArrowKey::Down => (false, tile.focus_id < old_focus_id), - _ => (false, false), - }; + let (wrapped_up, wrapped_down) = match &key { + ArrowKey::Up => (tile.focus_id > old_focus_id, false), + ArrowKey::Down => (false, tile.focus_id < old_focus_id), + _ => (false, false), + }; - let y = if wrapped_down { - 0.0 - } else if wrapped_up { - (len.saturating_sub(1)) as f32 * quantity - } else { - tile.focus_id as f32 * quantity - }; + let y = if wrapped_down { + 0.0 + } else if wrapped_up { + (len.saturating_sub(1)) as f32 * quantity + } else { + tile.focus_id as f32 * quantity + }; - Task::batch([ - task, - operation::scroll_to( - "results", - AbsoluteOffset { - x: None, - y: Some(y), - }, - ), - ]) + return_task = Task::batch([ + task, + operation::scroll_to( + "results", + AbsoluteOffset { + x: None, + y: Some(y), + }, + ), + ]); + } + return_task } Message::ResizeWindow(id, height) => { @@ -526,7 +532,7 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { id, ((max_elem * 55) + 35 + DEFAULT_WINDOW_HEIGHT as usize) as f32, )), - Task::done(Message::ChangeFocus(ArrowKey::Left)), + Task::done(Message::ChangeFocus(ArrowKey::Left, 1)), ])) } else if tile.page == Page::ClipboardHistory { task.chain(Task::batch([ @@ -534,7 +540,7 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { id, ((7 * 55) + 35 + DEFAULT_WINDOW_HEIGHT as usize) as f32, )), - Task::done(Message::ChangeFocus(ArrowKey::Left)), + Task::done(Message::ChangeFocus(ArrowKey::Left, 1)), ])) } else { task From 3e74943c8fb51523b6fabbfb3531d1b44c7bfc72 Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 16:40:12 +0800 Subject: [PATCH 2/9] Fix resize not happening when switching to clipboard history --- src/app/tile/update.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/app/tile/update.rs b/src/app/tile/update.rs index 7fc9dd3..688a5e8 100644 --- a/src/app/tile/update.rs +++ b/src/app/tile/update.rs @@ -298,9 +298,21 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { Message::SwitchToPage(page) => { tile.page = page; + let task = if tile.page == Page::ClipboardHistory { + window::latest().map(|x| { + let id = x.unwrap(); + Message::ResizeWindow( + id, + ((7 * 55) + 35 + DEFAULT_WINDOW_HEIGHT as usize) as f32, + ) + }) + } else { + Task::none() + }; Task::batch([ Task::done(Message::ClearSearchQuery), Task::done(Message::ClearSearchResults), + task, ]) } From d2485ccbbc4040354a74d6028dd8a88bb1621498 Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 17:17:24 +0800 Subject: [PATCH 3/9] Improve icon finding --- Cargo.lock | 1 + Cargo.toml | 1 + src/platform/macos/discovery.rs | 111 ++++++++++++++++++++++++++++---- src/utils.rs | 1 - 4 files changed, 99 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a49025..3761ee6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3808,6 +3808,7 @@ version = "0.1.0" dependencies = [ "anyhow", "arboard", + "block2 0.6.2", "emojis", "global-hotkey", "iced", diff --git a/Cargo.toml b/Cargo.toml index 1f7f5f4..555c0e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] anyhow = "1.0.100" arboard = "3.6.1" +block2 = "0.6.2" emojis = "0.8.0" global-hotkey = "0.7.0" iced = { version = "0.14.0", features = ["image", "tokio"] } diff --git a/src/platform/macos/discovery.rs b/src/platform/macos/discovery.rs index 82f34ff..1b33d39 100644 --- a/src/platform/macos/discovery.rs +++ b/src/platform/macos/discovery.rs @@ -16,19 +16,24 @@ use core::{ }; use std::{ env, + io::Cursor, path::{Path, PathBuf}, sync::LazyLock, }; +use iced::widget::image::Handle; use log::error; +use objc2::{Message, rc::Retained}; +use objc2_app_kit::{NSBitmapImageFileType, NSBitmapImageRep, NSImage, NSImageRep, NSWorkspace}; use objc2_core_foundation::{CFArray, CFRetained, CFURL}; -use objc2_foundation::{NSBundle, NSNumber, NSString, NSURL, ns_string}; +use objc2_foundation::{ + NSBundle, NSData, NSDictionary, NSNumber, NSSize, NSString, NSURL, ns_string, +}; use rayon::iter::{IntoParallelIterator, ParallelIterator as _}; use crate::{ app::apps::{App, AppCommand}, commands::Function, - utils::handle_from_icns, }; use super::super::cross; @@ -238,18 +243,17 @@ fn query_app(url: impl AsRef, store_icons: bool) -> Option { .map(|stem| stem.to_string_lossy().into_owned()) })?; - let icons = store_icons - .then(|| { - get_string(ns_string!("CFBundleIconFile")).and_then(|icon| { - let mut path = path.join("Contents/Resources").join(&icon); - if path.extension().is_none() { - path.set_extension("icns"); - } - - handle_from_icns(&path) - }) - }) - .flatten(); + let icon = icon_of_path_ns(path.to_str().unwrap_or(&name)).unwrap_or(vec![]); + let icons = if store_icons { + image::ImageReader::new(Cursor::new(icon)) + .with_guessed_format() + .unwrap() + .decode() + .ok() + .map(|img| Handle::from_rgba(img.width(), img.height(), img.into_bytes())) + } else { + None + }; Some(App { ranking: 0, @@ -307,3 +311,82 @@ fn is_helper_location(path: &Path) -> bool { || s.contains("/Contents/Frameworks/") || s.contains("/Library/PrivilegedHelperTools/") } + +/// https://github.com/cardisoft/cardinal/blob/339b27c3c6abaf94405a9ab09ec39296baba4f91/fs-icon/src/lib.rs#L37 +pub fn icon_of_path_ns(path: &str) -> Option> { + objc2::rc::autoreleasepool(|_| -> Option> { + let path_ns = NSString::from_str(path); + let image = NSWorkspace::sharedWorkspace().iconForFile(&path_ns); + + // Choose what you consider "high quality" output. + // 256 is a good default; you can bump to 512 if you want. + let target: f64 = 256.0; + + let png_data: Retained = (|| -> Option<_> { + unsafe { + // Pick the best representation: + // - Prefer the smallest rep that is >= target (avoids upscaling) + // - Otherwise pick the largest available rep + let mut best_rep = None::>; + let mut best_w = 0.0; + let mut best_h = 0.0; + + let mut largest_rep = None::>; + let mut largest_area = 0.0; + let mut largest_w = 0.0; + let mut largest_h = 0.0; + + for rep in image.representations().iter() { + let s = rep.size(); + let w = s.width; + let h = s.height; + + // Track largest (fallback) + let area = w * h; + if area > largest_area { + largest_area = area; + largest_rep = Some(rep.retain()); + largest_w = w; + largest_h = h; + } + + // Track best rep for target (no upscale if possible) + if w >= target && h >= target { + let best_area = best_w * best_h; + if best_rep.is_none() || area < best_area { + best_rep = Some(rep.retain()); + best_w = w; + best_h = h; + } + } + } + + let (rep, out_w, out_h) = if let Some(rep) = best_rep { + (rep, target, target) + } else if let Some(rep) = largest_rep { + // If nothing reaches target, use largest and render at its native size + (rep, largest_w, largest_h) + } else { + return None; + }; + + let new_image = NSImage::imageWithSize_flipped_drawingHandler( + NSSize::new(out_w, out_h), + false, + &block2::RcBlock::new(move |rect| { + rep.drawInRect(rect); + true.into() + }), + ); + + NSBitmapImageRep::imageRepWithData(&*new_image.TIFFRepresentation()?)? + .representationUsingType_properties( + NSBitmapImageFileType::PNG, + &NSDictionary::new(), + ) + } + })()?; + + Some(png_data.to_vec()) + }) +} diff --git a/src/utils.rs b/src/utils.rs index c22fb7c..c5bf998 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -7,7 +7,6 @@ use image::RgbaImage; use objc2_app_kit::NSWorkspace; use objc2_foundation::NSURL; -/// This logs an error to the error log file pub fn icns_data_to_handle(data: Vec) -> Option { let family = IconFamily::read(std::io::Cursor::new(&data)).ok()?; From f21a5c6b16028881c6b6ce6140d87f8f6101ed9c Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 17:33:24 +0800 Subject: [PATCH 4/9] disable notarization temporarily --- scripts/sign-macos.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/sign-macos.sh b/scripts/sign-macos.sh index 44a1826..eeafe4f 100755 --- a/scripts/sign-macos.sh +++ b/scripts/sign-macos.sh @@ -57,12 +57,12 @@ else printf '%s' "$MACOS_NOTARY_KEY" | base64 --decode > "$NOTARY_KEY_FILE" fi -xcrun notarytool submit "notarization.zip" \ - --team-id "$MACOS_NOTARY_TEAM_ID" \ - --issuer "$MACOS_NOTARY_ISSUER_ID" \ - --key-id "$MACOS_NOTARY_KEY_ID" \ - --key "$NOTARY_KEY_FILE" \ - --wait +# xcrun notarytool submit "notarization.zip" \ +# --team-id "$MACOS_NOTARY_TEAM_ID" \ +# --issuer "$MACOS_NOTARY_ISSUER_ID" \ +# --key-id "$MACOS_NOTARY_KEY_ID" \ +# --key "$NOTARY_KEY_FILE" \ +# --wait echo "Attach staple" xcrun stapler staple "$APP_PATH" From 57db840a95feb33775b6a60beceaf3de4dfdfc28 Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 17:41:49 +0800 Subject: [PATCH 5/9] Remove cargo test since there aren't any --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 818a0e8..dd6b2e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,5 +56,5 @@ jobs: - name: cargo clippy run: cargo clippy --all-targets - - name: cargo test - run: cargo test --all-targets +# - name: cargo test +# run: cargo test --all-targets From 3d43173295f5b7cdbd2e23909ad84e8d09abd834 Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 17:49:42 +0800 Subject: [PATCH 6/9] Fix signing script --- scripts/sign-macos-broken.sh | 68 ++++++++++++++++++++++++++++ scripts/sign-macos.sh | 86 +++++++++++------------------------- 2 files changed, 95 insertions(+), 59 deletions(-) create mode 100755 scripts/sign-macos-broken.sh diff --git a/scripts/sign-macos-broken.sh b/scripts/sign-macos-broken.sh new file mode 100755 index 0000000..eeafe4f --- /dev/null +++ b/scripts/sign-macos-broken.sh @@ -0,0 +1,68 @@ +#!/bin/bash +set -euo pipefail + +RELEASE_DIR="target/release" +APP_DIR="$RELEASE_DIR/macos" +APP_NAME="Rustcast.app" +APP_PATH="$APP_DIR/$APP_NAME" + +# --- Required env vars (using the names you provided) --- +environment=( + "MACOS_CERTIFICATE" + "MACOS_CERTIFICATE_PWD" + "MACOS_CI_KEYCHAIN_PWD" + "MACOS_CERTIFICATE_NAME" + "MACOS_NOTARIZATION_PWD" + "MACOS_NOTARY_TEAM_ID" + "MACOS_NOTARY_KEY_ID" + "MACOS_NOTARY_KEY" +) + +for var in "${environment[@]}"; do + if [[ -z "${!var:-}" ]]; then + echo "Error: $var is not set" + exit 1 + fi +done + +# Optional: only needed if you still want to keep this around +: "${MACOS_NOTARISATION_APPLE_ID:=}" + +echo "Decoding certificate" +echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 + +echo "Installing cert in a new keychain" +security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain +security default-keychain -s build.keychain +security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain +security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign +security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain + +echo "Signing..." +/usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime --timestamp "$APP_PATH" -v + +echo "Creating temp notarization archive" +ditto -c -k --keepParent "$APP_PATH" "notarization.zip" + +echo "Notarize app (API key auth)" +# MACOS_NOTARY_KEY can be either: +# - the *contents* of the .p8 key, or +# - base64 of the .p8 key (recommended for CI) +# +# If it's base64, decode it first. +NOTARY_KEY_FILE="AuthKey.p8" +if printf '%s' "$MACOS_NOTARY_KEY" | grep -q "BEGIN PRIVATE KEY"; then + printf '%s' "$MACOS_NOTARY_KEY" > "$NOTARY_KEY_FILE" +else + printf '%s' "$MACOS_NOTARY_KEY" | base64 --decode > "$NOTARY_KEY_FILE" +fi + +# xcrun notarytool submit "notarization.zip" \ +# --team-id "$MACOS_NOTARY_TEAM_ID" \ +# --issuer "$MACOS_NOTARY_ISSUER_ID" \ +# --key-id "$MACOS_NOTARY_KEY_ID" \ +# --key "$NOTARY_KEY_FILE" \ +# --wait + +echo "Attach staple" +xcrun stapler staple "$APP_PATH" diff --git a/scripts/sign-macos.sh b/scripts/sign-macos.sh index eeafe4f..881f50f 100755 --- a/scripts/sign-macos.sh +++ b/scripts/sign-macos.sh @@ -1,68 +1,36 @@ -#!/bin/bash -set -euo pipefail +#!/usr/bin/env -S bash -e -RELEASE_DIR="target/release" -APP_DIR="$RELEASE_DIR/macos" -APP_NAME="Rustcast.app" -APP_PATH="$APP_DIR/$APP_NAME" +APP_BUNDLE_PATH="${APP_BUNDLE_PATH:?APP_BUNDLE_PATH not set}" -# --- Required env vars (using the names you provided) --- -environment=( - "MACOS_CERTIFICATE" - "MACOS_CERTIFICATE_PWD" - "MACOS_CI_KEYCHAIN_PWD" - "MACOS_CERTIFICATE_NAME" - "MACOS_NOTARIZATION_PWD" - "MACOS_NOTARY_TEAM_ID" - "MACOS_NOTARY_KEY_ID" - "MACOS_NOTARY_KEY" -) +# 1. Create a temporary keychain and import certificate +KEYCHAIN=build.keychain-db -for var in "${environment[@]}"; do - if [[ -z "${!var:-}" ]]; then - echo "Error: $var is not set" - exit 1 - fi -done +if security list-keychains | grep -q "$KEYCHAIN"; then + echo "Keychain $KEYCHAIN already exists, using existing keychain." +else + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" +fi -# Optional: only needed if you still want to keep this around -: "${MACOS_NOTARISATION_APPLE_ID:=}" +security default-keychain -s "$KEYCHAIN" +security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" +security set-keychain-settings "$KEYCHAIN" +security default-keychain -s "$KEYCHAIN" +security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" +security set-keychain-settings "$KEYCHAIN" -echo "Decoding certificate" echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 +security import certificate.p12 \ + -k "$KEYCHAIN" \ + -P "$MACOS_CERTIFICATE_PWD" \ + -T /usr/bin/codesign -echo "Installing cert in a new keychain" -security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain -security default-keychain -s build.keychain -security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain -security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign -security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain - -echo "Signing..." -/usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime --timestamp "$APP_PATH" -v - -echo "Creating temp notarization archive" -ditto -c -k --keepParent "$APP_PATH" "notarization.zip" - -echo "Notarize app (API key auth)" -# MACOS_NOTARY_KEY can be either: -# - the *contents* of the .p8 key, or -# - base64 of the .p8 key (recommended for CI) -# -# If it's base64, decode it first. -NOTARY_KEY_FILE="AuthKey.p8" -if printf '%s' "$MACOS_NOTARY_KEY" | grep -q "BEGIN PRIVATE KEY"; then - printf '%s' "$MACOS_NOTARY_KEY" > "$NOTARY_KEY_FILE" -else - printf '%s' "$MACOS_NOTARY_KEY" | base64 --decode > "$NOTARY_KEY_FILE" -fi +security set-key-partition-list -S apple-tool:,apple:,codesign: \ + -s -k "$MACOS_CI_KEYCHAIN_PWD" "$KEYCHAIN" -# xcrun notarytool submit "notarization.zip" \ -# --team-id "$MACOS_NOTARY_TEAM_ID" \ -# --issuer "$MACOS_NOTARY_ISSUER_ID" \ -# --key-id "$MACOS_NOTARY_KEY_ID" \ -# --key "$NOTARY_KEY_FILE" \ -# --wait +# 2. Sign app bundle +codesign --deep --force --options runtime --timestamp \ + --sign "$MACOS_CERTIFICATE_NAME" \ + "$APP_BUNDLE_PATH" -echo "Attach staple" -xcrun stapler staple "$APP_PATH" +codesign --verify --deep --strict --verbose=2 "$APP_BUNDLE_PATH" +echo "Signed app at $APP_BUNDLE_PATH" From bdbf05a9148646c3c0f2d95e364cad81432cefc0 Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 18:06:37 +0800 Subject: [PATCH 7/9] move single up down instead --- src/app/tile.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/tile.rs b/src/app/tile.rs index 14896c4..6775c24 100644 --- a/src/app/tile.rs +++ b/src/app/tile.rs @@ -189,9 +189,9 @@ impl Tile { } else if modifiers.command() && chr.to_string() == "," { open_settings(); } else if chr.to_string() == "p" && modifiers.control() { - return Some(Message::ChangeFocus(ArrowKey::Up, 3)); + return Some(Message::ChangeFocus(ArrowKey::Up, 1)); } else if chr.to_string() == "n" && modifiers.control() { - return Some(Message::ChangeFocus(ArrowKey::Down, 3)); + return Some(Message::ChangeFocus(ArrowKey::Down, 1)); } else { return Some(Message::FocusTextInput(Move::Forwards( chr.to_string(), From 010e8ec16111a4e35d0629d0cae30742ee20347c Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 18:07:38 +0800 Subject: [PATCH 8/9] disable notarization temporarily --- scripts/package-macos.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/package-macos.sh b/scripts/package-macos.sh index c3befbf..95a5fac 100755 --- a/scripts/package-macos.sh +++ b/scripts/package-macos.sh @@ -28,14 +28,14 @@ echo "DMG_PATH=$DMG_PATH" >> "$GITHUB_ENV" if [[ -n "$MACOS_NOTARY_KEY_ID" ]]; then echo "$MACOS_NOTARY_KEY" | base64 --decode > notary.key - xcrun notarytool store-credentials "notarytool-profile" --apple-id "$MACOS_NOTARISATION_APPLE_ID" --team-id "$MACOS_NOTARY_TEAM_ID" --password "$MACOS_NOTARIZATION_PWD" - - xcrun notarytool submit "$DMG_PATH" \ - --key notary.key \ - --key-id "$MACOS_NOTARY_KEY_ID" \ - --issuer "$MACOS_NOTARY_ISSUER_ID" \ - --team-id "$MACOS_NOTARY_TEAM_ID" \ - --wait + # xcrun notarytool store-credentials "notarytool-profile" --apple-id "$MACOS_NOTARISATION_APPLE_ID" --team-id "$MACOS_NOTARY_TEAM_ID" --password "$MACOS_NOTARIZATION_PWD" + +# xcrun notarytool submit "$DMG_PATH" \ +# --key notary.key \ +# --key-id "$MACOS_NOTARY_KEY_ID" \ +# --issuer "$MACOS_NOTARY_ISSUER_ID" \ +# --team-id "$MACOS_NOTARY_TEAM_ID" \ +# --wait echo "Waiting for ticket propagation..." # sleep 30 From fb1d1f99de3d1a44a933abb6121aa91f300fd922 Mon Sep 17 00:00:00 2001 From: unsecretised Date: Thu, 5 Mar 2026 18:10:42 +0800 Subject: [PATCH 9/9] fix cmd + , opening config file twice --- src/app/tile.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app/tile.rs b/src/app/tile.rs index 6775c24..6804678 100644 --- a/src/app/tile.rs +++ b/src/app/tile.rs @@ -186,8 +186,6 @@ impl Tile { keyboard::Key::Character(chr) => { if modifiers.command() && chr.to_string() == "r" { return Some(Message::ReloadConfig); - } else if modifiers.command() && chr.to_string() == "," { - open_settings(); } else if chr.to_string() == "p" && modifiers.control() { return Some(Message::ChangeFocus(ArrowKey::Up, 1)); } else if chr.to_string() == "n" && modifiers.control() {