feat: add ability to specify connector as layout name and extend other layouts (#985)
* feat: add ability to specify connector as layout name and extend other layouts Signed-off-by: davfsa <davfsa@gmail.com> * chore: rename function Signed-off-by: davfsa <davfsa@gmail.com> * Update src/lib/options/types.ts Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com> * Update src/components/bar/utils/monitors/index.ts Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com> * Update src/components/bar/utils/monitors/index.ts --------- Signed-off-by: davfsa <davfsa@gmail.com> Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>
This commit is contained in:
@@ -3,6 +3,13 @@ import { BarLayout, BarLayouts } from 'src/lib/options/types';
|
||||
import { GdkMonitorService } from 'src/services/display/monitor';
|
||||
import { MonitorMapping } from './types';
|
||||
import { JSXElement } from 'src/core/types';
|
||||
import AstalHyprland from 'gi://AstalHyprland?version=0.1';
|
||||
|
||||
const emptyBar = {
|
||||
left: [],
|
||||
middle: [],
|
||||
right: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the bar layout configuration for a specific monitor
|
||||
@@ -12,24 +19,80 @@ import { JSXElement } from 'src/core/types';
|
||||
* @returns BarLayout configuration for the specified monitor, falling back to default if not found
|
||||
*/
|
||||
export const getLayoutForMonitor = (monitor: number, layouts: BarLayouts): BarLayout => {
|
||||
const matchingKey = Object.keys(layouts).find((key) => key === monitor.toString());
|
||||
const wildcard = Object.keys(layouts).find((key) => key === '*');
|
||||
const [rootKey, rootLayout] = _getResolveLayoutForMonitor(monitor, layouts);
|
||||
|
||||
if (matchingKey !== undefined) {
|
||||
return layouts[matchingKey];
|
||||
}
|
||||
let left = rootLayout.left;
|
||||
let middle = rootLayout.middle;
|
||||
let right = rootLayout.right;
|
||||
|
||||
if (wildcard) {
|
||||
return layouts[wildcard];
|
||||
let layout = rootLayout;
|
||||
const visited = [rootKey];
|
||||
while (
|
||||
layout.extends !== undefined &&
|
||||
(left === undefined || middle === undefined || right === undefined)
|
||||
) {
|
||||
if (visited.includes(layout.extends)) {
|
||||
console.error(`found circular reference in layout extensions: ${visited.join(' -> ')}`);
|
||||
return emptyBar;
|
||||
}
|
||||
visited.push(layout.extends);
|
||||
|
||||
if (!(layout.extends in layouts)) {
|
||||
console.error(
|
||||
`failed to find layout with name '${layout.extends}' (resolved path: ${visited.join(' -> ')})`,
|
||||
);
|
||||
return emptyBar;
|
||||
}
|
||||
|
||||
layout = layouts[layout.extends];
|
||||
|
||||
if (left === undefined) {
|
||||
left = layout.left;
|
||||
}
|
||||
if (middle === undefined) {
|
||||
middle = layout.middle;
|
||||
}
|
||||
if (right === undefined) {
|
||||
right = layout.right;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
left: ['dashboard', 'workspaces', 'windowtitle'],
|
||||
middle: ['media'],
|
||||
right: ['volume', 'network', 'bluetooth', 'battery', 'systray', 'clock', 'notifications'],
|
||||
left: left ?? [],
|
||||
middle: middle ?? [],
|
||||
right: right ?? [],
|
||||
};
|
||||
};
|
||||
|
||||
const _getResolveLayoutForMonitor = (monitor: number, layouts: BarLayouts): [string, BarLayout] => {
|
||||
const hyprlandService = AstalHyprland.get_default();
|
||||
const monitorConn = hyprlandService.get_monitor(monitor).get_name();
|
||||
|
||||
const matchingConn = Object.keys(layouts).find((key) => key === monitorConn);
|
||||
if (matchingConn !== undefined) {
|
||||
return [matchingConn, layouts[matchingConn]];
|
||||
}
|
||||
|
||||
const matchingNum = Object.keys(layouts).find((key) => key === monitor.toString());
|
||||
if (matchingNum !== undefined) {
|
||||
return [matchingNum, layouts[matchingNum]];
|
||||
}
|
||||
|
||||
const wildcard = Object.keys(layouts).find((key) => key === '*');
|
||||
if (wildcard) {
|
||||
return [wildcard, layouts[wildcard]];
|
||||
}
|
||||
|
||||
return [
|
||||
'default',
|
||||
{
|
||||
left: ['dashboard', 'workspaces', 'windowtitle'],
|
||||
middle: ['media'],
|
||||
right: ['volume', 'network', 'bluetooth', 'battery', 'systray', 'clock', 'notifications'],
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a bar layout configuration is empty
|
||||
*
|
||||
|
||||
@@ -16,9 +16,9 @@ export function getLayoutItems(): BarModule[] {
|
||||
const itemsInLayout: BarModule[] = [];
|
||||
|
||||
Object.keys(layouts.get()).forEach((monitor) => {
|
||||
const leftItems = layouts.get()[monitor].left;
|
||||
const rightItems = layouts.get()[monitor].right;
|
||||
const middleItems = layouts.get()[monitor].middle;
|
||||
const leftItems = layouts.get()[monitor].left ?? [];
|
||||
const rightItems = layouts.get()[monitor].right ?? [];
|
||||
const middleItems = layouts.get()[monitor].middle ?? [];
|
||||
|
||||
itemsInLayout.push(...leftItems);
|
||||
itemsInLayout.push(...middleItems);
|
||||
|
||||
@@ -46,6 +46,7 @@ export type BarLayout = {
|
||||
left: BarModule[];
|
||||
middle: BarModule[];
|
||||
right: BarModule[];
|
||||
extends?: string;
|
||||
};
|
||||
export type BarLayouts = {
|
||||
[key: string]: BarLayout;
|
||||
|
||||
@@ -60,7 +60,7 @@ export class GdkMonitorService {
|
||||
const tempUsedIds = new Set<number>();
|
||||
const monitorsToUse = validMonitors.length > 0 ? validMonitors : hyprlandMonitors;
|
||||
|
||||
const result = this._matchMonitor(
|
||||
return this._matchMonitor(
|
||||
monitorsToUse,
|
||||
gdkMonitor,
|
||||
monitor,
|
||||
@@ -68,8 +68,6 @@ export class GdkMonitorService {
|
||||
(mon, gdkMon) => this._matchMonitorKey(mon, gdkMon),
|
||||
tempUsedIds,
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user