diff --git a/README.md b/README.md index 44f23c4..968dec6 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,29 @@ KWin script to resize and move windows. Like Spectacle/Rectangle on mac. + +## Installation + Available in the [KDE store](https://store.kde.org/p/1492899/) +## Configuration + +The sizes can be changed by using the settings button in `System Settings +> KWin Scripts` + +![settings screenshot](meta/settings.png) + +To enable this menu you may need to link the script metadata to kservices5: + +```sh +mkdir -p ~/.local/share/kservices5/ +ln -s ~/.local/share/kwin/scripts/yanjing/metadata.desktop ~/.local/share/kservices5/yanjing.desktop +``` + +Why? See this [issue](https://github.com/faho/kwin-tiling/issues/79#issuecomment-311465357) + +Restarting plasma afterwards in recommended. + ## Commands - Yanjing LEFT - `no default` diff --git a/contents/code/main.js b/contents/code/main.js index 213be76..1012f1c 100644 --- a/contents/code/main.js +++ b/contents/code/main.js @@ -12,14 +12,38 @@ Yanjing.States = { ERROR: 'ERROR', }; -// Percent of screen to fill -Yanjing.Sizes = [ - 75, - 100 / 3 * 2, - 50, - 100 / 3, - 25, -]; +/** + * @param {string} sizesStringList comma separated + * @return {number[]} No zero/falsies + */ +Yanjing.sanitizeSizes = function (sizesStringList) { + return (sizesStringList + .split(',') + .map(function ensureFloat(v) { + return parseFloat(v); // also serves to trim() + }) + .filter(Boolean) // remove 0 and NaN + ); +} + +var DEFAULT_SIZES = '75,66.6666,50,33.3333,25'; + +var configSizes = []; +var configSizesString = ''; +try { + var configSizesString = readConfig('sizes', '').toString(); + configSizes = Yanjing.sanitizeSizes(configSizesString); +} catch (err) { + print(err); +} + +if (configSizes.length > 0) { + Yanjing.Sizes = configSizes; + print('Using custom sizes', configSizesString); +} else { + Yanjing.Sizes = Yanjing.sanitizeSizes(DEFAULT_SIZES); + print('Using DEFAULT_SIZES', DEFAULT_SIZES); +} Yanjing.Dirs = { Left: 'Left', @@ -123,6 +147,7 @@ Yanjing.cycle = function (client, dir) { rect.width = nextWidth; client.geometry = rect; + // Move again after cycle to fix reposition due to resize var after = Yanjing.AfterCycle[dir]; return after && after(client); }; diff --git a/contents/code/main.spec.js b/contents/code/main.spec.js index 5c88201..2e21e95 100644 --- a/contents/code/main.spec.js +++ b/contents/code/main.spec.js @@ -3,6 +3,11 @@ // =========================================================================== global.print = jest.fn()//.mockImplementation((str) => console.error(str)); + +global.readConfig = jest.fn().mockImplementation(function (key, defaults) { + return defaults; +}); + global.registerShortcut = jest.fn(); global.KWin = { @@ -48,6 +53,13 @@ it('calls registerShortcut in main', () => { expect(global.registerShortcut).toHaveBeenCalledTimes(6); }); +describe('sanitizeSizes', () => { + it('returns array of filtered floats', () => { + expect(Yanjing.sanitizeSizes('0, 5, 10, x, 111.111, 0, 222.333')) + .toEqual([5, 10, 111.111, 222.333]); + }); +}); + describe('sizeToWidth', () => { it(`should return px value against work area width`, () => { expect(Yanjing.sizeToWidth(33.333)).toBeCloseTo(615.99384); @@ -59,7 +71,7 @@ describe('sizeToWidth', () => { describe('widthToSizeIndex', () => { it(`should return size index relative to ${global.workspace.workspaceWidth}`, () => { expect(Yanjing.widthToSizeIndex(640)) - .toBe(Yanjing.Sizes.findIndex((s) => s === 100/3)); + .toBe(Yanjing.Sizes.findIndex((s) => s === 33.3333)); expect(Yanjing.widthToSizeIndex(HALF_SCREEN)) .toBe(Yanjing.Sizes.findIndex((s) => s === 50)); }); diff --git a/contents/config/main.xml b/contents/config/main.xml new file mode 100644 index 0000000..3e0c07d --- /dev/null +++ b/contents/config/main.xml @@ -0,0 +1,12 @@ + + + + + + 75,66.6666,50,33.3333,25 + + + diff --git a/contents/ui/config.ui b/contents/ui/config.ui new file mode 100644 index 0000000..415db2e --- /dev/null +++ b/contents/ui/config.ui @@ -0,0 +1,51 @@ + + + KWin::YanjingConfigForm + + + + 0 + 0 + 480 + 320 + + + + Yanjing + + + + + + + + Sizes, float, comma sep + + + + + + + Comma separated window size percentages, e.g. "66.6666, 50, 25" + + + Window width percentages + + + Window width percentages + + + 75,66.6666,50,33.3333,25 + + + e.g. 75,66.6666,50,33.3333,25 + + + + + + + + + + diff --git a/meta/settings.png b/meta/settings.png new file mode 100644 index 0000000..4e48683 Binary files /dev/null and b/meta/settings.png differ diff --git a/metadata.desktop b/metadata.desktop index 916e16b..61a39ba 100644 --- a/metadata.desktop +++ b/metadata.desktop @@ -5,7 +5,11 @@ Comment=Window size and movement Icon=preferences-system-windows-script-test Type=Service -X-KDE-ServiceTypes=KWin/Script +X-KDE-ServiceTypes=KWin/Script,KCModule +X-Plasma-API=javascript +X-Plasma-MainScript=code/main.js + +X-KDE-PluginInfo-EnabledByDefault=true X-KDE-PluginInfo-Name=yanjing X-KDE-PluginInfo-Version=4.1.1 @@ -16,8 +20,7 @@ X-KDE-PluginInfo-Website=https://github.com/davidosomething/yanjing X-KDE-PluginInfo-Email=me@davidosomething.com X-KDE-PluginInfo-License=MIT -X-KDE-PluginInfo-EnabledByDefault=true - -X-Plasma-API=javascript -X-Plasma-MainScript=code/main.js +X-KDE-Library=kwin/effects/configs/kcm_kwin4_genericscripted +X-KDE-PluginKeyword=yanjing +X-KDE-ParentComponents=yanjing diff --git a/package.json b/package.json index f90ab79..55c162a 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "scripts": { "test": "jest", "debugger": "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.showInteractiveKWinConsole", + "restartplasma": "kquitapp5 plasmashell; kstart5 plasmashell", "kwin:is_installed": "plasmapkg2 --type kwinscript --show yanjing", "kwin:install": "plasmapkg2 --type kwinscript --install .", "kwin:upgrade": "plasmapkg2 --type kwinscript --upgrade .", diff --git a/scripts/metadata.njk b/scripts/metadata.njk index cae5f0c..8b220ed 100644 --- a/scripts/metadata.njk +++ b/scripts/metadata.njk @@ -5,7 +5,11 @@ Comment={{ description }} Icon=preferences-system-windows-script-test Type=Service -X-KDE-ServiceTypes=KWin/Script +X-KDE-ServiceTypes=KWin/Script,KCModule +X-Plasma-API=javascript +X-Plasma-MainScript={{ main }} + +X-KDE-PluginInfo-EnabledByDefault=true X-KDE-PluginInfo-Name={{ name }} X-KDE-PluginInfo-Version={{ version }} @@ -16,7 +20,6 @@ X-KDE-PluginInfo-Website={{ homepage }} X-KDE-PluginInfo-Email={{ author.email }} X-KDE-PluginInfo-License={{ license }} -X-KDE-PluginInfo-EnabledByDefault=true - -X-Plasma-API=javascript -X-Plasma-MainScript={{ main }} +X-KDE-Library=kwin/effects/configs/kcm_kwin4_genericscripted +X-KDE-PluginKeyword=yanjing +X-KDE-ParentComponents=yanjing