diff --git a/src/config/bismuth_config.kcfg b/src/config/bismuth_config.kcfg index f4e57ede..67799221 100644 --- a/src/config/bismuth_config.kcfg +++ b/src/config/bismuth_config.kcfg @@ -43,6 +43,11 @@ false + + + true + + false diff --git a/src/core/ts-proxy.cpp b/src/core/ts-proxy.cpp index 0fa25a9f..fdfd9278 100644 --- a/src/core/ts-proxy.cpp +++ b/src/core/ts-proxy.cpp @@ -54,6 +54,7 @@ QJSValue TSProxy::jsConfig() addLayout("enableQuarterLayout", "QuarterLayout"); addLayout("enableFloatingLayout", "FloatingLayout"); addLayout("enableCascadeLayout", "CascadeLayout"); + addLayout("enableSlabsLayout", "SlabsLayout"); setProp("monocleMaximize", m_config.monocleMaximize()); setProp("maximizeSoleTile", m_config.maximizeSoleTile()); diff --git a/src/kcm/package/contents/ui/views/Layouts.qml b/src/kcm/package/contents/ui/views/Layouts.qml index cd59dc1d..442a272e 100644 --- a/src/kcm/package/contents/ui/views/Layouts.qml +++ b/src/kcm/package/contents/ui/views/Layouts.qml @@ -52,6 +52,11 @@ Kirigami.Page { settingName: "enableQuarterLayout" } + ListElement { + name: "Slabs" + settingName: "enableSlabsLayout" + } + ListElement { name: "Floating" settingName: "enableFloatingLayout" diff --git a/src/kwinscript/controller/action.ts b/src/kwinscript/controller/action.ts index c83da63f..5143c9ff 100644 --- a/src/kwinscript/controller/action.ts +++ b/src/kwinscript/controller/action.ts @@ -570,6 +570,19 @@ export class ToggleSpiralLayout extends ToggleCurrentLayout { } } +export class ToggleSlabsLayout extends ToggleCurrentLayout { + constructor(protected engine: Engine, protected log: Log) { + super( + engine, + "SlabsLayout", + "toggle_slabs_layout", + "Toggle Slabs Layout", + "", + log + ); + } +} + export class Rotate extends ActionImpl implements Action { constructor(protected engine: Engine, protected log: Log) { super(engine, "rotate", "Rotate", "Meta+R", log); diff --git a/src/kwinscript/controller/index.ts b/src/kwinscript/controller/index.ts index aae1af0d..e6c1393c 100644 --- a/src/kwinscript/controller/index.ts +++ b/src/kwinscript/controller/index.ts @@ -424,6 +424,7 @@ export class ControllerImpl implements Controller { new Action.ToggleFloatingLayout(this.engine, this.log), new Action.ToggleQuarterLayout(this.engine, this.log), new Action.ToggleSpiralLayout(this.engine, this.log), + new Action.ToggleSlabsLayout(this.engine, this.log), new Action.Rotate(this.engine, this.log), new Action.RotateReverse(this.engine, this.log), diff --git a/src/kwinscript/engine/layout/slabs_layout.ts b/src/kwinscript/engine/layout/slabs_layout.ts new file mode 100644 index 00000000..874f0061 --- /dev/null +++ b/src/kwinscript/engine/layout/slabs_layout.ts @@ -0,0 +1,83 @@ +// SPDX-FileCopyrightText: 2022 Joe Dean +// +// SPDX-License-Identifier: MIT + +import { WindowsLayout } from "."; + +import { WindowState, EngineWindow } from "../window"; + +import { Rect } from "../../util/rect"; +import { Config } from "../../config"; +import { Controller } from "../../controller"; + +/* "Slabs" stacks up to 5 windows bottom-to-top (ideal for vertically-rotated +monitors). It shares the available space equally between windows; if there are +more than 2 windows, the "first" window will be given 50% more than the others*/ +export default class SlabsLayout implements WindowsLayout { + public static readonly id = "SlabsLayout"; + public readonly classID = SlabsLayout.id; + public readonly name = "Slabs Layout"; + public readonly icon = "bismuth-slabs"; + public readonly capacity = 3; + + private config: Config; + + public constructor(config: Config) { + this.config = config; + } + + public clone(): WindowsLayout { + return new SlabsLayout(this.config); + } + + public apply( + _controller: Controller, + tileables: EngineWindow[], + area: Rect + ): void { + if (tileables.length <= 0) { + return; + } + + const tileCount = Math.min(this.capacity, tileables.length); + let tileSize = + (area.height - Math.max(0, tileCount - 1) * this.config.tileLayoutGap) / + tileCount; + let firstTileSize = tileSize; + if (tileCount > 2) { + firstTileSize *= 1.5; + tileSize = + (area.height - firstTileSize - tileCount * this.config.tileLayoutGap) / + (tileCount - 1); + } + + let xPos = 0; + for (let i = 0; i < tileCount; i++) { + const currentTileSize = i == 0 ? firstTileSize : tileSize; + tileables[i].geometry = new Rect( + area.x, + area.height - (xPos + currentTileSize), + area.width, + currentTileSize + ); + xPos += this.config.tileLayoutGap + currentTileSize; + } + for (let i = 0; i < tileables.length; i++) { + if (i < tileCount) { + tileables[i].state = WindowState.Tiled; + } else { + tileables[i].state = WindowState.TiledAfloat; + tileables[i].geometry = new Rect( + area.x, + area.y, + area.width, + area.height + ); + } + } + } + + public toString(): string { + return "SlabsLayout()"; + } +} diff --git a/src/kwinscript/engine/layout_store.ts b/src/kwinscript/engine/layout_store.ts index 8d1e8a68..4d765931 100644 --- a/src/kwinscript/engine/layout_store.ts +++ b/src/kwinscript/engine/layout_store.ts @@ -19,6 +19,7 @@ import SpiralLayout from "./layout/spiral_layout"; import SpreadLayout from "./layout/spread_layout"; import StairLayout from "./layout/stair_layout"; import ThreeColumnLayout from "./layout/three_column_layout"; +import SlabsLayout from "./layout/slabs_layout"; export class LayoutStoreEntry { public get currentLayout(): WindowsLayout { @@ -96,6 +97,8 @@ export class LayoutStoreEntry { return new ThreeColumnLayout(this.config); } else if (id == TileLayout.id) { return new TileLayout(this.config); + } else if (id == SlabsLayout.id) { + return new SlabsLayout(this.config); } else { return new FloatingLayout(); } diff --git a/src/kwinscript/icons/16-status-bismuth-slabs.svg b/src/kwinscript/icons/16-status-bismuth-slabs.svg new file mode 100644 index 00000000..59fc9017 --- /dev/null +++ b/src/kwinscript/icons/16-status-bismuth-slabs.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/src/kwinscript/icons/32-status-bismuth-slabs.svg b/src/kwinscript/icons/32-status-bismuth-slabs.svg new file mode 100644 index 00000000..16167003 --- /dev/null +++ b/src/kwinscript/icons/32-status-bismuth-slabs.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/src/kwinscript/icons/CMakeLists.txt b/src/kwinscript/icons/CMakeLists.txt index 0c73ca01..12253e98 100644 --- a/src/kwinscript/icons/CMakeLists.txt +++ b/src/kwinscript/icons/CMakeLists.txt @@ -7,6 +7,7 @@ ecm_install_icons( 16-status-bismuth-floating.svg 16-status-bismuth-monocle.svg 16-status-bismuth-quarter.svg + 16-status-bismuth-slabs.svg 16-status-bismuth-spiral.svg 16-status-bismuth-spread.svg 16-status-bismuth-stair.svg @@ -15,6 +16,7 @@ ecm_install_icons( 32-status-bismuth-floating.svg 32-status-bismuth-monocle.svg 32-status-bismuth-quarter.svg + 32-status-bismuth-slabs.svg 32-status-bismuth-spiral.svg 32-status-bismuth-spread.svg 32-status-bismuth-stair.svg