投稿者: the 猫

  • マウスジェスチャー/タスクビュー

    ひと工夫したので貼っておこー

    やりたいこと

    マウスジェスチャーで仮想デスクトップを切り替えたい。

    やったこと

    1. 以下のサイトからMouseGestureL.ahkをダウンロードします。

    MouseGestureL.ahk
    https://hp.vector.co.jp/authors/VA018351/mglahk.html

    「MouseGestureL.ahk Ver. 1.40 (2022/06/22)」リンクから「MGLahk140.zip」をダウンロードする。

    2. ダウンロードした「MGLahk140.zip」を展開し、以下に格納します。

    C:\tool\MGLahk140
    └─Setup.vbs
    └─ ・・・

    ※格納場所任意。

    3. 「Setup.vbs」を実行し、「MouseGestureL.exe」を生成します。

    C:\tool\MGLahk140
    └─Setup.vbs
    └─ ・・・
    └─ MouseGestureL.exe

    4. 生成した「MouseGestureL.exe」を実行します。
    →タスクトレイに「MouseGestureL.ahk」が常駐します。

    5. 「MouseGestureL.ahk」を右クリックし、「設定」を選択します。

    6. マウスジェスチャーに「タスクビュー」のキーボード操作を割り当てます。

    例:RB←

    アクションスクリプト

    ;左デスクトップに移動
    SendLevel 1
    ctrl := GetKeyState("Ctrl")
    shift := GetKeyState("Shift")
    win := GetKeyState("LWin")
    if (ctrl and shift and win) {
        Send,^+#{Left}
    } else if (ctrl and shift) {
        Send,^+{Left}
    } else if (ctrl and win) {
        Send,^#{Left}
    } else {
        Send,^#{Right}
    }

    RB← + Ctrl + Shift + Win:アクティブ画面を左デスクトップに移動して、左デスクトップに移動
    RB← + Ctrl + Shift:アクティブ画面を左デスクトップに移動
    RB← + Ctrl + Win:左デスクトップに移動

    RB←:右デスクトップに移動

    例:RB→

    アクションスクリプト

    ;右デスクトップに移動
    SendLevel 1
    ctrl := GetKeyState("Ctrl")
    shift := GetKeyState("Shift")
    win := GetKeyState("LWin")
    if (ctrl and shift and win) {
        Send,^+#{Right}
    } else if (ctrl and shift) {
        Send,^+{Right}
    } else if (ctrl and win) {
        Send,^#{Right}
    } else {
        Send,^#{Left}
    }

    RB→ + Ctrl + Shift + Win:アクティブ画面を右デスクトップに移動して、右デスクトップに移動
    RB→ + Ctrl + Shift:アクティブ画面を右デスクトップに移動
    RB→ + Ctrl + Win:右デスクトップに移動

    RB→:左デスクトップに移動

    注意事項

    上記のアクションスクリプトをそのままコピペする場合は読み飛ばしてください。

    MouseGestureL.ahk も AutoHotkey で作成されています。

    AutoHotkey 1.0:ASCII版
    AutoHotkey 1.1:Unicode版
    AutoHotkey 2.0:下位互換なし、レガシーシンタックス廃止版。

    MouseGestureL.ahk は、AutoHotkey 1.1 で、「タスクビュー」は、AutoHotkey 2.0 で実行されています。

    タスクビュー
    https://猫猫猫.tokyo/?p=1262

    通常、AutoHotkeyで生成したキーストロークは、AutoHotkeyでは処理されません。AutoHotkeyでAutoHotkeyのホットキーをトリガーするために、アクションスクリプトでSendする前にSendLevelの指定が必要となります。

    SendLevel 1

    SendLevel
    https://ahkscript.github.io/ja/docs/v2/lib/SendLevel.htm

    下位互換はないですが、SendLevel、InputLevelまわりは互換ありです。

    7. 「軌跡・ログ」タブで「ジェスチャーの軌跡を表示する」にチェックする。(任意)

    8. 「その他」タブで「スタートアップに登録」する。管理者権限は不要です。(任意)

    9. 「OK」ボタンをクリックする。

  • タスクビュー

    書き直したやつも貼っておこー

    https://猫猫猫.tokyo/?p=1259

    機能追加

    Ctrl + Win + F1~F6キー:デスクトップ切り替え
    Ctrl + Shift + F1~F6キー:アクティブ画面を指定のデスクトップに移動*
    Ctrl + Shift + Win + F1~F6キー:アクティブ画面を指定のデスクトップに移動してデスクトップも移動*
    Ctrl + Win + 左右キー:デスクトップ1と6を左右キーで移動*
    Ctrl + Shift + 左右キー:アクティブ画面を隣のデスクトップに移動*
    Ctrl + Shift + Win + 左右キー:アクティブ画面を隣のデスクトップに移動してデスクトップも移動*

    *:機能追加

    もうぐちゃぐちゃ。こんなの覚えてられん。これを覚えて使おうとする人おる?環境によっては、Ctrl + Shift + 左右キーあたりは他のソフトのホットキーと被るかもしれないので人によっては使えないのだろうなぁとは分かりつつも致し方なし。

    作ったもの

    taskview_ext_20240615.zip

    「タスクビュー」のソースファイル

    #Requires AutoHotkey v2.0+
    #SingleInstance Force
    
    ; ----------------------------------------
    ; define
    ; ----------------------------------------
    
    PREV := "Prev"
    NEXT := "Next"
    OK := True
    NG := False
    VDA_PATH := "C:\tool\taskview\VirtualDesktopAccessor.dll"
    hVirtualDesktopAccessor := DllCall("LoadLibrary", "Str", VDA_PATH, "Ptr")
    GetDesktopCountProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GetDesktopCount", "Ptr")
    GoToDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GoToDesktopNumber", "Ptr")
    GetCurrentDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GetCurrentDesktopNumber", "Ptr")
    MoveWindowToDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "MoveWindowToDesktopNumber", "Ptr")
    
    ; ----------------------------------------
    ; helper function
    ; ----------------------------------------
    
    GetDesktopCount() {
        count := DllCall(GetDesktopCountProc, "Int")
        return count
    }
    
    GoToDesktopNumber(number) {
        if (number > GetDesktopCount())
            return
        ; Win + 左右キーのアニメーションに操作感を合わせるため、
        ; 移動前後に0.5秒の待ち時間を設定している(機能的には不要)
        Sleep 500
        DllCall(GoToDesktopNumberProc, "Int", number - 1)
        Sleep 500
    }
    
    GetCurrentDesktopNumber() {
        number := DllCall(GetCurrentDesktopNumberProc, "Int")
        number++ ; デスクトップ番号を1オリジンで指定するため + 1
        return number
    }
    
    MoveWindowToDesktopNumber(number) {
        WinWaitActive WinExist("A")
        retry := 0
        Loop
            try {
                activeHwnd := WinGetID("A")
                number-- ; dllには0オリジンで渡すため - 1
                DllCall(MoveWindowToDesktopNumberProc, "Ptr", activeHwnd, "Int", number, "Int")
                result := OK
                break
            } catch {
                Sleep 250
                result := NG
                retry++
            }
        until retry == 10
    
        return result
    }
    
    moveWindow(desktop) {
        current := GetCurrentDesktopNumber()
        max := GetDesktopCount()
        if (desktop == PREV) {
            if (current == 1) {
                result := MoveWindowToDesktopNumber(max)
            } else {
                result := MoveWindowToDesktopNumber(current - 1)
            }
        } else if (desktop == NEXT) {
            if (current == max) {
                result := MoveWindowToDesktopNumber(1)
            } else {
                result := MoveWindowToDesktopNumber(current + 1)
            }
        } else {
            result := MoveWindowToDesktopNumber(desktop)
        }
        return result
    }
    
    moveDesktop(desktop) {
        current := GetCurrentDesktopNumber()
        max := GetDesktopCount()
        if (desktop == PREV) {
            if (current == 1) {
                GoToDesktopNumber(max)
            } else {
                Send "^#{Left}"
            }
            KeyWait "Left"
        } else if (desktop == NEXT) {
            if (current == max) {
                GoToDesktopNumber(1)
            } else {
                Send "^#{Right}"
            }
            KeyWait "Right"
        } else {
            GoToDesktopNumber(desktop)
        }
    }
    
    moveWindowMoveDesktop(desktop) {
        result := moveWindow(desktop)
        if (result == OK)
            moveDesktop(desktop)
    }
    
    ; ----------------------------------------
    ; main
    ; ----------------------------------------
    
    ; アクティブ画面移動
    ^+Left:: moveWindow(PREV)
    ^+Right:: moveWindow(NEXT)
    ^+F1:: moveWindow(1)
    ^+F2:: moveWindow(2)
    ^+F3:: moveWindow(3)
    ^+F4:: moveWindow(4)
    ^+F5:: moveWindow(5)
    ^+F6:: moveWindow(6)
    
    ; デスクトップ移動
    ^#Left:: moveDesktop(PREV)
    ^#Right:: moveDesktop(NEXT)
    ^#F1:: moveDesktop(1)
    ^#F2:: moveDesktop(2)
    ^#F3:: moveDesktop(3)
    ^#F4:: moveDesktop(4)
    ^#F5:: moveDesktop(5)
    ^#F6:: moveDesktop(6)
    
    ; アクティブ画面/デスクトップ移動
    ^#+Left:: moveWindowMoveDesktop(PREV)
    ^#+Right:: moveWindowMoveDesktop(NEXT)
    ^#+F1:: moveWindowMoveDesktop(1)
    ^#+F2:: moveWindowMoveDesktop(2)
    ^#+F3:: moveWindowMoveDesktop(3)
    ^#+F4:: moveWindowMoveDesktop(4)
    ^#+F5:: moveWindowMoveDesktop(5)
    ^#+F6:: moveWindowMoveDesktop(6)

    インストール手順

    1.「taskview_ext_20240615.zip」ファイルを展開し、C:ドライブの直下に格納します。

    C:\tool\taskview
    └─taskview_ext.ahk

    ※格納場所固定。変更する場合は、ソース内のパス「VDA_PATH := “C:\tool\taskview\VirtualDesktopAccessor.dll”」を変更する必要がある。

    2. 以下のサイトからDLLファイルをダウンロードします。

    VirtualDesktopAccessor.dll
    https://github.com/Ciantic/VirtualDesktopAccessor

    リリースページの「VirtualDesktopAccessor.dll」をダウンロードする。
    https://github.com/Ciantic/VirtualDesktopAccessor/releases

    3. ダウンロードしたDLLファイルを同じフォルダに格納します。

    C:\tool\taskview
    ├─taskview_ext.ahk
    └─VirtualDesktopAccessor.dll

    4. 「taskview_ext.ahk」を実行します。

    アンインストール

    フォルダごと削除するだけ。

    動作確認環境

    • Windows 11
    • Autohotkey V2
    • ディスプレイ:1枚だけ

    既知の問題点

    デスクトップ1と6を左右キーで移動するときにアニメーションがない。

    その他

    IVirtualDesktopManager インターフェイス (shobjidl_core.h)
    https://learn.microsoft.com/ja-jp/windows/win32/api/shobjidl_core/nn-shobjidl_core-ivirtualdesktopmanager

    • IVirtualDesktopManager::GetWindowDesktopId
      指定された最上位ウィンドウをホストしている仮想デスクトップの識別子を取得します。
    • IVirtualDesktopManager::IsWindowOnCurrentVirtualDesktop
      指定されたウィンドウが現在アクティブな仮想デスクトップ上にあるかどうかを示します。
    • IVirtualDesktopManager::MoveWindowToDesktop
      指定した仮想デスクトップにウィンドウを移動します。

    「VirtualDesktopAccessor.dll」には、このインターフェイスでは実現できない機能が含まれているのなんで?どうやって作ってるんだろう?仮想デスクトップ周りって他にも公開情報あるのか?ググったけど見つからなかったので継続調査中・・・

    ソースファイル、助かるーけど、COM周り、シェル周り、相変わらず難しい。Rustで書かれているので、これを機にRustも触ってみようかとインストールしてドキュメントをパラパラした。

    ヒープメモリを使用する変数に所有権あるらしいな。所有権ムーブしたり変数の変更に制限をかけることで二重開放などなどが起こりえない言語仕様になってるとか、なっていないとか?メモリの管理というか、状態の管理で良くバグるのあるある。おかしな動作がパソコン再起動したら直るってそういうことですよねえ。

    所有権を理解する
    https://doc.rust-jp.rs/book-ja/ch04-00-understanding-ownership.html

    25年、29年?何も変わらないWindows のデスクトップアプリの内部、一度公開されたインターフェイスは変わらないですねえ。

    Win32 API のプログラミング リファレンス
    https://learn.microsoft.com/ja-jp/windows/win32/api

    いにしえのソースやドキュメントを見ながら酒飲んでるw 🥴

    時には昔の話を

    https://www.youtube.com/results?search_query=時には昔の話を

  • タスクビュー

    おもちゃツールを作ったので貼っておこー

    Windows標準機能

    • 「Win」+「Tab」キーで表示
    • 「Ctrl」+「Win」+「左右」キーで隣のデスクトップに移動

    やりたいこと

    「Ctrl」+「Win」+「F1~F6」キーで離れたデスクトップに直接移動

    作ったもの

    taskview_ext_20240608.zip

    「タスクビュー」のソースファイル

    ; ----------------------------------------
    ;  prerequisites
    ;  display: 1 monitor only
    ;  os: Windows 11
    ;  virtual desktop: 1 - 6
    ; ----------------------------------------
    WINCOUNT := 4
    switchDesktop(desktopId) {
        winIds := WinGetList()
        Send "#{Tab}"
        WinWaitActive ("ahk_class XamlExplorerHostIslandWindow")
        Sleep 500
        count := 0
        Loop  {
            if count == 0 {
                if winIds.Length > WINCOUNT
                    Send "{Tab}"
            } else {
                Send "{Right}"
            }
            count++
        } Until count == desktopId
        Send "{Enter}"
    }   
    ^#F1::switchDesktop(1)
    ^#F2::switchDesktop(2)
    ^#F3::switchDesktop(3)
    ^#F4::switchDesktop(4)
    ^#F5::switchDesktop(5)
    ^#F6::switchDesktop(6)

    「Ctrl」+「Win」+「F1~F6」キーでデスクトップ切り替え

    前提

    事前に仮想デスクトップが6つ作成されていることを想定している。

    動作確認環境

    • Windows 11
    • Autohotkey V2
    • ディスプレイ:1枚だけ

    機能追加予定

    ディスプレイが2枚以上あると正しく動かないことが分かっている。「Win」+「Tab」キーを押下して、単純にTabキーを送り付けて最後にEnterキーを叩いているだけなのでディスプレイの枚数が増えると必ずバグる。

    Send “{Tab}” を Send “{Tab x}” にしてTabキーの回数を修正すれば動くのだろうけど、そもそもマルチディスプレイ環境であれば、タスクビューでデスクトップを切り替えるような使い方はしないか。

    あとは、実行時にタスクビューの画面が表示されてしまい宜しくない。

    余談

    Linuxの仮想コンソールは、「Ctrl」+「Alt」+「F1~F6」キーで切り替えていた。昔のLinuxのGUIは、すぐに固まってしまい仮想コンソールからプロセスを落とすことがよくあった。

    Linuxの仮想コンソールに倣い6つの仮想デスクトップを想定している。

  • キーのリマッピング for macOS

    Karabiner-Elementsの定義ファイルをバックアップしたので貼っておこー 

    Ctrl + 矢印キー:矢印キー5回連打*
    Ctrl + iキー :上キー*
    Ctrl + kキー :下キー*
    Ctrl + jキー :左キー*
    Ctrl + lキー :右キー*
    Ctrl + uキー :Homeキー*
    Ctrl + oキー :Endキー*
    Ctrl + hキー :BackSpace*
    Alt + 1キー :アクティブ画面左寄せ
    Alt + 2キー :アクティブ画面中央寄せ
    Alt + 3キー :アクティブ画面右寄せ
    Alt + qキー :アクティブ画面左上寄せ
    Alt + aキー :アクティブ画面左下寄せ
    Alt + wキー :アクティブ画面右上寄せ
    Alt + sキー :アクティブ画面右下寄せ
    Ctrl + F10 :音量ミュート
    Ctrl + F11 :音量Down
    Ctrl + F12 :音量UP

    *:Karabinerで定義

    Karabiner-Elements

    https://karabiner-elements.pqrs.org

    Karabiner-Elements Settings画面

    Exchange control + arrow key to 5 arrow keys
    {
        "description": "Exchange control + arrow key to 5 arrow keys",
        "manipulators": [
            {
                "from": {
                    "key_code": "right_arrow",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "left_arrow",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "up_arrow",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "down_arrow",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    },
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            }
        ]
    }
    Exchange control + h key to backspace key
    {
        "description": "Exchange control + h key to backspace key",
        "manipulators": [
            {
                "from": {
                    "key_code": "h",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "delete_or_backspace",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            }
        ]
    }
    Exchange control + ikjl key to arrow key
    {
        "description": "Exchange control + ikjl key to arrow key",
        "manipulators": [
            {
                "from": {
                    "key_code": "i",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "up_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "k",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "down_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "j",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "left_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "l",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "right_arrow",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            }
        ]
    }
    Exchange control + uo key to home end key
    {
        "description": "Exchange control + uo key to home end key",
        "manipulators": [
            {
                "from": {
                    "key_code": "u",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "home",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            },
            {
                "from": {
                    "key_code": "o",
                    "modifiers": {
                        "mandatory": [
                            "control"
                        ],
                        "optional": [
                            "any"
                        ]
                    }
                },
                "to": [
                    {
                        "key_code": "end",
                        "modifiers": []
                    }
                ],
                "type": "basic"
            }
        ]
    }

    Rectangle

    https://rectangleapp.com

    アクティブ画面の移動は、Rectangleを使っていた。

    Hammerspoon

    https://www.hammerspoon.org

    Hammerspoonでスクリプトを書くとAutoHotkeyと同じようなことができる。知らんけど。

  • MacBook Pro 2016

    https://support.apple.com/ja-jp/111999

    だとよ。そろそろ壊れるかもしれない。

    • MacBook Pro 2016
    • Thinkpad E450

    ここ何年かはこの2台でMacBook Proをメインで使ってきたけどトリグキーに移行する。トリグキーはまだ2か月ぐらいで長期間使えるかが怪しい。そして8年前のMacBook Proの方が未だにトリグキーより速い。

    • Apache 2.4
    • MySQL 8.4
    • Perl 5.38
    • Movable Type 8.0

    上記の構成でブログサイトを再構築するとMacBookが18分で完了するのにトリグキーは32分かかる。同じサイト資産を使って測定したのでトリグキーが遅いことは確定。何が足を引っ張っているのか分からないけど3万円だけのことはある。( ー`дー´)キリッ

    最近の速いMacBookが欲しいなぁとは思うものの必要かというと必要はなくて遅いパソコンで問題ない用途でしか使用していない。YouTubeやNetflixの視聴がメインだからなあ…

  • お引越しします!?

    🙀