intial commit

This commit is contained in:
Nginearing 2026-10-20 22:24:41 +01:00
parent ea05a30222
commit ade254883f
49 changed files with 5049 additions and 116 deletions

View file

@ -1,3 +0,0 @@
import { type RouteConfig, index } from "@react-router/dev/routes";
export default [index("routes/home.tsx")] satisfies RouteConfig;

View file

@ -1,111 +0,0 @@
import { Button } from "~/components/ui/button";
import logoDark from "./logo-dark.svg";
import logoLight from "./logo-light.svg";
import { Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter } from "~/components/ui/card";
import { Separator } from "~/components/ui/separator";
export function Welcome() {
return (
<main className="flex items-center justify-center pt-16 pb-4">
<div className="flex-1 flex flex-col items-center gap-16 min-h-0">
<header className="flex flex-col items-center gap-9">
<div className="w-[500px] max-w-[100vw] p-4">
<h1 className="text-5xl text-center">Risotro IME</h1>
</div>
</header>
<div className="max-w-[400px] w-full space-y-6 px-4">
<nav className="rounded-3xl border border-gray-200 p-6 dark:border-gray-700 space-y-4">
<div>
<p className="leading-6 text-gray-700 dark:text-gray-200 text-center">
Your scripts
</p>
</div>
<Separator
orientation="horizontal"
className="!block !h-px !w-full !bg-gray-400 dark:!bg-gray-500"
/>
<div className="flex flex-col gap-4">
<Card className="--tw-ring-shadow ring-1 ring-gray-200 dark:ring-gray-700 hover:--tw-ring-shadow-hover hover:ring-gray-300 dark:hover:ring-gray-300 transition-shadow">
<CardHeader>
<CardTitle>Virisotro</CardTitle>
<CardDescription>this is my fav</CardDescription>
<CardAction>
<Button className="bg-gray-200 text-gray-800 hover:bg-gray-300 dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-500">
Select
</Button>
</CardAction>
</CardHeader>
</Card>
<Card className="--tw-ring-shadow ring-1 ring-gray-200 dark:ring-gray-700 hover:--tw-ring-shadow-hover hover:ring-gray-300 dark:hover:ring-gray-300 transition-shadow">
<CardHeader>
<CardTitle>Virisotro</CardTitle>
<CardDescription>this is my fav</CardDescription>
<CardAction>
<Button className="bg-gray-200 text-gray-800 hover:bg-gray-300 dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-500">
Select
</Button>
</CardAction>
</CardHeader>
</Card>
<Card className="--tw-ring-shadow ring-1 ring-gray-200 dark:ring-gray-700 hover:--tw-ring-shadow-hover hover:ring-gray-300 dark:hover:ring-gray-300 transition-shadow">
<CardHeader>
<CardTitle>Virisotro</CardTitle>
<CardDescription>this is my fav</CardDescription>
<CardAction>
<Button className="bg-gray-200 text-gray-800 hover:bg-gray-300 dark:bg-gray-600 dark:text-gray-300 dark:hover:bg-gray-500">
Select
</Button>
</CardAction>
</CardHeader>
</Card>
</div>
</nav>
</div>
</div>
</main>
);
}
const resources = [
{
href: "https://reactrouter.com/docs",
text: "React Router Docs",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="20"
viewBox="0 0 20 20"
fill="none"
className="stroke-gray-600 group-hover:stroke-current dark:stroke-gray-300"
>
<path
d="M9.99981 10.0751V9.99992M17.4688 17.4688C15.889 19.0485 11.2645 16.9853 7.13958 12.8604C3.01467 8.73546 0.951405 4.11091 2.53116 2.53116C4.11091 0.951405 8.73546 3.01467 12.8604 7.13958C16.9853 11.2645 19.0485 15.889 17.4688 17.4688ZM2.53132 17.4688C0.951566 15.8891 3.01483 11.2645 7.13974 7.13963C11.2647 3.01471 15.8892 0.951453 17.469 2.53121C19.0487 4.11096 16.9854 8.73551 12.8605 12.8604C8.73562 16.9853 4.11107 19.0486 2.53132 17.4688Z"
strokeWidth="1.5"
strokeLinecap="round"
/>
</svg>
),
},
{
href: "https://rmx.as/discord",
text: "Join Discord",
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="20"
viewBox="0 0 24 20"
fill="none"
className="stroke-gray-600 group-hover:stroke-current dark:stroke-gray-300"
>
<path
d="M15.0686 1.25995L14.5477 1.17423L14.2913 1.63578C14.1754 1.84439 14.0545 2.08275 13.9422 2.31963C12.6461 2.16488 11.3406 2.16505 10.0445 2.32014C9.92822 2.08178 9.80478 1.84975 9.67412 1.62413L9.41449 1.17584L8.90333 1.25995C7.33547 1.51794 5.80717 1.99419 4.37748 2.66939L4.19 2.75793L4.07461 2.93019C1.23864 7.16437 0.46302 11.3053 0.838165 15.3924L0.868838 15.7266L1.13844 15.9264C2.81818 17.1714 4.68053 18.1233 6.68582 18.719L7.18892 18.8684L7.50166 18.4469C7.96179 17.8268 8.36504 17.1824 8.709 16.4944L8.71099 16.4904C10.8645 17.0471 13.128 17.0485 15.2821 16.4947C15.6261 17.1826 16.0293 17.8269 16.4892 18.4469L16.805 18.8725L17.3116 18.717C19.3056 18.105 21.1876 17.1751 22.8559 15.9238L23.1224 15.724L23.1528 15.3923C23.5873 10.6524 22.3579 6.53306 19.8947 2.90714L19.7759 2.73227L19.5833 2.64518C18.1437 1.99439 16.6386 1.51826 15.0686 1.25995ZM16.6074 10.7755L16.6074 10.7756C16.5934 11.6409 16.0212 12.1444 15.4783 12.1444C14.9297 12.1444 14.3493 11.6173 14.3493 10.7877C14.3493 9.94885 14.9378 9.41192 15.4783 9.41192C16.0471 9.41192 16.6209 9.93851 16.6074 10.7755ZM8.49373 12.1444C7.94513 12.1444 7.36471 11.6173 7.36471 10.7877C7.36471 9.94885 7.95323 9.41192 8.49373 9.41192C9.06038 9.41192 9.63892 9.93712 9.6417 10.7815C9.62517 11.6239 9.05462 12.1444 8.49373 12.1444Z"
strokeWidth="1.5"
/>
</svg>
),
},
];

View file

@ -7,7 +7,6 @@
html, html,
body { body {
@apply bg-white dark:bg-gray-950;
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
color-scheme: dark; color-scheme: dark;

View file

@ -0,0 +1,14 @@
export default function library({
className,
...props
}: React.ComponentProps<"p">) {
return (
<div className="flex w-full h-full p-10 ">
<div className="w-full h-full bg-black">
</div>
</div>
);
}

10
src/app/routes.ts Normal file
View file

@ -0,0 +1,10 @@
// src/routes.ts
import { type RouteConfig, index, route } from "@react-router/dev/routes";
export default [
// Your main studio window lands here
index("routes/home.tsx"),
// Your secondary borderless IME window lands here
route("ime", "routes/ime-overlay.tsx"),
] satisfies RouteConfig;

View file

@ -0,0 +1,23 @@
// src/routes/ime-overlay.tsx
export default function ImeOverlay() {
return (
<div style={{
width: "100vw",
height: "100vh",
backgroundColor: "rgba(25, 25, 25, 0.95)", // Glassy dark styling
borderRadius: "12px",
border: "1px solid rgba(255, 255, 255, 0.15)",
color: "white",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
fontFamily: "sans-serif"
}}>
<h2 style={{ margin: 0, fontSize: "1.2rem" }}>Risotro IME</h2>
<p style={{ margin: "4px 0 0 0", fontSize: "0.85rem", opacity: 0.7 }}>
Floating Overlay Active
</p>
</div>
);
}

View file

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 6 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 6 KiB

Before After
Before After

View file

@ -0,0 +1,14 @@
import { Button } from "~/components/ui/button";
import logoDark from "./logo-dark.svg";
import logoLight from "./logo-light.svg";
import { Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter } from "~/components/ui/card";
import { Separator } from "~/components/ui/separator";
import Library from "~/components/library";
export function Welcome() {
return (
<div className="flex items-center justify-center h-screen">
<Library/>
</div>
);
}``

View file

@ -19,6 +19,7 @@
"devDependencies": { "devDependencies": {
"@react-router/dev": "^8.4.0", "@react-router/dev": "^8.4.0",
"@tailwindcss/vite": "^4.2.2", "@tailwindcss/vite": "^4.2.2",
"@tauri-apps/cli": "^2.12.3",
"@types/node": "^22", "@types/node": "^22",
"@types/react": "^19.2.18", "@types/react": "^19.2.18",
"@types/react-dom": "^19.2.7", "@types/react-dom": "^19.2.7",
@ -1130,6 +1131,223 @@
"vite": "^5.2.0 || ^6 || ^7 || ^8" "vite": "^5.2.0 || ^6 || ^7 || ^8"
} }
}, },
"node_modules/@tauri-apps/cli": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.12.3.tgz",
"integrity": "sha512-f7/LsY74SVb1ChmOPw1ajOpxii0GSzDAgmWHRci8JUYuuai04rXsSbFobpmB0sP2DdlvMD/B5ZotEn8GOGMRUg==",
"dev": true,
"license": "Apache-2.0 OR MIT",
"bin": {
"tauri": "tauri.js"
},
"engines": {
"node": ">= 10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.12.3",
"@tauri-apps/cli-darwin-x64": "2.12.3",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.12.3",
"@tauri-apps/cli-linux-arm64-gnu": "2.12.3",
"@tauri-apps/cli-linux-arm64-musl": "2.12.3",
"@tauri-apps/cli-linux-riscv64-gnu": "2.12.3",
"@tauri-apps/cli-linux-x64-gnu": "2.12.3",
"@tauri-apps/cli-linux-x64-musl": "2.12.3",
"@tauri-apps/cli-win32-arm64-msvc": "2.12.3",
"@tauri-apps/cli-win32-ia32-msvc": "2.12.3",
"@tauri-apps/cli-win32-x64-msvc": "2.12.3"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.12.3.tgz",
"integrity": "sha512-xmVNoJOOKzKLj7GLHXmXLimRby9M42aBIJa0sB80N7o24eKV5JiVmToKTRLVH9yhL05GZ/B6rSSOmbzNFJwBAA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.12.3.tgz",
"integrity": "sha512-URd+0usfmUQQyb5kNPiKt2OT8gp7oGU7QR+qOppB6e35mpVBFFVNhWc9oWb3p0u71fDJ09DpF4T6m9xYxoIB8g==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.12.3.tgz",
"integrity": "sha512-0kwUVx2LbmOoTRlwF1oDww7th4/NSluv4ZBQ6KRZsFKg4g0TlTcIiJ0VehqkQYUeC9xIT1Mk6XtF52mI155VSQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.12.3.tgz",
"integrity": "sha512-gKSGDx6fx+HBLQmG6guChFdisbrCSdx9Yli+j5teOa64gm1CeM+C6NLru5Pj3ZkkEep05BmCFjxvX+cjqAycZQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.12.3.tgz",
"integrity": "sha512-Yr59qMy/gcvAfBuFdCGlAmGiLsYWMFDbsP4bAI6iNBzcJTGrYWZGeiQhGDo29MQwfF/NUBqyM2qljXu5tZ6wjQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.12.3.tgz",
"integrity": "sha512-jKr0/REBMnLKC0OwPQZkyge0mKDaNZ0b/AbfGwVyCgFfwS730EVLfVDo3nt7MUu6jJaytRq08+xSj5qfy+U1+Q==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.12.3.tgz",
"integrity": "sha512-gTkEqJAGCMROGanxHnzaJzQ+/rXl39HWVg0/hDODS1wDWBGqoceqGC6Qm1+mQbyT11xnsB8mKu/gyVID/YpFIw==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.12.3.tgz",
"integrity": "sha512-T2dTxL1svRym71fZtaW4pZYXbthbfFsEJr1NeOUg/p7laWXZbUt/8DMSZf8recu9f7+1F/Lv00HtzsEu6vDO9w==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.12.3.tgz",
"integrity": "sha512-eoiQwpEZWbpsVHcM9BAzqqe4TCHszvr3rsM7pUQ4ofLK0lF1i1d/jX0Qo5DYMqcrUtwQuDdDuOCbcT0Izf1VwQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.12.3.tgz",
"integrity": "sha512-kE+KUg6Dbbkgvcw0m99wJVIToFQzJqpMBAXah74WqxaLzssNwSTUccrHp6+QVzMhjQP330tvekFmnQF+0NbE6Q==",
"cpu": [
"ia32"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.12.3.tgz",
"integrity": "sha512-L7wndWAgX2mLW7alswpL3d1R0P9FN2WYBgHaQkAYEBxHHGkY4vFX9CjcRQ1LAxDAMIJxrY7/aDziFJeChS84NQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.20.5", "version": "22.20.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.5.tgz",

View file

@ -3,6 +3,7 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"server": "nodemon server.js",
"build": "react-router build", "build": "react-router build",
"dev": "react-router dev", "dev": "react-router dev",
"start": "react-router-serve ./build/server/index.js", "start": "react-router-serve ./build/server/index.js",
@ -22,6 +23,7 @@
"devDependencies": { "devDependencies": {
"@react-router/dev": "^8.4.0", "@react-router/dev": "^8.4.0",
"@tailwindcss/vite": "^4.2.2", "@tailwindcss/vite": "^4.2.2",
"@tauri-apps/cli": "^2.12.3",
"@types/node": "^22", "@types/node": "^22",
"@types/react": "^19.2.18", "@types/react": "^19.2.18",
"@types/react-dom": "^19.2.7", "@types/react-dom": "^19.2.7",

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

@ -3,5 +3,5 @@ import type { Config } from "@react-router/dev/config";
export default { export default {
// Config options... // Config options...
// Server-side render by default, to enable SPA mode set this to `false` // Server-side render by default, to enable SPA mode set this to `false`
ssr: true, ssr: false,
} satisfies Config; } satisfies Config;

4
src/src-tauri/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
# Generated by Cargo
# will have compiled files and executables
/target/
/gen/schemas

4582
src/src-tauri/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

26
src/src-tauri/Cargo.toml Normal file
View file

@ -0,0 +1,26 @@
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2024"
rust-version = "1.90"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2.7.3", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.12.4", features = [] }
tauri-plugin-log = "2"
tauri-plugin-global-shortcut = "2.0"

3
src/src-tauri/build.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View file

@ -0,0 +1,15 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Default capabilities",
"windows": [
"main_window",
"ime_window"
],
"permissions": [
"core:default",
"global-shortcut:allow-is-registered",
"global-shortcut:allow-register",
"global-shortcut:allow-unregister"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

79
src/src-tauri/src/lib.rs Normal file
View file

@ -0,0 +1,79 @@
use tauri::{Manager, WebviewUrl, WebviewWindowBuilder, PhysicalPosition};
use tauri_plugin_global_shortcut::{Code, GlobalShortcutExt, Modifiers, Shortcut, ShortcutState};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.setup(|app| {
// 1. Setup your primary main studio window normally
let main_win = WebviewWindowBuilder::new(
app,
"main_window",
WebviewUrl::App("/".into())
)
.title("Risotro Studio")
.inner_size(1000.0, 700.0)
.build()
.unwrap();
// 2. Define your system-wide shortcut (Ctrl + Alt + Space)
let ctrl_alt_space = Shortcut::new(
Some(Modifiers::CONTROL | Modifiers::ALT),
Code::Space,
);
let app_handle = app.handle().clone();
// 3. Listen for the shortcut globally
app.global_shortcut().on_shortcut(ctrl_alt_space, move |_app, _shortcut, event| {
if event.state() == ShortcutState::Pressed {
// Fetch the current mouse position coordinates relative to the screen
// We fall back to (0,0) if the OS fails to read the hardware state
let mouse_pos = main_win.cursor_position().unwrap_or(PhysicalPosition::new(0.0, 0.0));
let win_width = 420.0;
let win_height = 160.0;
// Calculate position to center the window directly under the mouse cursor
let target_x = mouse_pos.x - (win_width / 2.0);
// Optional: Add a +20.0 offset to y if you want it slightly below the cursor
let target_y = mouse_pos.y - (win_height / 2.0);
let target_position = PhysicalPosition::new(target_x, target_y);
if let Some(ime_win) = app_handle.get_webview_window("ime_window") {
if ime_win.is_visible().unwrap_or(false) {
let _ = ime_win.hide();
} else {
// If window exists but was hidden, move it to the current mouse spot before showing
let _ = ime_win.set_position(target_position);
let _ = ime_win.show();
}
} else {
// 4. Create the borderless overlay window dynamically at the mouse location
let _ime_win = WebviewWindowBuilder::new(
&app_handle,
"ime_window",
WebviewUrl::App("/ime".into()),
)
.decorations(false)
.transparent(true)
.always_on_top(true)
.focusable(false)
.skip_taskbar(true)
.inner_size(win_width, win_height)
// Initialize the window directly at the calculated coordinate position
.position(target_position.x, target_position.y)
.build()
.unwrap();
}
}
}).unwrap();
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View file

@ -0,0 +1,6 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}

View file

@ -0,0 +1,52 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "RisotroStudioAndIME",
"version": "0.1.0",
"identifier": "com.nginearing.dev",
"build": {
"frontendDist": "../build/client",
"devUrl": "http://localhost:5173",
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build"
},
"app": {
"windows": [
{
"title": "Risotro Studio and IME",
"width": 800,
"height": 600,
"resizable": true,
"fullscreen": false
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"android": {
"debugApplicationIdSuffix": ".debug"
}
},
"plugins": {
"cli": {
"description": "Risotro Studio CLI parser",
"args": [
{
"name": "launch-ime",
"description": "Instantly boots into the React Router IME overlay view",
"boolean": true
}
]
}
}
}