implement parsing of presetWidths
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
1
src/extern/global.d.ts
vendored
1
src/extern/global.d.ts
vendored
@@ -3,3 +3,4 @@ declare const KWin: KWin;
|
||||
declare const Workspace: Workspace;
|
||||
declare const qmlBase: QmlObject;
|
||||
declare const notificationInvalidWindowRules: Notification;
|
||||
declare const notificationInvalidPresetWidths: Notification;
|
||||
|
||||
@@ -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
38
src/lib/config/utils.ts
Normal 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));
|
||||
});
|
||||
}
|
||||
@@ -316,6 +316,7 @@ namespace Actions {
|
||||
export type Config = {
|
||||
manualScrollStep: number;
|
||||
manualResizeStep: number;
|
||||
presetWidths: PresetWidth[];
|
||||
columnResizer: ColumnResizer;
|
||||
};
|
||||
|
||||
|
||||
@@ -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(),
|
||||
});
|
||||
|
||||
|
||||
32
src/tests/units/config/utils.ts
Normal file
32
src/tests/units/config/utils.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -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}
|
||||
|
||||
@@ -3,3 +3,4 @@ let KWin: KWin;
|
||||
let Workspace: Workspace;
|
||||
let qmlBase: QmlObject;
|
||||
let notificationInvalidWindowRules: Notification;
|
||||
let notificationInvalidPresetWidths: Notification;
|
||||
|
||||
Reference in New Issue
Block a user