Skip to content

Develop - #50

Open
KonstantinMerkel wants to merge 90 commits into
masterfrom
develop
Open

KonstantinMerkel wants to merge 90 commits into
masterfrom
develop

Conversation

@KonstantinMerkel

Copy link
Copy Markdown
Owner

Next big version upgrade.

Test phase started...

KonstantinMerkel and others added 30 commits June 19, 2026 17:29
Moved architecture.md, layouts.md, vision.md to docs/
Added Issues and Feature Requests to CONTRIBUTING.md
Restructured CONTRIBUTING.md topics to follow the typical development process
Added a Summary, Customization Information to README.md and restructured the file

---------

Co-authored-by: Alexander Pechmann <alexander.pechmann@hm.edu>
Co-authored-by: Konstantin Merkel <konstantin.merkel@tutanota.de>
#8)

* refactor(keybindings): transition to native Mutter intercept and SRP architecture

* chore: update docs acccordingly

* feat: implement dynamic schema shadowing for custom keybindings

* docs: add dynamic schema shadowing architecture documentation
…rst fully working version

- Added cross-monitor dragging with dynamic visual N+1 and N-1 matrix previews
- Introduced 'Monitor Transition Behavior' settings ('Escalate' vs 'Swap')
- Implemented floating fallback when attempting to drag over a monitor at maximum layout capacity
- Resolved cross-monitor preview bugs by cleanly reverting both source and target tracker geometries
- Prevented drag-and-drop desync bugs during rapid movements by calculating monitor indices using absolute pointer geometry instead of global.display.get_current_monitor()
- Updated keybinding logic and restored missing dragging indicator styles
- Extensive unit tests covering cross-monitor transitions and regressions
Replace the controller-centric implementation with three layers:

- lib/domain: pure tiling state (TilingState, slot lists per workspace
  and monitor, immutable window records), layout model, topology,
  entry-slot capacity rule, override and hotplug policies
- lib/app: Engine as the only writer of the state, Reconciler as the
  only issuer of window commands (frame-synced, compares intended
  state with Mutter's facts), DragSession building a preview state
- lib/shell: thin adapters for Mutter signals, windows, monitors,
  GSettings, keybindings and the drag indicator

Behaviour: windows open directly in their tile, overflow windows float
and are promoted when a slot frees up, external moves and resizes are
reverted, evacuated windows return only to the same physical monitor
(EDID), state survives the lock screen (unlock-dialog session mode),
an invalid layout JSON suspends tiling without losing state.

Supported GNOME Shell versions are 49 and 50. The swap transition
setting and port-monitor shortcuts are removed, prefs-only modules
move to prefs/, the JSON editor validates before saving and the
"Moving to Workspace" shortcut group is dropped from the preferences.

AGENTS.md is no longer tracked.
ESLint enforces layer boundaries (domain and app free of GNOME imports,
inward-only dependencies, prefs limited to domain and utils) and the
extensions.gnome.org review guidelines (no Gtk in the Shell process, no
Shell libraries in prefs, no timeouts, no legacy imports, no feature
sniffing, no console). max-params and a local max-returns rule are
enabled at 4.

Fixes the findings: prefs calls the surface shortcut-inhibit API
directly and logs through Logger, onWindowMoved is split into helpers,
and ScreenEstate takes a rect object.
The drag keeps no copy of the tiling state. Its preview is the live state
plus the candidate drop, rebuilt when the pointer moves or the state's
version changes, so windows opening or closing during a drag are tiled
right away and the drop is checked against the live state: a target that
filled up mid-drag makes the dropped window floating.
A size change that answers a request settles it with the actual frame,
so the pass it used to schedule could never issue a command.
Slot geometry (cuts, resizing, splitting, colours) lives in prefs/draft.js
and is unit tested; prefs/preview.js keeps each UI piece with its own
handlers and shares one drawing routine across all canvases.

Percentage spinners and cut dragging edit the same draft and resync in
place, which removes the timeout debounce. Slots are coloured per id with
golden-angle hues and labelled by their own number. The cascading
deletion policy is unchanged.
toDraft rounds slot edges instead of sizes, so shared edges stay shared
and dragged cuts cannot produce overlaps or gaps. A draft whose layout
was removed by a cascading delete is dropped, and adding or editing
another layout is unavailable while a draft is open.

Split Largest is disabled when no slot can be halved, the cursor follows
the pointer after a drag and on leave, a save rebuilds the page once, and
layouts are read from the parsed escalator.
Apps may maximize or fullscreen their tiled windows themselves depending
on a setting: never, only listed apps (popular browsers by default) or
all except listed apps (LibreOffice and OrcaSlicer by default). Other
apps are put back into their tile, as before.

A focus policy decides what happens to a maximized window when another
window of its layout gains focus or opens: keep it, unmaximize it, or
pass the maximization on. Except under keep, a layout holds one
maximized window at a time.

Dropping a dragged window on the top screen edge maximizes it in its
tile, Super+Down only ends a maximization, and the maximize button can
be hidden from all title bars through button-layout, with the original
layout saved before it is changed.

The override rules live in lib/domain/policies/override/ (toggle,
self-maximize, focus); preferences get a Maximizing page.
A client constrains only the size of a tile. When the answer to a
request arrives at another position, as when an unmaximize races the
request in Mutter, the frame is requested once more; a repeat that lands
elsewhere again is left alone.
A window that cannot be resized reported its current size as its size
limits, which is 0x0 before it has a frame; clampToLimits then shrank
the tile request to an empty frame. Limits of zero or less now count
as unknown, and fixed-size windows report limits only once they have
a frame.
A new hotplug-policy setting (Monitors page) chooses between
restore-by-monitor, the previous behaviour, and follow-primary: the
primary monitor's windows move to whichever monitor becomes primary,
and that monitor's own windows are evacuated until it is secondary
again. A primary changed in the display settings counts as a hotplug.
prefs.js only composes the window now. General, Keyboard Shortcuts,
Maximizing, Monitors and the layout pages each live in prefs/, and the
shared choice row moves to prefs/rows.js.
zip -r added to an existing extension.zip, so files deleted from the
tree (the whole pre-rewrite lib/) stayed in the package. pack now
removes the old archive first and leaves gschemas.compiled out: GNOME
44+ compiles the schema on install, and the review guidelines ask for
the XML only.
master holds the pre-rewrite architecture; every patch on it is already
in develop (git cherry finds none missing). develop's tree is kept as is,
so the release PR into master merges without conflicts.
Nothing is translated, and the review guidelines ask for no
unnecessary keys in metadata.json.
The General and Keyboard Shortcuts pages never disconnected their
settings listeners. The preferences process outlives its window, so a
later settings change ran the handlers on disposed widgets. The
Maximizing page's disconnect-on-destroy pattern moves to
pageListener() in prefs/rows.js and is used by all three pages.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants