Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
AutotileEngine.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 fuddlesworth
2// SPDX-License-Identifier: LGPL-2.1-or-later
3//
4// FILE-SIZE EXCEPTION (sanctioned): AutotileEngine is one class — the tiling
5// engine's whole public and internal surface — and C++ cannot split a class
6// declaration across headers. The IMPLEMENTATION is already partitioned by
7// concern under src/autotileengine/; shrinking this header means extracting
8// collaborator classes (drag preview, script-state stash, per-screen config),
9// which is a deliberate refactor, not a mechanical file split. Same rationale
10// as plasmazoneseffect.h / daemon.h / windowtrackingadaptor.h.
11
12#pragma once
13
14#include <phosphortileengine_export.h>
24#include <QHash>
25#include <QJsonObject>
26#include <QObject>
27#include <QRect>
28#include <QSet>
29#include <QSize>
30#include <QString>
31#include <QStringList>
32#include <QTimer>
33#include <cstdint>
34#include <functional>
35#include <memory>
36#include <optional>
37
40
41namespace PhosphorZones {
42class Layout;
43class LayoutRegistry;
44}
45
46namespace PhosphorTileEngine {
47
48class AutotileConfig;
49
50class NavigationController;
51class PerScreenConfigResolver;
52} // namespace PhosphorTileEngine
53
54// ScreenManager lives in libs/phosphor-screens; forward-declared here.
55namespace PhosphorScreens {
56class ScreenManager;
57}
58
59namespace PhosphorTiles {
61class TilingAlgorithm;
62class TilingState;
63}
64
65namespace PhosphorTileEngine {
66
77class PHOSPHORTILEENGINE_EXPORT AutotileEngine : public PhosphorEngine::PlacementEngineBase
78{
79 Q_OBJECT
80 Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged)
81 Q_PROPERTY(QString algorithm READ algorithm WRITE setAlgorithm NOTIFY algorithmChanged)
82
85
86public:
87 explicit AutotileEngine(PhosphorZones::LayoutRegistry* layoutManager,
88 PhosphorEngine::IWindowTrackingService* windowTracker,
89 PhosphorScreens::ScreenManager* screenManager,
90 PhosphorTiles::ITileAlgorithmRegistry* algorithmRegistry, QObject* parent = nullptr);
91 ~AutotileEngine() override;
92
94 PhosphorTiles::ITileAlgorithmRegistry* algorithmRegistry() const
95 {
96 return m_algorithmRegistry;
97 }
98
115 void setWindowRegistry(QObject* registry) override;
116
117 // ═══════════════════════════════════════════════════════════════════════════
118 // Per-screen autotile state (derived from layout assignments)
119 // ═══════════════════════════════════════════════════════════════════════════
120
125 bool isEnabled() const noexcept override;
126
138 QSet<int> desktopsWithActiveState() const override;
139
145 bool isAutotileScreen(const QString& screenId) const;
146
154 bool isWindowTracked(const QString& windowId) const override
155 {
156 // Canonicalize like every sibling predicate (isWindowTiled,
157 // screenForTrackedWindow): callers pass raw daemon/effect composite
158 // ids, and a mutated-appId window must still resolve to its
159 // tracked entry.
160 return m_states.hasWindow(canonicalizeForLookup(windowId));
161 }
162
170 bool isWindowTiled(const QString& rawWindowId) const override;
171
183 bool isWindowFloatingInAutotile(const QString& windowId) const;
184
193 QStringList allFloatingWindows() const;
194
195 // IPlacementEngine
196 bool isActiveOnScreen(const QString& screenId) const override;
197
198 // ═══════════════════════════════════════════════════════════════════════════
199 // IPlacementEngine — generic screen/window management overrides
200 //
201 // Each override delegates to the concrete autotile method below it.
202 // AutotileAdaptor continues to call the concrete methods directly.
203 // ═══════════════════════════════════════════════════════════════════════════
204
205 QSet<QString> activeScreens() const override
206 {
207 return autotileScreens();
208 }
209 void setActiveScreens(const QSet<QString>& screens) override
210 {
211 setAutotileScreens(screens);
212 }
220 QStringList managedWindowOrder(const QString& screenId) const override
221 {
222 return capturedWindowOrder(screenId);
223 }
224 QStringList capturedWindowOrder(const QString& screenId) const;
229 QString managedFocusedWindow(const QString& screenId) const override;
232 int stickyPinnedDesktopForScreen(const QString& screenId) const override
233 {
234 return m_context.stickyPinnedDesktop(screenId);
235 }
236 bool isModeSpecificFloated(const QString& windowId) const override
237 {
238 return isAutotileFloated(windowId);
239 }
240 void clearModeSpecificFloatMarker(const QString& windowId) override
241 {
242 clearAutotileFloated(windowId);
243 }
244 bool isWindowManaged(const QString& windowId) const override
245 {
246 return isWindowTiled(windowId);
247 }
248 QString algorithmId() const override
249 {
250 return algorithm();
251 }
252 void markModeSpecificFloated(const QString& windowId) override
253 {
254 markAutotileFloated(windowId);
255 }
256
261 const QSet<QString>& autotileScreens() const
262 {
263 return m_autotileScreens;
264 }
265
270 QString activeScreen() const override
271 {
272 return m_activeScreen;
273 }
274
292 void setAutotileScreens(const QSet<QString>& screens);
293
303 void setCurrentDesktop(int desktop) override;
304
315 void setCurrentDesktopForScreen(const QString& screenId, int desktop) override;
316
318 void clearCurrentDesktopForScreen(const QString& screenId) override;
319
323 {
324 m_crossSurfaceResolver = resolver;
325 }
326
336 void setCurrentActivity(const QString& activity) override;
337
352 void updateStickyScreenPins(const std::function<bool(const QString&)>& isWindowSticky) override;
353
360 void pruneStatesForDesktop(int removedDesktop) override;
361
368 void pruneStatesForActivities(const QStringList& validActivities) override;
369
380 void pruneStatesForRemovedScreen(const QString& physicalScreenId) override;
381
385 int currentDesktop() const noexcept
386 {
387 return m_context.currentDesktop();
388 }
389
393 const QString& currentActivity() const noexcept
394 {
395 return m_context.currentActivity();
396 }
397
398 // ═══════════════════════════════════════════════════════════════════════════
399 // Algorithm selection
400 // ═══════════════════════════════════════════════════════════════════════════
401
406 QString algorithm() const noexcept;
407
415 void setAlgorithm(const QString& algorithmId) override;
416
421 PhosphorTiles::TilingAlgorithm* currentAlgorithm() const;
422
423 // ═══════════════════════════════════════════════════════════════════════════
424 // Tiling state access
425 // ═══════════════════════════════════════════════════════════════════════════
426
435 PhosphorTiles::TilingState* tilingStateForScreen(const QString& screenId);
436
437 PhosphorEngine::IPlacementState* stateForScreen(const QString& screenId) override;
438 const PhosphorEngine::IPlacementState* stateForScreen(const QString& screenId) const override;
439
444 AutotileConfig* config() const noexcept;
445
446 // ═══════════════════════════════════════════════════════════════════════════
447 // Session Persistence
448 // ═══════════════════════════════════════════════════════════════════════════
449
459 void saveState() override;
460
469 void loadState() override;
470
481 void setPersistenceDelegate(std::function<void()> saveFn, std::function<void()> loadFn)
482 {
483 m_persistSaveFn = std::move(saveFn);
484 m_persistLoadFn = std::move(loadFn);
485 }
486
508 using RestorePositionPredicate = std::function<bool(const QString& windowId, const QString& screenIdHint)>;
509
513 {
514 m_restorePositionPredicate = std::move(predicate);
515 }
516
533 using FloatPredicate = std::function<bool(const QString& windowId, const QString& screenId)>;
534
536 {
537 m_floatPredicate = std::move(predicate);
538 }
539
540 // Cross-engine handoff (see PhosphorEngine/IPlacementEngine.h for contract)
541 // Layout capability (see IPlacementEngine's Layout capability section)
545 {
546 return LayoutSupport::Placement;
547 }
548
549 QString engineId() const override
550 {
551 return QStringLiteral("autotile");
552 }
553 void handoffReceive(const HandoffContext& ctx) override;
554 void handoffRelease(const QString& windowId) override;
555 QString screenForTrackedWindow(const QString& windowId) const override
556 {
557 return m_states.keyForWindow(canonicalizeForLookup(windowId)).screenId;
558 }
559
579 void onWindowResized(const QString& rawWindowId, const QRect& oldFrame, const QRect& newFrame,
580 const QString& screenId) override;
581 // ═══════════════════════════════════════════════════════════════════════════
582 // Settings synchronization
583 // ═══════════════════════════════════════════════════════════════════════════
584
588
589 // Per-screen config — forwarded to PerScreenConfigResolver (IPlacementEngine overrides)
590 void applyPerScreenConfig(const QString& screenId, const QVariantMap& overrides) override;
591 void clearPerScreenConfig(const QString& screenId) override;
592 QVariantMap perScreenOverrides(const QString& screenId) const override;
593 bool hasPerScreenOverride(const QString& screenId, const QString& key) const;
594 void updatePerScreenOverride(const QString& screenId, const QString& key, const QVariant& value);
595
596 // Inject the per-context (window-rule) gap-override provider — forwarded to
597 // PerScreenConfigResolver. The daemon supplies the screen's current-context
598 // gap overrides so tiled windows honour context gap rules like snapping does.
599 void setContextGapProvider(std::function<QVariantMap(const QString& screenId)> provider);
600
613 std::function<bool(const QString& screenId, int desktop, const QString& activity)> resolver)
614 {
615 m_scrollingModeResolver = std::move(resolver);
616 }
617
618 // Mark the active (screen, desktop, activity) state's split ratio / master
619 // count as user-tuned so propagateGlobalSplitRatio/MasterCount leaves it
620 // alone — the adjustment stays local to that desktop instead of bleeding into
621 // the global config. Called by NavigationController after a shortcut/resize
622 // adjustment in the no-per-screen-override case.
623 void noteSplitRatioUserTuned(const QString& screenId);
624 void noteMasterCountUserTuned(const QString& screenId);
625
626 // Effective per-screen values — forwarded to PerScreenConfigResolver
627 int effectiveInnerGap(const QString& screenId) const;
628 ::PhosphorLayout::EdgeGaps effectiveOuterGaps(const QString& screenId) const;
629 bool effectiveSmartGaps(const QString& screenId) const;
630 bool effectiveRespectMinimumSize(const QString& screenId) const;
631 int effectiveMaxWindows(const QString& screenId) const;
633 qreal effectiveSplitRatioStep(const QString& screenId) const override;
634 int runtimeMaxWindows() const override;
645 std::optional<int> savedMaxWindowsForAlgorithm(const QString& algorithmId) const override;
646 QString effectiveAlgorithmId(const QString& screenId) const;
647 PhosphorTiles::TilingAlgorithm* effectiveAlgorithm(const QString& screenId) const;
648
656 void clearScreenScheduling(const QString& screenId);
657
664 void clearPendingInitialOrder(const QString& screenId);
665
673 void purgeFromPendingOrders(const QString& windowId);
674
684 void notifyAlgorithmWindowAdded(PhosphorTiles::TilingState* state, const QString& screenId,
685 const QString& windowId);
686
698 void requestPostRetileFocus(const QString& screenId, const QString& windowId);
699
700 // ═══════════════════════════════════════════════════════════════════════════
701 // Manual tiling operations
702 // ═══════════════════════════════════════════════════════════════════════════
703
704 void setInnerGap(int gap);
705 void setOuterGap(int gap);
706 void setSmartGaps(bool enabled);
707 void setFocusNewWindows(bool enabled);
716 Q_INVOKABLE void retile(const QString& screenId = QString()) override;
717
724 Q_INVOKABLE void swapWindows(const QString& windowId1, const QString& windowId2);
725
734 Q_INVOKABLE void promoteToMaster(const QString& windowId);
735
743 Q_INVOKABLE void demoteFromMaster(const QString& windowId);
744
751 Q_INVOKABLE void swapFocusedWithMaster() override;
752
753 // ═══════════════════════════════════════════════════════════════════════════
754 // Focus/window cycling
755 // ═══════════════════════════════════════════════════════════════════════════
756
762 Q_INVOKABLE void focusNext();
763
769 Q_INVOKABLE void focusPrevious();
770
776 Q_INVOKABLE void focusMaster() override;
777
786 void setFocusedWindow(const QString& windowId);
787
797 void setActiveScreenHint(const QString& screenId) override;
798
799 // ═══════════════════════════════════════════════════════════════════════════
800 // Split ratio adjustment
801 // ═══════════════════════════════════════════════════════════════════════════
802
810 Q_INVOKABLE void increaseMasterRatio(qreal delta = kDefaultSplitRatioStep) override;
811
819 Q_INVOKABLE void decreaseMasterRatio(qreal delta = kDefaultSplitRatioStep) override;
820
836 void setGlobalSplitRatio(qreal ratio);
837
848 void setGlobalMasterCount(int count);
849
850 // ═══════════════════════════════════════════════════════════════════════════
851 // Master count adjustment
852 // ═══════════════════════════════════════════════════════════════════════════
853
857 Q_INVOKABLE void increaseMasterCount() override;
858
862 Q_INVOKABLE void decreaseMasterCount() override;
863
864 // ═══════════════════════════════════════════════════════════════════════════
865 // Window rotation and floating (context-aware shortcuts support)
866 // ═══════════════════════════════════════════════════════════════════════════
867
877 Q_INVOKABLE void rotateWindowOrder(bool clockwise = true);
878
888 Q_INVOKABLE void toggleFocusedWindowFloat();
889
905 Q_INVOKABLE void switchFocusBetweenFloatingAndTiling(const QString& screenId) override;
906
918 Q_INVOKABLE void toggleWindowFloat(const QString& windowId, const QString& screenId) override;
919
930 Q_INVOKABLE void swapFocusedInDirection(const QString& direction, const QString& action = QStringLiteral("move"));
931
940 Q_INVOKABLE void focusInDirection(const QString& direction, const QString& action = QStringLiteral("focus"));
941
949 Q_INVOKABLE void moveFocusedToPosition(int position);
950
951 // ═══════════════════════════════════════════════════════════════════════════
952 // IPlacementEngine — navigation overrides
953 //
954 // Each override absorbs what AutotileNavigationAdapter did: translate
955 // the user-intent-shaped IPlacementEngine call into the existing
956 // concrete AutotileEngine method with the right parameters.
957 // ═══════════════════════════════════════════════════════════════════════════
958
959 void focusInDirection(const QString& direction, const PhosphorEngine::NavigationContext& ctx) override;
960 void moveFocusedInDirection(const QString& direction, const PhosphorEngine::NavigationContext& ctx) override;
961 void spanFocusedInDirection(const QString& direction, const PhosphorEngine::NavigationContext& ctx) override;
962 void swapFocusedInDirection(const QString& direction, const PhosphorEngine::NavigationContext& ctx) override;
963 void moveFocusedToPosition(int position, const PhosphorEngine::NavigationContext& ctx) override;
964 void rotateWindows(bool clockwise, const PhosphorEngine::NavigationContext& ctx) override;
965
970 QString entryWindowForCrossing(const QString& screenId, const QString& direction) const;
975 int windowOrderIndexForWindow(const QString& screenId, const QString& windowId) const;
978 std::optional<PhosphorEngine::WindowPlacement> capturePlacement(const QString& windowId) const override;
981 void cycleFocus(bool forward, const PhosphorEngine::NavigationContext& ctx) override;
984
985 // Autotile-specific navigation, callable on the concrete engine.
986 void rotateWindows(bool clockwise, const QString& screenId);
987
1003 Q_INVOKABLE void setWindowFloat(const QString& windowId, bool shouldFloat,
1004 const QString& screenId = QString()) override;
1005
1009 Q_INVOKABLE void floatWindow(const QString& windowId);
1010
1014 Q_INVOKABLE void unfloatWindow(const QString& windowId);
1015
1016 // ═══════════════════════════════════════════════════════════════════════════
1017 // PhosphorZones::Zone-ordered window transitions (snapping ↔ autotile)
1018 // ═══════════════════════════════════════════════════════════════════════════
1019
1033 void setInitialWindowOrder(const QString& screenId, const QStringList& windowIds) override;
1034
1045 QStringList tiledWindowOrder(const QString& screenId) const;
1046
1047 // ═══════════════════════════════════════════════════════════════════════════
1048 // Window event handlers (public API for external notification)
1049 // ═══════════════════════════════════════════════════════════════════════════
1050
1064 using IPlacementEngine::windowOpened;
1065 void windowOpened(const QString& windowId, const QString& screenId, int minWidth, int minHeight) override;
1076 bool claimCrossScreenReopen(const QString& windowId, const QString& openingScreenId, int minWidth,
1077 int minHeight) override;
1078 QString heldScreenForWindow(const QString& windowId) const override;
1079
1090 void windowMinSizeUpdated(const QString& windowId, int minWidth, int minHeight) override;
1091 QSize windowMinimumSize(const QString& windowId) const override;
1092
1101 void windowClosed(const QString& windowId) override;
1102
1112 void windowFocused(const QString& windowId, const QString& screenId) override;
1113
1114 // ═══════════════════════════════════════════════════════════════════════════
1115 // Retile helpers (public — used by extracted classes)
1116 // ═══════════════════════════════════════════════════════════════════════════
1117
1125 void scheduleRetileForScreen(const QString& screenId) override;
1126
1127 // ═══════════════════════════════════════════════════════════════════════════
1128 // Drag-insert preview (trigger-held window drag reorders autotile stack)
1129 // ═══════════════════════════════════════════════════════════════════════════
1130
1155 bool beginDragInsertPreview(const QString& rawWindowId, const QString& screenId) override;
1156
1168 void updateDragInsertPreview(int insertIndex);
1169
1177 void updateDragInsertPreview(const DragInsertTarget& target) override;
1178
1187
1192
1214 int computeDragInsertIndexAtPoint(const QString& screenId, const QPoint& cursorPos) const;
1215
1220 DragInsertTarget computeDragInsertTargetAtPoint(const QString& screenId, const QPoint& cursorPos) const override;
1221
1225 bool hasDragInsertPreview() const override
1226 {
1227 return m_dragInsertPreview.has_value();
1228 }
1229
1236 {
1237 return m_dragInsertPreview ? m_dragInsertPreview->windowId : QString();
1238 }
1239
1243 QString dragInsertPreviewScreenId() const override
1244 {
1245 return m_dragInsertPreview ? m_dragInsertPreview->targetScreenId : QString();
1246 }
1247
1255 QString dragInsertPreviewPriorScreenId() const override
1256 {
1257 return m_dragInsertPreview && m_dragInsertPreview->hadPriorState ? m_dragInsertPreview->priorKey.screenId
1258 : QString();
1259 }
1260
1270 void retileAfterOperation(const QString& screenId, bool operationSucceeded);
1271
1272Q_SIGNALS:
1277 void enabledChanged(bool enabled);
1278
1291 void autotileScreensChanged(const QStringList& screenIds, bool isDesktopSwitch);
1292
1293 // algorithmChanged(const QString&) — inherited from PlacementEngineBase.
1294 // placementChanged(const QString&) — inherited from PlacementEngineBase.
1295 // Replaces the former tilingChanged signal; all internal emitters now
1296 // emit placementChanged, and callers connect to the base-class signal.
1297 // windowsReleased(const QStringList&, const QSet<QString>&) — inherited
1298 // from PlacementEngineBase. Replaces windowsReleasedFromTiling.
1299
1300 // windowFloatingChanged (emitted from performToggleFloat and
1301 // setWindowFloat with user-intent semantics: the downstream handler
1302 // restores pre-tile geometry, shows the navigation OSD, etc.),
1303 // activateWindowRequested, and navigationFeedback are inherited from
1304 // PlacementEngineBase. Plain comments, not a doxygen block — this class
1305 // declares no signal of those names for a doc block to attach to.
1306
1307 // windowFloatingStateSynced and windowsBatchFloated are inherited from
1308 // PlacementEngineBase. Autotile-specific documentation: windowFloatingStateSynced
1309 // is emitted when the engine's TilingState::isFloating diverges from WTS's view
1310 // (e.g. a newly-inserted window carries stale snap-mode float state). The
1311 // downstream handler updates WTS bookkeeping without geometry restore.
1312 // windowsBatchFloated is emitted when overflow windows are batch-floated
1313 // during applyTiling; the daemon handler updates WTS state directly.
1314
1323 void windowsTiled(const QString& tileRequestsJson);
1324
1325public:
1326 // ═══════════════════════════════════════════════════════════════════════════
1327 // Autotile-float origin tracking (ephemeral, not persisted)
1328 // ═══════════════════════════════════════════════════════════════════════════
1329
1330 void markAutotileFloated(const QString& rawWindowId);
1331 void clearAutotileFloated(const QString& rawWindowId);
1332 bool isAutotileFloated(const QString& rawWindowId) const;
1333
1334 int pruneStaleWindows(const QSet<QString>& aliveWindowIds) override;
1335
1342 QRect lastManagedRect(const QString& rawWindowId) const override;
1343
1344private Q_SLOTS:
1345 void onWindowZoneChanged(const QString& windowId, const QString& zoneId);
1346 void onWindowAdded(const QString& windowId);
1347 void onWindowRemoved(const QString& windowId);
1348 void onWindowFocused(const QString& windowId);
1349 void onScreenGeometryChanged(const QString& screenId);
1350 void onLayoutChanged(PhosphorZones::Layout* layout);
1351
1352private:
1353 void connectSignals();
1354 bool insertWindow(const QString& windowId, const QString& screenId);
1355 // Passive float-state sync after insertWindow() places a window: notify the
1356 // daemon it opened floating (matched Float rule / restored saved float), or
1357 // clear a stale WTS float when it was placed tiled. Shared by onWindowAdded
1358 // and backfillWindows so the two cannot diverge.
1359 void emitInsertFloatStateSync(const QString& windowId, const QString& screenId);
1363 void insertWindowByConfigOrder(PhosphorTiles::TilingState* state, const QString& windowId, const QString& screenId);
1364 void removeWindow(const QString& windowId);
1365
1371 QString removeTrackedWindowNoRetile(const QString& windowId);
1372
1377 void dropClosedWindowFromDragPreview(const QString& windowId);
1378 bool storeWindowMinSize(const QString& windowId, int minWidth, int minHeight);
1379 bool recalculateLayout(const QString& screenId);
1380 void applyTiling(const QString& screenId);
1381
1391 bool applyTreeResizeReflow(PhosphorTiles::TilingState* state, const QString& windowId, const QRect& oldFrame,
1392 const QRect& newFrame, const QString& screenId);
1393 bool shouldTileWindow(const QString& windowId) const;
1394 QString screenForWindow(const QString& windowId) const;
1395 QRect screenGeometry(const QString& screenId) const;
1396
1400 bool isKnownScreen(const QString& screenId) const;
1401
1435 bool releaseScreenStateForTeardown(const QString& screenId, PhosphorTiles::TilingState* state,
1436 QStringList& releasedWindows, bool drainOverflow = true,
1437 bool clearScreenOrderMaps = true);
1438
1449 void migrateWindowBetweenKeys(const QString& windowId, const PhosphorEngine::TilingStateKey& oldKey,
1450 const QString& newScreenId);
1451
1462 void revalidateWindowContext(const QString& windowId, const QString& screenId);
1463
1472 PhosphorEngine::TilingStateKey currentKeyForScreen(const QString& screenId) const
1473 {
1474 // Precedence and the sticky-pin / per-output subtleties live in the
1475 // shared ScreenContextTracker (sticky-pin override > per-output desktop >
1476 // global desktop; activity = current activity).
1477 return m_context.currentKeyForScreen(screenId);
1478 }
1479
1487 enum class PropagateScope {
1488 CurrentContext,
1489 AllContexts,
1490 };
1491
1495 void propagateGlobalSplitRatio(PropagateScope scope = PropagateScope::CurrentContext);
1496
1500 void propagateGlobalMasterCount(PropagateScope scope = PropagateScope::CurrentContext);
1501
1513 void backfillWindows();
1514
1527 void retileScreen(const QString& screenId);
1528
1538 void scheduleRetileRetry(const QString& screenId);
1539
1543 void processRetileRetries();
1544
1545 // ═══════════════════════════════════════════════════════════════════════════════
1546 // Helper Methods
1547 // ═══════════════════════════════════════════════════════════════════════════════
1548
1559 bool cleanupPendingOrderIfResolved(const QString& screenId);
1560 void schedulePendingOrderTimeout(const QString& screenId, uint64_t generation);
1561
1568 bool warnIfEmptyWindowId(const QString& windowId, const char* operation) const;
1569
1585 QString canonicalizeWindowId(const QString& rawWindowId);
1586
1593 void cleanupCanonical(const QString& anyWindowId);
1594
1602 QString canonicalizeForLookup(const QString& rawWindowId) const;
1603
1616 QString currentAppIdFor(const QString& anyWindowId) const;
1617
1623 void performToggleFloat(PhosphorTiles::TilingState* state, const QString& windowId, const QString& screenId);
1624
1633 void toggleWindowFloatAs(const QString& rawWindowId, const QString& screenId, const QString& failureAction);
1634
1644 PhosphorTiles::TilingState* stateForWindow(const QString& windowId, QString* outScreenId = nullptr);
1645
1646 QSet<QString> m_autotileFloatedWindows;
1647
1648 PhosphorZones::LayoutRegistry* m_layoutManager = nullptr;
1650 std::function<bool(const QString& screenId, int desktop, const QString& activity)> m_scrollingModeResolver;
1651 PhosphorEngine::IWindowTrackingService* m_windowTracker = nullptr;
1652 PhosphorScreens::ScreenManager* m_screenManager = nullptr;
1656 PhosphorEngine::ICrossSurfaceResolver* m_crossSurfaceResolver = nullptr;
1657 PhosphorEngine::IWindowRegistry* m_windowRegistry = nullptr;
1661 QMetaObject::Connection m_appIdResolverHook;
1662 PhosphorTiles::ITileAlgorithmRegistry* m_algorithmRegistry = nullptr;
1663 std::unique_ptr<AutotileConfig> m_config;
1664 std::unique_ptr<PerScreenConfigResolver> m_configResolver;
1665 std::unique_ptr<NavigationController> m_navigation;
1666 QTimer m_writeBackGuardTimer;
1667 QTimer m_settingsRetileTimer;
1668
1669 // Persistence delegates (KConfig stays in WTA layer)
1670 std::function<void()> m_persistSaveFn;
1671 std::function<void()> m_persistLoadFn;
1672
1673 // Floated-position-restore gate. Empty until the daemon wires it; while empty
1674 // the engine always re-applies a floated window's recorded position (historical
1675 // behaviour). See RestorePositionPredicate doc above.
1676 RestorePositionPredicate m_restorePositionPredicate{};
1677
1678 // Rule-driven open-floating gate. Empty until the daemon wires it; while empty
1679 // no window is rule-floated. See FloatPredicate doc above.
1680 FloatPredicate m_floatPredicate{};
1681
1682 // MigrationArrival moved to AutotileEngineTypes.h; alias keeps the
1683 // AutotileEngine::MigrationArrival spelling valid for existing call sites.
1684 using MigrationArrival = ::PhosphorTileEngine::MigrationArrival;
1685 std::optional<MigrationArrival> m_migrationArrival;
1686
1689 bool insertShouldFloat(const QString& windowId, const QString& screenId) const;
1690
1691 QSet<QString> m_autotileScreens;
1692 QString m_algorithmId;
1693 bool m_algorithmEverSet = false;
1701 bool m_refreshingFromSettings = false;
1702 QString m_activeScreen; // Last-focused screen (updated by onWindowFocused)
1703
1704 // Per-screen tiling states + the windowId→owning-key reverse map. States are
1705 // owned via Qt parent (this); PerScreenStates holds only the two maps and
1706 // their lockstep bookkeeping — engine-specific lifecycle stays in this class.
1708
1709 // Screen+desktop states whose split ratio / master count the user has
1710 // explicitly tuned (keyboard shortcut or interactive resize). propagateGlobal*
1711 // skips these so a per-desktop tweak survives a settings refresh and is never
1712 // written into the global config — keeping the adjustment local to that
1713 // (screen, desktop, activity). Cleared on an algorithm switch and when the
1714 // user changes the corresponding global value in settings. This is
1715 // within-session state only: it is not persisted, so the per-desktop tweak
1716 // does not survive a daemon restart (neither does the value it guards —
1717 // autotile persistence is per-window, not per-desktop ratio/count).
1718 QSet<PhosphorEngine::TilingStateKey> m_userTunedSplitRatio;
1719 QSet<PhosphorEngine::TilingStateKey> m_userTunedMasterCount;
1720
1721 // Script-state bags rescued from TilingStates that a teardown destroys, so a
1722 // re-created state for the same key can pick its bag back up. See
1723 // StashedScriptState in AutotileEngineTypes.h for the full rationale (harvest
1724 // rules, the algorithm tag, split-tree carry). The alias keeps the
1725 // AutotileEngine::StashedScriptState spelling valid for existing call sites.
1726 using StashedScriptState = ::PhosphorTileEngine::StashedScriptState;
1727 std::unordered_map<PhosphorEngine::TilingStateKey, StashedScriptState> m_scriptStateStash;
1728
1737 void stashScriptState(const PhosphorEngine::TilingStateKey& key, PhosphorTiles::TilingState* state);
1738
1747 void restoreStashedScriptState(const PhosphorEngine::TilingStateKey& key, PhosphorTiles::TilingState* state);
1748
1763 void restoreStashedSplitTree(const PhosphorEngine::TilingStateKey& key, PhosphorTiles::TilingState* state,
1764 const PhosphorTiles::TilingAlgorithm* algo);
1765
1773 void dropStashedScriptStatesForAlgorithmChange(const QString& screenId, const QString& newAlgorithmId);
1774
1775 QHash<QString, QSize> m_windowMinSizes; // windowId -> minimum size from KWin
1776
1777 // Canonical windowId → tile rect last emitted for it by applyTiling.
1778 // Backs lastManagedRect(): deliberately NOT cleared when the window
1779 // leaves the tiled state (that survival is the point — see the base
1780 // doc). Cleared on exactly two events: a genuine cross-screen move off
1781 // an autotile screen (the reposition has already moved the frame off
1782 // the old tile rect) and stale-window pruning. Everything else KEEPS
1783 // the entry — windowClosed (the effect notifies autotile before
1784 // WindowTracking, so the orchestrator's close capture and its tile-rect
1785 // guard run after this engine's teardown), handoffRelease (the adopting
1786 // engine's capture runs right after the release), and
1787 // releaseScreenStateForTeardown (windows still open) — because in each
1788 // the live frame can still be the tile rect, exactly when the
1789 // orchestrator's guard needs this memory. Closed windows' entries are
1790 // reclaimed by pruneStaleWindows, whose sweep is independent of
1791 // tracking. Used solely for an exact frame comparison, so a stale rect
1792 // is harmless.
1793 QHash<QString, QRect> m_lastAppliedTileRect;
1794
1795 // Instance id → first-seen canonical windowId.
1796 //
1797 // Fallback for when no shared WindowRegistry is attached (unit tests).
1798 // With a registry, canonicalization delegates to it instead. Production
1799 // daemons always take the registry path, so this map stays empty.
1800 //
1801 // The canonical form is the FIRST windowId string we saw for a given
1802 // instance id. Subsequent arrivals with a mutated appId (Electron/CEF
1803 // apps that swap WM_CLASS mid-session) resolve back to that canonical
1804 // form so every map/PhosphorTiles::TilingState key in the engine stays consistent.
1805 QHash<QString, QString> m_canonicalByInstance;
1806
1807 // Current desktop/activity context — the global current desktop, per-output
1808 // desktop overrides (#648), the sticky-desktop pin, the current activity, and
1809 // the "ever set" arming flags. Used by tilingStateForScreen() to construct
1810 // the owning key via currentKeyForScreen(). Fed by setCurrentDesktop()/
1811 // setCurrentActivity()/setCurrentDesktopForScreen() BEFORE updateEngineScreens()
1812 // runs on a desktop/activity switch.
1814
1815 // Armed by a genuine desktop/activity switch (see the setCurrent* mutators);
1816 // consumed by setAutotileScreens()/the desktop-switch pass. Engine-specific,
1817 // so it stays here rather than in the shared ScreenContextTracker.
1818 bool m_isDesktopContextSwitch = false;
1819
1820 // Pre-seeded window order for snapping → autotile transitions.
1821 // Keyed by stable EDID-based screen ID (PhosphorScreens::ScreenIdentity::identifierFor).
1822 // Consumed by the strict seed in setAutotileScreens() (visible windows,
1823 // eagerly) and by insertWindow() as remaining windows arrive; purged
1824 // per-window via purgeFromPendingOrders (close, cap rejection), swept
1825 // by pruneStaleWindows, and reaped by the pending-order timeout — which
1826 // deliberately RETAINS an order holding live minimized placeholders, so
1827 // those entries persist until the window opens or closes.
1828 QHash<QString, QStringList> m_pendingInitialOrders;
1829 QHash<QString, uint64_t> m_pendingOrderGeneration;
1835 uint64_t m_pendingOrderSerial = 0;
1836 // Screens whose pendingInitialOrders entry is "strict" — saved order
1837 // wins even when arrival order differs. Set by setInitialWindowOrder
1838 // (mode transition: the daemon intentionally pre-computed an order from
1839 // the previous mode's zones, and that order MUST be preserved).
1840 // Lifetime is TIED to the pending order's own: cleared wherever the
1841 // order is removed (full consumption, per-window purge emptying it,
1842 // stale-window sweep, timeout reap, screen teardown) — an order retained
1843 // for a minimized placeholder keeps its strict flag with it. Entries seeded by
1844 // setInitialWindowOrder (mode transition) are the strict ones, and it is the
1845 // only producer in the tree, so every entry is strict today. Advisory
1846 // entries reconstructed per-window from the placement store would NOT be in
1847 // this set — for those the saved position is honored only when it appends at the
1848 // current tail, otherwise insertPosition takes over. This is the behaviour
1849 // users expect from their "After existing" / "After focused" / "As main
1850 // window" preference for new windows.
1851 QSet<QString> m_strictInitialOrderScreens;
1852
1853 // Per-screen overflow tracking with O(1) reverse-index lookups.
1854 OverflowManager m_overflow;
1855
1856 bool m_retiling = false;
1857
1858 // Queued-connection retile coalescing: windowOpened D-Bus calls arriving in
1859 // the same event loop pass are coalesced into a single retile per screen.
1860 // Uses QMetaObject::invokeMethod(Qt::QueuedConnection) which fires after
1861 // all currently-pending events are processed — no fixed delay needed.
1862 QSet<QString> m_pendingRetileScreens;
1863 bool m_retilePending = false;
1864
1865 // Bounded retry for transient screen geometry failures.
1866 // When QScreen is temporarily unavailable (e.g. during Wayland desktop switch),
1867 // recalculateLayout cannot compute zone geometry. Rather than silently dropping
1868 // the retile (leaving stale zones), we retry after a short interval.
1869 // Per-screen retry counts prevent infinite loops; cleared on success or screen removal.
1870 static constexpr int MaxRetileRetries = 3;
1871 static constexpr int RetileRetryIntervalMs = 150;
1872 QTimer m_retileRetryTimer;
1873 QSet<QString> m_retileRetryScreens;
1874 QHash<QString, int> m_retileRetryCount;
1875
1876 // Deferred focus, keyed by screen: set by onWindowAdded and
1877 // requestPostRetileFocus, emitted after that screen's applyTiling so the
1878 // focus request arrives at KWin AFTER windowsTiled (whose onComplete raises
1879 // windows in tiling order). Without this, the raise loop buries the new
1880 // window. Per-screen so an entry stranded by a no-op retile cannot be
1881 // consumed by another screen's batch and activate the wrong window.
1882 QHash<QString, QString> m_pendingFocusByScreen;
1883
1884 // Focus-before-track reseed: a windowFocused() notification can arrive before
1885 // the window it names is tracked in a TilingState — most visibly on daemon
1886 // restart, where the effect re-notifies the active window during bring-up but
1887 // the window re-announce (windowsOpenedBatch) lands afterwards. onWindowFocused
1888 // would otherwise drop that focus, leaving a focus-driven layout (Theater) with
1889 // no focused window until the user clicks around. Stash the dropped id here and
1890 // replay it in onWindowAdded once the window is tracked.
1891 QString m_pendingFocusReseedWindowId;
1892
1893 // DragInsertPreview moved to AutotileEngineTypes.h; alias keeps the
1894 // AutotileEngine::DragInsertPreview spelling valid for existing call sites.
1895 using DragInsertPreview = ::PhosphorTileEngine::DragInsertPreview;
1896 std::optional<DragInsertPreview> m_dragInsertPreview;
1897
1904 void processPendingRetiles();
1905};
1906
1907} // namespace PhosphorTileEngine
Definition IAutotileSettings.h:15
Resolves the neighbouring surface — output or virtual desktop — in a direction, for cross-surface win...
Definition ICrossSurfaceResolver.h:21
LayoutSupport
How this engine relates to user-selectable layouts — the entries the layout picker,...
Definition IPlacementEngine.h:964
Definition IWindowRegistry.h:14
Definition IWindowTrackingService.h:34
The two cooperating maps a per-monitor placement engine keeps: a forward map from PlacementStateKey t...
Definition PerScreenStates.h:35
Abstract base class for placement engines.
Definition PlacementEngineBase.h:32
Tracks the "current context" of each screen for a placement engine: the global current virtual deskto...
Definition ScreenContextTracker.h:46
Centralized screen-topology service.
Definition Manager.h:75
Core engine for automatic window tiling.
Definition AutotileEngine.h:78
void snapAllWindows(const PhosphorEngine::NavigationContext &ctx) override
Bring every unmanaged window on the screen back under this engine's placement (zones for snap,...
void setGlobalMasterCount(int count)
Set master count globally (config + every state, every desktop)
QSet< QString > activeScreens() const override
Definition AutotileEngine.h:205
void setCurrentDesktop(int desktop) override
Set the current virtual desktop for per-desktop tiling state.
void promoteToMaster(const QString &windowId)
Promote a window to the master area.
void pruneStatesForActivities(const QStringList &validActivities) override
Prune PhosphorTiles::TilingState entries for activities not in the given set.
bool effectiveSmartGaps(const QString &screenId) const
void pruneStatesForRemovedScreen(const QString &physicalScreenId) override
Prune PhosphorTiles::TilingState entries for a permanently removed monitor.
void updateStickyScreenPins(const std::function< bool(const QString &)> &isWindowSticky) override
Pin screens where all autotiled windows are sticky (on all desktops)
void swapFocusedInDirection(const QString &direction, const PhosphorEngine::NavigationContext &ctx) override
Swap the focused window with the adjacent window.
QString dragInsertPreviewWindowId() const
Get the window ID of the active drag-insert preview, or empty.
Definition AutotileEngine.h:1235
void clearModeSpecificFloatMarker(const QString &windowId) override
Definition AutotileEngine.h:240
void setFocusNewWindows(bool enabled)
QString algorithmId() const override
Definition AutotileEngine.h:248
void retileAfterOperation(const QString &screenId, bool operationSucceeded)
Helper to retile a screen after a window operation.
void decreaseMasterRatio(qreal delta=kDefaultSplitRatioStep) override
Decrease the master area ratio.
void setRestorePositionPredicate(RestorePositionPredicate predicate)
Inject the floated-position-restore gate.
Definition AutotileEngine.h:512
void increaseMasterCount() override
Increase the number of master windows.
std::function< bool(const QString &windowId, const QString &screenId)> FloatPredicate
Predicate deciding whether an opening window should start FLOATING because a "Float this app" rule ma...
Definition AutotileEngine.h:533
void setGlobalSplitRatio(qreal ratio)
Set master ratio globally (config + every state, every desktop)
void purgeFromPendingOrders(const QString &windowId)
Purge windowId from every pending initial order, with full bookkeeping: empty orders drop their gener...
PhosphorEngine::IAutotileSettings * autotileSettings() const
void setFloatPredicate(FloatPredicate predicate)
Definition AutotileEngine.h:535
QStringList tiledWindowOrder(const QString &screenId) const
Get the current tiled window order for a screen.
void reapplyLayout(const PhosphorEngine::NavigationContext &ctx) override
Re-apply the current layout to all managed windows.
bool effectiveRespectMinimumSize(const QString &screenId) const
void applyPerScreenConfig(const QString &screenId, const QVariantMap &overrides) override
void windowFocused(const QString &windowId, const QString &screenId) override
Notify the engine that a window was focused.
void toggleFocusedWindowFloat()
Toggle the focused window between tiled and floating states.
QStringList capturedWindowOrder(const QString &screenId) const
void commitDragInsertPreview() override
Commit the active drag-insert preview.
bool isWindowTiled(const QString &rawWindowId) const override
Check if a window is currently tiled (tracked AND not floating).
QString dragInsertPreviewScreenId() const override
Get the target screen ID of the active drag-insert preview, or empty.
Definition AutotileEngine.h:1243
void moveFocusedToPosition(int position)
Move the focused window to a specific position in the tiling order.
void markAutotileFloated(const QString &rawWindowId)
void refreshConfigFromSettings() override
Re-read all tuning values from the engine's settings interface.
void moveFocusedInDirection(const QString &direction, const PhosphorEngine::NavigationContext &ctx) override
Move the focused window to the adjacent slot.
bool isActiveOnScreen(const QString &screenId) const override
Whether this engine is active on the given screen.
void setCrossSurfaceResolver(PhosphorEngine::ICrossSurfaceResolver *resolver) override
Inject the cross-surface resolver (neighbouring output / desktop lookup) used by directional navigati...
Definition AutotileEngine.h:322
int currentDesktop() const noexcept
Get the current virtual desktop tracked by the engine.
Definition AutotileEngine.h:385
void windowOpened(const QString &windowId, const QString &screenId, int minWidth, int minHeight) override
A new window appeared on this engine's screen.
int windowOrderIndexForWindow(const QString &screenId, const QString &windowId) const
The RAW window-order index of windowId on screenId (current desktop; counts floats,...
void windowsTiled(const QString &tileRequestsJson)
Emitted when windows are tiled to new geometries (batch)
void rotateWindowOrder(bool clockwise=true)
Rotate all tiled windows by one position.
void scheduleRetileForScreen(const QString &screenId) override
Schedule a deferred retile for a screen.
void windowMinSizeUpdated(const QString &windowId, int minWidth, int minHeight) override
Update a window's minimum size at runtime.
void pushToEmptyZone(const PhosphorEngine::NavigationContext &ctx) override
Move the focused window to the first empty slot.
void swapWindows(const QString &windowId1, const QString &windowId2)
Swap positions of two tiled windows.
void toggleFocusedFloat(const PhosphorEngine::NavigationContext &ctx) override
Toggle the focused window between managed and floating.
void setCurrentDesktopForScreen(const QString &screenId, int desktop) override
Set a single screen's current virtual desktop (Plasma 6.7 per-output virtual desktops,...
void focusPrevious()
Focus the previous tiled window.
void clearScreenScheduling(const QString &screenId)
Drop every per-screen SCHEDULING entry for screenId: pending retiles, retile retry state,...
void toggleWindowFloat(const QString &windowId, const QString &screenId) override
Toggle a specific window between tiled and floating states.
bool hasDragInsertPreview() const override
Query whether a drag-insert preview is currently active.
Definition AutotileEngine.h:1225
QStringList managedWindowOrder(const QString &screenId) const override
Capture-on-leave order: the tiled order PLUS minimize-floated windows at their windowOrder positions.
Definition AutotileEngine.h:220
bool isAutotileFloated(const QString &rawWindowId) const
void clearPerScreenConfig(const QString &screenId) override
void setInitialWindowOrder(const QString &screenId, const QStringList &windowIds) override
Pre-seed initial window order for deterministic snapping → autotile transitions.
void setWindowFloat(const QString &windowId, bool shouldFloat, const QString &screenId=QString()) override
Set the floating state of a specific window.
void cycleFocus(bool forward, const PhosphorEngine::NavigationContext &ctx) override
Cycle keyboard focus through managed windows.
void moveFocusedToPosition(int position, const PhosphorEngine::NavigationContext &ctx) override
Move the focused window to the Nth position.
void decreaseMasterCount() override
Decrease the number of master windows.
void noteMasterCountUserTuned(const QString &screenId)
void focusNext()
Focus the next tiled window.
void rotateWindows(bool clockwise, const QString &screenId)
int effectiveInnerGap(const QString &screenId) const
void floatWindow(const QString &windowId)
Float a specific window by its ID (convenience forwarder)
QString algorithm() const noexcept
Get current algorithm ID.
void spanFocusedInDirection(const QString &direction, const PhosphorEngine::NavigationContext &ctx) override
Grow or shrink the focused window's zone span toward the direction: extend into the adjacent zone(s) ...
DragInsertTarget computeDragInsertTargetAtPoint(const QString &screenId, const QPoint &cursorPos) const override
IPlacementEngine drop-target form: wraps the flat index into DragInsertTarget::primary (invalid when ...
void autotileScreensChanged(const QStringList &screenIds, bool isDesktopSwitch)
Emitted when the set of autotile screens changes.
void cancelDragInsertPreview() override
Cancel the active drag-insert preview, restoring the original order.
void focusInDirection(const QString &direction, const QString &action=QStringLiteral("focus"))
Focus the adjacent window in tiling order with OSD feedback.
std::function< bool(const QString &windowId, const QString &screenIdHint)> RestorePositionPredicate
Predicate consulted on reopen to decide whether a FLOATED (untiled) window should have its previous g...
Definition AutotileEngine.h:508
void increaseMasterRatio(qreal delta=kDefaultSplitRatioStep) override
Increase the master area ratio.
bool isWindowManaged(const QString &windowId) const override
Whether the engine considers the window "managed" (eligible for layout operations).
Definition AutotileEngine.h:244
void updatePerScreenOverride(const QString &screenId, const QString &key, const QVariant &value)
int pruneStaleWindows(const QSet< QString > &aliveWindowIds) override
Drop any per-engine bookkeeping for windows not in aliveWindowIds.
void setActiveScreens(const QSet< QString > &screens) override
Definition AutotileEngine.h:209
QString entryWindowForCrossing(const QString &screenId, const QString &direction) const
Cross-mode swap support (queried by the daemon when THIS engine is the target): the tiled window at s...
QString managedFocusedWindow(const QString &screenId) const override
Capture half only.
bool hasPerScreenOverride(const QString &screenId, const QString &key) const
void focusMaster() override
Focus the master window.
void switchFocusBetweenFloatingAndTiling(const QString &screenId) override
Jump focus between the float layer and the tiled layout.
PhosphorTiles::AutotileInsertPosition effectiveInsertPosition(const QString &screenId) const
bool isWindowFloatingInAutotile(const QString &windowId) const
Authoritative per-window autotile float state.
QString dragInsertPreviewPriorScreenId() const override
The screen the previewed window sat on before begin adopted it.
Definition AutotileEngine.h:1255
void setAutotileScreens(const QSet< QString > &screens)
Set which screens use autotile (derived from layout assignments)
void setScrollingModeResolver(std::function< bool(const QString &screenId, int desktop, const QString &activity)> resolver)
Scrolling-mode resolver for windowOpened's cross-screen tile-restore defer term, invoked as (screenId...
Definition AutotileEngine.h:612
void requestPostRetileFocus(const QString &screenId, const QString &windowId)
Request that a window is activated after the given screen's next applyTiling.
void demoteFromMaster(const QString &windowId)
Demote a window from the master area.
void swapFocusedWithMaster() override
Swap the currently focused window with the master window.
QVariantMap perScreenOverrides(const QString &screenId) const override
qreal effectiveSplitRatioStep(const QString &screenId) const override
void setContextGapProvider(std::function< QVariantMap(const QString &screenId)> provider)
void handoffRelease(const QString &windowId) override
Release ownership of a window WITHOUT modifying its geometry.
void restoreFocusedWindow(const PhosphorEngine::NavigationContext &ctx) override
Restore the focused window out of its managed state.
QStringList allFloatingWindows() const
All windows currently floating in autotile across every tracked state.
void focusInDirection(const QString &direction, const PhosphorEngine::NavigationContext &ctx) override
Move keyboard focus to the adjacent window.
int stickyPinnedDesktopForScreen(const QString &screenId) const override
The desktop this engine has pinned this screen to, or 0.
Definition AutotileEngine.h:232
void clearCurrentDesktopForScreen(const QString &screenId) override
Drop a screen's per-output desktop, reverting it to m_context's global desktop.
void notifyAlgorithmWindowAdded(PhosphorTiles::TilingState *state, const QString &screenId, const QString &windowId)
Run the algorithm's onWindowAdded lifecycle hook for a just-inserted window.
PhosphorTiles::TilingAlgorithm * effectiveAlgorithm(const QString &screenId) const
const QString & currentActivity() const noexcept
Get the current activity tracked by the engine.
Definition AutotileEngine.h:393
void noteSplitRatioUserTuned(const QString &screenId)
int effectiveMaxWindows(const QString &screenId) const
LayoutSupport layoutSupport() const override
Autotile algorithms appear as cards in the layout picker / quick slots, so this engine is a placement...
Definition AutotileEngine.h:544
void onWindowResized(const QString &rawWindowId, const QRect &oldFrame, const QRect &newFrame, const QString &screenId) override
Reflow neighbors after a window was interactively resized.
void retile(const QString &screenId=QString()) override
Force retiling of windows.
bool isModeSpecificFloated(const QString &windowId) const override
Definition AutotileEngine.h:236
void rotateWindows(bool clockwise, const PhosphorEngine::NavigationContext &ctx) override
Rotate all managed windows on the screen.
QString engineId() const override
Stable engine identity for HandoffContext.fromEngineId.
Definition AutotileEngine.h:549
void setWindowRegistry(QObject *registry) override
Wire up the shared WindowRegistry.
void reapplyManagedWindowAppearance() override
Re-drive the compositor's per-window appearance (border, hidden title bar) for every window this engi...
void clearAutotileFloated(const QString &rawWindowId)
QRect lastManagedRect(const QString &rawWindowId) const override
The tile rect this engine last emitted for rawWindowId via applyTiling, remembered PAST the window's ...
bool claimCrossScreenReopen(const QString &windowId, const QString &openingScreenId, int minWidth, int minHeight) override
Cross-screen session reclaim (see IPlacementEngine for the base contract).
void setFocusedWindow(const QString &windowId)
Notify the engine that a window has been focused.
QString screenForTrackedWindow(const QString &windowId) const override
Return the screen this engine considers the window to be on, or empty if the window isn't tracked by ...
Definition AutotileEngine.h:555
const QSet< QString > & autotileScreens() const
Get the set of screens currently using autotile.
Definition AutotileEngine.h:261
void unfloatWindow(const QString &windowId)
Unfloat a specific window by its ID (convenience forwarder)
::PhosphorLayout::EdgeGaps effectiveOuterGaps(const QString &screenId) const
void windowClosed(const QString &windowId) override
Notify the engine that a window was closed.
void markModeSpecificFloated(const QString &windowId) override
Definition AutotileEngine.h:252
QString heldScreenForWindow(const QString &windowId) const override
OPTIONAL: the screen this engine genuinely HOLDS the window on IN THE SCREEN'S CURRENT CONTEXT — a ME...
void enabledChanged(bool enabled)
Emitted when the enabled state changes.
void setActiveScreenHint(const QString &screenId) override
Set the active screen hint for keyboard shortcut handlers.
bool isEnabled() const noexcept override
Check if any screen has autotile enabled.
std::optional< int > savedMaxWindowsForAlgorithm(const QString &algorithmId) const override
The user's saved per-algorithm max-windows tuning, if any.
QSize windowMinimumSize(const QString &windowId) const override
The window's client-reported minimum size as last known by this engine, or an UNKNOWN answer when it ...
void updateDragInsertPreview(int insertIndex)
Update the target insert index for the active drag preview.
bool beginDragInsertPreview(const QString &rawWindowId, const QString &screenId) override
Begin a drag-insert preview on screenId, ADOPTING the window when necessary.
void updateDragInsertPreview(const DragInsertTarget &target) override
IPlacementEngine drop-target form: primary is the tiled-only insert index; secondary/newSlot are mean...
int runtimeMaxWindows() const override
Runtime max-windows limit.
std::optional< PhosphorEngine::WindowPlacement > capturePlacement(const QString &windowId) const override
Report windowId's CURRENT placement for persistence, or nullopt if this engine does not manage it.
void handoffReceive(const HandoffContext &ctx) override
Receive ownership of a window from another engine.
void clearPendingInitialOrder(const QString &screenId)
Drop a screen's initial-order seed: the order, its generation counter and its strict marker,...
QString effectiveAlgorithmId(const QString &screenId) const
QString activeScreen() const override
Get the last-focused screen (updated by onWindowFocused)
Definition AutotileEngine.h:270
void swapFocusedInDirection(const QString &direction, const QString &action=QStringLiteral("move"))
Swap the focused window with the adjacent window in tiling order.
void setCurrentActivity(const QString &activity) override
Set the current activity for per-activity tiling state.
void pruneStatesForDesktop(int removedDesktop) override
Prune PhosphorTiles::TilingState and saved floating entries for a removed desktop.
int computeDragInsertIndexAtPoint(const QString &screenId, const QPoint &cursorPos) const
Compute the insert index for a cursor position on an autotile screen.
Handles navigation, focus cycling, and ratio/count adjustments.
Definition NavigationController.h:34
Resolves per-screen configuration overrides for autotiling.
Definition PerScreenConfigResolver.h:41
Abstract contract for a tiling-algorithm registry.
Definition ITileAlgorithmRegistry.h:41
Abstract base class for tiling algorithms.
Definition TilingAlgorithm.h:54
Tracks tiling state for a single screen.
Definition TilingState.h:40
Manual zone-layout registry + per-context assignment store.
Definition LayoutRegistry.h:89
Represents a collection of zones that form a layout.
Definition Layout.h:42
Definition EngineTypes.h:14
constexpr QLatin1String LayoutRegistry("org.plasmazones.LayoutRegistry")
Definition IWindowTrackingService.h:27
Definition AutotileConfig.h:13
Definition AutotileEngine.h:59
AutotileInsertPosition
Definition AutotileConstants.h:191
Definition IWindowTrackingService.h:23
Where a drag-insert preview should place the dragged window, in the TARGET ENGINE's slot vocabulary.
Definition IPlacementEngine.h:543
Context for a cross-engine window handoff.
Definition IPlacementEngine.h:872
Target window + screen for a navigation or lifecycle operation.
Definition NavigationContext.h:18
Identity of a per-screen placement state: a window's placement is scoped to the (screen,...
Definition EngineTypes.h:22
Per-side edge gap values (resolved, non-negative pixel values)
Definition EdgeGaps.h:27
Configuration for autotiling behavior.
Definition AutotileConfig.h:82
Active drag-insert preview state.
Definition AutotileEngineTypes.h:125
An already-managed window ARRIVING in a state via migrateWindowBetweenKeys, with the float state it h...
Definition AutotileEngineTypes.h:32
Script-state bag rescued from a TilingState that a teardown destroys, so a re-created state for the s...
Definition AutotileEngineTypes.h:107