Nicky Lao

Tauri开发笔记

发布于 · 预估阅读 9 分钟 · -- 阅读量

Tauri真的是又轻又快,但由于初次使用不熟难免遇到坑。

一、虚拟键盘触摸屏之坑

ubuntu系统是一个触摸屏,不能接入键盘和鼠标,所以界面上的操作输入都是通过虚拟键盘实现。代码使用的是react-simple-keyboard 组件

import { Button } from 'antd';
import { CloseOutlined } from '@ant-design/icons';
import React, { useRef } from 'react';
import { omit } from 'lodash';
import Keyboard from 'react-simple-keyboard';
import chineseLayout from "simple-keyboard-layouts/build/layouts/chinese";
import 'react-simple-keyboard/build/css/index.css';
interface RhKeyboardProps {
 show: boolean;
 onClose: () => void;
 init?: (r: any) => void;
 onChange: (input: string) => void;
 layoutType?: string;
}
// 添加自定义布局配置
const keyboardLayout = {
 default: [
 "` 1 2 3 4 5 6 7 8 9 0 - = {bksp}",
 "{tab} q w e r t y u i o p [ ] \\",
 "{lock} a s d f g h j k l ; ' {enter}",
 "{shift} z x c v b n m , . / {shift}",
 "{space}",
 ],
 shift: [
 "~ ! @ # $ % ^ & * ( ) _ + {bksp}",
 "{tab} Q W E R T Y U I O P { } |",
 '{lock} A S D F G H J K L : " {enter}',
 "{shift} Z X C V B N M < > ? {shift}",
 "{space}",
 ],
 ...chineseLayout.layout // 保留中文布局
};
export const RhKeyboard: React.FC<RhKeyboardProps> = ({
 show,
 onClose,
 init,
 onChange,
 layoutType,
}) => {
 const keyboardRef = useRef<any>(null);
 if (!show) return null;
 return (
 <div className="fixed bottom-0 left-0 w-full z-50 bg-gray-100"
 onTouchStart={(e) => e.stopPropagation()}
 onTouchMove={(e) => e.preventDefault()}
 ><div className="flex justify-end p-2"><Button
 type="text"
 icon={<CloseOutlined />}
 onClick={onClose}
 style={{ color: '#000' }}
 /></div> <Keyboard
 keyboardRef={(r) => {
 (keyboardRef.current = r);
 init?.(r);
 }} layout={keyboardLayout}{...(layoutType === 'chinese' ? omit(chineseLayout, 'layout') : {})} layoutName="default"
 onChange={onChange} useTouchEvents={true} // 启用触摸事件支持
 // useMouseEvents={true} // 启用鼠标事件
 disableCaretPositioning={true} // 禁用光标定位,避免触摸冲突
 onKeyPress={(button: string) => {
 if (button === "{shift}") {
 const currentLayout = keyboardRef.current.options.layoutName;
 const layoutName = currentLayout === "default" ? "shift" : "default";
 keyboardRef.current.setOptions({ layoutName });
 }
 }} theme="hg-theme-default custom-keyboard"
 buttonTheme={[
 {
 class: "hg-red",
 buttons: "{shift} {lock}"
 }
 ]} display={{
 "{bksp}": "退格",
 "{enter}": "回车",
 "{shift}": "Shift",
 "{space}": "空格",
 "{tab}": "Tab",
 "{lock}": "Lock"
 }} />
</div>
 );
};

二、自动启动服务之坑

需求是开机自动启动服务并且让软件全屏,这样ubuntu的系统的盒子就像一个定制好软件的系统了。

leekhub-ui.service

[Unit]
Description=Sanyems UI Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3
[Service]
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/ubuntu/.Xauthority
Environment=RUST_BACKTRACE=1
ExecStartPre=/bin/bash -c 'export DISPLAY=:0; export XAUTHORITY=/home/ubuntu/.Xauthority'
ExecStart=/usr/bin/leekhub-ui
Restart=always
User=ubuntu
RestartSec=5
[Install]
WantedBy=multi-user.target

其中缺少这2行代码,脚本服务启动失败。

message: "failed to initialize gtk", filename: "/home/ubuntu/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gtk-0.18.2/src/rt.rs", function: "gtk::rt::init", line: 141
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/ubuntu/.Xauthority

执行 sudo -u ubuntu /usr/bin/leekhub-ui 测试手动启动是否成功,注意这里的-u 指定的用户和配置文件里的User要一致,不然可能有权限问题。

权限问题则执行 sudo chown user:user /usr/bin/leekhub-ui 的方式,命令表示用户组 user,具体根据系统用户情况修改。

export DISPLAY=:0
export XAUTHORITY=/home/user/.Xauthority
source .bashrc
sudo -u user /usr/bin/leekhub-ui

如果是GTK异常,则需要安装依赖

sudo apt install libgdk-pixbuf2.0-dev libpango1.0-dev libcairo2-dev

配置文件

以下是 tauri.conf.json 代码,其中 postInstallScript 是deb包安装完成后执行的开机自动启动脚本。

{
 "$schema": "https://schema.tauri.app/config/2",
 "productName": "leekhub-ui",
 "version": "0.2.0",
 "identifier": "com.leekhub.ems",
 "mainBinaryName": "leekhub-ui",
 "build": {
 "frontendDist": "../dist",
 "devUrl": "http://localhost:3500",
 "beforeDevCommand": "pnpm dev",
 "beforeBuildCommand": "pnpm build"
 },
 "app": {
 "withGlobalTauri": true,
 "windows": [
 {
 "title": "sanyems-ui",
 "width": 1280,
 "height": 800,
 "resizable": true,
 "fullscreen": false,
 "devtools": true
 }
 ],
 "security": {
 "csp": null,
 "capabilities": [
 {
 "identifier": "custom-permision",
 "windows": [
 "*"
 ],
 "permissions": [
 "core:window:allow-create",
 "core:window:allow-close",
 "core:webview:allow-create-webview",
 "core:webview:allow-webview-close",
 "core:webview:allow-create-webview-window"
 ],
 "allowlist": {
 "http": {
 "all": true,
 "request": true,
 "scope": [
 "http://127.0.0.1:1880/ws/*",
 "http://127.0.0.1:9001/api/history/*",
 "http://127.0.0.1:9001/api/auth/*"
 ]
 },
 "protocol": {
 "asset": true,
 "assetScope": [
 "**"
 ]
 }
 }
 }
 ]
 }
 },
 "bundle": {
 "active": true,
 "targets": "all",
 "icon": [
 "icons/32x32.png",
 "icons/128x128.png",
 "icons/128x128@2x.png",
 "icons/icon.icns",
 "icons/icon.ico"
 ],
 "linux": {
 "deb": {
 "postInstallScript": "../scripts/postinstall.sh"
 }
 }
 }
}

本人自动发布于:https://github.com/giscafer/blog/issues/74

相关文章

AltStyle によって変換されたページ (->オリジナル) /