implement parsing of presetWidths

This commit is contained in:
Peter Fajdiga
2024-10-02 23:36:58 +02:00
parent f5ca5e71c0
commit 3ff7688e42
9 changed files with 101 additions and 0 deletions

View File

@@ -25,4 +25,14 @@ Item {
flags: Notification.Persistent
urgency: Notification.HighUrgency
}
Notification {
id: notificationInvalidPresetWidths
componentName: "plasma_workspace"
eventId: "notification"
title: "Karousel"
text: "Your preset widths are malformed, please review your Karousel configuration"
flags: Notification.Persistent
urgency: Notification.HighUrgency
}
}

View File

@@ -3,3 +3,4 @@ declare const KWin: KWin;
declare const Workspace: Workspace;
declare const qmlBase: QmlObject;
declare const notificationInvalidWindowRules: Notification;
declare const notificationInvalidPresetWidths: Notification;

View File

@@ -7,6 +7,7 @@ type Config = {
gapsInnerVertical: number;
manualScrollStep: number;
manualResizeStep: number;
presetWidths: string;
offScreenOpacity: number;
untileOnDrag: boolean;
stackColumnsByDefault: boolean;

38
src/lib/config/utils.ts Normal file
View File

@@ -0,0 +1,38 @@
type PresetWidth = ((screenWidth: number, spacing: number) => number);
function parsePresetWidths(presetWidths: string): PresetWidth[] {
function parseNumberSafe(str: string) {
const num = Number(str);
if (isNaN(num) || num <= 0) {
throw new Error("Invalid number: " + str);
}
return num;
}
function parseNumberWithSuffix(str: string, suffix: string) {
if (!str.endsWith(suffix)) {
return undefined;
}
return parseNumberSafe(str.substring(0, str.length-suffix.length).trim());
}
function getRatioFunction(ratio: number) {
return (screenWidth: number, spacing: number) => Math.floor((screenWidth + spacing) * ratio - spacing);
}
return presetWidths.split(",").map((widthStr: string) => {
widthStr = widthStr.trim();
const widthPx = parseNumberWithSuffix(widthStr, "px");
if (widthPx !== undefined) {
return () => widthPx;
}
const widthPct = parseNumberWithSuffix(widthStr, "%");
if (widthPct !== undefined) {
return getRatioFunction(widthPct / 100.0);
}
return getRatioFunction(parseNumberSafe(widthStr));
});
}

View File

@@ -316,6 +316,7 @@ namespace Actions {
export type Config = {
manualScrollStep: number;
manualResizeStep: number;
presetWidths: PresetWidth[];
columnResizer: ColumnResizer;
};

View File

@@ -8,9 +8,19 @@ class World {
constructor(config: Config) {
this.workspaceSignalManager = initWorkspaceSignalHandlers(this);
let presetWidths: PresetWidth[] = [];
try {
presetWidths = parsePresetWidths(config.presetWidths);
} catch (error: any) {
notificationInvalidPresetWidths.sendEvent();
log("failed to parse presetWidths:", error);
}
this.shortcutActions = registerKeyBindings(this, {
manualScrollStep: config.manualScrollStep,
manualResizeStep: config.manualResizeStep,
presetWidths: presetWidths,
columnResizer: config.scrollingCentered ? new RawResizer() : new ContextualResizer(),
});

View File

@@ -0,0 +1,32 @@
tests.register("parsePresetWidths", 1, () => {
const screenWidth = 800;
const spacing = 10;
const testCases = [
{ str: "100%, 50%", result: [800, 395] },
{ str: "100px,50 px", result: [100, 50] },
{ str: "100px, 25 % , 0.1 ", result: [100, 192, 71] },
{ str: "100px, 25 % , 0.1p", error: true },
{ str: "100px, % , 0.1 ", error: true },
{ str: "100px, , 0.1 ", error: true },
{ str: "100px,, 0.1 ", error: true },
{ str: "100px, 25 % , ", error: true },
{ str: "asdf", error: true },
{ str: "", error: true },
{ str: " ", error: true },
];
function applyPresetWidths(presetWidths: PresetWidth[]) {
return presetWidths.map(f => f(screenWidth, spacing));
}
for (const testCase of testCases) {
try {
const result = parsePresetWidths(testCase.str);
assert(!testCase.error);
assertArrayEqual(applyPresetWidths(result), testCase.result!);
} catch (error) {
assert(testCase.error === true);
}
}
});

View File

@@ -29,6 +29,13 @@ Expected: ${expected}
Actual: ${actual}`, skip+1);
}
function assertArrayEqual(actual: any[], expected: any[], skip: number = 0) {
const equal = actual.length === expected.length && actual.every((item, index) => item === expected[index]);
assert(equal, `Arrays not equal
Expected: ${expected}
Actual: ${actual}`, skip+1);
}
function assertRectEqual(actual: QmlRect, expected: QmlRect, skip: number = 0) {
assert(rectEquals(expected, actual), `QmlRect not equal
Expected: ${expected}

View File

@@ -3,3 +3,4 @@ let KWin: KWin;
let Workspace: Workspace;
let qmlBase: QmlObject;
let notificationInvalidWindowRules: Notification;
let notificationInvalidPresetWidths: Notification;