CopyQ を使ってクリップボード履歴を管理する の履歴(No.2)
更新概要†
Windows は標準で Win + V キーでクリップボード履歴を利用できる。
でも、パスワードなどの情報が長時間にわたって履歴に残ってしまうと気持ちが悪いので使いにくい。
そこでクリップボード履歴とスニペットの管理 を CopyQ というフリーソフトで行うことにして、ログイン画面が表示されたら自動的にクリップボード内容を消去する機能を持たせることにした。
目次†
Windows では標準で Winキー + V でクリップボード履歴にアクセスできる†
例えばこの記事でも紹介されている:
https://atmarkit.itmedia.co.jp/ait/articles/1903/08/news028.html
#ref(): File not found: "スクリーンショット 2024-08-26 213447.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
過去にコピーまたは切り取りしたデータを貼り付けできる「クリップボードの履歴」機能の使い方を紹介する。「履歴」機能を使えば、クリップボードに保存した過去のデータを利用したり、よく使うデータをクリップボードに保存しておき必要に応じて呼び出したりすることができる。
2023年08月18日 05時00分 公開
[小林章彦,デジタルアドバンテージ]
問題点†
クリップボード履歴、という機能はとても便利そうなのだけれど、
パスワードや個人情報をコピーした履歴が長時間残ってしまうのは困る。
そう考えると Windows 標準の機能をそのまま使うわけにはいかない・・・
実現したい機能†
- 履歴にアクセスできるのは便利そう
- でもそんなに昔のコピー履歴にアクセスする必要はないので 30 分くらい経ったら消えてくれていい
- スクリーンセーバーが起動したり、ロック画面が表示されたら履歴を消去してほしい
- ただし、よく使う内容は履歴と別に保存しておいて、スニペットとして使いたい
そんなソフトはないかと探しました
CopyQ というソフト†
https://copyq.readthedocs.io/en/latest/
これは Windows だけじゃなく Mac OS や Linux 上でも動く、オープンソースのクリップボード履歴管理アプリとして有名なもの。
クリップボード履歴の機能だけでなく、スニペット的に使える内容を複数のタブに分類して保存しておいたりもできて便利そう。
標準では自動的に履歴を消す機能はないけれど、Java Script 的な独自のスクリプト言語で標準動作をカスタマイズしたり、追加の機能を実装したりできるので、それを使えば自動消去に対応できそう。
基本的な使い方†
- コピーした内容は自動的に CopyQ の履歴に入る
- タスクトレイのアイコンを左クリックするとメイン画面が表示される
- そのままキー入力するとクリップボード内容を検索可能
- 上下矢印キーで選択して ENTER で貼り付け
メイン画面表示のショートカットを設定†
わざわざタスクトレーアイコンをクリックするのは面倒なのでショートカット設定は必須。
タスクトレーアイコンの右クリックから [設定] を選択
[ショートカット] の [メインウィンドウの表示切り替え] の + をクリックして、 例えば Ctrl + @ を割り当てる。
(CopyQ のショートカット機能では Winキー は選択できないので Win + V にはできない)
すると、他のアプリを使用中でも Ctrl + @ で CopyQ が立ち上がるようになる。
スニペット機能†
メインウィンドウの [タブ] メニューから新しくタブを追加して、 そこにスニペットとして使う内容を追加するのが良さそう。
- 左右の矢印キーで表示するタブを変更できる
#ref(): File not found: "スクリーンショット 2024-08-26 220951.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
このように各項目の行数が多くて一覧性が悪い場合には、
設定で 「アイテムをシンプルに表示」 をチェックしておくと
#ref(): File not found: "スクリーンショット 2024-08-26 221333.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
このように見やすくなる。
#ref(): File not found: "スクリーンショット 2024-08-26 221607.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
クリップボード履歴の自動消去†
- 作業中に30分以上前の古い履歴は削除する
- ロック画面が表示されたら、ピン止めされておらず、タグもついていないクリップボード履歴はすべて削除する
- スクリーンセーバーの設定を、スクリーンセーバーからの復帰時にロック画面へ飛ぶようにしておく
とすることで、クリップボード履歴の機能を使いつつも、 機密性の高い情報がクリップボード履歴に長時間残ってしまう可能性を減らせるはず。
クリップボード履歴にコピーした時刻を持たせる†
「古い履歴」を消すにはそれがいつコピーされたかの情報を持たなければならない。
CopyQ のサイトにほとんどそのまま使えるコードがあった。
https://copyq.readthedocs.io/en/latest/command-examples.html#show-copy-time
ほんのちょっとだけ変更したのがこれ:
(タグの区切り文字のカンマの後ろにあったスペースを除去した)
[Command]
Automatic=true
Command="
copyq:
var time = dateString('yyyy-MM-dd hh:mm:ss')
setData('application/x-copyq-user-copy-time', time)
var tagsMime = 'application/x-copyq-tags'
var tags = str(data(tagsMime)) + ',' + time
setData(tagsMime, tags)"
Icon=\xf017
Name=Store Copy Time
使い方は、
- このコードをコピーしてから CopyQ のメインウィンドウを表示する
- F6 を押すとコマンドウィンドウが現れる
- Ctrl + V で張り付けると Store Copy Time という項目が追加される
Automatic=true の指定があるため、このコードはクリップボードへデータがコピーされるたびに呼び出される。
- 時刻を表す文字列は "2024-01-01 01:01:01" の形式
- application/x-copyq-user-copy-time タイプの情報としてクリップボードに入れる
- 同時に、タグとしても同じデータを付けておく(これは表示用)
時刻で選別して古いものを消すコマンドを実装する†
これが Auto Delete 相当の機能になる
同様の手順で以下を張り付ける:
[Command]
Name="removeOldItems(millisec=0)"
Command="
copyq:
global.removeOldItems = function(millisec=0) {
var old = new Date(Date.now()-millisec)
var str = ''
str += ('000' + old.getFullYear()).slice(-4)
str += '-' + ('0' + (old.getMonth() + 1)).slice(-2)
str += '-' +('0' + old.getDate()).slice(-2)
str += ' ' + ('0' + old.getHours()).slice(-2)
str += ':' + ('0' + old.getMinutes()).slice(-2)
str += ':' + ('0' + old.getSeconds()).slice(-2)
var save = selectedTab()
tab(tab()[0])
var i = size() - 1 // iterate from the last to the first
while(i >= 0){
var time = getItem(i)['application/x-copyq-user-copy-time']
if(time && time < str && !plugins.itempinned.isPinned(i)) {
if(!plugins.itemtags.tags(i).find((tag)=>tag!=time)) {
remove(i)
}
}
i--
}
tab(save)
if(millisec==0) copy('') // 消せるときと消せないときがある???
}
"
IsScript=true
すると、removeOldItems(millisec=0) という項目が追加される。
この項目は [スクリプト] に指定されており、内部では global という名のグローバル変数プールに removeOldItems という関数を追加している。
このように追加した関数は、他のスクリプトから呼び出せるほか、コマンドライン引数の中からも実行が可能になる。
で、肝心の関数の中身は、
- 現在時刻から millisec で指定されただけ過去の時刻を元に "2000-01-01 00:00:00" 形式の文字列を作る
- 1つめのタブ(これがクリップボード履歴に相当する)の項目を後ろから順に見ていく
- 後ろから見るのは項目を消去したときにおかしくならないようにするため
- 'application/x-copyq-user-copy-time' の情報を取り出して、時刻を比較し古いものだけを処理
- ピン止めされておらず、時刻以外のタグが付いていなければ消去する
- 何も残らなければ、つまり最新の除法でさえ古いものであれば、クリップボード自体もクリアする
- millisec を省略すると 0 を指定したのと同じになるため、常にすべての履歴が消去される
クリップボードへのコピーがあった時に呼び出す†
クリップボードへコピーがあるたびに、古い履歴を消すようにした。
[Command]
Automatic=true
Command="
copyq:
removeOldItems(30*60*1000) // 30 min
"
Icon=\xf12d
Name=Clear Old History
クリップボードへのコピーを行わないと消えないので本当はちょっと不満なのだけれど、 今のところこれより良い方法を見つけられていない・・・
履歴一覧の表示前に呼び出されるコールバックがあればそこに記述したいのだけれどなあ。
アイコンの文字コード†
上記の Clear Old History のスクリプトには消しゴムマークのアイコンを付けたのだけれど、 CopyQ の「選択したコマンドをコピー」でコピーすると、
となって、現状ではこれはブラウザ上では文字化けしてしまった。
https://ao-system.net/entity/ こちらのサイトで html エンティティに変換したところ、
\xf12d
と表記すればよいことが分かった。
Windows のロック画面が表示されたらクリップボードを空にする†
- ピン止め・タグ付けされていないすべての履歴を消す
- クリップボード自体も空にする
これは引数無しで removeOldItems() を呼び出せばいいのだけれど、
「Windows のロック画面(ログイン画面)が表示されたら実行する」という設定は CopyQ にはない
そこで Wimdows 標準の「タスクスケジューラ」から CopyQ を呼び出す形で対応する。
ロックされたら copyq.exe に --eval "removeOldItems()" を付けて呼び出せばいい。
タスクスケジューラを起動†
スタートボタンを押して task と入れればタスクスケジューラが見つかるはず。
#ref(): File not found: "スクリーンショット 2024-08-26 231836.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
タスクを作成&名前を付ける†
#ref(): File not found: "スクリーンショット 2024-08-26 232052.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
#ref(): File not found: "スクリーンショット 2024-08-26 232148.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
トリガーを「ワークステーション ロック時」にする†
トリガータブで「新規」
#ref(): File not found: "スクリーンショット 2024-08-26 232209.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
「ワークステーション ロック時」としてOK
#ref(): File not found: "スクリーンショット 2024-08-26 232308.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
トリガーが追加された
#ref(): File not found: "スクリーンショット 2024-08-26 232332.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
操作で CopyQ を呼び出す†
[操作] タブで [新規]
#ref(): File not found: "スクリーンショット 2024-08-26 232348.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
[プログラム] にフルパスで copyq.exe を指定、引数に --eval "removeOldItems()" を指定
#ref(): File not found: "スクリーンショット 2024-08-26 232519.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
正しく項目が追加された
#ref(): File not found: "スクリーンショット 2024-08-26 232537.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
条件で AC 接続時のみのチェックを外す†
#ref(): File not found: "スクリーンショット 2024-08-26 232617.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
完成†
これで Windows のロック時に CopyQ の履歴とクリップボード内容が消去されるようになった
すばらしい
スクリーンセーバーの再開時にロック画面を表示する†
デスクトップの右クリックから [個人用設定]
#ref(): File not found: "スクリーンショット 2024-08-26 234317.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
[ロック画面] から [スクリーンセーバーの設定]
#ref(): File not found: "スクリーンショット 2024-08-26 222925.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
[再開時にログオン画面を表示]にチェック
#ref(): File not found: "スクリーンショット 2024-08-26 234515.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
5分おきに removeOldItems(30*60*1000) を呼び出してもいいけれど†
タスクスケジューラのトリガーには5分ごとに繰り返す、というような指定もできるので、 5分おきに removeOldItems(30*60*1000) を呼び出せば、長時間コピー操作をしていない場合にも 確実に古い履歴を消すことができる。
できるけど・・・ロック画面で消えてくれるならそこまでする必要もない・・・かな???
#ref(): File not found: "スクリーンショット 2024-08-26 234929.png" at page "ソフトウェア/CopyQ を使ってクリップボード履歴を管理する"
しばらくこれでやってみる†
履歴やスニペット、なんとなく便利そうではあるけれど、実際にはどこまで使うことになるのか。
しばらくこれでやってみようと思う。
万一それらがそこまで役に立たなくても、これまではクリップボードにコピーされたデータ自体、場合によっては長時間残ってしまっていたのだけれど、上記の手順でPCのロック時に確実に消えるようにできただけでも収穫があったはず。→ いやこれなんかうまく消えない時があるぞ???
copy('') が効くときと効かないときの差は何なのか???