mirror of
https://github.com/project-gauntlet/gauntlet.git
synced 2025-12-23 10:35:53 +00:00
Unify Vec<u8> usage to ArrayBuffer in js. Fixes icon in EntrypointGenerator requiring number[]
This commit is contained in:
parent
61eca05f42
commit
b8f07d5028
13 changed files with 94 additions and 46 deletions
|
|
@ -29,7 +29,7 @@ enum_values = [
|
|||
|
||||
[[entrypoint]]
|
||||
id = 'windows'
|
||||
name = 'All Open Windows'
|
||||
name = 'Open Windows'
|
||||
path = 'src/windows.tsx'
|
||||
type = 'view'
|
||||
description = 'Show all open windows'
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ export function ListOfWindows({ windows, focus }: { windows: OpenWindowData[], f
|
|||
onAction={(id: string | undefined) => {
|
||||
if (id) {
|
||||
focus(id)
|
||||
console.log("focus: " + id)
|
||||
return { close: true }
|
||||
}
|
||||
}}
|
||||
|
|
@ -123,9 +122,9 @@ export function applicationAccessories(id: string, experimentalWindowTracking: b
|
|||
if (appWindows.length == 0) {
|
||||
return []
|
||||
} else if (appWindows.length == 1) {
|
||||
return [{ text: "1 window open" }]
|
||||
return [{ text: "1 window" }]
|
||||
} else if (appWindows.length > 1) {
|
||||
return [{ text: `${appWindows.length} windows open` }]
|
||||
return [{ text: `${appWindows.length} windows` }]
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
|
|
@ -182,4 +181,4 @@ export function openLinuxApplication(appId: string) {
|
|||
return () => {
|
||||
linux_open_application(appId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ export const Clipboard: Clipboard = {
|
|||
}
|
||||
|
||||
if (data.png_data) {
|
||||
result["image/png"] = new Uint8Array(data.png_data).buffer;
|
||||
result["image/png"] = data.png_data;
|
||||
}
|
||||
|
||||
return result
|
||||
|
|
@ -92,18 +92,18 @@ export const Clipboard: Clipboard = {
|
|||
readText: async function (): Promise<string | undefined> {
|
||||
return await clipboard_read_text()
|
||||
},
|
||||
write: async function (data: { "text/plain"?: string | undefined; "image/png"?: ArrayBuffer | undefined; }): Promise<void> {
|
||||
write: async function (data: { "text/plain"?: string | undefined; "image/png"?: Uint8Array | undefined; }): Promise<void> {
|
||||
const text_data = data["text/plain"];
|
||||
const png_data = data["image/png"];
|
||||
|
||||
const write_data: { text_data?: string, png_data?: number[] } = {};
|
||||
const write_data: { text_data?: string, png_data?: ArrayBuffer } = {};
|
||||
|
||||
if (text_data) {
|
||||
write_data.text_data = text_data;
|
||||
}
|
||||
|
||||
if (png_data) {
|
||||
write_data.png_data = Array.from(new Uint8Array(png_data));
|
||||
write_data.png_data = png_data;
|
||||
}
|
||||
|
||||
return await clipboard_write(write_data)
|
||||
|
|
|
|||
|
|
@ -117,13 +117,11 @@ export function useGauntletContext() {
|
|||
}
|
||||
|
||||
export async function getAssetData(path: string): Promise<ArrayBuffer> {
|
||||
const vecU8 = await asset_data(path);
|
||||
return new Uint8Array(vecU8).buffer; // FIXME move array creation into rust if possible
|
||||
return await asset_data(path);
|
||||
}
|
||||
|
||||
export function getAssetDataSync(path: string): ArrayBuffer {
|
||||
const vecU8 = asset_data_blocking(path);
|
||||
return new Uint8Array(vecU8).buffer;
|
||||
return asset_data_blocking(path);
|
||||
}
|
||||
|
||||
export function getPluginPreferences(): Record<string, any> {
|
||||
|
|
|
|||
8
js/typings/index.d.ts
vendored
8
js/typings/index.d.ts
vendored
|
|
@ -219,8 +219,8 @@ declare module "ext:core/ops" {
|
|||
function op_log_error(target: string, message: string): void;
|
||||
|
||||
function op_component_model(): Record<string, Component>;
|
||||
function asset_data(path: string): Promise<number[]>;
|
||||
function asset_data_blocking(path: string): number[];
|
||||
function asset_data(path: string): Promise<ArrayBuffer>;
|
||||
function asset_data_blocking(path: string): ArrayBuffer;
|
||||
|
||||
function op_inline_view_entrypoint_id(): string | null;
|
||||
function op_entrypoint_names(): Record<string, string | undefined>;
|
||||
|
|
@ -246,9 +246,9 @@ declare module "ext:core/ops" {
|
|||
|
||||
function fetch_action_id_for_shortcut(entrypointId: string, key: string, modifierShift: boolean, modifierControl: boolean, modifierAlt: boolean, modifierMeta: boolean): Promise<string | undefined>;
|
||||
|
||||
function clipboard_read(): Promise<{ text_data?: string, png_data?: number[] }>;
|
||||
function clipboard_read(): Promise<{ text_data?: string, png_data?: ArrayBuffer }>;
|
||||
function clipboard_read_text(): Promise<string | undefined>;
|
||||
function clipboard_write(data: { text_data?: string, png_data?: number[] }): Promise<void>;
|
||||
function clipboard_write(data: { text_data?: string, png_data?: ArrayBuffer }): Promise<void>;
|
||||
function clipboard_write_text(data: string): Promise<void>;
|
||||
function clipboard_clear(): Promise<void>;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,6 @@ pub fn asset_data_blocking(state: Rc<RefCell<OpState>>, #[string] path: String)
|
|||
outer_handle.block_on(async {
|
||||
let data = api.get_asset_data(&path).await?;
|
||||
|
||||
Ok(data)
|
||||
Ok(data.into())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,22 +3,16 @@ use std::rc::Rc;
|
|||
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::api::BackendForPluginRuntimeApi;
|
||||
use crate::api::BackendForPluginRuntimeApiProxy;
|
||||
use crate::model::JsClipboardData;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct JSClipboardData {
|
||||
text_data: Option<String>,
|
||||
png_data: Option<Vec<u8>>,
|
||||
}
|
||||
use crate::DenoInClipboardData;
|
||||
use crate::DenoOutClipboardData;
|
||||
use crate::JsClipboardData;
|
||||
|
||||
#[op2(async)]
|
||||
#[serde]
|
||||
pub async fn clipboard_read(state: Rc<RefCell<OpState>>) -> anyhow::Result<JSClipboardData> {
|
||||
pub async fn clipboard_read(state: Rc<RefCell<OpState>>) -> anyhow::Result<DenoOutClipboardData> {
|
||||
let api = {
|
||||
let state = state.borrow();
|
||||
|
||||
|
|
@ -29,9 +23,9 @@ pub async fn clipboard_read(state: Rc<RefCell<OpState>>) -> anyhow::Result<JSCli
|
|||
|
||||
let result = api.clipboard_read().await?;
|
||||
|
||||
Ok(JSClipboardData {
|
||||
Ok(DenoOutClipboardData {
|
||||
text_data: result.text_data,
|
||||
png_data: result.png_data,
|
||||
png_data: result.png_data.map(|buffer| buffer.into()),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +44,7 @@ pub async fn clipboard_read_text(state: Rc<RefCell<OpState>>) -> anyhow::Result<
|
|||
}
|
||||
|
||||
#[op2(async)]
|
||||
pub async fn clipboard_write(state: Rc<RefCell<OpState>>, #[serde] data: JSClipboardData) -> anyhow::Result<()> {
|
||||
pub async fn clipboard_write(state: Rc<RefCell<OpState>>, #[serde] data: DenoInClipboardData) -> anyhow::Result<()> {
|
||||
let api = {
|
||||
let state = state.borrow();
|
||||
|
||||
|
|
@ -61,7 +55,7 @@ pub async fn clipboard_write(state: Rc<RefCell<OpState>>, #[serde] data: JSClipb
|
|||
|
||||
let clipboard_data = JsClipboardData {
|
||||
text_data: data.text_data,
|
||||
png_data: data.png_data,
|
||||
png_data: data.png_data.map(|buffer| buffer.to_vec()),
|
||||
};
|
||||
|
||||
api.clipboard_write(clipboard_data).await
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ use std::fmt;
|
|||
|
||||
use bincode::Decode;
|
||||
use bincode::Encode;
|
||||
use deno_core::JsBuffer;
|
||||
use deno_core::ToJsBuffer;
|
||||
use gauntlet_common::model::EntrypointId;
|
||||
use gauntlet_common::model::Icons;
|
||||
use gauntlet_common::model::PluginId;
|
||||
|
|
@ -174,7 +176,7 @@ pub enum JsRequest {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Encode, Decode)]
|
||||
#[derive(Encode, Decode)]
|
||||
pub struct JsGeneratedSearchItem {
|
||||
pub entrypoint_name: String,
|
||||
pub generator_entrypoint_id: String,
|
||||
|
|
@ -199,6 +201,28 @@ impl fmt::Debug for JsGeneratedSearchItem {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct DenoOutGeneratedSearchItem {
|
||||
pub entrypoint_name: String,
|
||||
pub generator_entrypoint_id: String,
|
||||
pub entrypoint_id: String,
|
||||
pub entrypoint_uuid: String,
|
||||
pub entrypoint_icon: Option<ToJsBuffer>,
|
||||
pub entrypoint_actions: Vec<JsGeneratedSearchItemAction>,
|
||||
pub entrypoint_accessories: Vec<JsGeneratedSearchItemAccessory>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct DenoInGeneratedSearchItem {
|
||||
pub entrypoint_name: String,
|
||||
pub generator_entrypoint_id: String,
|
||||
pub entrypoint_id: String,
|
||||
pub entrypoint_uuid: String,
|
||||
pub entrypoint_icon: Option<JsBuffer>,
|
||||
pub entrypoint_actions: Vec<JsGeneratedSearchItemAction>,
|
||||
pub entrypoint_accessories: Vec<JsGeneratedSearchItemAccessory>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Encode, Decode)]
|
||||
pub struct JsGeneratedSearchItemAction {
|
||||
pub id: Option<String>,
|
||||
|
|
@ -236,8 +260,20 @@ pub enum JsGeneratedSearchItemAccessory {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Encode, Decode)]
|
||||
#[derive(Debug, Encode, Decode)]
|
||||
pub struct JsClipboardData {
|
||||
pub text_data: Option<String>,
|
||||
pub png_data: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct DenoOutClipboardData {
|
||||
pub text_data: Option<String>,
|
||||
pub png_data: Option<ToJsBuffer>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct DenoInClipboardData {
|
||||
pub text_data: Option<String>,
|
||||
pub png_data: Option<JsBuffer>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use std::rc::Rc;
|
|||
use anyhow::anyhow;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ToJsBuffer;
|
||||
use gauntlet_common::detached_process::CommandExt;
|
||||
use image::imageops::FilterType;
|
||||
use image::ImageFormat;
|
||||
|
|
@ -46,7 +47,7 @@ pub enum DesktopPathAction {
|
|||
pub struct DesktopApplication {
|
||||
name: String,
|
||||
desktop_file_path: String,
|
||||
icon: Option<Vec<u8>>,
|
||||
icon: Option<ToJsBuffer>,
|
||||
startup_wm_class: Option<String>,
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ pub struct DesktopApplication {
|
|||
pub struct DesktopApplication {
|
||||
name: String,
|
||||
path: String,
|
||||
icon: Option<Vec<u8>>,
|
||||
icon: Option<ToJsBuffer>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
|
|
@ -63,7 +64,7 @@ pub struct DesktopApplication {
|
|||
pub struct DesktopApplication {
|
||||
name: String,
|
||||
path: String,
|
||||
icon: Option<Vec<u8>>,
|
||||
icon: Option<ToJsBuffer>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
|
|
@ -71,7 +72,7 @@ pub struct DesktopApplication {
|
|||
pub struct DesktopSettingsPre13Data {
|
||||
name: String,
|
||||
path: String,
|
||||
icon: Option<Vec<u8>>,
|
||||
icon: Option<ToJsBuffer>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
|
|
@ -79,7 +80,7 @@ pub struct DesktopSettingsPre13Data {
|
|||
pub struct DesktopSettings13AndPostData {
|
||||
name: String,
|
||||
preferences_id: String,
|
||||
icon: Option<Vec<u8>>,
|
||||
icon: Option<ToJsBuffer>,
|
||||
}
|
||||
|
||||
#[op2]
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use std::rc::Rc;
|
|||
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ToJsBuffer;
|
||||
use freedesktop_entry_parser::parse_entry;
|
||||
use freedesktop_icons::lookup;
|
||||
use gauntlet_common::detached_process::CommandExt;
|
||||
|
|
@ -267,7 +268,8 @@ fn create_app_entry(desktop_file_path: &Path) -> Option<DesktopApplication> {
|
|||
res.inspect_err(|err| tracing::warn!("error processing icon of {:?}: {:?}", desktop_file_path, err))
|
||||
.ok()
|
||||
})
|
||||
.flatten();
|
||||
.flatten()
|
||||
.map(|buffer| buffer.into());
|
||||
|
||||
Some(DesktopApplication {
|
||||
name: name.to_string(),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use cacao::filesystem::FileManager;
|
|||
use cacao::filesystem::SearchPathDirectory;
|
||||
use cacao::filesystem::SearchPathDomainMask;
|
||||
use cacao::url::Url;
|
||||
use deno_core::ToJsBuffer;
|
||||
use objc2::ClassType;
|
||||
use objc2_app_kit::NSBitmapImageRep;
|
||||
use objc2_app_kit::NSCalibratedWhiteColorSpace;
|
||||
|
|
@ -464,7 +465,7 @@ unsafe fn resize_ns_image(source_image: &NSImage, width: NSInteger, height: NSIn
|
|||
Some(data.bytes().to_vec())
|
||||
}
|
||||
|
||||
fn get_application_icon(app_path: &Path) -> anyhow::Result<Vec<u8>> {
|
||||
fn get_application_icon(app_path: &Path) -> anyhow::Result<ToJsBuffer> {
|
||||
unsafe {
|
||||
let workspace = NSWorkspace::sharedWorkspace();
|
||||
|
||||
|
|
@ -478,7 +479,7 @@ fn get_application_icon(app_path: &Path) -> anyhow::Result<Vec<u8>> {
|
|||
|
||||
let bytes = resize_ns_image(&image, 40, 40).ok_or(anyhow!("Unable to resize the image"))?;
|
||||
|
||||
Ok(bytes)
|
||||
Ok(bytes.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use std::ptr;
|
|||
use anyhow::anyhow;
|
||||
use anyhow::Context;
|
||||
use deno_core::op2;
|
||||
use deno_core::ToJsBuffer;
|
||||
use image::RgbaImage;
|
||||
use tokio::task::spawn_blocking;
|
||||
use windows::core::GUID;
|
||||
|
|
@ -89,7 +90,7 @@ fn windows_app_from_path_blocking(file_path: String) -> anyhow::Result<Option<De
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_icon(file_path: &str) -> anyhow::Result<Vec<u8>> {
|
||||
fn extract_icon(file_path: &str) -> anyhow::Result<ToJsBuffer> {
|
||||
unsafe {
|
||||
let mut shfileinfow = Shell::SHFILEINFOW::default();
|
||||
|
||||
|
|
@ -188,7 +189,7 @@ fn extract_icon(file_path: &str) -> anyhow::Result<Vec<u8>> {
|
|||
|
||||
let data = resize_icon(data)?;
|
||||
|
||||
Ok(data)
|
||||
Ok(data.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@ use deno_core::OpState;
|
|||
|
||||
use crate::api::BackendForPluginRuntimeApi;
|
||||
use crate::api::BackendForPluginRuntimeApiProxy;
|
||||
use crate::model::JsGeneratedSearchItem;
|
||||
use crate::DenoInGeneratedSearchItem;
|
||||
use crate::JsGeneratedSearchItem;
|
||||
|
||||
#[op2(async)]
|
||||
pub async fn reload_search_index(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
#[serde] generated_entrypoints: Vec<JsGeneratedSearchItem>,
|
||||
#[serde] generated_entrypoints: Vec<DenoInGeneratedSearchItem>,
|
||||
refresh_search_list: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
let api = {
|
||||
|
|
@ -22,6 +23,21 @@ pub async fn reload_search_index(
|
|||
api
|
||||
};
|
||||
|
||||
let generated_entrypoints = generated_entrypoints
|
||||
.into_iter()
|
||||
.map(|item| {
|
||||
JsGeneratedSearchItem {
|
||||
entrypoint_name: item.entrypoint_name,
|
||||
generator_entrypoint_id: item.generator_entrypoint_id,
|
||||
entrypoint_id: item.entrypoint_id,
|
||||
entrypoint_uuid: item.entrypoint_uuid,
|
||||
entrypoint_icon: item.entrypoint_icon.map(|buffer| buffer.to_vec()),
|
||||
entrypoint_actions: item.entrypoint_actions,
|
||||
entrypoint_accessories: item.entrypoint_accessories,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
api.reload_search_index(generated_entrypoints, refresh_search_list)
|
||||
.await?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue