Acknowledgement: The original idea and the first implementation of gTile was developed by vibou with the help from multiple contributors. gTile is now a community supported project and licensed under the GPL v2+.
The preferred installation is through Gnome Extensions.
Alternatively, the most recent stable version may also be downloaded as a distributable archive (gtile.dist.tgz) through the GitHub releases page.
# Replace `VERSION` with the most recent release.
wget https://github.com/gTile/gTile/releases/download/VERSION/gtile.dist.tgz
# The `-f` flag will perform an upgrade, if necessary.
gnome-extensions install -f ~/Downloads/gtile.dist.tgz
# The changes only become effective once the shell session was restarted.
# In case the extension was installed for the first time it must be enabled afterwards.
gnome-extensions enable gTile@vibou
Alternatively, you can build and install the latest version from GitHub. Make sure to have a working git and npm installation.
git clone https://github.com/gTile/gTile.git
cd gTile
npm ci
npm run build:dist
npm run install:extension
After restarting your Gnome shell session you can enable the extension via:
gnome-extensions enable gTile@vibou
The extension can be configured through a dedicated preferences dialog. You can open the extension settings either through the Gnome Extensions app, or by executing the following command in your terminal:
gnome-extensions prefs gTile@vibou
Note that most settings are applied either immediately or after toggling the gTile overlay. There is one exception though. When the theme is changed, the extension needs to be disabled and then enabled again for the new theme to become effective.
gTile can be used either through its graphical user interface ("overlay") or exclusively with the keyboard via shortcuts.
<Super>+<Enter> (default)Option A: Mouse usage:
Option B: Keyboard usage:
Space to change the grid scheme [optional]Enter and the window will resizeEscape to cancel resizeOption C: Using the keyboard with configured presets:
Resize presets are defined in the preferences window (Resize Presets tab).
3x3 1:1 1:1, 2:2 2:2 on the first press will put the window on the top left corner, on the second press - in the middle of the screen.Presets have a format of "[grid size] [top left coordinate]:[bottom right coordinate]".
3x3 1:1 1:1, 2:2 2:2 (when 2:2 2:2 is triggered, gTile will use 3x3 grid size).You can also resize windows using keyboard shortcuts directly.
There are 3 groups of pre-configured shortcuts, representing the following grid schemes:
Super+AltSuper+ControlSuper+ShiftThese "grid selectors" are then combined with a keypad number to define the window placement.
Default shortcuts for Super+Alt+[KP_1..KP_9]
| Shortcut | Description |
|---|---|
Super+Alt+KP_1 |
Bottom left quarter of screen |
Super+Alt+KP_2 |
Bottom half |
Super+Alt+KP_3 |
Bottom right quarter |
Super+Alt+KP_4 |
Center left |
Super+Alt+KP_5 |
Center |
Super+Alt+KP_6 |
Center right |
Super+Alt+KP_7 |
Top left quarter |
Super+Alt+KP_8 |
Top half |
Super+Alt+KP_9 |
Top right quarter |
Notes: 1. Preconfigured keyboard shortcuts are optimized for horizontal screens. 2. For cyclable presets, invoke the corresponding shortcut consecutively on a window to activate format variants.
You can do auto tiling for all windows on screen
Super+KP_Enter or clicking on gTile icon[1..9,0] (total 10 available) for vertical columns autotiling, or M for "main" autotiling.M multiple times to cycle through variants.The autotiling layouts can be customized through GridSpec, a tiny DSL used to describe complex grids. The following Wirth notation describes the syntax of GridSpec.
gridspec = [ ( colspec | rowspec ) ] .
colspec = "cols" "(" cellspec { "," cellspec } ")" .
rowspec = "rows" "(" cellspec { "," cellspec } ")" .
cellspec = <number> [ ( "d" | ":" ( colspec | rowspec ) ) ] .
Some examples of valid GridSpec definitions:
cols(1, 3, 1)rows(1, 1:cols(3,3,3), 1d)dynamic row, which affects how autotiling does place windows in it. Usually, autotiling assigns at most 1 window to each cell. Cells declared as dynamic may hold as many windows as necessary. Windows placed into a dynamic cell all get the same share of this cell. For instance, if 2 windows were to be placed in the dynamic cell above, they would each take 50% of the rows width.In general, the autotiling algorithm works as follows:
1. Given a GridSpec, find the largest non-dynamic cell (if there are multiple largest cells, the first one is used).
- Place the focused window inside it, if any.
2. For all (remaining) windows on the currently active monitor: Place each window in one of the (remaining) non-dynamic cells and make it take the full width and height of that cell.
3. If there are still more windows remaining that couldn't yet be placed in a cell: Find all dynamic cells in the grid and place the remaining windows inside them.
- Each window gets the same share of a dynamic cell (or its full size for a single window).
You can expand window - it will fill all available space up to borders with neighbors.
Default keyboard shortcut is <Alt><Ctrl>s
Autogrow works only when gTile window is activated
<Super>+<Enter><Alt><Ctrl>s. Your windows will snap to neighbors.EscapeBy default, windows snap seamlessly to one another. You can optionally configure an inset and window spacing to apply a margin between windows (aka spacing) or the screen edges (aka insets). The illustration below depicts how insets and margins are applied to the windows.
gTile is intended to supplement existing Gnome-shell keyboard shortcuts.
Here are some useful Gnome built-ins to keep in mind when configuring gTile:
| Shortcut | Description |
|---|---|
Super+Up |
Maximize |
Super+Down |
Un-Maximize (return to size and position previous to maximizing) |
Super+Left/Right |
left/right half of screen |
Shift+Super+Up/Down/Left/Right |
move window to adjacent monitor/workspace |
To build and develop the extension node, npm, git and a few standard GNU utilities are required. Check the scripts section of package.json to see which GNU utilities are used.
To get started, checkout the repository and install the required dependencies:
git clone https://github.com/gTile/gTile.git
cd gTile
npm ci
Testing changes can be tedious at times because an extension cannot be updated in-place. The Gnome shell session must be restarted in order for changes to take effect. In Wayland it is usually much easier to start a nested session instead. Check the GJS documentation on how to best debug extensions. Note that nested gnome sessions can take time to load and does not allow to test multi-screen setups. I personally found it most productive to have a second remote system which I used to continuously test the extension on. For this purpose I added a simple new script to package.json:
{
"scripts": {
"install:remote": "scp gtile.dist.tgz remotehost:~/Downloads && ssh remotehost gnome-extensions install -f ~/Downloads/gtile.dist.tgz",
}
}
Deploying a change is as simple as executing npm run build:dist && npm run install:remote and restart the Gnome session on the remote system. When developing locally use the npm run install:extension command instead.
Functional tests are written in TypeScript and must be transpiled via tsc before AVA can run the tests. The following command takes care of everything and is best be used to run the tests in a one-off fashion.
# For a one-off run of all tests
npm run test
When actively developing tests, it is more convinient (and also faster) to let tsc continuously transpile the tests and have them run by AVA.
# Let the TypeScript compiler watch for changes and auto-transpile files
npx tsc -w
# In a separate terminal: Run the AVA test runner in watch mode
npm run test -- --watch
Note: All tests are strictly kept in the test/ directory, in isolation to the src/ directory. Test files do not have a special naming convention such as a required .spec.ts suffix. Thus, keeping tests in a separate directory allows them to be transpiled on-demand when needed and avoids pollution of the redistributable build.
There are some domain-specific terms used throughout the entire code base. This table ought to be a glossary for these terms. Some of these may also translate 1:1 into a TypeScript interface. Check the src/types/ directory.
| Term | Meaning |
|---|---|
GridSpec |
A simple domain specific language (DSL) used to describe complex grids with weighted col and row sizes and the ability to have cols and rows span over |
$ claude mcp add gTile \
-- python -m otcore.mcp_server <graph>