basyura's blog

あしたになったらほんきだす。

ブラウザのウインドウサイズをコマンド実行で変更する

背景

Inkdrop の vim plugin を使ってウインドウサイズを変えられるようになったのに気を良くしてブラウザ (Vivaldi) でもやってみる。

主に mac ではアプリをフルスクリーン (cmd+control+f) で使ってはいないけどスクリーンいっぱいに広げて使う。フルスクリーンにするとアプリの切り替えがワンテンポ遅いので思考が止まる (遅いことが気になる)。嫌なのでフルスクリーンはほぼ使わない。フルスクリーンを独自にやっていて切り替えが早い MacVim ぐらい。特に Terminal は下に隙間が空くし、行間で微調整してもタブを追加したら空くので一番困り中 (BigSur の前は大丈夫だった気がするけど、Monterey にしたら直ったりする?)。

ブラウザと Inkdrop を並べて調べ物をしながらまとめていくことがよくある。その際に OS 標準の横並びを使ってもいいのだけど、他のウインドウとの切り替えが遅いし中央の黒線も気になる。

chromium-vim

ブラウザで vim キーバーインドが使えるようになる拡張である chromium-vim にウインドウサイズを変える機能を組み込んで見る。オリジナルはメンテされなくなったので fork した版に固有コマンドを定義できるようにカスタマイズ済み。

Vivaldi は Chrome ベースなので Chrome の API をそのまま叩けた。

const opt = {
  width: screen.availWidth / 2,
  height: screen.availHeight,
  top: screen.availTop,
  left: 0,
};
chrome.windows.update(
  chrome.windows.WINDOW_ID_CURRENT,
  opt,
);

fork 版 chromium-vim に組み込むとこんな感じで。

CommandExecuter.add("half", "half window", {
  match: function (value) {
    return value == "half" || value == "ha" || value == "hal";
  },
  execute: function (value, repeats, tab) {
    const opt = {
      width: screen.availWidth / 2,
      height: screen.availHeight,
      top: screen.availTop,
      left: 0,
    };
    chrome.windows.update(
      chrome.windows.WINDOW_ID_CURRENT,
      opt,
    );
  },
});

CommandExecuter.add("full", "full window", {
  match: function (value) {
    return value == "full" || value == "fu" || value == "ful";
  },
  execute: function (value, repeats, tab) {
    const opt = {
      width: screen.availWidth,
      height: screen.availHeight,
      top: screen.availTop,
      left: 0,
    };
    chrome.windows.update(
      chrome.windows.WINDOW_ID_CURRENT,
      opt,
    );
  },
});

まとめ

わりとまんぞく。 フルスクリーンのウインドウ切り替えが速くなれば解決しそうなのだけど、意図的にワンテンポ遅いのか何かしらの制限があるからなのかどっちなんだろう。

マウスパッドを買い変えた

何年使ったか覚えてないぐらい使ってた。端の方の表面のフィルムが剥がれ気味になっていたのが気になりつつも放置していた。気まぐれで「剥がしても大丈夫じゃね?」と思って全部剥がしたら滑りが悪くなりすぎて腱鞘炎になっちゃうんじゃないかレベルになってしまった。新しい版があったのですぐに注文。

白すぎて最初は気になるなぁと思っていたけどすぐに慣れた。マウスの滑りもいいので問題なさそう。

Inkdrop - vim plugin で独自コマンド定義

v5.5 @ windows

v5.5 がリリースされたものの、Electron のバージョンが上がったからなのか Windows でウインドウを最大化するとタスクバーの前面に出てしまう現象に悩み中。タスクバーの位置を上にしたうえで非表示にして使っているのでいろいろ困る。ウインドウを最大化せずに最大のサイズ(スクリーンサイズ)にリサイズすればタスクバーの前には出てこないので、これで回避中。MS の PowerBI でも発生してるし (最近使ってないから知らないが)、何かしらのアプリが掴むからなのかタスクバーが常に表示された状態になることもしばしばなので根本的になにかあるんだろうと思うけど直る気配は無い。アイコン点灯してタスクバー出してくるのはいいとしても一定期間 (3sとか) 過ぎたら非表示に戻って欲しいんだな、ホントは。

いろいろ手間

Inkdrop は基本的に最大化して使っていて、自分で画面を表示しながらメモを取りたい場合や、資料と並べてメモを取ることがしばしばある。最大化状態とサイズ (主に横幅) を小さくした通常状態で切り分けていたので、最大化相当状態としてスクリーンサイズに広げただけでは、マウスを使ってサイズを変える手間が増える。最大化相当状態に戻すのも手間。

vim plugin を愛用しているので独自コマンドを定義して代用することにした (本来はフォーラムに登録しろよなんだけど、手元の課題を自分でできる範囲でプログラムを書いて解決してしまいたくなってしまう病)。

コマンド定義

init.js に定義しておけば :slim<CR> or :sl<CR> で発動できる。便利。 Inkdrop のコマンドとして定義してショートカットキーに当ててもいいのだけど、組み合わせは有限なので vim plugin のコマンドとして定義できると便利。引数も使えるし。

inkdrop.onEditorLoad(() => {
  const CodeMirror = require("codemirror");
  // 幅を指定してリサイズ
  CodeMirror.Vim.defineEx("width", "wi", (cm, event) => {
    if (event.args == null) {
      showConfirm(cm, "requires an argument.");
      return;
    }
    const height = window.screen.height;
    const width = window.screen.width;
    const arg = parseInt(event.args[0], 10);
    const info = { x: width - arg, y: 0, width: arg, height: height };
    inkdrop.window.setBounds(info);
  });
  // 横幅細めでリサイズ
  CodeMirror.Vim.defineEx("slim", "sl", (_, event) => {
    const height = window.screen.height;
    const width = window.screen.width;
    const info = { x: width - 600, y: 0, width: 600, height: height };
    inkdrop.window.setBounds(info);
  });
  // 横幅半分にリサイズ
  CodeMirror.Vim.defineEx("half", "ha", (_, event) => {
    const height = window.screen.height;
    const width = window.screen.width;
    const info = { x: width / 2, y: 0, width: width / 2, height: height };
    inkdrop.window.setBounds(info);
  });
  // 画面いっぱいにリサイズ (≠ Full Screen)
  CodeMirror.Vim.defineEx("full", "fu", (_, event) => {
    const height = window.screen.height;
    const width = window.screen.width;
    const info = { x: 0, y: 0, width, height };
    inkdrop.window.setBounds(info);
  });
});

// メッセージ表示 (Vim Plugin から拝借)
function showConfirm(cm, text) {
  if (cm.openNotification) {
    cm.openNotification('<span style="color: red">' + text + "</span>", {
      bottom: true,
      duration: 5000,
    });
  } else {
    alert(text);
  }
}

Windows で最大サイズにしたらタスクバーが出なくなったのでちょっと修正

  // 画面いっぱいにリサイズ (≠ Full Screen)
  CodeMirror.Vim.defineEx("full", "fu", (_, event) => {
    const height = window.screen.height - 1;   // 高さを微調整
    const width = window.screen.width;
    const info = { x: 0, y: 1, width, height };  // 位置を微調整
    inkdrop.window.setBounds(info);
  });

もうひとこと

zenn.dev に書こうとすると "ちゃんとかこう" と思ってしまったりでハードルが上がるので、こっちでひとまずアウトプットしたうえでまとめたものを zenn.dev に登録するのがいいのかなぁと思う今日このごろ。

Inkdrop - vim plugin とカーソルの色 : その3

カーソルが点滅しないようにするのは頑張らなくていいことが発覚。

init.js で点滅を止める。

inkdrop.onEditorLoad((e) => {
  const { cm } = inkdrop.getActiveEditor();
  cm.setOption("cursorBlinkRate", 0);
})

styles.less でカーソルの色をオレンジっぽくする。

.CodeMirror-cursor {
    border-left: 2px solid #ffa87d;
}
.cm-fat-cursor .CodeMirror-cursor {
    background: #ffa87d;
}

フォーカスが外れたときにカーソルが消えるようになった。めでたしめでたし。

Inkdrop - vim plugin とカーソルの色 : その2

カーソルの blink を止めたのはいいけど、フォーカスが外れた時は非表示にしたい。 お試し中。

inkdrop.onEditorLoad((e) => {
  const editor = inkdrop.getActiveEditor();
  const { cm } = editor;
  const container = document.querySelector(".CodeMirror-lines");
  const changeVisibility = (visibility) => {
    const cursor = container.querySelector(".CodeMirror-cursor");
    cursor.style.visibility = visibility;
  };

  cm.on("update", () => {
    if (!cm.hasFocus()) {
      changeVisibility("hidden");
    }
  });
  cm.on("blur", () => changeVisibility("hidden"));
  cm.on("focus", () => changeVisibility("visible"));
});

update イベントは頻繁に走るので負荷が気になる。

Inkdrop - vim plugin とカーソルの色

Inkdrop 5.5 がリリースされた。electron のバージョンアップ起因かもしれないが、日頃から愛用している vim plugin のカーソル表示がおかしい。 見てみると、そもそものスタイル指定が間違ってたっぽい。

合わせて blink も止めたくなったので見直した。

.editor {
  /* insert mode */
  .CodeMirror-cursor {
    border-left: 2px solid #ffa87d;
    visibility: visible;
  }
  /* normal mode */
  .cm-fat-cursor .CodeMirror-cursor {
    background: #ffa87d;
    visibility: visible;
  }
}

javascript : getter, setter, Proxy, Reflect

最近の javascript もある程度勉強したつもりだったけど、全く知らなかった。

明示的な getter & setter

const hogeProxy = {
  _hoge: null,
  set hoge(v) {
    this._hoge = v;
  },
  get fuga() {
    return this._hoge;
  },
};

hogeProxy.hoge = "(=ΦωΦ)";
console.log(hogeProxy.hoge);  //=> undefined
console.log(hogeProxy._hoge); //=> (=ΦωΦ)
console.log(hogeProxy.fuga);  //=> (=ΦωΦ)

汎用的な getter & setter

const person = {
  name: "basyura",
  age: -1,
};

const personProxy = new Proxy(person, {
  get: (obj, prop) => {
    return Reflect.get(obj, prop);
  },
  set: (obj, prop, value) => {
    Reflect.set(obj, prop, value);
  },
});

console.log(personProxy);      //=> { name: 'basyura', age: -1 }
console.log(personProxy.name); //=> basyura
personProxy.age = 99;
console.log(personProxy.age);  //=> 99

便利。