diff --git a/.gitignore b/.gitignore index be6e2d58..c61a7cec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,11 @@ -/.vscode -/dist -/out -/node_modules +.vscode +dist +out +node_modules .env target gen -/.cert +.cert # Submission Files /scripts/SBTemp diff --git a/documentation/schemas/layout.schema.json b/documentation/schemas/layout.schema.json index 3593f323..da6d16d3 100644 --- a/documentation/schemas/layout.schema.json +++ b/documentation/schemas/layout.schema.json @@ -1,275 +1,355 @@ { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "WindowManagerLayout", "type": "object", "properties": { "info": { + "default": { + "author": "", + "description": "", + "displayName": "", + "filename": "" + }, + "allOf": [ + { + "$ref": "#/definitions/WManagerLayoutInfo" + } + ] + }, + "noFallbackBehavior": { + "default": "Float", + "allOf": [ + { + "$ref": "#/definitions/NoFallbackBehavior" + } + ] + }, + "structure": { + "default": { + "active": null, + "condition": null, + "growFactor": 1.0, + "handles": [], + "priority": 1, + "subtype": "Permanent", + "type": "Fallback" + }, + "allOf": [ + { + "$ref": "#/definitions/WmNode" + } + ] + } + }, + "definitions": { + "NoFallbackBehavior": { + "type": "string", + "enum": [ + "Float", + "Unmanaged" + ] + }, + "NodeSubtype": { + "type": "string", + "enum": [ + "Temporal", + "Permanent" + ] + }, + "WManagerLayoutInfo": { "type": "object", "properties": { - "displayName": { - "type": "string", - "default": "Unknown" - }, "author": { - "type": "string", - "default": "Unknown" + "description": "Author of the layout", + "default": "", + "type": "string" }, "description": { - "type": "string", - "default": "Empty" + "description": "Description of the layout", + "default": "", + "type": "string" + }, + "displayName": { + "description": "Display name of the layout", + "default": "", + "type": "string" + }, + "filename": { + "description": "Filename of the layout, is overridden by the program on load.", + "default": "", + "type": "string" } - }, - "additionalProperties": false, - "default": {} + } }, - "structure": { - "anyOf": [ + "WmNode": { + "oneOf": [ { "type": "object", + "required": [ + "type" + ], "properties": { - "type": { - "type": "string", - "const": "Stack" - }, - "subtype": { - "type": "string", - "enum": [ - "Temporal", - "Permanent" - ], - "default": "Permanent" + "children": { + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/WmNode" + } }, - "priority": { - "type": "number", - "exclusiveMinimum": 0, - "description": "Order in how the tree will be traversed (1 = first, 2 = second, etc.)", - "default": 1 + "condition": { + "description": "Math Condition for the node to be shown, e.g: n >= 3", + "type": [ + "string", + "null" + ] }, "growFactor": { - "type": "number", "description": "How much of the remaining space this node will take", - "default": 1 + "default": 1.0, + "type": "number", + "format": "double" }, - "condition": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "string" - } - ] - }, - { - "type": "null" - } - ], - "description": "Math Condition for the node to be shown, e.g: n >= 3" + "priority": { + "description": "Order in how the tree will be traversed (1 = first, 2 = second, etc.)", + "default": 1, + "type": "integer", + "format": "uint32", + "minimum": 0.0 }, - "active": { - "anyOf": [ - { - "type": "number", - "minimum": 0, - "description": "Window handle" - }, + "subtype": { + "default": "Permanent", + "allOf": [ { - "type": "null" + "$ref": "#/definitions/NodeSubtype" } - ], - "description": "Window handle", - "default": null + ] }, - "handles": { - "type": "array", - "items": { - "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" - }, - "default": [] + "type": { + "type": "string", + "enum": [ + "Vertical" + ] } - }, - "required": [ - "type" - ], - "additionalProperties": false + } }, { "type": "object", + "required": [ + "type" + ], "properties": { - "type": { - "type": "string", - "const": "Fallback" - }, - "subtype": { - "type": "string", - "const": "Permanent", - "default": "Permanent" + "children": { + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/WmNode" + } }, - "priority": { - "$ref": "#/properties/structure/anyOf/0/properties/priority" + "condition": { + "description": "Math Condition for the node to be shown, e.g: n >= 3", + "type": [ + "string", + "null" + ] }, "growFactor": { - "$ref": "#/properties/structure/anyOf/0/properties/growFactor" + "description": "How much of the remaining space this node will take", + "default": 1.0, + "type": "number", + "format": "double" }, - "condition": { - "$ref": "#/properties/structure/anyOf/0/properties/condition" + "priority": { + "description": "Order in how the tree will be traversed (1 = first, 2 = second, etc.)", + "default": 1, + "type": "integer", + "format": "uint32", + "minimum": 0.0 }, - "active": { - "anyOf": [ - { - "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" - }, + "subtype": { + "default": "Permanent", + "allOf": [ { - "type": "null" + "$ref": "#/definitions/NodeSubtype" } - ], - "description": "Window handle", - "default": null + ] }, - "handles": { - "type": "array", - "items": { - "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" - }, - "default": [] + "type": { + "type": "string", + "enum": [ + "Horizontal" + ] } - }, - "required": [ - "type" - ], - "additionalProperties": false + } }, { "type": "object", + "required": [ + "type" + ], "properties": { - "type": { - "type": "string", - "const": "Leaf" - }, - "subtype": { - "$ref": "#/properties/structure/anyOf/0/properties/subtype" - }, - "priority": { - "$ref": "#/properties/structure/anyOf/0/properties/priority" + "condition": { + "description": "Math Condition for the node to be shown, e.g: n >= 3", + "type": [ + "string", + "null" + ] }, "growFactor": { - "$ref": "#/properties/structure/anyOf/0/properties/growFactor" - }, - "condition": { - "$ref": "#/properties/structure/anyOf/0/properties/condition" + "description": "How much of the remaining space this node will take", + "default": 1.0, + "type": "number", + "format": "double" }, "handle": { - "anyOf": [ - { - "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" - }, + "description": "window handle (HWND) in the node", + "type": [ + "integer", + "null" + ], + "format": "int" + }, + "priority": { + "description": "Order in how the tree will be traversed (1 = first, 2 = second, etc.)", + "default": 1, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "subtype": { + "default": "Permanent", + "allOf": [ { - "type": "null" + "$ref": "#/definitions/NodeSubtype" } - ], - "description": "Window handle", - "default": null + ] + }, + "type": { + "type": "string", + "enum": [ + "Leaf" + ] } - }, - "required": [ - "type" - ], - "additionalProperties": false + } }, { "type": "object", + "required": [ + "type" + ], "properties": { - "type": { - "type": "string", - "const": "Horizontal" - }, - "subtype": { - "$ref": "#/properties/structure/anyOf/0/properties/subtype" + "active": { + "description": "active window handle (HWND) in the node", + "type": [ + "integer", + "null" + ], + "format": "int" }, - "priority": { - "$ref": "#/properties/structure/anyOf/0/properties/priority" + "condition": { + "description": "Math Condition for the node to be shown, e.g: n >= 3", + "type": [ + "string", + "null" + ] }, "growFactor": { - "$ref": "#/properties/structure/anyOf/0/properties/growFactor" - }, - "condition": { - "$ref": "#/properties/structure/anyOf/0/properties/condition" + "description": "How much of the remaining space this node will take", + "default": 1.0, + "type": "number", + "format": "double" }, - "children": { + "handles": { + "description": "window handles (HWND) in the node", + "default": [], "type": "array", "items": { - "$ref": "#/properties/structure" - }, - "minItems": 1 + "type": "integer", + "format": "int" + } + }, + "priority": { + "description": "Order in how the tree will be traversed (1 = first, 2 = second, etc.)", + "default": 1, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "subtype": { + "default": "Permanent", + "allOf": [ + { + "$ref": "#/definitions/NodeSubtype" + } + ] + }, + "type": { + "type": "string", + "enum": [ + "Stack" + ] } - }, - "required": [ - "type", - "children" - ], - "additionalProperties": false + } }, { "type": "object", + "required": [ + "type" + ], "properties": { - "type": { - "type": "string", - "const": "Vertical" - }, - "subtype": { - "$ref": "#/properties/structure/anyOf/0/properties/subtype" + "active": { + "description": "active window handle (HWND) in the node", + "type": [ + "integer", + "null" + ], + "format": "int" }, - "priority": { - "$ref": "#/properties/structure/anyOf/0/properties/priority" + "condition": { + "description": "Math Condition for the node to be shown, e.g: n >= 3", + "type": [ + "string", + "null" + ] }, "growFactor": { - "$ref": "#/properties/structure/anyOf/0/properties/growFactor" - }, - "condition": { - "$ref": "#/properties/structure/anyOf/0/properties/condition" + "description": "How much of the remaining space this node will take", + "default": 1.0, + "type": "number", + "format": "double" }, - "children": { + "handles": { + "description": "window handles (HWND) in the node", + "default": [], "type": "array", "items": { - "$ref": "#/properties/structure" - }, - "minItems": 1 - } - }, - "required": [ - "type", - "children" - ], - "additionalProperties": false - } - ], - "description": "The layout tree", - "default": { - "type": "Fallback" - } - }, - "no_fallback_behavior": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} + "type": "integer", + "format": "int" + } + }, + "priority": { + "description": "Order in how the tree will be traversed (1 = first, 2 = second, etc.)", + "default": 1, + "type": "integer", + "format": "uint32", + "minimum": 0.0 }, - { + "subtype": { + "default": "Permanent", + "allOf": [ + { + "$ref": "#/definitions/NodeSubtype" + } + ] + }, + "type": { "type": "string", "enum": [ - "Float", - "Unmanaged" + "Fallback" ] } - ] - }, - { - "type": "null" + } } ] } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } } \ No newline at end of file diff --git a/documentation/schemas/placeholder.schema.json b/documentation/schemas/placeholder.schema.json index 01fe1cb6..70f0db3f 100644 --- a/documentation/schemas/placeholder.schema.json +++ b/documentation/schemas/placeholder.schema.json @@ -1,348 +1,885 @@ { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Placeholder", "type": "object", "properties": { + "center": { + "description": "Items to be displayed in the toolbar", + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/ToolbarItem" + } + }, "info": { + "description": "Metadata about the placeholder", + "default": { + "author": "", + "description": "", + "displayName": "", + "filename": "" + }, + "allOf": [ + { + "$ref": "#/definitions/PlaceholderInfo" + } + ] + }, + "left": { + "description": "Items to be displayed in the toolbar", + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/ToolbarItem" + } + }, + "right": { + "description": "Items to be displayed in the toolbar", + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/ToolbarItem" + } + } + }, + "definitions": { + "DateUpdateInterval": { + "type": "string", + "enum": [ + "millisecond", + "second", + "minute", + "hour", + "day" + ] + }, + "PlaceholderInfo": { "type": "object", "properties": { - "displayName": { - "type": "string", - "default": "Unknown" - }, "author": { - "type": "string", - "default": "Unknown" + "description": "Author of the placeholder", + "default": "", + "type": "string" }, "description": { - "type": "string", - "default": "Empty" + "description": "Description of the placeholder", + "default": "", + "type": "string" + }, + "displayName": { + "description": "Display name of the placeholder", + "default": "", + "type": "string" + }, + "filename": { + "description": "Filename of the placeholder, is overridden by the program on load.", + "default": "", + "type": "string" } - }, - "additionalProperties": false, - "default": {} + } }, - "left": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "object", - "properties": { - "id": { - "type": "string", - "default": "e0113b78-2a87-4706-b69c-d565384ab101" - }, - "type": { - "type": "string", - "enum": [ - "generic", - "text" + "StyleValue": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + { + "description": "Always less than zero.", + "type": "integer", + "format": "int64" + }, + { + "description": "Always finite.", + "type": "number", + "format": "double" + } + ] + }, + "ToolbarItem": { + "oneOf": [ + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Base Item Scope Have all icons defined on [React Icons](https://react-icons.github.io/react-icons) as properties of the object. ```js const icon: object; ``` Haves all environment variables defined on the system as properties of the object. ```js const env: object; ``` Functions to add images to the item. ```js function imgFromUrl (url: string, size: number = 16): string function imgFromPath (path: string, size: number = 16): string function imgFromExe (exe_path: string, size: number = 16): string ```", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "fc8df356-8876-445c-bb24-d0b91ec64b59", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Base Item Scope Have all icons defined on [React Icons](https://react-icons.github.io/react-icons) as properties of the object. ```js const icon: object; ``` Haves all environment variables defined on the system as properties of the object. ```js const env: object; ``` Functions to add images to the item. ```js function imgFromUrl (url: string, size: number = 16): string function imgFromPath (path: string, size: number = 16): string function imgFromExe (exe_path: string, size: number = 16): string ```", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] + } + }, + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Base Item Scope Have all icons defined on [React Icons](https://react-icons.github.io/react-icons) as properties of the object. ```js const icon: object; ``` Haves all environment variables defined on the system as properties of the object. ```js const env: object; ``` Functions to add images to the item. ```js function imgFromUrl (url: string, size: number = 16): string function imgFromPath (path: string, size: number = 16): string function imgFromExe (exe_path: string, size: number = 16): string ```", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Base Item Scope Have all icons defined on [React Icons](https://react-icons.github.io/react-icons) as properties of the object. ```js const icon: object; ``` Haves all environment variables defined on the system as properties of the object. ```js const env: object; ``` Functions to add images to the item. ```js function imgFromUrl (url: string, size: number = 16): string function imgFromPath (path: string, size: number = 16): string function imgFromExe (exe_path: string, size: number = 16): string ```", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "text" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Generic Item Scope ```ts // the current focused window const window: { name: string; title: string; exe: string | null; }; ```", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "8917dd3c-e730-4984-9196-6abcd855a1a0", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Generic Item Scope ```ts // the current focused window const window: { name: string; title: string; exe: string | null; }; ```", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } ] - }, - "template": { - "type": "string", - "default": "\"Unset\"" - }, - "tooltip": { - "type": [ - "string", - "null" - ], - "default": null - }, - "onClick": { - "type": [ - "string", - "null" - ], - "default": null - }, - "style": { - "type": "object", - "additionalProperties": {}, - "default": {} } }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "date" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - }, - "each": { - "type": "string", - "enum": [ - "second", - "minute", - "hour", - "day" - ], - "description": "Time unit to update the showing date", - "default": "minute" - }, - "format": { - "type": "string", - "default": "MMM Do, HH:mm" + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Generic Item Scope ```ts // the current focused window const window: { name: string; title: string; exe: string | null; }; ```", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Generic Item Scope ```ts // the current focused window const window: { name: string; title: string; exe: string | null; }; ```", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "generic" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Date Item Scope ```ts const date: string; // the formatted date ```", + "type": [ + "string", + "null" + ] + }, + "each": { + "description": "Time unit to refresh the showing date", + "default": "minute", + "allOf": [ + { + "$ref": "#/definitions/DateUpdateInterval" + } + ] + }, + "format": { + "description": "Format of the date, see [moment.js displaying format](https://momentjs.com/docs/#/displaying/format/)", + "default": "MMM Do, HH:mm", + "type": "string" + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "62e99c05-a17a-4c7a-b6f7-388cb80e89f0", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Date Item Scope ```ts const date: string; // the formatted date ```", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] + } + }, + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Date Item Scope ```ts const date: string; // the formatted date ```", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Date Item Scope ```ts const date: string; // the formatted date ```", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "date" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Power Item Scope ```ts interface PowerStatus { acLineStatus: number; batteryFlag: number; batteryLifePercent: number; systemStatusFlag: number; batteryLifeTime: number; batteryFullLifeTime: number; }\n\ninterface Battery { // Static info vendor: string | null; model: string | null; serialNumber: string | null; technology: string;\n\n// Common information state: string; capacity: number; temperature: number | null; percentage: number; cycleCount: number | null; smartCharging: boolean;\n\n// Energy stats energy: number; energyFull: number; energyFullDesign: number; energyRate: number; voltage: number;\n\n// Charge stats timeToFull: number | null; timeToEmpty: number | null; }\n\nconst power: PowerStatus; const batteries: Battery[]; const battery: Battery | null; ```", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "152e2c48-f4ac-4ed5-802e-0eed2d5e222f", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Power Item Scope ```ts interface PowerStatus { acLineStatus: number; batteryFlag: number; batteryLifePercent: number; systemStatusFlag: number; batteryLifeTime: number; batteryFullLifeTime: number; }\n\ninterface Battery { // Static info vendor: string | null; model: string | null; serialNumber: string | null; technology: string;\n\n// Common information state: string; capacity: number; temperature: number | null; percentage: number; cycleCount: number | null; smartCharging: boolean;\n\n// Energy stats energy: number; energyFull: number; energyFullDesign: number; energyRate: number; voltage: number;\n\n// Charge stats timeToFull: number | null; timeToEmpty: number | null; }\n\nconst power: PowerStatus; const batteries: Battery[]; const battery: Battery | null; ```", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] } }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "power" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Power Item Scope ```ts interface PowerStatus { acLineStatus: number; batteryFlag: number; batteryLifePercent: number; systemStatusFlag: number; batteryLifeTime: number; batteryFullLifeTime: number; }\n\ninterface Battery { // Static info vendor: string | null; model: string | null; serialNumber: string | null; technology: string;\n\n// Common information state: string; capacity: number; temperature: number | null; percentage: number; cycleCount: number | null; smartCharging: boolean;\n\n// Energy stats energy: number; energyFull: number; energyFullDesign: number; energyRate: number; voltage: number;\n\n// Charge stats timeToFull: number | null; timeToEmpty: number | null; }\n\nconst power: PowerStatus; const batteries: Battery[]; const battery: Battery | null; ```", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Power Item Scope ```ts interface PowerStatus { acLineStatus: number; batteryFlag: number; batteryLifePercent: number; systemStatusFlag: number; batteryLifeTime: number; batteryFullLifeTime: number; }\n\ninterface Battery { // Static info vendor: string | null; model: string | null; serialNumber: string | null; technology: string;\n\n// Common information state: string; capacity: number; temperature: number | null; percentage: number; cycleCount: number | null; smartCharging: boolean;\n\n// Energy stats energy: number; energyFull: number; energyFullDesign: number; energyRate: number; voltage: number;\n\n// Charge stats timeToFull: number | null; timeToEmpty: number | null; }\n\nconst power: PowerStatus; const batteries: Battery[]; const battery: Battery | null; ```", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "power" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Network Item Scope ```ts interface NetworkInterface { name: string; description: string; status: 'up' | 'down'; dnsSuffix: string; type: string; gateway: string | null; mac: string; ipv4: string | null; ipv6: string | null; } const online: boolean; const interfaces: NetworkInterface[]; const usingInterface: NetworkInterface | null; ```", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "fc1cc55c-f08d-4430-82fa-5fa9e5070217", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Network Item Scope ```ts interface NetworkInterface { name: string; description: string; status: 'up' | 'down'; dnsSuffix: string; type: string; gateway: string | null; mac: string; ipv4: string | null; ipv6: string | null; } const online: boolean; const interfaces: NetworkInterface[]; const usingInterface: NetworkInterface | null; ```", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] } }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "settings" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Network Item Scope ```ts interface NetworkInterface { name: string; description: string; status: 'up' | 'down'; dnsSuffix: string; type: string; gateway: string | null; mac: string; ipv4: string | null; ipv6: string | null; } const online: boolean; const interfaces: NetworkInterface[]; const usingInterface: NetworkInterface | null; ```", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Network Item Scope ```ts interface NetworkInterface { name: string; description: string; status: 'up' | 'down'; dnsSuffix: string; type: string; gateway: string | null; mac: string; ipv4: string | null; ipv6: string | null; } const online: boolean; const interfaces: NetworkInterface[]; const usingInterface: NetworkInterface | null; ```", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "network" + ] + }, + "withWlanSelector": { + "description": "Show Wi-fi selector popup on click]", + "default": false, + "type": "boolean" + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Media Item Scope ```ts const volume: number; // output master volume from 0 to 1 const isMuted: boolean; // output master volume is muted const inputVolume: number; // input master volume from 0 to 1 const inputIsMuted: boolean; // input master volume is muted\n\ninterface MediaSession { id: string; title: string; author: string; thumbnail: string | null; // path to temporal media session image playing: boolean; default: boolean; }\n\nconst mediaSession: MediaSession | null; ```", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "be7167af-90cd-4334-8de6-88a8fd1ad508", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Media Item Scope ```ts const volume: number; // output master volume from 0 to 1 const isMuted: boolean; // output master volume is muted const inputVolume: number; // input master volume from 0 to 1 const inputIsMuted: boolean; // input master volume is muted\n\ninterface MediaSession { id: string; title: string; author: string; thumbnail: string | null; // path to temporal media session image playing: boolean; default: boolean; }\n\nconst mediaSession: MediaSession | null; ```", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] } }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "workspaces" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - }, - "mode": { - "type": "string", - "enum": [ - "dotted", - "named", - "numbered" - ], - "default": "numbered" + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Media Item Scope ```ts const volume: number; // output master volume from 0 to 1 const isMuted: boolean; // output master volume is muted const inputVolume: number; // input master volume from 0 to 1 const inputIsMuted: boolean; // input master volume is muted\n\ninterface MediaSession { id: string; title: string; author: string; thumbnail: string | null; // path to temporal media session image playing: boolean; default: boolean; }\n\nconst mediaSession: MediaSession | null; ```", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Media Item Scope ```ts const volume: number; // output master volume from 0 to 1 const isMuted: boolean; // output master volume is muted const inputVolume: number; // input master volume from 0 to 1 const inputIsMuted: boolean; // input master volume is muted\n\ninterface MediaSession { id: string; title: string; author: string; thumbnail: string | null; // path to temporal media session image playing: boolean; default: boolean; }\n\nconst mediaSession: MediaSession | null; ```", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "media" + ] + }, + "withMediaControls": { + "description": "Show media controls popup on click", + "default": false, + "type": "boolean" + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Notifications Item Scope ```ts const count: number; ```", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "de8ad69e-c73b-45e8-a317-c0aa57f638ef", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Notifications Item Scope ```ts const count: number; ```", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] } }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "tray" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Notifications Item Scope ```ts const count: number; ```", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Notifications Item Scope ```ts const count: number; ```", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "notifications" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Workspace Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "59a54a5f-5013-4204-a36a-d00eefff318d", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Workspace Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] } }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "network" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - }, - "withWlanSelector": { - "type": "boolean", - "description": "Show Wi-fi settings on click (overrides onClick property)", - "default": false + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Workspace Item Scope this module does no expand the scope of the item", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Workspace Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "tray" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Device Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "9d1a7325-8ce1-4848-ac6c-2dc51789bed6", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Device Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] } }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "media" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - }, - "withMediaControls": { - "type": "boolean", - "default": false + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Device Item Scope this module does no expand the scope of the item", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Device Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "device" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Settings Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "02540ac5-eee6-4711-a5f6-4bc91540c6d6", + "type": "string" + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Settings Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] } }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "device" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Settings Item Scope this module does no expand the scope of the item", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Settings Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "settings" + ] + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "badge": { + "description": "Badge will be displayed over the item, useful as notifications.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Workspace Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Id to identify the item, should be unique.", + "default": "72ffc210-76ff-4ad5-844c-f7d70f31318c", + "type": "string" + }, + "mode": { + "default": "dotted", + "allOf": [ + { + "$ref": "#/definitions/WorkspaceToolbarItemMode" + } + ] + }, + "onClick": { + "description": "Deprecated use `onClickV2` instead.", + "type": [ + "string", + "null" + ] + }, + "onClickV2": { + "description": "This code will be parsed and executed when the item is clicked.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Workspace Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "style": { + "description": "Styles to be added to the item. This follow the same interface of React's `style` prop.", + "default": {}, + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/definitions/StyleValue" + }, + { + "type": "null" + } + ] } }, - "required": [ - "type" - ], - "additionalProperties": false + "template": { + "description": "Content to display in the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Workspace Item Scope this module does no expand the scope of the item", + "default": "", + "type": "string" + }, + "tooltip": { + "description": "Content to display in tooltip of the item.\n\nShould follow the [mathjs expression syntax](https://mathjs.org/docs/expressions/syntax.html).\n\n## Workspace Item Scope this module does no expand the scope of the item", + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "workspaces" + ] + } } - ] - }, - "default": [] - }, - "center": { - "type": "array", - "items": { - "$ref": "#/properties/left/items" - }, - "default": [] + } + ] }, - "right": { - "type": "array", - "items": { - "$ref": "#/properties/left/items" - }, - "default": [] + "WorkspaceToolbarItemMode": { + "type": "string", + "enum": [ + "dotted", + "named", + "numbered" + ] } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } } \ No newline at end of file diff --git a/documentation/schemas/settings.schema.json b/documentation/schemas/settings.schema.json index 596e8a29..333588a0 100644 --- a/documentation/schemas/settings.schema.json +++ b/documentation/schemas/settings.schema.json @@ -1,673 +1,1175 @@ { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Settings", "type": "object", "properties": { - "fancy_toolbar": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": true + "ahkEnabled": { + "description": "enable or disable ahk", + "default": true, + "type": "boolean" + }, + "ahkVariables": { + "description": "ahk variables", + "default": { + "decreaseHeight": { + "ahk": "#+-", + "fancy": "Win + Shift + -" }, - "height": { - "type": "number", - "exclusiveMinimum": 0, - "default": 30 + "decreaseWidth": { + "ahk": "#!-", + "fancy": "Win + Alt + -" }, - "placeholder": { - "type": [ - "string", - "null" - ], - "default": null - } - }, - "additionalProperties": false, - "default": {} - }, - "seelenweg": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": true + "focusBottom": { + "ahk": "#+s", + "fancy": "Win + Shift + S" }, - "mode": { - "type": "string", - "enum": [ - "Full-Width", - "Min-Content" - ], - "default": "Min-Content" + "focusLatest": { + "ahk": "#+e", + "fancy": "Win + Shift + E" }, - "hide_mode": { - "type": "string", - "enum": [ - "Never", - "Always", - "On-Overlap" - ], - "default": "On-Overlap" + "focusLeft": { + "ahk": "#+a", + "fancy": "Win + Shift + A" }, - "position": { - "type": "string", - "enum": [ - "Left", - "Right", - "Top", - "Bottom" - ], - "default": "Bottom" + "focusRight": { + "ahk": "#+d", + "fancy": "Win + Shift + D" }, - "visible_separators": { - "type": "boolean", - "default": true + "focusTop": { + "ahk": "#+w", + "fancy": "Win + Shift + W" }, - "size": { - "type": "number", - "exclusiveMinimum": 0, - "default": 40, - "description": "Item size in pixels" + "increaseHeight": { + "ahk": "#+=", + "fancy": "Win + Shift + =" }, - "zoom_size": { - "type": "number", - "exclusiveMinimum": 0, - "default": 70, - "description": "Zoomed item size in pixels" + "increaseWidth": { + "ahk": "#!=", + "fancy": "Win + Alt + =" }, - "margin": { - "type": "number", - "minimum": 0, - "default": 8, - "description": "Dock/Bar margin in pixels" + "moveToWorkspace0": { + "ahk": "!+1", + "fancy": "Alt + Shift + 1" }, - "padding": { - "type": "number", - "minimum": 0, - "default": 8, - "description": "Dock/Bar padding in pixels" + "moveToWorkspace1": { + "ahk": "!+2", + "fancy": "Alt + Shift + 2" }, - "space_between_items": { - "type": "number", - "minimum": 0, - "default": 8, - "description": "Space between items (gap) in pixels" - } - }, - "additionalProperties": false, - "default": {} - }, - "window_manager": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": false + "moveToWorkspace2": { + "ahk": "!+3", + "fancy": "Alt + Shift + 3" }, - "auto_stacking_by_category": { - "type": "boolean", - "default": true + "moveToWorkspace3": { + "ahk": "!+4", + "fancy": "Alt + Shift + 4" }, - "border": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": true - }, - "width": { - "type": "number", - "minimum": 0, - "default": 3 - }, - "offset": { - "type": "number", - "default": -1 - } - }, - "additionalProperties": false, - "default": {} + "moveToWorkspace4": { + "ahk": "!+5", + "fancy": "Alt + Shift + 5" }, - "resize_delta": { - "type": "number", - "default": 10, - "description": "% to add or remove on resize of windows using the CLI" + "moveToWorkspace5": { + "ahk": "!+6", + "fancy": "Alt + Shift + 6" }, - "workspace_gap": { - "type": "number", - "minimum": 0, - "default": 10, - "description": "Space between windows" + "moveToWorkspace6": { + "ahk": "!+7", + "fancy": "Alt + Shift + 7" }, - "workspace_padding": { - "type": "number", - "minimum": 0, - "default": 10 - }, - "global_work_area_offset": { - "type": "object", - "properties": { - "top": { - "type": "number", - "default": 0 - }, - "left": { - "type": "number", - "default": 0 - }, - "right": { - "type": "number", - "default": 0 - }, - "bottom": { - "type": "number", - "default": 0 - } - }, - "additionalProperties": false, - "default": {} + "moveToWorkspace7": { + "ahk": "!+8", + "fancy": "Alt + Shift + 8" }, - "floating": { - "type": "object", - "properties": { - "width": { - "type": "number", - "exclusiveMinimum": 0, - "default": 800 - }, - "height": { - "type": "number", - "exclusiveMinimum": 0, - "default": 500 - } - }, - "additionalProperties": false, - "default": {} + "moveToWorkspace8": { + "ahk": "!+9", + "fancy": "Alt + Shift + 9" }, - "default_layout": { - "type": [ - "string", - "null" - ], - "default": null + "moveToWorkspace9": { + "ahk": "!+0", + "fancy": "Alt + Shift + 0" + }, + "reserveBottom": { + "ahk": "#+k", + "fancy": "Win + Shift + K" + }, + "reserveFloat": { + "ahk": "#+u", + "fancy": "Win + Shift + U" + }, + "reserveLeft": { + "ahk": "#+j", + "fancy": "Win + Shift + J" + }, + "reserveRight": { + "ahk": "#+l", + "fancy": "Win + Shift + L" + }, + "reserveStack": { + "ahk": "#+o", + "fancy": "Win + Shift + O" + }, + "reserveTop": { + "ahk": "#+i", + "fancy": "Win + Shift + I" + }, + "restoreSizes": { + "ahk": "#!0", + "fancy": "Win + Alt + 0" + }, + "sendToWorkspace0": { + "ahk": "#+1", + "fancy": "Win + Shift + 1" + }, + "sendToWorkspace1": { + "ahk": "#+2", + "fancy": "Win + Shift + 2" + }, + "sendToWorkspace2": { + "ahk": "#+3", + "fancy": "Win + Shift + 3" + }, + "sendToWorkspace3": { + "ahk": "#+4", + "fancy": "Win + Shift + 4" + }, + "sendToWorkspace4": { + "ahk": "#+5", + "fancy": "Win + Shift + 5" + }, + "sendToWorkspace5": { + "ahk": "#+6", + "fancy": "Win + Shift + 6" + }, + "sendToWorkspace6": { + "ahk": "#+7", + "fancy": "Win + Shift + 7" + }, + "sendToWorkspace7": { + "ahk": "#+8", + "fancy": "Win + Shift + 8" + }, + "sendToWorkspace8": { + "ahk": "#+9", + "fancy": "Win + Shift + 9" + }, + "sendToWorkspace9": { + "ahk": "#+0", + "fancy": "Win + Shift + 0" + }, + "switchWorkspace0": { + "ahk": "!1", + "fancy": "Alt + 1" + }, + "switchWorkspace1": { + "ahk": "!2", + "fancy": "Alt + 2" + }, + "switchWorkspace2": { + "ahk": "!3", + "fancy": "Alt + 3" + }, + "switchWorkspace3": { + "ahk": "!4", + "fancy": "Alt + 4" + }, + "switchWorkspace4": { + "ahk": "!5", + "fancy": "Alt + 5" + }, + "switchWorkspace5": { + "ahk": "!6", + "fancy": "Alt + 6" + }, + "switchWorkspace6": { + "ahk": "!7", + "fancy": "Alt + 7" + }, + "switchWorkspace7": { + "ahk": "!8", + "fancy": "Alt + 8" + }, + "switchWorkspace8": { + "ahk": "!9", + "fancy": "Alt + 9" + }, + "switchWorkspace9": { + "ahk": "!0", + "fancy": "Alt + 0" } }, - "additionalProperties": false, - "default": {} + "allOf": [ + { + "$ref": "#/definitions/AhkVarList" + } + ] }, - "monitors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "workspaces": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "default": "New Workspace" - }, - "layout": { - "type": "string", - "default": "BSP" - }, - "padding": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number", - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "gap": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number", - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "minItems": 1, - "default": [ - { - "name": "New Workspace", - "layout": "BSP" - } - ] - }, - "work_area_offset": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "$ref": "#/properties/window_manager/properties/global_work_area_offset" - } - ] - }, - { - "type": "null" - } - ] - }, - "editing_workspace": { - "type": "number", - "minimum": 0, - "default": 0 - } - }, - "additionalProperties": false + "devTools": { + "description": "enable or disable dev tools tab in settings", + "default": false, + "type": "boolean" + }, + "fancyToolbar": { + "description": "fancy toolbar config", + "default": { + "enabled": true, + "height": 30, + "placeholder": "default.yml" }, - "minItems": 1, + "allOf": [ + { + "$ref": "#/definitions/FancyToolbarSettings" + } + ] + }, + "language": { + "description": "language to use, if null the system locale is used", + "default": "en", + "type": "string" + }, + "monitors": { + "description": "list of monitors", "default": [ { + "workAreaOffset": null, "workspaces": [ { + "gap": null, + "layout": "BSP", "name": "New Workspace", - "layout": "BSP" + "padding": null } - ], - "editing_workspace": 0 + ] + } + ], + "type": "array", + "items": { + "$ref": "#/definitions/Monitor" + } + }, + "seelenweg": { + "description": "seelenweg (dock/taskbar) config", + "default": { + "enabled": true, + "hideMode": "On-Overlap", + "margin": 8, + "mode": "Min-Content", + "padding": 8, + "position": "Bottom", + "size": 40, + "spaceBetweenItems": 8, + "visibleSeparators": true, + "zoomSize": 70 + }, + "allOf": [ + { + "$ref": "#/definitions/SeelenWegSettings" } ] }, - "ahk_enabled": { - "type": "boolean", - "default": true + "selectedTheme": { + "description": "list of selected themes", + "default": [ + "default" + ], + "type": "array", + "items": { + "type": "string" + } }, - "ahk_variables": { + "windowManager": { + "description": "window manager config", + "default": { + "autoStackingByCategory": true, + "border": { + "enabled": true, + "offset": -1.0, + "width": 3.0 + }, + "defaultLayout": "default.yml", + "enabled": false, + "floating": { + "height": 500.0, + "width": 800.0 + }, + "globalWorkAreaOffset": { + "bottom": 0, + "left": 0, + "right": 0, + "top": 0 + }, + "resizeDelta": 10.0, + "workspaceGap": 10.0, + "workspacePadding": 10.0 + }, + "allOf": [ + { + "$ref": "#/definitions/WindowManagerSettings" + } + ] + } + }, + "definitions": { + "AhkVar": { "type": "object", + "required": [ + "ahk", + "fancy" + ], "properties": { - "reserve_top": { - "type": "object", - "properties": { - "fancy": { - "type": "string" - }, - "ahk": { - "type": "string" - } - }, - "required": [ - "fancy", - "ahk" - ], - "additionalProperties": false, + "ahk": { + "type": "string" + }, + "fancy": { + "type": "string" + } + } + }, + "AhkVarList": { + "type": "object", + "properties": { + "decreaseHeight": { "default": { - "fancy": "Win + Shift + I", - "ahk": "#+i" - } + "ahk": "#+-", + "fancy": "Win + Shift + -" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "reserve_bottom": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "decreaseWidth": { "default": { - "fancy": "Win + Shift + K", - "ahk": "#+k" - } + "ahk": "#!-", + "fancy": "Win + Alt + -" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "reserve_left": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "focusBottom": { "default": { - "fancy": "Win + Shift + J", - "ahk": "#+j" - } + "ahk": "#+s", + "fancy": "Win + Shift + S" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "reserve_right": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "focusLatest": { "default": { - "fancy": "Win + Shift + L", - "ahk": "#+l" - } + "ahk": "#+e", + "fancy": "Win + Shift + E" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "reserve_float": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "focusLeft": { "default": { - "fancy": "Win + Shift + U", - "ahk": "#+u" - } + "ahk": "#+a", + "fancy": "Win + Shift + A" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "reserve_stack": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "focusRight": { "default": { - "fancy": "Win + Shift + O", - "ahk": "#+o" - } + "ahk": "#+d", + "fancy": "Win + Shift + D" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "focus_top": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "focusTop": { "default": { - "fancy": "Win + Shift + W", - "ahk": "#+w" - } + "ahk": "#+w", + "fancy": "Win + Shift + W" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "focus_bottom": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "increaseHeight": { "default": { - "fancy": "Win + Shift + S", - "ahk": "#+s" - } + "ahk": "#+=", + "fancy": "Win + Shift + =" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "focus_left": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "increaseWidth": { "default": { - "fancy": "Win + Shift + A", - "ahk": "#+a" - } + "ahk": "#!=", + "fancy": "Win + Alt + =" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "focus_right": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace0": { "default": { - "fancy": "Win + Shift + D", - "ahk": "#+d" - } + "ahk": "!+1", + "fancy": "Alt + Shift + 1" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "focus_latest": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace1": { "default": { - "fancy": "Win + Shift + E", - "ahk": "#+e" - } + "ahk": "!+2", + "fancy": "Alt + Shift + 2" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "increase_width": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace2": { "default": { - "fancy": "Win + Alt + =", - "ahk": "#!=" - } + "ahk": "!+3", + "fancy": "Alt + Shift + 3" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "decrease_width": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace3": { "default": { - "fancy": "Win + Alt + -", - "ahk": "#!-" - } + "ahk": "!+4", + "fancy": "Alt + Shift + 4" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "increase_height": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace4": { "default": { - "fancy": "Win + Shift + =", - "ahk": "#+=" - } + "ahk": "!+5", + "fancy": "Alt + Shift + 5" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "decrease_height": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace5": { "default": { - "fancy": "Win + Shift + -", - "ahk": "#+-" - } + "ahk": "!+6", + "fancy": "Alt + Shift + 6" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "restore_sizes": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace6": { "default": { - "fancy": "Win + Alt + 0", - "ahk": "#!0" - } + "ahk": "!+7", + "fancy": "Alt + Shift + 7" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_0": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace7": { "default": { - "fancy": "Alt + 1", - "ahk": "!1" - } + "ahk": "!+8", + "fancy": "Alt + Shift + 8" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_1": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace8": { "default": { - "fancy": "Alt + 2", - "ahk": "!2" - } + "ahk": "!+9", + "fancy": "Alt + Shift + 9" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_2": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "moveToWorkspace9": { "default": { - "fancy": "Alt + 3", - "ahk": "!3" - } + "ahk": "!+0", + "fancy": "Alt + Shift + 0" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_3": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "reserveBottom": { "default": { - "fancy": "Alt + 4", - "ahk": "!4" - } + "ahk": "#+k", + "fancy": "Win + Shift + K" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_4": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "reserveFloat": { "default": { - "fancy": "Alt + 5", - "ahk": "!5" - } + "ahk": "#+u", + "fancy": "Win + Shift + U" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_5": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "reserveLeft": { "default": { - "fancy": "Alt + 6", - "ahk": "!6" - } + "ahk": "#+j", + "fancy": "Win + Shift + J" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_6": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "reserveRight": { "default": { - "fancy": "Alt + 7", - "ahk": "!7" - } + "ahk": "#+l", + "fancy": "Win + Shift + L" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_7": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "reserveStack": { "default": { - "fancy": "Alt + 8", - "ahk": "!8" - } + "ahk": "#+o", + "fancy": "Win + Shift + O" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_8": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "reserveTop": { "default": { - "fancy": "Alt + 9", - "ahk": "!9" - } + "ahk": "#+i", + "fancy": "Win + Shift + I" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "switch_workspace_9": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "restoreSizes": { "default": { - "fancy": "Alt + 0", - "ahk": "!0" - } + "ahk": "#!0", + "fancy": "Win + Alt + 0" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_0": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace0": { "default": { - "fancy": "Alt + Shift + 1", - "ahk": "!+1" - } + "ahk": "#+1", + "fancy": "Win + Shift + 1" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_1": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace1": { "default": { - "fancy": "Alt + Shift + 2", - "ahk": "!+2" - } + "ahk": "#+2", + "fancy": "Win + Shift + 2" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_2": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace2": { "default": { - "fancy": "Alt + Shift + 3", - "ahk": "!+3" - } + "ahk": "#+3", + "fancy": "Win + Shift + 3" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_3": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace3": { "default": { - "fancy": "Alt + Shift + 4", - "ahk": "!+4" - } + "ahk": "#+4", + "fancy": "Win + Shift + 4" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_4": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace4": { "default": { - "fancy": "Alt + Shift + 5", - "ahk": "!+5" - } + "ahk": "#+5", + "fancy": "Win + Shift + 5" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_5": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace5": { "default": { - "fancy": "Alt + Shift + 6", - "ahk": "!+6" - } + "ahk": "#+6", + "fancy": "Win + Shift + 6" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_6": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace6": { "default": { - "fancy": "Alt + Shift + 7", - "ahk": "!+7" - } + "ahk": "#+7", + "fancy": "Win + Shift + 7" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_7": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace7": { "default": { - "fancy": "Alt + Shift + 8", - "ahk": "!+8" - } + "ahk": "#+8", + "fancy": "Win + Shift + 8" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_8": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace8": { "default": { - "fancy": "Alt + Shift + 9", - "ahk": "!+9" - } + "ahk": "#+9", + "fancy": "Win + Shift + 9" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "move_to_workspace_9": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "sendToWorkspace9": { "default": { - "fancy": "Alt + Shift + 0", - "ahk": "!+0" - } + "ahk": "#+0", + "fancy": "Win + Shift + 0" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_0": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace0": { "default": { - "fancy": "Win + Shift + 1", - "ahk": "#+1" - } + "ahk": "!1", + "fancy": "Alt + 1" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_1": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace1": { "default": { - "fancy": "Win + Shift + 2", - "ahk": "#+2" - } + "ahk": "!2", + "fancy": "Alt + 2" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_2": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace2": { "default": { - "fancy": "Win + Shift + 3", - "ahk": "#+3" - } + "ahk": "!3", + "fancy": "Alt + 3" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_3": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace3": { "default": { - "fancy": "Win + Shift + 4", - "ahk": "#+4" - } + "ahk": "!4", + "fancy": "Alt + 4" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_4": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace4": { "default": { - "fancy": "Win + Shift + 5", - "ahk": "#+5" - } + "ahk": "!5", + "fancy": "Alt + 5" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_5": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace5": { "default": { - "fancy": "Win + Shift + 6", - "ahk": "#+6" - } + "ahk": "!6", + "fancy": "Alt + 6" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_6": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace6": { "default": { - "fancy": "Win + Shift + 7", - "ahk": "#+7" - } + "ahk": "!7", + "fancy": "Alt + 7" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_7": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace7": { "default": { - "fancy": "Win + Shift + 8", - "ahk": "#+8" - } + "ahk": "!8", + "fancy": "Alt + 8" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_8": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace8": { "default": { - "fancy": "Win + Shift + 9", - "ahk": "#+9" - } + "ahk": "!9", + "fancy": "Alt + 9" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] }, - "send_to_workspace_9": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", + "switchWorkspace9": { "default": { - "fancy": "Win + Shift + 0", - "ahk": "#+0" - } + "ahk": "!0", + "fancy": "Alt + 0" + }, + "allOf": [ + { + "$ref": "#/definitions/AhkVar" + } + ] } - }, - "additionalProperties": false, - "default": {} + } }, - "selected_theme": { - "anyOf": [ - { + "Border": { + "type": "object", + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "offset": { + "default": -1.0, + "type": "number", + "format": "double" + }, + "width": { + "default": 3.0, + "type": "number", + "format": "double" + } + } + }, + "FancyToolbarSettings": { + "type": "object", + "properties": { + "enabled": { + "description": "enable or disable the fancy toolbar", + "default": true, + "type": "boolean" + }, + "height": { + "description": "height of the fancy toolbar", + "default": 30, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "placeholder": { + "description": "default placeholder for the fancy toolbar", + "default": "default.yml", "type": "string" + } + } + }, + "FloatingWindowSettings": { + "type": "object", + "properties": { + "height": { + "default": 500.0, + "type": "number", + "format": "double" }, - { + "width": { + "default": 800.0, + "type": "number", + "format": "double" + } + } + }, + "Monitor": { + "type": "object", + "properties": { + "workAreaOffset": { + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/Rect" + }, + { + "type": "null" + } + ] + }, + "workspaces": { + "default": [ + { + "gap": null, + "layout": "BSP", + "name": "New Workspace", + "padding": null + } + ], "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/Workspace" } } + } + }, + "Rect": { + "type": "object", + "required": [ + "bottom", + "left", + "right", + "top" ], - "default": [ - "default" + "properties": { + "bottom": { + "type": "integer", + "format": "int32" + }, + "left": { + "type": "integer", + "format": "int32" + }, + "right": { + "type": "integer", + "format": "int32" + }, + "top": { + "type": "integer", + "format": "int32" + } + } + }, + "SeelenWegHideMode": { + "oneOf": [ + { + "description": "never hide", + "type": "string", + "enum": [ + "Never" + ] + }, + { + "description": "auto-hide always on", + "type": "string", + "enum": [ + "Always" + ] + }, + { + "description": "auto-hide only if is overlaped by the focused window", + "type": "string", + "enum": [ + "On-Overlap" + ] + } ] }, - "dev_tools": { - "type": "boolean", - "default": false + "SeelenWegMode": { + "type": "string", + "enum": [ + "Full-Width", + "Min-Content" + ] }, - "language": { + "SeelenWegSettings": { + "type": "object", + "properties": { + "enabled": { + "description": "enable or disable the seelenweg", + "default": true, + "type": "boolean" + }, + "hideMode": { + "description": "When to hide the dock", + "default": "On-Overlap", + "allOf": [ + { + "$ref": "#/definitions/SeelenWegHideMode" + } + ] + }, + "margin": { + "description": "Dock/Taskbar margin in px", + "default": 8, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "mode": { + "description": "Dock/Taskbar mode", + "default": "Min-Content", + "allOf": [ + { + "$ref": "#/definitions/SeelenWegMode" + } + ] + }, + "padding": { + "description": "Dock/Taskbar padding in px", + "default": 8, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "position": { + "description": "Dock position", + "default": "Bottom", + "allOf": [ + { + "$ref": "#/definitions/SeelenWegSide" + } + ] + }, + "size": { + "description": "item size in px", + "default": 40, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "spaceBetweenItems": { + "description": "space between items in px", + "default": 8, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "visibleSeparators": { + "description": "enable or disable separators visibility", + "default": true, + "type": "boolean" + }, + "zoomSize": { + "description": "zoomed item size in px", + "default": 70, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + }, + "SeelenWegSide": { "type": "string", - "default": "en" + "enum": [ + "Left", + "Right", + "Top", + "Bottom" + ] + }, + "WindowManagerSettings": { + "type": "object", + "properties": { + "autoStackingByCategory": { + "description": "enable or disable auto stacking by category", + "default": true, + "type": "boolean" + }, + "border": { + "description": "window manager border", + "default": { + "enabled": true, + "offset": -1.0, + "width": 3.0 + }, + "allOf": [ + { + "$ref": "#/definitions/Border" + } + ] + }, + "defaultLayout": { + "description": "default layout", + "default": "default.yml", + "type": "string" + }, + "enabled": { + "description": "enable or disable the window manager", + "default": false, + "type": "boolean" + }, + "floating": { + "description": "floating window settings", + "default": { + "height": 500.0, + "width": 800.0 + }, + "allOf": [ + { + "$ref": "#/definitions/FloatingWindowSettings" + } + ] + }, + "globalWorkAreaOffset": { + "description": "default workspace margin", + "default": { + "bottom": 0, + "left": 0, + "right": 0, + "top": 0 + }, + "allOf": [ + { + "$ref": "#/definitions/Rect" + } + ] + }, + "resizeDelta": { + "description": "the resize size in % to be used when resizing via cli", + "default": 10.0, + "type": "number", + "format": "double" + }, + "workspaceGap": { + "description": "default gap between containers", + "default": 10.0, + "type": "number", + "format": "double" + }, + "workspacePadding": { + "description": "default workspace padding", + "default": 10.0, + "type": "number", + "format": "double" + } + } + }, + "Workspace": { + "type": "object", + "properties": { + "gap": { + "default": null, + "type": [ + "number", + "null" + ], + "format": "double" + }, + "layout": { + "default": "BSP", + "type": "string" + }, + "name": { + "default": "New Workspace", + "type": "string" + }, + "padding": { + "default": null, + "type": [ + "number", + "null" + ], + "format": "double" + } + } } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } } \ No newline at end of file diff --git a/documentation/schemas/settings_by_app.schema.json b/documentation/schemas/settings_by_app.schema.json new file mode 100644 index 00000000..978a8cc4 --- /dev/null +++ b/documentation/schemas/settings_by_app.schema.json @@ -0,0 +1,126 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_AppConfig", + "type": "array", + "items": { + "$ref": "#/definitions/AppConfig" + }, + "definitions": { + "AppConfig": { + "type": "object", + "required": [ + "identifier", + "name" + ], + "properties": { + "bound_monitor_idx": { + "type": [ + "integer", + "null" + ], + "format": "uint", + "minimum": 0.0 + }, + "bound_workspace_name": { + "type": [ + "string", + "null" + ] + }, + "category": { + "type": [ + "string", + "null" + ] + }, + "identifier": { + "$ref": "#/definitions/AppIdentifier" + }, + "is_bundled": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "options": { + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/AppExtraFlag" + } + } + } + }, + "AppExtraFlag": { + "type": "string", + "enum": [ + "float", + "force", + "unmanage", + "pinned", + "object_name_change", + "layered", + "border_overflow", + "tray_and_multi_window" + ] + }, + "AppIdentifier": { + "type": "object", + "required": [ + "id", + "kind", + "matching_strategy" + ], + "properties": { + "and": { + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/AppIdentifier" + } + }, + "id": { + "type": "string" + }, + "kind": { + "$ref": "#/definitions/AppIdentifierType" + }, + "matching_strategy": { + "$ref": "#/definitions/MatchingStrategy" + }, + "negation": { + "default": false, + "type": "boolean" + }, + "or": { + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/AppIdentifier" + } + } + } + }, + "AppIdentifierType": { + "type": "string", + "enum": [ + "Exe", + "Class", + "Title", + "Path" + ] + }, + "MatchingStrategy": { + "type": "string", + "enum": [ + "Equals", + "StartsWith", + "EndsWith", + "Contains", + "Regex", + "Legacy" + ] + } + } +} \ No newline at end of file diff --git a/documentation/schemas/theme.schema.json b/documentation/schemas/theme.schema.json index 55e65ebe..1cf198f0 100644 --- a/documentation/schemas/theme.schema.json +++ b/documentation/schemas/theme.schema.json @@ -1,141 +1,90 @@ { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Theme", "type": "object", "properties": { "info": { - "type": "object", - "properties": { - "displayName": { - "type": "string", - "default": "Unknown" - }, - "author": { - "type": "string", - "default": "Unknown" - }, - "description": { - "type": "string", - "default": "Empty" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - } + "description": "Metadata about the theme", + "default": { + "author": "", + "description": "", + "displayName": "", + "filename": "", + "tags": [] }, - "additionalProperties": false, - "default": {} + "allOf": [ + { + "$ref": "#/definitions/ThemeInfo" + } + ] }, - "variables": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "pattern": "^\\-\\-" + "styles": { + "description": "Css Styles of the theme", + "default": { + "toolbar": "", + "weg": "", + "wm": "" }, - "default": {} - }, - "layers": { + "allOf": [ + { + "$ref": "#/definitions/ThemeCss" + } + ] + } + }, + "definitions": { + "ThemeCss": { "type": "object", "properties": { + "toolbar": { + "description": "Css Styles for the window manager", + "default": "", + "type": "string" + }, "weg": { - "type": "object", - "properties": { - "bg": { - "type": "number", - "minimum": 1, - "default": 1 - }, - "items": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - }, - "contextMenu": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - }, - "preview": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - } - }, - "additionalProperties": false, - "default": {} + "description": "Css Styles for the dock/taskbar", + "default": "", + "type": "string" }, - "toolbar": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - }, - "fastSettings": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - }, - "systemTray": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - } - }, - "additionalProperties": false, - "default": {} + "wm": { + "description": "Css Styles for the window manager", + "default": "", + "type": "string" } - }, - "additionalProperties": false, - "default": {} + } }, - "styles": { + "ThemeInfo": { "type": "object", "properties": { - "weg": { - "type": "string", - "default": "" + "author": { + "description": "Author of the theme", + "default": "", + "type": "string" }, - "toolbar": { - "type": "string", - "default": "" + "description": { + "description": "Description of the theme", + "default": "", + "type": "string" }, - "wm": { - "type": "string", - "default": "" + "displayName": { + "description": "Display name of the theme", + "default": "", + "type": "string" + }, + "filename": { + "description": "Filename of the theme, is overridden by the program on load.", + "default": "", + "type": "string" + }, + "tags": { + "description": "Tags to be used in search", + "default": [], + "type": "array", + "items": { + "type": "string" + } } - }, - "additionalProperties": false, - "default": {} + } } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } } \ No newline at end of file diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 2ff5be66..723a6e71 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "convert_case" version = "0.4.0" @@ -29,6 +35,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -296,6 +313,9 @@ name = "uuid" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", +] [[package]] name = "version_check" @@ -303,6 +323,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "windows" version = "0.57.0" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 1a84a39d..6a191047 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,7 +11,7 @@ serde_alias = "0.0.2" schemars = "0.8.21" regex = "1.10.4" sys-locale = "0.3.1" -uuid = "1.8.0" +uuid = { version = "1.8.0", features = ["v4"] } [dependencies.windows] version = "=0.57.0" diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 80ec7817..3534c741 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -1,2 +1,2 @@ pub mod rect; -pub mod state; \ No newline at end of file +pub mod state; diff --git a/lib/src/main.rs b/lib/src/main.rs index 52501984..88f668c5 100644 --- a/lib/src/main.rs +++ b/lib/src/main.rs @@ -1,15 +1,17 @@ -use seelen_core::state::{Placeholder, Settings, Theme}; +use seelen_core::state::{AppConfig, Placeholder, Settings, Theme, WindowManagerLayout}; -fn write_schema(filename: &str) +fn write_schema(path: &str) where T: schemars::JsonSchema, { let schema = schemars::schema_for!(T); - std::fs::write(filename, serde_json::to_string_pretty(&schema).unwrap()).unwrap(); + std::fs::write(path, serde_json::to_string_pretty(&schema).unwrap()).unwrap(); } fn main() { - write_schema::("settings.schema.json"); - write_schema::("placeholder.schema.json"); - write_schema::("theme.schema.json"); + write_schema::("./dist/settings.schema.json"); + write_schema::("./dist/placeholder.schema.json"); + write_schema::("./dist/theme.schema.json"); + write_schema::("./dist/layout.schema.json"); + write_schema::>("./dist/settings_by_app.schema.json"); } diff --git a/lib/src/state/settings.rs b/lib/src/state/settings.rs index 80987856..e2a82e48 100644 --- a/lib/src/state/settings.rs +++ b/lib/src/state/settings.rs @@ -62,7 +62,7 @@ pub struct FancyToolbarSettings { /// height of the fancy toolbar pub height: u32, /// default placeholder for the fancy toolbar - pub placeholder: Option, + pub placeholder: String, } impl Default for FancyToolbarSettings { @@ -70,7 +70,7 @@ impl Default for FancyToolbarSettings { Self { enabled: true, height: 30, - placeholder: None, + placeholder: String::from("default.yml"), } } } @@ -187,7 +187,7 @@ pub struct WindowManagerSettings { /// floating window settings pub floating: FloatingWindowSettings, /// default layout - pub default_layout: Option, + pub default_layout: String, } impl Default for Border { @@ -220,7 +220,7 @@ impl Default for WindowManagerSettings { workspace_padding: 10.0, global_work_area_offset: Rect::default(), floating: FloatingWindowSettings::default(), - default_layout: None, // added in frontend + default_layout: String::from("default.yml"), } } } diff --git a/lib/src/state/settings_by_app.rs b/lib/src/state/settings_by_app.rs index 8f9a5652..36b508ed 100644 --- a/lib/src/state/settings_by_app.rs +++ b/lib/src/state/settings_by_app.rs @@ -1,7 +1,8 @@ use regex::Regex; +use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all(deserialize = "snake_case"))] pub enum AppExtraFlag { Float, @@ -15,7 +16,7 @@ pub enum AppExtraFlag { TrayAndMultiWindow, } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub enum AppIdentifierType { #[serde(alias = "exe")] Exe, @@ -27,7 +28,7 @@ pub enum AppIdentifierType { Path, } -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub enum MatchingStrategy { #[serde(alias = "equals")] Equals, @@ -44,7 +45,7 @@ pub enum MatchingStrategy { Legacy, } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct AppIdentifier { pub id: String, pub kind: AppIdentifierType, @@ -60,20 +61,6 @@ pub struct AppIdentifier { pub regex: Option, } -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct AppConfig { - pub name: String, - pub category: Option, - pub bound_monitor_idx: Option, - pub bound_workspace_name: Option, - pub identifier: AppIdentifier, - #[serde(default)] - pub options: Vec, - #[serde(default)] - pub is_bundled: bool, -} - - impl AppIdentifier { pub fn cache_regex(&mut self) { if matches!(self.matching_strategy, MatchingStrategy::Regex) { @@ -136,3 +123,16 @@ impl AppIdentifier { } } } + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct AppConfig { + pub name: String, + pub category: Option, + pub bound_monitor_idx: Option, + pub bound_workspace_name: Option, + pub identifier: AppIdentifier, + #[serde(default)] + pub options: Vec, + #[serde(default)] + pub is_bundled: bool, +} diff --git a/lib/src/state/weg_items.rs b/lib/src/state/weg_items.rs index 218401c2..fac519a9 100644 --- a/lib/src/state/weg_items.rs +++ b/lib/src/state/weg_items.rs @@ -1,4 +1 @@ - - - -pub type WegItems = serde_yaml::Value; \ No newline at end of file +pub type WegItems = serde_yaml::Value; diff --git a/lib/src/state/wm_layout.rs b/lib/src/state/wm_layout.rs index d7b0aecd..2f346345 100644 --- a/lib/src/state/wm_layout.rs +++ b/lib/src/state/wm_layout.rs @@ -1,3 +1,133 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +macro_rules! common_item { + ( + $( + struct $name:ident { + $($rest:tt)* + } + )* + ) => { + $( + #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] + #[serde(rename_all = "camelCase")] + pub struct $name { + #[serde(default = "WmNode::default_subtype")] + subtype: NodeSubtype, + /// Order in how the tree will be traversed (1 = first, 2 = second, etc.) + #[serde(default = "WmNode::default_priority")] + priority: u32, + /// How much of the remaining space this node will take + #[serde(default = "WmNode::default_grow_factor")] + grow_factor: f64, + /// Math Condition for the node to be shown, e.g: n >= 3 + condition: Option, + $($rest)* + } + )* + }; +} -pub type WindowManagerLayout = serde_yaml::Value; \ No newline at end of file +common_item! { + struct WmVerticalNode { + #[serde(default)] + children: Vec, + } + struct WmHorizontalNode { + #[serde(default)] + children: Vec, + } + struct WmLeafNode { + /// window handle (HWND) in the node + handle: Option, + } + struct WmStackNode { + /// active window handle (HWND) in the node + active: Option, + /// window handles (HWND) in the node + #[serde(default)] + handles: Vec, + } + struct WmFallbackNode { + /// active window handle (HWND) in the node + active: Option, + /// window handles (HWND) in the node + #[serde(default)] + handles: Vec, + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +#[serde(tag = "type")] +pub enum WmNode { + Vertical(WmVerticalNode), + Horizontal(WmHorizontalNode), + Leaf(WmLeafNode), + Stack(WmStackNode), + Fallback(WmFallbackNode), +} + +impl WmNode { + fn default_subtype() -> NodeSubtype { + NodeSubtype::Permanent + } + + fn default_priority() -> u32 { + 1 + } + + fn default_grow_factor() -> f64 { + 1f64 + } +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)] +#[serde(default, rename_all = "camelCase")] +pub struct WManagerLayoutInfo { + /// Display name of the layout + pub display_name: String, + /// Author of the layout + pub author: String, + /// Description of the layout + pub description: String, + /// Filename of the layout, is overridden by the program on load. + pub filename: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +pub enum NodeSubtype { + Temporal, + Permanent, +} + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +pub enum NoFallbackBehavior { + Float, + Unmanaged, +} + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +#[serde(default, rename_all = "camelCase")] +pub struct WindowManagerLayout { + pub info: WManagerLayoutInfo, + pub structure: WmNode, + pub no_fallback_behavior: NoFallbackBehavior, +} + +impl Default for WindowManagerLayout { + fn default() -> Self { + Self { + info: Default::default(), + structure: WmNode::Fallback(WmFallbackNode { + subtype: WmNode::default_subtype(), + priority: WmNode::default_priority(), + grow_factor: WmNode::default_grow_factor(), + condition: None, + active: None, + handles: vec![], + }), + no_fallback_behavior: NoFallbackBehavior::Float, + } + } +} diff --git a/src/apps/settings/modules/shared/store/storeApi.ts b/src/apps/settings/modules/shared/store/storeApi.ts index 057b25d6..9cb2dbe5 100644 --- a/src/apps/settings/modules/shared/store/storeApi.ts +++ b/src/apps/settings/modules/shared/store/storeApi.ts @@ -1,80 +1,13 @@ import { UserSettings } from '../../../../../shared.interfaces'; -import { parseAsCamel, safeParseAsCamel, VariableConvention } from '../../../../shared/schemas'; -import { Layout, LayoutSchema } from '../../../../shared/schemas/Layout'; +import { parseAsCamel, VariableConvention } from '../../../../shared/schemas'; import { SettingsSchema } from '../../../../shared/schemas/Settings'; import { path } from '@tauri-apps/api'; import { convertFileSrc, invoke } from '@tauri-apps/api/core'; -import { DirEntry } from '@tauri-apps/plugin-fs'; import yaml from 'js-yaml'; import { resolveDataPath } from '../config/infra'; import { dialog, fs } from '../tauri/infra'; -interface Entry extends DirEntry { - path: string; -} - -async function getEntries(folderName: string) { - const bundledPath = await path.join(await path.resourceDir(), 'static', folderName); - const userPath = await path.join(await path.appDataDir(), folderName); - - const entries: Entry[] = []; - - for (const entry of await fs.readDir(bundledPath)) { - entries.push({ - ...entry, - path: await path.join(bundledPath, entry.name), - }); - } - - for (const entry of await fs.readDir(userPath)) { - entries.push({ - ...entry, - path: await path.join(userPath, entry.name), - }); - } - - return entries; -} - -async function loadUserLayouts(ref: UserSettings) { - const defaultLayout = ref.jsonSettings.windowManager.defaultLayout; - let found = false; - - for (const entry of await getEntries('layouts')) { - if (entry.isFile && entry.name.endsWith('.json')) { - let layout: Layout = JSON.parse(await fs.readTextFile(entry.path)); - - layout = safeParseAsCamel(LayoutSchema, layout); - if (!layout) { - continue; - } - - const sanitizedLayout: Layout = { - ...layout, - info: { - ...layout.info, - filename: entry.name, - }, - }; - - if (sanitizedLayout.info.displayName === 'Unknown') { - sanitizedLayout.info.displayName = entry.name; - } - - if (defaultLayout === entry.name) { - found = true; - } - - ref.layouts.push(sanitizedLayout); - } - } - - if (!found) { - ref.jsonSettings.windowManager.defaultLayout = ref.layouts[0]?.info.filename || null; - } -} - export class UserSettingsLoader { private _withUserApps: boolean = false; private _withLayouts: boolean = false; @@ -129,7 +62,7 @@ export class UserSettingsLoader { } if (this._withLayouts) { - await loadUserLayouts(userSettings); + userSettings.layouts = await invoke('state_get_layouts'); } if (this._withPlaceholders) { diff --git a/src/background/exposed.rs b/src/background/exposed.rs index 513abca5..220a9e36 100644 --- a/src/background/exposed.rs +++ b/src/background/exposed.rs @@ -140,6 +140,7 @@ pub fn register_invoke_handler(app_builder: Builder) -> Builder { get_auto_start_status, state_get_themes, state_get_placeholders, + state_get_layouts, state_get_weg_items, state_get_settings, state_get_specific_apps_configurations, diff --git a/src/background/modules/cli/domain.rs b/src/background/modules/cli/domain.rs index f34aabf3..b6ade86c 100644 --- a/src/background/modules/cli/domain.rs +++ b/src/background/modules/cli/domain.rs @@ -1,7 +1,6 @@ +use seelen_core::state::{Placeholder, Theme, WindowManagerLayout}; use serde::{Deserialize, Serialize}; -use crate::state::domain::{Placeholder, Theme}; - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Resource { pub id: String, @@ -14,5 +13,5 @@ pub struct Resource { pub struct ResourceItems { pub theme: Option, pub placeholder: Option, - pub layout: Option, + pub layout: Option, } diff --git a/src/background/state/application/mod.rs b/src/background/state/application/mod.rs index 3c67399a..34cc6504 100644 --- a/src/background/state/application/mod.rs +++ b/src/background/state/application/mod.rs @@ -118,6 +118,9 @@ impl FullState { let user_placeholders = self.data_dir.join("placeholders"); let bundled_placeholders = self.resources_dir.join("static/placeholders"); + let user_layouts = self.data_dir.join("layouts"); + let bundled_layouts = self.resources_dir.join("static/layouts"); + let user_app_configs = self.data_dir.join("applications.yml"); let bundled_app_configs = self.resources_dir.join("static/apps_templates"); @@ -157,6 +160,17 @@ impl FullState { self.emit_placeholders()?; } + if event + .paths + .iter() + .any(|p| p.starts_with(&user_layouts) || p.starts_with(&bundled_layouts)) + { + log::info!("Layouts changed"); + self.load_layouts()?; + self.store_cloned(); + self.emit_layouts()?; + } + if event .paths .iter() @@ -322,12 +336,56 @@ impl FullState { } } - if let Some(selected) = &self.settings.fancy_toolbar.placeholder { - if !self.placeholders.contains_key(selected) { - self.settings.fancy_toolbar.placeholder = Some("default.yml".to_owned()); + let selected = &mut self.settings.fancy_toolbar.placeholder; + if !self.placeholders.contains_key(selected) { + *selected = "default.yml".to_string(); + } + + Ok(()) + } + + fn load_layout_from_file(path: PathBuf) -> Result { + match path.extension() { + Some(ext) if ext == "yml" || ext == "yaml" || ext == "json" => { + let content = std::fs::read_to_string(&path)?; + if ext == "json" { + Ok(serde_json::from_str(&content)?) + } else { + Ok(serde_yaml::from_str(&content)?) + } + } + _ => Err("Invalid layout file extension".into()), + } + } + + fn load_layouts(&mut self) -> Result<()> { + let user_path = self.data_dir.join("layouts"); + let resources_path = self.resources_dir.join("static/layouts"); + let entries = std::fs::read_dir(&resources_path)?.chain(std::fs::read_dir(&user_path)?); + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + continue; + } + + let layout = Self::load_layout_from_file(path); + + match layout { + Ok(mut layout) => { + layout.info.filename = entry.file_name().to_string_lossy().to_string(); + self.layouts.insert(layout.info.filename.clone(), layout); + } + Err(err) => { + log::error!("Failed to load layout ({:?}): {:?}", entry.path(), err) + } } } + let selected = &mut self.settings.window_manager.default_layout; + if !self.layouts.contains_key(selected) { + *selected = "BSP.json".to_string(); + } + Ok(()) } @@ -363,6 +421,7 @@ impl FullState { self.load_weg_items()?; self.load_themes()?; self.load_placeholders()?; + self.load_layouts()?; self.load_settings_by_app()?; Ok(()) } @@ -390,6 +449,12 @@ impl FullState { Ok(()) } + fn emit_layouts(&self) -> Result<()> { + self.handle + .emit("layouts", self.layouts().values().collect_vec())?; + Ok(()) + } + fn emit_settings_by_app(&self) -> Result<()> { self.handle .emit("settings-by-app", self.settings_by_app())?; @@ -439,7 +504,7 @@ impl FullState { self.data_dir.join(format!("placeholders/{id}.yml")), serde_yaml::to_string(&placeholder)?, )?; - self.settings.fancy_toolbar.placeholder = Some(format!("{id}.yml")); + self.settings.fancy_toolbar.placeholder = format!("{id}.yml"); } if let Some(layout) = resource.resources.layout { @@ -447,7 +512,7 @@ impl FullState { self.data_dir.join(format!("layouts/{id}.yml")), serde_yaml::to_string(&layout)?, )?; - self.settings.window_manager.default_layout = Some(format!("{id}.yml")); + self.settings.window_manager.default_layout = format!("{id}.yml"); } self.save_settings()?; diff --git a/src/background/state/infrastructure.rs b/src/background/state/infrastructure.rs index 28cb04b0..6f3f56cd 100644 --- a/src/background/state/infrastructure.rs +++ b/src/background/state/infrastructure.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use itertools::Itertools; +use seelen_core::state::WindowManagerLayout; use crate::{error_handler::Result, windows_api::WindowsApi}; @@ -24,6 +25,11 @@ pub fn state_get_placeholders() -> Vec { .collect_vec() } +#[tauri::command(async)] +pub fn state_get_layouts() -> Vec { + FULL_STATE.load().layouts().values().cloned().collect_vec() +} + #[tauri::command(async)] pub fn state_get_weg_items() -> WegItems { FULL_STATE.load().weg_items().clone()