Skip to main content

Centre

License: MIT PyPI version Python Versions

Centre is your window position manager.

Take control of your windows by choosing where they appear, how they’re arranged, and what size they should be.

Consistency is centre's goal.

Preview

https://github.com/user-attachments/assets/d088a951-8c6b-4731-8228-80b063f1a6e5

What Centre Tries to Achieve

Centre was built for users who want consistent window placement across desktop sessions.

Requirements

  • Windows
  • Python 3.10 or newer

Install

pip install centre

Update

pip install -U centre

Start Centre Automatically

To do that, create a Windows Task Scheduler task.

Run the following command as Administrator in PowerShell/cmd to create a Task in Windows Task Scheduler.

schtasks /Create /TN "centre" /SC ONLOGON /TR "centre -s" /RL LIMITED /F

Usage

After your window configuration is ready, start the listener:

centre -s

Single-Instance Listener

Centre allows one centre --start listener per Windows login session. If a listener is already running, another start attempt prints Centre already running and exits.

The other CLI commands remain available while the listener is running.

Stopping Centre

When Centre is running interactively in a terminal, press Ctrl+C to stop it. Centre will remove its keyboard hooks and stop its configuration observer before exiting.

The CLI

The action flags are mutually exclusive, so use one action per invocation.

Command Description
centre -s, --start Start the listener.
centre -l, --list Print window titles, sizes, and positions as formatted JSON.
centre -c, --read-config Print the loaded and validated configuration.
centre -v, --version Print the installed Centre version.
centre -h, --help Show the available CLI options.

Automatic Configuration Reload

While Centre is running, it watches config.json for changes. Saving a valid change reloads presets, ignored applications, logging settings, and action-sound preferences without restarting the process.

Keyboard shortcuts are registered when the listener starts. Changing a shortcut in bindings or wm.presets requires you to stop and restart Centre before the new shortcut is used. Setting wm.enabled to false stops registered Focus Window actions immediately; enabling it or adding a Focus Window shortcut requires a restart so the keyboard hook can be registered.

If config.json is invalid at startup, Centre reports the problem and exits without starting the listener. If a saved configuration becomes invalid while Centre is running, Centre performs an orderly shutdown. Correct config.json, then run centre --start again.

Window Configuration (config.json)

Your config will be created at the first startup in:

CMD

%USERPROFILE%\.centre\config.json

PowerShell

$env:USERPROFILE\.centre\config.json

The default config includes these values:

  • The resolution key is based on your display resolution.
{
    "logging": false,
    "play_sound": {
        "center": false,
        "capture": false,
        "ignore": false
    },
    "predefined_keybindings": {
        "enabled": true,
        "bindings": {
            "center": "ctrl+alt+d",
            "minimize": "ctrl+alt+m",
            "capture": "ctrl+alt+p",
            "ignore_preset": "ctrl+alt+i",
            "center_all": "ctrl+alt+a"
        }
    },
    "wm": {
        "enabled": false,
        "target_preset": "",
        "presets": []
    },
    "presets": {
        "1920x1080": {}
    },
    "ignored_presets": []
}

Configuration Validation and Migration

Centre validates the complete configuration, including window presets, predefined keyboard shortcuts, Focus Window hotkey syntax, and action-sound preferences. Unknown configuration fields, shortcut names, and preset properties are rejected.

When a valid configuration is missing fields that have defaults, Centre adds those defaults and writes the migrated configuration back to config.json.

The listener requires predefined_keybindings.enabled to be true. If it is false, centre --start exits instead of continuing without keyboard shortcuts.

Logging

File logging is disabled by default. To enable it, set logging to true in config.json:

{
  "logging": true
}

When logging is enabled, Centre creates or appends to:

%USERPROFILE%\.centre\centre.log

While Centre is running, saving a valid configuration change applies the new logging setting without requiring a restart. Changing logging to false closes the file handler and stops new log entries from being written.

Log entries include a timestamp, severity level, and message:

[2026-07-27 12:34:56,789] INFO - Centering NOTEPAD

Centre logs window-management activity and errors. Entries may contain normalized executable names and captured preset details. The log file is append-only and is not automatically rotated or deleted.

Action Sounds

Action sounds are disabled by default. Enable only the confirmations you want under play_sound in config.json:

{
    "play_sound": {
        "center": true,
        "capture": true,
        "ignore": true
    }
}

The center setting applies to both the active-window Center action and Center All. The capture and ignore settings control their corresponding actions. Centre plays a sound only after an action succeeds; pressing Ignore for an application that is already ignored does not play another confirmation.

Saving valid action-sound changes applies them immediately while the listener is running. No restart is required.

Focus Window Shortcuts

Focus Window assigns a shortcut directly to an application WindowPreset. It is disabled by default and does not launch applications that are not already open.

The configured executable must exactly match a key in the selected target layout. Captured WindowPreset keys are uppercase and omit .exe, such as WINDOWSTERMINAL.

{
    "wm": {
        "enabled": true,
        "target_preset": "1920x1080",
        "presets": [
            {
                "center_on_focus": true,
                "executable": "WINDOWSTERMINAL",
                "hotkey": "ctrl+alt+1",
                "title_contains": "PowerShell"
            }
        ]
    }
}
  • enabled controls the complete Focus Window feature and defaults to false.
  • target_preset selects the layout containing the required WindowPresets. If exactly one layout exists and this value is empty, Centre selects and saves it automatically. With multiple layouts, configure the target explicitly.
  • executable must exactly match a WindowPreset key under target_preset.
  • hotkey is validated when the configuration loads.
  • title_contains optionally narrows matches using a case-insensitive title substring. Use null when the executable match is sufficient.
  • center_on_focus defaults to false. When true, Centre focuses the window and then applies its position and size from the target layout.

If multiple visible windows match, Centre keeps the active match when possible; otherwise it focuses the first match returned by Windows. Minimized matches are restored before activation.

Focus Window shortcuts must be unique. If any two Focus Window shortcuts are equivalent, or one conflicts with a predefined Centre shortcut, none of the Focus Window shortcuts are registered. Invalid hotkey names make the configuration invalid.

Changing a Focus Window hotkey, executable, or title filter requires a listener restart. Layout positions and target_preset are read from the current valid configuration when a registered shortcut runs. Disabling wm or removing its WindowPreset prevents a previously registered callback from acting.


Window presets should be placed inside the "presets" object in config.json.

Capture a Window

Focus the window you want to capture and press ctrl+alt+p. Centre stores its current position and size under the current display resolution.

Captured windows are identified by their executable name without the .exe extension. The name is normalized to uppercase, for example:

  • notepad++.exe becomes NOTEPAD++
  • WindowsTerminal.exe becomes WINDOWSTERMINAL

Executable names remain stable when an application changes its window title, such as when switching tabs in Notepad++.

Capturing the same application again updates its existing preset.

Ignore a Window Preset

Focus the window you want Centre to ignore and press ctrl+alt+i. Centre adds the active application's executable name to ignored_presets.

Ignored applications are skipped when you press the center shortcut. Centre will not apply the application's custom preset or Default_Position.

To allow Centre to manage the application again, remove its executable name from ignored_presets in config.json.

Center All Configured Windows

Press ctrl+alt+a to apply presets to all currently open windows that have a matching entry under the current display resolution.

Centre skips open windows that do not have a named preset or whose executable appears in ignored_presets. Default_Position is only used by the regular center shortcut for the active window.


A window preset should look like this:

{
    "NOTEPAD++": {
        "LEFT": 224,
        "TOP": 168,
        "SIZE_X": 1473,
        "SIZE_Y": 697
    },
    "Default_Position": {
        "LEFT": 25,
        "TOP": 34,
        "SIZE_X": 1860,
        "SIZE_Y": 980
    }
}
  • Be sure to add Default_Position in your presets under the generated default resolution. When Centre does not find the active window in your presets, it uses Default_Position as the fallback size and position.

  • Default_Position is useful when you have a list of apps that you have set a custom position for, but intend to keep all other apps in one specific location.

Default Shortcuts

Action Shortcut Description
Center ctrl+alt+d Apply the active application's preset or Default_Position.
Minimize ctrl+alt+m Minimize the active window.
Capture ctrl+alt+p Save or update the active application's position and size.
Ignore ctrl+alt+i Add the active application to ignored_presets.
Center All ctrl+alt+a Apply presets to all matching open windows.

Focus Window shortcuts have no defaults; define them individually under wm.presets.

Your final config should look something like this:

{
    "logging": true,
    "play_sound": {
        "center": true,
        "capture": true,
        "ignore": true
    },
    "predefined_keybindings": {
        "enabled": true,
        "bindings": {
            "center": "ctrl+alt+d",
            "minimize": "ctrl+alt+m",
            "capture": "ctrl+alt+p",
            "ignore_preset": "ctrl+alt+i",
            "center_all": "ctrl+alt+a"
        }
    },
    "wm": {
        "enabled": true,
        "target_preset": "1920x1080",
        "presets": [
            {
                "center_on_focus": true,
                "executable": "WINDOWSTERMINAL",
                "hotkey": "ctrl+alt+1",
                "title_contains": null
            }
        ]
    },
    "presets": {
        "1920x1080": {
          "WINDOWSTERMINAL": {
                "LEFT": 217,
                "TOP": 169,
                "SIZE_X": 1486,
                "SIZE_Y": 695
            },
            "NOTEPAD++": {
                "LEFT": -5,
                "TOP": 374,
                "SIZE_X": 1930,
                "SIZE_Y": 664
            },
            "Default_Position": {
                "LEFT": 25,
                "TOP": 34,
                "SIZE_X": 1860,
                "SIZE_Y": 980
            }
        }
    },
    "ignored_presets": [
        "EXPLORER"
    ]
}

Changelog

See CHANGELOG.md for release history.

License

This project is licensed under the MIT License. See LICENSE for details.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

centre-0.10.0.tar.gz (62.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

centre-0.10.0-py3-none-any.whl (64.0 kB view details)

Uploaded Python 3

File details

Details for the file centre-0.10.0.tar.gz.

File metadata

  • Download URL: centre-0.10.0.tar.gz
  • Upload date:
  • Size: 62.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for centre-0.10.0.tar.gz
Algorithm Hash digest
SHA256 4fc8ac0b0a2055e3505a05d7fa1050f35290245a989b09a6ec3081183162d08e
MD5 3a87e229483c5b1f2a81dcd33d5a9a8b
BLAKE2b-256 30539ded1eb70bd87f2f92602366e6669164460418febf76e5a8a20f8e6880a5

See more details on using hashes here.

File details

Details for the file centre-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: centre-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 64.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for centre-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 05bce5185e586aaf9080ad98b6713fcdac4d3fad04a903b43e07e3fcc7871a5b
MD5 05d53b40ac955a2b17e97882e1d17822
BLAKE2b-256 2d6fab53dd69fa86607d86917dc96a434cbb924d1983615d2883ab2886497ef0

See more details on using hashes here.

Release history Release notifications | RSS feed

0.10.3

2 files

0.10.2

2 files

0.10.1

2 files

This release

0.10.0 This release

2 files

0.9.1

2 files

0.9.0

2 files

0.8.4

2 files

0.8.3

2 files

0.8.2

2 files

0.7.1

2 files

0.7.0

2 files

0.4.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page