keyhacでWindows7のエアロスナップをマネマネ。

Windows7から導入されたエアロスナップ。要は画面左・右半分の最大化がマウス操作で簡単に実行できる機能です。ご存知ない方はこの30秒の動画を見てください。すごく便利な機能なんですが、僕の普段使いのPCはXP。当然エアロスナップなんてありません。
だったらkeyhacの出番です。本家にない上半分・下半分も出来ちゃいます。ついでに移動、リサイズも紹介しときます。

■ コード

from keyhac import *

## 関数を返す関数にするデコレータ
def ret_func(func):
    import functools

    @functools.wraps(func)
    def _ret_func(*args, **kw):
        @functools.wraps(func)
        def __ret_func():
            return func(*args, **kw)
        return __ret_func
    return _ret_func

def configure(keymap):

    ## 10pixel単位のウインドウのリサイズ(最大最小のときは何もしない)
    #
    @ret_func
    def resize_window(direction):
        if not keymap.getTopLevelWindow().isMaximized():
            i = "LRUD".find(direction)
            dx, dy = ((-10, 0),  # L
                      (+10, 0),  # R
                      (0, -10),  # U
                      (0, +10)   # D
                     )[i]

            wnd = keymap.getTopLevelWindow()
            rect = list(wnd.getRect())
            rect[2] += dx
            rect[3] += dy
            wnd.setRect(rect)

    ## 10pixel単位のウインドウの移動(最大最小のときは何もしない)
    #
    @ret_func
    def move_window(direction):
        if not keymap.getTopLevelWindow().isMaximized():
            i = "LRUD".find(direction)
            dx, dy = ((-10, 0),  # L
                      (+10, 0),  # R
                      (0, -10),  # U
                      (0, +10)   # D
                     )[i]

            # keyhac_keymap.py 定義の関数を利用
            keymap.command_MoveWindow(dx, dy)()

    ## ウィンドウを画面端まで移動(最大最小のときは何もしない)
    #
    @ret_func
    def move_window_monitoredge(direction):
        if not keymap.getTopLevelWindow().isMaximized():
            i = "LURD".find(direction)
            # keyhac_keymap.py 定義の関数を利用
            keymap.command_MoveWindow_MonitorEdge(i)()

    ## 画面半分の切り替え(Windows7のエアロスナップ風)
    #
    @ret_func
    def toggle_aero_snap(direction):
        wnd = keymap.getTopLevelWindow()
        if wnd.isMaximized():
            # 元に戻す
            wnd.restore()
        else:
            # 最大化
            wnd.maximize()

            # ウィンドウのサイズを取得
            rect = list(wnd.getRect())

            # ウィンドウの幅/高さの半分
            width_50 = (rect[0] + rect[2]) / 2
            height50 = (rect[1] + rect[3]) / 2

            # 入力された方向に応じて対応する座標を幅/高さの半分で上書き
            i = "RDLU".find(direction)
            rect[i] = (width_50,  # R
                       height50,  # D
                       width_50,  # L
                       height50   # U
                      )[i]

            # ウィンドウの新しいサイズを反映
            wnd.setRect(rect)

    # どのウインドウにフォーカスがあっても効くキーマップ
    keymap_global = keymap.defineWindowKeymap()

    ## ウィンドウ移動系
    for arrow_key in ("Left", "Right", "Up", "Down"):
        c = arrow_key[:1]

        # Win+←→↑↓ : 10pixel単位のウインドウの移動
        keymap_global["W-" + arrow_key] = move_window(c)
        # Win+Ctrl+←→↑↓ : 画面の端まで移動
        keymap_global["W-C-" + arrow_key] = move_window_monitoredge(c)
        # Win+Shift+←→↑↓ : 10pixel単位のウインドウのリサイズ
        keymap_global["W-S-" + arrow_key] = resize_window(c)
        # Win+Alt+←→↑↓ : Windows7のエアロスナップ風
        keymap_global["W-A-" + arrow_key] = toggle_aero_snap(c)

■ 軽〜く説明

Win+←→↑↓ 10pixel単位のウインドウの移動
Win+Ctrl+←→↑↓ 画面の端まで移動
Win+Shift+←→↑↓ 10pixel単位のウインドウのリサイズ
Win+Alt+←→↑↓ Windows7のエアロスナップ風

■ 参考リンク