ブラウザで動いても、アプリで動くとは限らない
Handler(ハンドラー。タスクとスケジュール管理アプリ)のタスク一覧の表には、行ごとに横3本線のつまみが付いている。掴める。でも、ドラッグしても行が動かない。カンバン(タスクをカードにして、状態ごとの列に並べる画面)の方でも、カードの順番をドラッグで変えたかった。
多分余裕で終わる。そう思って、コーディングしてくれているClaude Code(以降Code)に頼んだ。
前提を書いておく。Handlerは、中身はWebページ。MacではそれをTauri(タウリ。Webページをそのままデスクトップアプリにする仕組み)で包んで、普通のアプリとして毎日使っている。MONET(僕が普段話しかけている、中心のAI)を載せたMONETアプリも同じ作り。Codeは作業を確かめる時、同じページを自分のブラウザで開いて、実際にマウスで操作してみる。そこでうまく動けば、できたと報告が来る。
Codeのブラウザでは全部通ったのに、僕のアプリでは動かなかった
Codeがコードを読んでみると、表のつまみは、ブラウザに最初から付いているドラッグの仕組みを使っていた。Codeの最初の見立ては、ドラッグがそもそも始まっていない、だった。そこでCodeは、Handlerのガント(横棒の日程表)でバーを動かす時と同じ方式に置き換えた。ブラウザの仕組みに頼らず、マウスの位置を自分で追いかける方式。カンバンは、列の間の移動がもともとブラウザのドラッグで動いていたので、その仕組みのまま、列の中の順番も変えられるようにした。
報告には、ブラウザで実際にマウスを使ってドラッグした、など確かめたことが並んでいた。最後は、反映したので一度リロードしてね、で終わっていた。
アプリで触ってみて、僕はCodeに返した。カンバンが機能しなくなっている。縦の順番だけじゃなく、前からあったはずの列の間の移動までできない。
Codeは僕が普段使っているのと同じページを自分のブラウザで開いて、確かめ始めた。その途中で、僕は一言だけ送った。僕が使っているHandlerは、単体のアプリだと。
Webページをアプリにする仕組みが、落とした場所を伝えていなかった
Codeのブラウザでは、同じページがちゃんと動いていた。僕の一言から、Codeは僕の画面ではTauriの中のWebKit(Safariと同じ系統)がページを表示していると見当をつけた。Codeが確かめに使っているのはChromium(Chromeと同じ系統)のブラウザ。同じページでも、Codeのブラウザと僕のアプリでは、動かしているエンジンが違う。
Codeは推測で直さず、Macに入っていたTauriの部品のコードまで読みに行った。分かったのはこう。Tauriには、画面へのドラッグを先に受け取る処理がある。この処理が、どんなドラッグが来ても「自分が処理した」と答えてしまう。そのせいで、ドラッグの知らせがページまで回ってこない。ページに届くのは「ドラッグが始まった」だけで、「ここに落とした」は来ない。
Codeの最初の見立てとは違って、ドラッグは始まっていた。掴むところまではページに届くけど、落とした先が届かない。最初の「掴めるのに動かせない」も、これが理由だった。Codeはこうも書いてきた。「アプリの中では、カンバンの列の移動も、たぶん前から動いていなかった。動いていたのはブラウザの中だけ」。Handlerの別の画面(Today)など、並び替えがまだブラウザのドラッグのままの所も、たぶんアプリでは動かない、とも。
Codeはカンバンも、表と同じマウスを追いかける方式に書き直した。アプリで触ると、カンバンも表も動いた。
動くようになってから触ってみると、表では、落とす位置を示す線が見えなかった。これもエンジンの違いだった。線は、行に付ける影として描いていた。Codeによると、WebKitは表の行には影を描かない。Codeは線を、行全体ではなく、1つ1つのマスの方に描くように変えた。
同じ原因で動かない所は、1つずつ直さず、仕組みの側の1行でまとめて直してもらった
Codeの見立てどおり、Todayは動かなかった。前から動かせたのかは、僕も覚えていない。
Codeは直し方を2つ出してきた。
- Tauriの側で、さっきの処理を止める。1行足して、MONETアプリとHandlerのアプリを作り直す。ブラウザのドラッグが、そのまま全部アプリの中でも動くようになる
- 残りの所も、カンバンや表と同じ方式に書き直す。アプリの作り直しは要らない
Codeのおすすめは1だった。Code「今後MONET側で何かをドラッグする時にも、同じ罠を踏まないため」。2は目の前の所を直すだけ。1は同じ種類の問題をまとめて消せる、という見立てだった。僕は1を選んだ。
Codeが1行足して、両方のアプリを作り直して入れ替えた。起動し直してTodayのドラッグを試してみて、とも頼まれた。僕は、完璧っす、と返した。今回はスムーズでしたね、とも。Codeの返事はこうだった。「スムーズだったのは、途中で『Handlerは単体アプリ』と一言くれたのが大きかった。あれで原因にすぐ辿り着けました」
その後、ブラウザで確かめた所と、僕がアプリで試す所を分けた報告が来た
次に直してもらったのは、MONETアプリの中の境界線だった。左の会話と右のパネルの間の線を右にドラッグすると、線がカーソルに置いていかれて、掴み直すまで動かなくなる。Codeが調べると、右のパネルに埋め込んだHandlerのページにカーソルが入った瞬間、マウスの動きが外側のMONETのページに届かなくなっていた。
これはエンジンの違いではなく、ブラウザでも起きる不具合だった。Codeは直して、ブラウザで直ったのを確かめた。そのうえで、報告の最後にこう書いてきた。Code「未確認:アプリの中(WebKit)での実際のドラッグ。確認に使ったブラウザはChromium。MONETアプリでパネルの線を一度右にドラッグしてみて」。僕がアプリで試すと、ちゃんと動いた。
設定画面では、またアプリの中だけ何も出なかった
それでも、毎回分けて書いてくれたわけではない。別の日、MONETアプリの設定画面を作り直してもらった。Codeはブラウザで確かめて、反映した。報告には確かめたことが並んでいたが、アプリの中で試してほしい所は書いていなかった。
アプリの設定画面で、上のメニューのタブを足すボタンを押すと、何も出ない。
Code「追加ボタンは、ブラウザの入力用の小窓を出す作りだった。MONETアプリ(Tauri)の中にはその小窓を出す仕組みが無いので、小窓は出ず、何も入力されなかったことになっていた」。
Codeは追加ボタンだけで止めず、同じ小窓を使っている所を、MONETアプリの画面のコード全体から探した。確認の小窓も、どれも同じ問題があった。タブの削除、保存していないまま別の所へ移る時の確認、保存していないまま戻る時の確認。アプリの中では、どれも黙って何もしない。Codeはそれを全部、ページの中に直接出す入力欄と確認の表示に置き換えた。会話画面のスレッドの削除も同じ確認の小窓を使っていて、アプリの中では削除できない状態だった。Codeはこれも続けて、小窓を使わない形に直した。
ドラッグの時も設定画面の時も、最初は僕がアプリで触って見つけた。同じ作りの残りは、Codeがコードの中から探して見つけた。
ブラウザで動くことと、僕が毎日使うアプリで動くことは、別の確認だった。原因が分かるまで、アプリで動くかどうかは、アプリで触ってみないと分からない。