From 1070bcffd95911759afe54765211924b2f017ec5 Mon Sep 17 00:00:00 2001 From: Diogo Ferreira Date: Fri, 5 Aug 2022 13:29:50 +0100 Subject: [PATCH] feat(smartgaps): Hide gaps if showing a single window Currently disabled by default but adds a toggle that will hide gaps if only a single window is visible. The feature is implemented both in the cpp and ts engines. --- src/config/bismuth_config.kcfg | 5 ++ src/core/engine/engine.cpp | 2 +- src/core/engine/layout/layout.cpp | 6 ++- src/core/engine/layout/layout.hpp | 2 +- src/core/ts-proxy.cpp | 1 + src/kcm/package/contents/ui/Appearance.qml | 5 ++ src/kwinscript/config.ts | 1 + src/kwinscript/engine/index.ts | 53 +++++++++++++--------- 8 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/config/bismuth_config.kcfg b/src/config/bismuth_config.kcfg index f4e57ede..8a2be8bf 100644 --- a/src/config/bismuth_config.kcfg +++ b/src/config/bismuth_config.kcfg @@ -163,6 +163,11 @@ 0 + + + false + + false diff --git a/src/core/engine/engine.cpp b/src/core/engine/engine.cpp index b7528308..71bbc5d5 100644 --- a/src/core/engine/engine.cpp +++ b/src/core/engine/engine.cpp @@ -230,11 +230,11 @@ Surface Engine::activeSurface() const void Engine::arrangeWindowsOnSurface(const Surface &surface) { auto &layout = m_activeLayouts.layoutOnSurface(surface); - auto tilingArea = layout.tilingArea(workingArea(surface)); auto visibleWindows = m_windows.visibleWindowsOn(surface); auto windowsThatCanBeTiled = visibleWindows; // TODO: Filter windows + auto tilingArea = layout.tilingArea(workingArea(surface), windowsThatCanBeTiled); layout.apply(tilingArea, windowsThatCanBeTiled); } diff --git a/src/core/engine/layout/layout.cpp b/src/core/engine/layout/layout.cpp index de21cd42..b6d1bac0 100644 --- a/src/core/engine/layout/layout.cpp +++ b/src/core/engine/layout/layout.cpp @@ -10,8 +10,12 @@ Layout::Layout(const Bismuth::Config &config) { } -QRect Layout::tilingArea(QRect workingArea) const +QRect Layout::tilingArea(QRect workingArea, std::vector &windows) const { + if (windows.size() == 1 && m_config.smartGaps()) { + return workingArea; + } + auto marginLeft = m_config.screenGapLeft(); auto marginTop = m_config.screenGapTop(); auto marginRight = m_config.screenGapRight(); diff --git a/src/core/engine/layout/layout.hpp b/src/core/engine/layout/layout.hpp index d36983bf..70df8a65 100644 --- a/src/core/engine/layout/layout.hpp +++ b/src/core/engine/layout/layout.hpp @@ -24,7 +24,7 @@ struct Layout { /** * Get the area on which tiled windows could be placed given the general @p workingArea */ - virtual QRect tilingArea(QRect workingArea) const; + virtual QRect tilingArea(QRect workingArea, std::vector &windows) const; protected: const Bismuth::Config &m_config; diff --git a/src/core/ts-proxy.cpp b/src/core/ts-proxy.cpp index 0fa25a9f..1b8be1c9 100644 --- a/src/core/ts-proxy.cpp +++ b/src/core/ts-proxy.cpp @@ -75,6 +75,7 @@ QJSValue TSProxy::jsConfig() setProp("screenGapRight", m_config.screenGapRight()); setProp("screenGapTop", m_config.screenGapTop()); setProp("tileLayoutGap", m_config.tileLayoutGap()); + setProp("smartGaps", m_config.smartGaps()); setProp("newWindowAsMaster", m_config.newWindowAsMaster()); setProp("layoutPerActivity", m_config.layoutPerActivity()); diff --git a/src/kcm/package/contents/ui/Appearance.qml b/src/kcm/package/contents/ui/Appearance.qml index 7be410aa..54baf0ea 100644 --- a/src/kcm/package/contents/ui/Appearance.qml +++ b/src/kcm/package/contents/ui/Appearance.qml @@ -41,6 +41,11 @@ Kirigami.FormLayout { Kirigami.FormData.label: "Inner Gaps" } + BIC.ConfigCheckBox { + text: i18n("Hide gaps if showing a single window") + settingName: "smartGaps" + } + BIC.PixelsConfigSpinBox { Kirigami.FormData.label: i18n("All:") settingName: "tileLayoutGap" diff --git a/src/kwinscript/config.ts b/src/kwinscript/config.ts index 4241ec03..a8ac8fca 100644 --- a/src/kwinscript/config.ts +++ b/src/kwinscript/config.ts @@ -26,6 +26,7 @@ export interface Config { screenGapRight: number; screenGapTop: number; tileLayoutGap: number; + smartGaps: boolean; //#endregion //#region Behavior diff --git a/src/kwinscript/engine/index.ts b/src/kwinscript/engine/index.ts index 149c972a..656fdf66 100644 --- a/src/kwinscript/engine/index.ts +++ b/src/kwinscript/engine/index.ts @@ -191,13 +191,16 @@ export class EngineImpl implements Engine { const srf = basis.surface; const layout = this.layouts.getCurrentLayout(srf); if (layout.adjust) { - const area = srf.workingArea.gap( - this.config.screenGapLeft, - this.config.screenGapRight, - this.config.screenGapTop, - this.config.screenGapBottom - ); const tiles = this.windows.visibleTiledWindowsOn(srf); + const noGaps = tiles.length == 1 && this.config.smartGaps; + const area = noGaps + ? srf.workingArea + : srf.workingArea.gap( + this.config.screenGapLeft, + this.config.screenGapRight, + this.config.screenGapTop, + this.config.screenGapBottom + ); layout.adjust(area, tiles, basis, basis.geometryDelta); } } @@ -285,18 +288,17 @@ export class EngineImpl implements Engine { const layout = this.layouts.getCurrentLayout(srf); if (layout.adjust) { - const area = srf.workingArea.gap( - this.config.screenGapLeft, - this.config.screenGapRight, - this.config.screenGapTop, - this.config.screenGapBottom - ); - layout.adjust( - area, - this.windows.visibleTileableWindowsOn(srf), - basis, - delta - ); + const tiles = this.windows.visibleTiledWindowsOn(srf); + const noGaps = tiles.length == 1 && this.config.smartGaps; + const area = noGaps + ? srf.workingArea + : srf.workingArea.gap( + this.config.screenGapLeft, + this.config.screenGapRight, + this.config.screenGapTop, + this.config.screenGapBottom + ); + layout.adjust(area, tiles, basis, delta); } } @@ -330,9 +332,8 @@ export class EngineImpl implements Engine { const layout = this.layouts.getCurrentLayout(screenSurface); const workingArea = screenSurface.workingArea; - const tilingArea = this.getTilingArea(workingArea, layout); - const visibleWindows = this.windows.visibleWindowsOn(screenSurface); + const tilingArea = this.getTilingArea(workingArea, layout, visibleWindows); // Set correct window state for new windows visibleWindows.forEach((win: EngineWindow) => { @@ -740,9 +741,17 @@ export class EngineImpl implements Engine { * * @param workingArea area in which we are allowed to work. @see DriverSurface#workingArea * @param layout windows layout used + * @param visibleWindows the windows visible in the working area. */ - private getTilingArea(workingArea: Rect, layout: WindowsLayout): Rect { - if (this.config.monocleMaximize && layout instanceof MonocleLayout) { + private getTilingArea( + workingArea: Rect, + layout: WindowsLayout, + visibleWindows: EngineWindow[] + ): Rect { + if ( + (this.config.monocleMaximize && layout instanceof MonocleLayout) || + (visibleWindows.length == 1 && this.config.smartGaps) + ) { return workingArea; } else { return workingArea.gap(