6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RCC (立命館コンピュータークラブ)Advent Calendar 2024

Day 25

クリスマスなのでデスクトップ上に雪を降らせてみた[Mac、Tauri]

Posted at

今日は12/25クリスマスですね。

みなさん良いクリスマスをお過ごしですか?

僕はクリぼっちです、はい。

今回はクリスマスといえば雪!ということでデスクトップ上に雪を降らせてみようと思います。

使用する技術

今回はTauriを使ってみようと思います。

Tauriとは、Rustで作成されたクロスプラットフォームGUIフレームワークです。

Tauriを使うことでWindows、macOS、Linux向けのデスクトップアプリをReactなどのweb技術で書くことができます。

Tauriのセットアップ

インストール

tauriには、Bash、Powershell、npm、yarn、pnpm、deno、bun、Cargoなど多くのパッケージマネージャーを使うことができます。

今回はcargoでやってみようと思います。
create-tauri-app

cargo install create-tauri-app --locked

create-tauri-appでtaruiプロジェクトを作成します。

cargo create-tauri-app

すると諸々の設定が出てきます。
それを以下のように設定してみました。

❯ cargo create-tauri-app
✔ Project name · christmas
✔ Identifier · com.christmas.app
✔ Choose which language to use for your frontend · TypeScript / JavaScript - (pnpm, yarn, npm, deno, bun)
✔ Choose your package manager · pnpm
✔ Choose your UI template · React - (https://react.dev/)
✔ Choose your UI flavor · TypeScript

tauriのCLIツールを依存関係に追加します。

pnpm add -D @tauri-apps/cli@1

バックエンド側(Rust)

ウィンドウがマウスのイベントを透過するようにする必要があったので、Tauriのウィンドウを制御しているsrc-tauriをいじっていこうと思います。

Tauriではtauri.conf.jsonでいくつか設定を行うことができます。

設定の種類は下から探すことができます。

src-tauritauri.conf.jsonがあるので、下のように書きました。

tauri.conf.json
{
  "$schema": "https://schema.tauri.app/config/2",
  "productName": "christmas",
  "version": "0.1.0",
  "identifier": "com.christmas.app",
  "build": {
    "beforeDevCommand": "pnpm dev",
    "devUrl": "http://localhost:1420",
    "beforeBuildCommand": "pnpm build",
    "frontendDist": "../dist"
  },

  "app": {
    "windows": [
      {
        "maximized": true,
        "transparent": true,
        "alwaysOnTop": true,
        "decorations": false
       }
    ],
    "macOSPrivateApi": true,
    "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"
    ]
  }
}

ポイントは、appwindowsにWindowConfigの設定を行うことがです。
この部分をいじることで画面の大きさや透明度やバーの表示などいろいろいじることができるようになります。

設定した項目としては下のようになっています。

項目 設定内容
maximized 画面を最大化
transparent 画面を透明化
alwaysOnTop 画面を再上面に
decorations 上部のバーを消す

フロント側(React)

フロント側はReactで書いている関係でReactのライブラリを使うことができるので、react-snowfallを使おうと思います。

依存関係に追加します。

zsh
pnpm add react-snowfall

このライブラリをApp.tsxで使用します。

App.tsx
import './App.css';
import {Snowfall} from "react-snowfall";

function App() {

    const snowflake1 = document.createElement('img')
    snowflake1.src = '/snowflake.png';

    const image = [snowflake1]

    return (
        <Snowfall
            color="#fff"
            images={image}
            style={{
                position: 'fixed',
                width: '100vw',
                height: '100vh',
            }}
            radius={[5,20]}
            snowflakeCount={200}
        />
    )
}

export default App;

注意としては、ルートにあるpublicディレクトリに画像を入れる必要があります。
viteの仕様でpublicの置いた画像は/ファイル名でアクセスできるようになります。

snowflakeのgithubpagesで使われている画像を持ってきました。

使用した結果

こんな感じで雪を降らせながら後ろにあるターミナル操作をできるようにしました。
snowflake.gif

ビルドしてみる

ビルドは下のコマンドで行うことができます。

zsh
pnpm tauri build

アイコンを変えてみる

デフォルトだと、ビルドしたアプリケーションのアイコンはTauriのiconになってしまいます。

アイコンを変えるには、ルートディレクトリにアイコンにしたい画像を配置して、app-icon.pngとします。

そこからtauriのicon生成コマンドがあるのでそれを打ちます。

zsh
pnpm tauri icon

すると、さまざまなサイズのアイコンがsrc-tauri/iconsの中に複製させれます。

zsh
❯ pnpm tauri icon

> christmas@0.1.0 tauri /Users/maoz/Documents/application/christmas
> tauri "icon"

    Appx Creating StoreLogo.png
    Appx Creating Square30x30Logo.png
    Appx Creating Square44x44Logo.png
    Appx Creating Square71x71Logo.png
    Appx Creating Square89x89Logo.png
    Appx Creating Square107x107Logo.png
    Appx Creating Square142x142Logo.png
    Appx Creating Square150x150Logo.png
    Appx Creating Square284x284Logo.png
    Appx Creating Square310x310Logo.png
    ICNS Creating icon.icns
    ICO Creating icon.ico
    PNG Creating 32x32.png
    PNG Creating 128x128.png
    PNG Creating 128x128@2x.png
    PNG Creating icon.png
    PNG Creating mipmap-hdpi/ic_launcher_foreground.png
    PNG Creating mipmap-hdpi/ic_launcher_round.png
    PNG Creating mipmap-hdpi/ic_launcher.png
    PNG Creating mipmap-mdpi/ic_launcher_foreground.png
    PNG Creating mipmap-mdpi/ic_launcher_round.png
    PNG Creating mipmap-mdpi/ic_launcher.png
    PNG Creating mipmap-xhdpi/ic_launcher_foreground.png
    PNG Creating mipmap-xhdpi/ic_launcher_round.png
    PNG Creating mipmap-xhdpi/ic_launcher.png
    PNG Creating mipmap-xxhdpi/ic_launcher_foreground.png
    PNG Creating mipmap-xxhdpi/ic_launcher_round.png
    PNG Creating mipmap-xxhdpi/ic_launcher.png
    PNG Creating mipmap-xxxhdpi/ic_launcher_foreground.png
    PNG Creating mipmap-xxxhdpi/ic_launcher_round.png
    PNG Creating mipmap-xxxhdpi/ic_launcher.png
    iOS Creating AppIcon-20x20@2x-1.png
    iOS Creating AppIcon-20x20@1x.png
    iOS Creating AppIcon-20x20@2x.png
    iOS Creating AppIcon-20x20@3x.png
    iOS Creating AppIcon-29x29@2x-1.png
    iOS Creating AppIcon-29x29@1x.png
    iOS Creating AppIcon-29x29@2x.png
    iOS Creating AppIcon-29x29@3x.png
    iOS Creating AppIcon-40x40@2x-1.png
    iOS Creating AppIcon-40x40@1x.png
    iOS Creating AppIcon-40x40@2x.png
    iOS Creating AppIcon-40x40@3x.png
    iOS Creating AppIcon-60x60@2x.png
    iOS Creating AppIcon-60x60@3x.png
    iOS Creating AppIcon-76x76@1x.png
    iOS Creating AppIcon-76x76@2x.png
    iOS Creating AppIcon-83.5x83.5@2x.png
    iOS Creating AppIcon-512@2x.png

ここからビルドすると変更したいアプリのアイコンになります。

CIで自動ビルドさせる

GithubActionsを使って自動ビルドしてみようと思います。

.github/workflows/build.ymlに下のように記述します。

.github/workflows/build.yml
name: 'build'

on:
  push:
    branches:
      - main

jobs:
  publish-tauri:
    permissions:
      contents: write
    strategy:
      fail-fast: false
      matrix:
        include:
          - platform: 'macos-latest' # for Arm based macs (M1 and above).
            args: '--target aarch64-apple-darwin'

    runs-on: ${{ matrix.platform }}
    steps:
      - uses: actions/checkout@v4

      - name: setup node
        uses: actions/setup-node@v4
        with:
          node-version: lts/*

      - name: setup pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: install Rust stable
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable

      - name: install frontend dependencies
        run: pnpm install

      - uses: tauri-apps/tauri-action@v0.5.18
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tagName: app-v__VERSION__
          releaseName: 'App v__VERSION__'
          releaseBody: 'See the assets to download this version and install.'
          releaseDraft: false
          prerelease: false
          args: ${{ matrix.args }}

mainブランチにpush(or PRでマージされた時)にactionsが走るようにしています。

またmatrixを使うことでos毎にビルドの仕方を変えるようにしています。

stepsで行ってることは以下の通りです。

step 内容
actions/checkout@v4 actions内にリポジトリをクローンしています
actions/setup-node@v4 actions内にnodeをセットアップしています
pnpm/action-setup@v4 pnpmをセットアップしています
dtolnay/rust-toolchain@stable 安定ver(stable)のrustの環境をセットアップしています。
pnpm install pnpmで依存関係をインストールしています
tauri-apps/tauri-action@v0.5.18 自動ビルドとreleaseに自動的にあげるようにしています

これでmainにpushされるとreleasesページに作成されます。

image.png

しかしそのまま実行しようとすると下のような表示が出ます。
image.png

これはおそらくですが、公証というアプリケーションに対して安全であるという署名がないからだと考えられます。

なのでxattrコマンドで許可する必要があります。

自己責任でお願いします

xattr -rc /Applicaions/christmas.app

おまけ

setIgnoreMouseEventのやり方を調べる過程でしたのissueを参考にしようとしました。

しかし、ここに書いてあるのは2年前の文法でTauriはv2.0で変わったばっかりでここに書かれているコードでは動かすことができませんでした。

その際にGPTとかドキュメントとかを読んで動いたコードは下のようになりました。

lib.rs
use tauri::Manager;
#[cfg(target_os = "macos")]
use cocoa::appkit::NSWindow;
pub fn run() {

    tauri::Builder::default()
        .setup(|app| {
            let window = app.get_webview_window("main").unwrap();
    
            #[cfg(target_os = "macos")]
            unsafe {
                let ns_window = window.ns_window().unwrap() as cocoa::base::id;
                // マウスイベントを透過させる
                ns_window.setIgnoresMouseEvents_(cocoa::base::YES);
            }
    
            window.set_always_on_top(true)?;
            window.set_decorations(false)?;
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

use cocoa::appkit::NSWindowは、macOSのアプリケーションで使われるappKitのNSWindowクラスを呼び出しています。

TauriはRustでOSのAPIを叩くことができます。それを利用して上記のようにAPIを無理やり叩いていました。

ただ、ver2.0から標準設定ができるようになりよしなに叩くAPIを切り替えたりしてくれるようになったぽいです。

さすがTauriですね。

リポジトリ

リポジトリは下にあります。
よかったらクローンして遊んでみてください!

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?