カテゴリー: その他

  • Ctrl押しっぱなし問題

    バグ修正

    • Ctrlキーの押下が解除されない

    この件、AutohotKey界隈ではよく知られた現象らしく、Ctrlキー以外にも修飾キー全般で押しっぱなしになる不具合が発生する模様。

    ググると沢山情報が出てくる。

    • AutoHotkey:キー押しっぱなし病・ホットキーすり抜け病対策の研究
    • AutoHotkeyの押しっぱなし問題
    • 快適キーボード操作のためのキーカスタマイズ 〜AutoHotKeyのキー押しっぱなし問題とScrollLockの非推奨~
    • 【AutoHotkey】キーが押しっぱなしになる現象の対策メモ(2024年6月最新版)
    • AutoHotkeyでShiftの単押しと修飾キーとしての押しっぱなしを別のキーマップにする
    • AutoHotkeyを始めるなら最初にこれを書いておこう

    ・・・

    機能修正

    SendMode "Event"
    
    ; 不具合対処
    ; 稀に修飾キーが押下した状態のままになる現象が発生する。
    ; ホットキー終了時に必ずCtrl/Altキーを上げる。
    sendWrap(key)
    {
        try
            Send key
        finally
            Send "{Ctrl Up}"
    }
    setWindowPositionWrap(windowPosition, monitorNum*)
    {
        try
            if (monitorNum.Length > 0)
                setWindowPosition(windowPosition, monitorNum[1])
            else
                setWindowPosition(windowPosition)
        finally
            Send "{Alt Up}"
    }
    ^!r:: {
        Send "{Ctrl Down}"
        Send "{Ctrl Up}"
        Send "{Alt Down}"
        Send "{Alt Up}"
        Reload
    }

    現象がまったく出なくなるような対処方法はないようだけど、SendをSendEventに変更したら発生頻度が下がったとの情報があったので「SendMode “Event”」の1行を追加した。

    また、send/setWindowPosition関数をWrapしてホットキーの終了時に無条件でCtrl/AltのUpイベントを発行するように修正した。無条件でUpイベントが発生することによる副作用が懸念されるけれど押しっぱなしになるよりは良いかと思われる。

    暫定対処で追加したCtrl+Alt+Rキーの処理は残してAltキーの対処も追加しておいた。

    これでも再発するならsleepを入れたり、修飾キーをF13~F14キーに割り当てたり、別の方法で試行錯誤しながら修正していくことになる。

    しばらく様子見です。

    作ったもの

    keyremap_20241222.zip

  • 「Python」で簡単にGUIを構築できる国産フレームワーク「TkEasyGUI」がv1.0に

    https://forest.watch.impress.co.jp/docs/news/1637592.html

    TkEasyGUI – Pythonで最も素早くデスクトップアプリを創るライブラリ

    https://note.com/kujirahand/n/n33a2df3aa3e5

    WindowsのGUIが汚い… これはどうにもならんですね。🤔

  • 「もうええでしょ」のダウンロード方法

    YT-DLP

    yt-dlp is a feature-rich command-line audio/video downloader with support for thousands of sites.

    https://github.com/yt-dlp/yt-dlp?#release-files

    yt-dlp.exeをダウンロードし、URLを引数にして実行する。

    yt-dlp.exe https://www.youtube.com/watch?v=FCt2mryVhtM

    →「もうええでしょ [FCt2mryVhtM].mp4」がダウンロードされる。

    以上

    補足

    ダウンロード時に以下の警告メッセージが出力されます。低画質のmp4ファイルのダウンロードで良い場合は対処不要です。

    WARNING: ffmpeg not found. The downloaded format may not be the best available. Installing ffmpeg is strongly recommended: https://github.com/yt-dlp/yt-dlp#dependencies

    FFmpeg Static Auto-Builds

    https://github.com/yt-dlp/FFmpeg-Builds#downloads

    WINDOWS X64:「ffmpeg-master-latest-win64-gpl.zip」

    警告メッセージに従い ffmpeg をダウンロードしてパスを通すと警告が消えてmkvファイルがダウンロードされるようになります。

    FORMAT SELECTION

    By default, yt-dlp tries to download the best available quality if you don’t pass any options.

    ファイル形式を指定しない場合は、最も高画質な形式でダウンロードされます。

    You can also use a file extension (currently 3gpaacflvm4amp3mp4oggwavwebm are supported) to download the best quality format of a particular file extension served as a single file.

    ファイルの拡張子は、-f mp4 のように指定できます。

  • ざわ・・・メーカー

    /**
     * ざわ・・・メーカー
     * @param {obj} cs: canvas object
     * @param {number} zawaNum: 生成する「ざわ・・・」の数
     * @param {boolean} isBordering: 縁取りするかどうか
     *     黒文字の場合は白フチに、白文字の場合は黒フチに
     * @param {boolean} isColorBlack: 黒文字にするかどうか(falseで白文字)
     * @param {boolean} isRightFlow: 右から流れるようにするか
     */
    var zawaMaker = function(cs, zawaNum, isBordering, isColorBlack, isRightFlow ) {
        var ctx      = cs.getContext('2d');
        var csWidth  = cs.width;
        var csHeight = cs.height;
        var zawas    = [];
    
        /**
         * ランダムな整数を返す
         * @param max 最大値
         * @param min 最小値
         * @return min ~ max
         */
        var getRandomInt = function(max, min) {
            return Math.floor(Math.random() * (max - min)) + min;
        };
    
        /**
         * @constructor
         */
        var ZawaZawa = function() {
            this.initialize();
        };
    
        ZawaZawa.prototype = {
            initialize: function() {
                this.scale     = getRandomInt(10, 5) / 10; // 1 ~ 0.5の倍率
                this.width     = this.scale * 160;  // 元サイズを大体150pxくらいと規定
                this.height    = this.scale * 60;   // 元サイズを大体60pxくらいと規定
                this.moveX     = getRandomInt(csWidth  - this.width, 0);
                this.moveY     = getRandomInt(csHeight - this.height, 0);
                this.addMoveX  = this.scale * 5;  // 奥行きを出すために、小さい要素は移動量を少なくする
                this.alpha     = 1;
            },
            setStatus: function() {
                /* 変換マトリクスを初期化 */
                ctx.setTransform(1, 0, 0, 1, 0, 0);
    
                ctx.scale(this.scale, this.scale);
                ctx.translate(this.moveX, this.moveY);
                ctx.globalAlpha = this.alpha;
            },
            update: function() {
                /* scaleで座標軸がズレているので、scaleした分を割った値をCanvasサイズとする */
                var _csWidth = csWidth / this.scale;
    
                /* 流れる向きの条件分岐 */
                if (isRightFlow) {
                    if (this.moveX + this.width + 50 < 0 ) {
                        this.alpha = 0;
                        this.moveX = _csWidth + this.width;
    
                        /* scaleを変えるため再設定 */
                        this.scale    = getRandomInt(10, 5) / 10;
                        this.width    = this.scale * 160;
                        this.height   = this.scale * 60;
                        this.moveY    = getRandomInt(csHeight - this.height, 0);
                        this.addMoveX = this.scale * 5;
                    } else {
                        this.moveX -= this.addMoveX;
                        this.alpha += 0.01;
                    }
                } else {
                    if (this.moveX >_csWidth) {
                        this.alpha = 0;
                        this.moveX = - this.width;
    
                        /* scaleを変えるため再設定 */
                        this.scale    = getRandomInt(10, 5) / 10;
                        this.width    = this.scale * 160;
                        this.height   = this.scale * 60;
                        this.moveY    = getRandomInt(csHeight - this.height, 0);
                        this.addMoveX = this.scale * 5;
                    } else {
                        this.moveX += this.addMoveX;
                        this.alpha += 0.01;
                    }
                }
    
                /* 透明度が1以上の場合は透明度の増加を止める */
                if (this.alpha > 1) {
                    this.alpha = 1;
                }
            },
            draw: function() {
                /**
                 * @param {number} width: 線の太さ
                 * @param {string} color: 線の色
                 */
                function createZawaPath(width, color) {
                    ctx.lineWidth = width;
                    ctx.strokeStyle = color;
                    ctx.beginPath();
                    ctx.lineCap = "round";
                    ctx.lineJoin = "round";
    
                    // ざ
                    ctx.moveTo(10, 45);
                    ctx.lineTo(50, 45);
    
                    ctx.moveTo(25, 35);
                    ctx.lineTo(50, 60);
                    ctx.lineTo(20, 60);
                    ctx.bezierCurveTo(5, 60, 5, 75, 20, 75);
                    ctx.lineTo(50, 75);
    
                    ctx.moveTo(38, 30);
                    ctx.lineTo(38, 36);
    
                    ctx.moveTo(46, 30);
                    ctx.lineTo(46, 36);
    
                    // わ
                    ctx.moveTo(70, 35);
                    ctx.lineTo(70, 75);
    
                    ctx.moveTo(60, 45);
                    ctx.lineTo(80, 45);
                    ctx.lineTo(60, 75);
                    ctx.bezierCurveTo(80, 25, 120, 70, 85, 75);
    
                    // ・・・
                    ctx.moveTo(110, 60);
                    ctx.lineTo(115, 60);
    
                    ctx.moveTo(125, 60);
                    ctx.lineTo(130, 60);
    
                    ctx.moveTo(140, 60);
                    ctx.lineTo(145, 60);
    
                    ctx.closePath();
                    ctx.stroke();
                }
    
                /* 縁取と黒・白文字の条件分岐 */
                if (isBordering && isColorBlack) {
                    createZawaPath(15, 'white');
                    createZawaPath(6, 'black');
                }
                if (isBordering && !isColorBlack) {
                    createZawaPath(15, 'black');
                    createZawaPath(6, 'white');
                }
                if (!isBordering && isColorBlack) {
                    createZawaPath(6, 'black');
                }
                if (!isBordering && !isColorBlack) {
                    createZawaPath(6, 'white');
                }
    
            },
            render: function() {
                this.setStatus();
                this.draw();
                this.update();
            }
        };
    
    
        /**
         * ざわインスタンスの作成
         * @return zawas[instance, instance...];
         */
        function createZawas(num) {
            var i = 0;
            for (; i < num; i++) {
                zawas[zawas.length] = new ZawaZawa();
            }
        }
    
       /**
         * 描画
         */
        function render() {
            var i = 0;
            var l = zawas.length;
            ctx.setTransform(1,0,0,1,0,0);
            ctx.clearRect(0, 0, csWidth, csHeight);
            for (; i < l; i++) {
                zawas[i].render();
            }
            requestAnimationFrame(render);
        }
    
        /* 実行 */
        createZawas(zawaNum);
        render();
    };
    
    var cs = document.getElementById('myCanvas1');
    
    /* args: canvasオブジェクト, ざわの数, 縁取りか, 黒文字か, 右から流すか */
    zawaMaker(cs, 10, false, true, false);
    

    https://qiita.com/nekoneko-wanwan/items/4b196365183580831758

    👍

  • ざわ…ざわ…ざわ…

  • VPN経由で映画やドラマを視聴する

    注意:広告つきプランをご利用の場合、VPN経由でNetflixを視聴することはできません。NetflixのライブイベントはVPN経由で視聴することはできません。

    https://help.netflix.com/ja/node/114701

    VPN 無料 – VPN Chrome Zenmate

    プライバシーへの取り組み

    https://chromewebstore.google.com/detail/fdcgdnkidjaadafnichfpabhfomcebme/privacy

    拡張機能をインストールして「火垂るの墓」を観たけど個人情報は抜かれてそう。ご利用は自己責任でお願い致します… 🙄

    ブラウザーのストレージ制限と削除基準

    https://developer.mozilla.org/ja/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria

    Chromeのゴミ掃除

    1. 「設定」画面で「プライバシーとセキュリティ」メニューを選択する。
    2. 「サイトの設定」を選択する。
    3. 「すべてのサイトに保存されている権限とデータを表示」を選択する。

    または、以下のページを開く。

    chrome://settings/content/all

    1. 表示した画面で「サイトの合計ストレージ使用状況」を確認する。
    2. 「並べ替え」で「保存データ」を選択する。
    3. 各サイトのゴミ箱アイコンから不要なデータを削除する。

    「すべてのデータを削除」ボタンで一括削除するとすべてのサイトのログイン情報が削除されてIDやパスワードの再入力が必要となります。IDやパスワードを適切に管理していない場合には、Webサイト/サービスにログインできなくなりますので、ご利用は自己責任でお願い致します… 🙄

    Windowsのゴミ掃除

    DiskInfo
    https://forest.watch.impress.co.jp/library/software/diskinfo

    フリーソフトを使ってごみファイルを探し、手動で削除しています。

    たまにゴミ掃除したくなるけど数十ギガバイトのゴミファイルを削除しても体感できるようなパフォーマンス改善が見込めるわけではないので悪しからずご了承くださいませ…

  • Mozilla Firefoxノススメ

    デスクトップ、モバイル、エンタープライズ用 Firefox をダウンロード – Mozilla
    https://www.mozilla.org/ja/firefox

    Google Trends

    2004-現在

    昔はすごかった?

    現在のブラウザのシェアを見るとChrome一択だけど、最近複数画面/複数タブでピクチャーインピクチャー機能を使用するためにFirefoxをインストールした。

    Chromeでも拡張機能をインストールすればピクチャーインピクチャー機能を使用できるけれどマルチウインドウには対応していない。

    Picture-in-Picture Extension (by Google)

    https://chromewebstore.google.com/detail/picture-in-picture-extens/hkgfoiooedgoejojocmhlaklaeopbecg

    Support multiple window picture-in-picture #19

    https://github.com/GoogleChromeLabs/picture-in-picture-chrome-extension/issues/19

    マルチウインドウに対応するには大きな改修が必要らしい。データフォルダを用意して起動時に指定してやれば複数画面で使用できるみたいなことが書かれている?

    Firefox のピクチャーインピクチャーについて

    Firefox ならマルチウインドウで使用できる。

    https://support.mozilla.org/ja/kb/about-picture-picture-firefox

    動画にレイヤーが重ねられていてアクセサリーなどが配置されている場合は、ピクチャーインピクチャーのボタンが押せないので、Ctrl + Shift + ] キーのキーボードショートカットを使用している。

    追記:アドレスバーにもアイコンが用意されている。

    Firefox のダメなところについて

    アドレスバーでのサイト内検索機能が使いづらい。ブックマークでタグを設定してURLに「%s」を埋め込んでやれば検索できそうではあるけどChromeのアドレスバー/オムニバーの方がいい感じ。

    Firefoxでも過去の機能を復活させればショートカット+tab/spaceでサイト内検索できる模様。

    How do I add a custom search engine to Firefox desktop?

    https://stackoverflow.com/questions/77219507/how-do-i-add-a-custom-search-engine-to-firefox-desktop

    Re-enable a feature from the past

    1. Type in about:config in the address bar. Accept all the scary warnings.
    2. Search for browser.urlbar.update2.engineAliasRefresh.
    3. Press the + (on the right hand side).
    4. Now when you go to Settings > Search, there should be an Add button under the box which lists the various search engines available.
    5. Don’t let this post get popular, otherwise this method will also be deprecated to make Firefox better than ever!
    検索エンジン名別名URL
    Amazon Prime Videopvhttps://www.amazon.co.jp/s?k=%s&i=instant-video
    Netflixnfhttps://www.netflix.com/search?q=%s
    YouTubeythttps://www.youtube.com/results?search_query=%s
    Wikipediawphttps://ja.wikipedia.org/w/index.php?search=%s

    とりあえず4つ登録した。

    あとは、Firefoxは標準機能でフォントの指定を強制できるのはいいけどレンダリング結果が汚い。フォントがにじむの何とかならないのか調査中…

    Firefox Color

    Chromeの画面なのかFirefoxの画面なのかぱっと見で区別できないので、ブラウザの「テーマ」を初めて設定してみた。

    https://color.firefox.com/

    しばらくオレンジ色で使ってみる。

    フォクすけ

    https://ja.wikipedia.org/wiki/フォクすけ

    フォクすけ、ぐぐっても古い情報しかヒットしないですね… 終わったんですね。

    ブラウザ戦争

    https://ja.wikipedia.org/wiki/ブラウザ戦争

    ブラウザ戦争は死語ですか?そうですかー

  • How to unregister all installed service workers in Chrome

    https://www.stefanjudis.com/snippets/how-to-unregister-all-installed-service-workers-in-chrome

    サービスワーカー API

    サービスワーカーは、基本的にウェブアプリケーション、ブラウザー、そして(もし繋がっていれば)ネットワークの間に介在するプロキシサーバーのように振る舞います。これは、よりよいオフラインの操作性を可能にするように意図されており、ネットワークのリクエストに介在してネットワークの使用可否の状況に基づいて適切な対応を取ったり、サーバー上にある資産を更新したりします。また、プッシュ通知やバックグラウンド同期の API 群へのアクセスもできるようになります。

    https://developer.mozilla.org/ja/docs/Web/API/Service_Worker_API

    よりよいオフラインの操作性?そんなのはいらん。

    やったこと

    1. Chromeで以下のページを開く
      chrome://serviceworker-internals/
      →登録されているサービスワーカーが表示される
    2. 「F12」キーを押下してディベロッパーツールを開く
    3. ディベロッパーツールのコンソールで以下を実行する
      $$('.unregister').forEach(b => b.click())
      →サービスワーカーが削除される

    補足

    他のタブで開いているサイトや使っている拡張機能のサービスワーカーは削除されない。

    たまにゴミ掃除したくなるけどサービスワーカーを削除しても体感できるようなパフォーマンス改善が見込めるわけではないので悪しからずご了承くださいませ…

  • Quickstart: Deploy RESTful API application to Azure Spring Apps

    https://learn.microsoft.com/ja-jp/azure/spring-apps/quickstart-deploy-restful-api-app

    テスト

    実際にデプロイしたURLがこれ。
    https://deploy-test-simple-todo-api.azuremicroservices.io/swagger-ui/index.html (※削除済)

    便利なようで便利じゃないやつ多すぎて草。

    Raspberry Pi がいいね。