Compare commits

...

10 Commits

Author SHA1 Message Date
434d15169a Initial commit 2025-11-10 10:56:42 +01:00
Jas Singh
d4895922de fix: build output (#1032)
* Fix build output

* Fix command
2025-06-27 22:17:47 -07:00
Jas Singh
a46929e4c5 Build fix (#1030)
* Fix build flag

* Fix the build process for new ags update.
2025-06-27 19:48:53 -07:00
Jas Singh
ec93ae2e35 Fix build flag (#1029) 2025-06-27 19:18:44 -07:00
DADA30000
2c0c66a8dd change accepted type to float (#1021)
Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>
2025-06-22 11:46:56 -07:00
Jas Singh
0c2bcb773c fix: Revert auto-hide dropdown to fix popover regression and improve bash poller to handle strings better. (#1017) 2025-06-20 23:13:09 -07:00
DADA30000
d563cdb1f6 chore: Make wrapper as the default option (#1013)
* Make wrapper as the default option, clean up code a little

* Update docs
2025-06-19 19:33:51 -07:00
davfsa
e03666ab5d 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>
2025-06-15 16:00:51 -07:00
Luiz Felipe Machado
daf45665c4 fix(scripts): update flatpak only if command exists (#1000)
* fix(scripts): update flatpak only if command exists

Add a check to run flatpak update only when the flatpak command is
available, since Flatpak is not installed by default on Arch Linux,
preventing errors if flatpak is missing.

* Update scripts/runUpdates.sh

---------

Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>
2025-06-14 14:19:33 -07:00
geri1701
f0ca0fbf64 Chore: Add GIO_EXTRA_MODULES to overlay (#992)
Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>
2025-06-14 14:16:13 -07:00
19 changed files with 4483 additions and 4310 deletions

View File

@@ -194,7 +194,7 @@ Once you've set up the overlay, you can reference HyprPanel with `pkgs.hyprpanel
# install it as a system package # install it as a system package
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
# ... # ...
inputs.hyprpanel.packages.${pkgs.system}.wrapper # this one if you want to avoid overlays/didn't enable them inputs.hyprpanel.packages.${pkgs.system}.default # this one if you want to avoid overlays/didn't enable them
hyprpanel hyprpanel
# ... # ...
]; ];
@@ -202,7 +202,7 @@ environment.systemPackages = with pkgs; [
# or install it as a user package # or install it as a user package
users.users.<username>.packages = with pkgs; [ users.users.<username>.packages = with pkgs; [
# ... # ...
inputs.hyprpanel.packages.${pkgs.system}.wrapper # this one if you want to avoid overlays/didn't enable them inputs.hyprpanel.packages.${pkgs.system}.default # this one if you want to avoid overlays/didn't enable them
hyprpanel hyprpanel
# ... # ...
]; ];
@@ -213,7 +213,7 @@ users.users.<username>.packages = with pkgs; [
# install it as a user package with home-manager # install it as a user package with home-manager
home.packages = with pkgs; [ home.packages = with pkgs; [
# ... # ...
inputs.hyprpanel.packages.${pkgs.system}.wrapper # this one if you want to avoid overlays/didn't enable them inputs.hyprpanel.packages.${pkgs.system}.default # this one if you want to avoid overlays/didn't enable them
hyprpanel hyprpanel
# ... # ...
]; ];

6
app.ts
View File

@@ -6,7 +6,7 @@ import { runCLI } from 'src/services/cli/commander';
import { InitializationService } from 'src/core/initialization'; import { InitializationService } from 'src/core/initialization';
App.start({ App.start({
instanceName: 'hyprpanel', instanceName: 'hyprpanel-levl',
requestHandler: (request: string, res: (response: unknown) => void) => runCLI(request, res), requestHandler: (request: string, res: (response: unknown) => void) => runCLI(request, res),
main: () => InitializationService.initialize(), main: () => InitializationService.initialize(),
}); });

View File

@@ -1,7 +1,6 @@
{ {
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
astal = { astal = {
url = "github:aylur/astal"; url = "github:aylur/astal";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@@ -120,38 +119,39 @@
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
in in
{ {
default = ags.lib.bundle { unwrapped = ags.lib.bundle {
inherit pkgs; inherit pkgs;
src = ./.; src = ./.;
name = "hyprpanel"; # name of executable name = "hyprpanel"; # name of executable
entry = "app.ts"; entry = "app.ts";
extraPackages = packages system pkgs; extraPackages = packages system pkgs;
}; };
default = self.packages.${pkgs.stdenv.system}.wrapper;
# Make a wrapper package to avoid overlay # Make a wrapper package to avoid overlay
wrapper = pkgs.writeShellScriptBin "hyprpanel" '' wrapper = pkgs.writeShellScriptBin "hyprpanel" ''
# Exporting glib-networking modules # Exporting glib-networking modules
export GIO_EXTRA_MODULES="${pkgs.glib-networking}/lib/gio/modules" export GIO_EXTRA_MODULES="${pkgs.glib-networking}/lib/gio/modules"
if [ "$#" -eq 0 ]; then if [ "$#" -eq 0 ]; then
exec ${self.packages.${pkgs.stdenv.system}.default}/bin/hyprpanel exec ${self.packages.${pkgs.stdenv.system}.unwrapped}/bin/hyprpanel
else else
exec ${ags.packages.${pkgs.stdenv.system}.io}/bin/astal -i hyprpanel "$@" exec ${ags.packages.${pkgs.stdenv.system}.io}/bin/astal -i hyprpanel "$*"
fi fi
''; '';
} }
); );
# Define .overlay to expose the package as pkgs.hyprpanel based on the system # Define .overlay to expose the package as pkgs.hyprpanel based on the system
overlay = final: prev: { overlay =
hyprpanel = prev.writeShellScriptBin "hyprpanel" '' final: prev:
if [ "$#" -eq 0 ]; then let
exec ${self.packages.${final.stdenv.system}.default}/bin/hyprpanel pkgs = final;
else in
exec ${ags.packages.${final.stdenv.system}.io}/bin/astal -i hyprpanel "$@" {
fi hyprpanel = self.packages.${pkgs.stdenv.system}.wrapper;
''; };
};
homeManagerModules.hyprpanel = import ./nix/module.nix self; homeManagerModules.hyprpanel = import ./nix/module.nix self;
}; };

View File

@@ -18,12 +18,13 @@ custom_target(
command: [ command: [
ags, ags,
'bundle', 'bundle',
'--gtk', '3',
'--define', 'DATADIR="' + datadir + '"', '--define', 'DATADIR="' + datadir + '"',
'--root', meson.project_source_root(), '--root', meson.project_source_root(),
meson.project_source_root() / 'app.ts', meson.project_source_root() / 'app.ts',
'@OUTPUT@', '@OUTPUT@',
], ],
output: meson.project_name() + '.js', output: 'hyprpanel-app',
install: true, install: true,
install_dir: datadir, install_dir: datadir,
build_always_stale: true, build_always_stale: true,

View File

@@ -605,7 +605,7 @@ in
theme.font.size = mkStrOption "1.2rem"; theme.font.size = mkStrOption "1.2rem";
theme.font.weight = mkIntOption 600; theme.font.weight = mkIntOption 600;
theme.matugen = mkBoolOption false; theme.matugen = mkBoolOption false;
theme.matugen_settings.contrast = mkIntOption 0; theme.matugen_settings.contrast = mkFloatOption 0.0;
theme.matugen_settings.mode = mkStrOption "dark"; theme.matugen_settings.mode = mkStrOption "dark";
theme.matugen_settings.scheme_type = mkStrOption "tonal-spot"; theme.matugen_settings.scheme_type = mkStrOption "tonal-spot";
theme.matugen_settings.variation = mkStrOption "standard_1"; theme.matugen_settings.variation = mkStrOption "standard_1";

8484
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +1,31 @@
{ {
"name": "hyprpanel", "name": "hyprpanel",
"version": "1.0.0", "version": "1.0.0",
"description": "A customizable panel built for Hyprland.", "description": "A customizable panel built for Hyprland.",
"main": "app.ts", "main": "app.ts",
"scripts": { "scripts": {
"lint": "eslint --config .eslintrc.json .", "lint": "eslint --config .eslintrc.json .",
"lint:fix": "eslint --config .eslintrc.json . --fix", "lint:fix": "eslint --config .eslintrc.json . --fix",
"format": "prettier --write 'modules/**/*.ts'", "format": "prettier --write 'modules/**/*.ts'",
"knip": "knip" "knip": "knip"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"astal": "/usr/share/astal/gjs" "astal": "/usr/share/astal/gjs"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.15.17", "@types/node": "^22.15.17",
"@typescript-eslint/eslint-plugin": "^8.5.0", "@typescript-eslint/eslint-plugin": "^8.5.0",
"@typescript-eslint/parser": "^8.5.0", "@typescript-eslint/parser": "^8.5.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.30.0", "eslint-plugin-import": "^2.30.0",
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
"knip": "^5.55.1", "knip": "^5.55.1",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"tsconfig-paths": "^4.2.0", "tsconfig-paths": "^4.2.0",
"typescript": "5.7.3" "typescript": "5.7.3"
} }
} }

View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
if [ "$#" -eq 0 ]; then if [ "$#" -eq 0 ]; then
exec gjs -m "@DATADIR@/hyprpanel.js" exec "@DATADIR@/hyprpanel-app"
else else
exec astal -i hyprpanel "$*" exec astal -i hyprpanel "$*"
fi fi

View File

@@ -13,8 +13,10 @@ install_arch_updates() {
else else
echo "Missing AUR Helper. Try installing yay or paru" echo "Missing AUR Helper. Try installing yay or paru"
fi fi
echo "Updating Flatpak packages..." if command -v flatpak &> /dev/null; then
flatpak update -y echo "Updating Flatpak packages..."
flatpak update -y
fi
echo "Done with Arch & AUR updates." echo "Done with Arch & AUR updates."
} }

View File

@@ -5,6 +5,7 @@ import { isValidGjsColor } from 'src/lib/validation/colors';
import { AppIconOptions } from './types'; import { AppIconOptions } from './types';
import { WorkspaceIconMap } from '../types'; import { WorkspaceIconMap } from '../types';
import { unique } from 'src/lib/array/helpers'; import { unique } from 'src/lib/array/helpers';
import {Apps ,AstalAppsApplication} from "gi://AstalApps"
const hyprlandService = AstalHyprland.get_default(); const hyprlandService = AstalHyprland.get_default();
const { monochrome, background } = options.theme.bar.buttons; const { monochrome, background } = options.theme.bar.buttons;
@@ -151,7 +152,13 @@ export const getAppIcon = (
return iconEntry?.[1] ?? defaultIcon; return iconEntry?.[1] ?? defaultIcon;
}; };
let icons = workspaceClients.reduce((iconAccumulator, [clientClass, clientTitle]) => {
let icons = getAppIconNew(hyprlandService
.get_clients()
.filter((client) => client?.workspace?.id === workspaceIndex))
icons = workspaceClients.reduce((iconAccumulator, [clientClass, clientTitle]) => {
const icon = findIconForClient(clientClass, clientTitle); const icon = findIconForClient(clientClass, clientTitle);
if (icon !== undefined) { if (icon !== undefined) {
@@ -160,6 +167,7 @@ export const getAppIcon = (
return iconAccumulator; return iconAccumulator;
}, []); }, []);
if (icons.length) { if (icons.length) {
if (removeDuplicateIcons) { if (removeDuplicateIcons) {
@@ -172,6 +180,35 @@ export const getAppIcon = (
return defaultIcon; return defaultIcon;
}; };
// todo implement caching to make it so much faster hopefully
export function getAppIconNew(
workspaceIndex: number,
apps: AstalAppsApplication
) : string[] {
const clients = hyprlandService
.get_clients()
.filter((client) => client?.workspace?.id === workspaceIndex);
let icons = clients?.map((client) =>
apps
.filter((app: AstalHyprland.app) =>
app.wm_class == client.get_class() ||
app.wm_class == client?.initial_title ||
app.wm_class == getWMClass(client) ||
app.name == client?.initial_title)
.map((app: AstalHyprland.app) => app.icon_name).at(0) ?? "missing-symbolic"
)
return icons.length > 0 ? icons : ["application-x-executable"]
}
function getWMClass(client: AstalHyprland.Client | undefined) {
return client.initial_class.split(".").reverse().at(0)
}
/** /**
* Renders the class names for a workspace. * Renders the class names for a workspace.
* *

View File

@@ -1,5 +1,5 @@
import { initWorkspaceEvents } from './helpers/utils'; import { initWorkspaceEvents } from './helpers/utils';
import { getAppIcon, getWsColor, renderClassnames, renderLabel } from './helpers'; import { getAppIcon, getWsColor, renderClassnames, renderLabel, getAppIconNew } from './helpers';
import { bind, Variable } from 'astal'; import { bind, Variable } from 'astal';
import AstalHyprland from 'gi://AstalHyprland?version=0.1'; import AstalHyprland from 'gi://AstalHyprland?version=0.1';
import { Gtk } from 'astal/gtk3'; import { Gtk } from 'astal/gtk3';
@@ -7,6 +7,8 @@ import { WorkspaceService } from 'src/services/workspace';
import options from 'src/configuration'; import options from 'src/configuration';
import { isPrimaryClick } from 'src/lib/events/mouse'; import { isPrimaryClick } from 'src/lib/events/mouse';
import { WorkspaceIconMap, ApplicationIcons } from './types'; import { WorkspaceIconMap, ApplicationIcons } from './types';
import Apps from "gi://AstalApps"
const workspaceService = WorkspaceService.getInstance(); const workspaceService = WorkspaceService.getInstance();
@@ -100,15 +102,11 @@ export const WorkspaceModule = ({ monitor }: WorkspaceModuleProps): JSX.Element
isMonitorSpecific, isMonitorSpecific,
monitorList, monitorList,
); );
const apps = new Apps.Apps({}).get_list()
return workspacesToRender.map((wsId, index) => { return workspacesToRender.map((wsId, index) => {
const appIcons = displayApplicationIcons const appIcons = getAppIconNew(wsId, apps);
? getAppIcon(wsId, appIconOncePerWorkspace, {
iconMap: applicationIconMapping,
defaultIcon: applicationIconFallback,
emptyIcon: applicationIconEmptyWorkspace,
})
: '';
return ( return (
<button <button
@@ -119,9 +117,8 @@ export const WorkspaceModule = ({ monitor }: WorkspaceModuleProps): JSX.Element
} }
}} }}
> >
<label <box
valign={Gtk.Align.CENTER} css={
css={
`margin: 0rem ${0.375 * spacingValue}rem;` + `margin: 0rem ${0.375 * spacingValue}rem;` +
`${displayWorkspaceIcons && !matugenEnabled ? getWsColor(workspaceIconMapping, wsId, smartHighlightEnabled, monitor) : ''}` `${displayWorkspaceIcons && !matugenEnabled ? getWsColor(workspaceIconMapping, wsId, smartHighlightEnabled, monitor) : ''}`
} }
@@ -134,27 +131,21 @@ export const WorkspaceModule = ({ monitor }: WorkspaceModuleProps): JSX.Element
monitor, monitor,
wsId, wsId,
)} )}
label={renderLabel(
displayIcons,
availableStatus,
activeStatus,
occupiedStatus,
displayApplicationIcons,
appIcons,
workspaceMaskFlag,
displayWorkspaceIcons,
workspaceIconMapping,
wsId,
index,
monitor,
)}
setup={(self) => { setup={(self) => {
const currentWsClients = clients.filter( const currentWsClients = clients.filter(
(client) => client?.workspace?.id === wsId, (client) => client?.workspace?.id === wsId,
); );
self.toggleClassName('occupied', currentWsClients.length > 0); self.toggleClassName('occupied', currentWsClients.length > 0);
}} }}>
/>
{
appIcons?.map(icon =>
<icon
icon={icon || "image-missing"}
/>
)}
</box>
</button> </button>
); );
}); });

View File

@@ -3,6 +3,13 @@ import { BarLayout, BarLayouts } from 'src/lib/options/types';
import { GdkMonitorService } from 'src/services/display/monitor'; import { GdkMonitorService } from 'src/services/display/monitor';
import { MonitorMapping } from './types'; import { MonitorMapping } from './types';
import { JSXElement } from 'src/core/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 * 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 * @returns BarLayout configuration for the specified monitor, falling back to default if not found
*/ */
export const getLayoutForMonitor = (monitor: number, layouts: BarLayouts): BarLayout => { export const getLayoutForMonitor = (monitor: number, layouts: BarLayouts): BarLayout => {
const matchingKey = Object.keys(layouts).find((key) => key === monitor.toString()); const [rootKey, rootLayout] = _getResolveLayoutForMonitor(monitor, layouts);
const wildcard = Object.keys(layouts).find((key) => key === '*');
if (matchingKey !== undefined) { let left = rootLayout.left;
return layouts[matchingKey]; let middle = rootLayout.middle;
} let right = rootLayout.right;
if (wildcard) { let layout = rootLayout;
return layouts[wildcard]; 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 { return {
left: ['dashboard', 'workspaces', 'windowtitle'], left: left ?? [],
middle: ['media'], middle: middle ?? [],
right: ['volume', 'network', 'bluetooth', 'battery', 'systray', 'clock', 'notifications'], 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 * Checks if a bar layout configuration is empty
* *

View File

@@ -32,9 +32,6 @@ export default ({
self.visible = false; self.visible = false;
} }
}} }}
onFocusOutEvent={(self) => {
self.visible = false;
}}
onButtonPressEvent={(self, event) => { onButtonPressEvent={(self, event) => {
const buttonClicked = event.get_button()[1]; const buttonClicked = event.get_button()[1];

View File

@@ -16,9 +16,9 @@ export function getLayoutItems(): BarModule[] {
const itemsInLayout: BarModule[] = []; const itemsInLayout: BarModule[] = [];
Object.keys(layouts.get()).forEach((monitor) => { Object.keys(layouts.get()).forEach((monitor) => {
const leftItems = layouts.get()[monitor].left; const leftItems = layouts.get()[monitor].left ?? [];
const rightItems = layouts.get()[monitor].right; const rightItems = layouts.get()[monitor].right ?? [];
const middleItems = layouts.get()[monitor].middle; const middleItems = layouts.get()[monitor].middle ?? [];
itemsInLayout.push(...leftItems); itemsInLayout.push(...leftItems);
itemsInLayout.push(...middleItems); itemsInLayout.push(...middleItems);

View File

@@ -46,6 +46,7 @@ export type BarLayout = {
left: BarModule[]; left: BarModule[];
middle: BarModule[]; middle: BarModule[];
right: BarModule[]; right: BarModule[];
extends?: string;
}; };
export type BarLayouts = { export type BarLayouts = {
[key: string]: BarLayout; [key: string]: BarLayout;

View File

@@ -57,7 +57,7 @@ export class BashPoller<Value, Parameters extends unknown[]> {
*/ */
public execute = async (): Promise<void> => { public execute = async (): Promise<void> => {
try { try {
const res = await execAsync(`bash -c "${this._updateCommand}"`); const res = await execAsync(['bash', '-c', this._updateCommand]);
this._targetVariable.set(await this._pollingFunction(res, ...this._params)); this._targetVariable.set(await this._pollingFunction(res, ...this._params));
} catch (error) { } catch (error) {
console.error(`Error executing bash command "${this._updateCommand}":`, error); console.error(`Error executing bash command "${this._updateCommand}":`, error);

View File

@@ -60,7 +60,7 @@ export class GdkMonitorService {
const tempUsedIds = new Set<number>(); const tempUsedIds = new Set<number>();
const monitorsToUse = validMonitors.length > 0 ? validMonitors : hyprlandMonitors; const monitorsToUse = validMonitors.length > 0 ? validMonitors : hyprlandMonitors;
const result = this._matchMonitor( return this._matchMonitor(
monitorsToUse, monitorsToUse,
gdkMonitor, gdkMonitor,
monitor, monitor,
@@ -68,8 +68,6 @@ export class GdkMonitorService {
(mon, gdkMon) => this._matchMonitorKey(mon, gdkMon), (mon, gdkMon) => this._matchMonitorKey(mon, gdkMon),
tempUsedIds, tempUsedIds,
); );
return result;
} }
/** /**

View File

@@ -57,7 +57,9 @@ export class WorkspaceService {
let allPotentialWorkspaces = range(totalWorkspaces || 8); let allPotentialWorkspaces = range(totalWorkspaces || 8);
const allWorkspaceInstances = workspaceInstances ?? []; const allWorkspaceInstances = workspaceInstances ?? [];
const activeWorkspaceIds = allWorkspaceInstances.map((workspaceInstance) => workspaceInstance.id); const activeWorkspaceIds = allWorkspaceInstances.filter(
(workspaceInstance) => !workspaceInstance.name.startsWith("special:")
).map((workspaceInstance) => workspaceInstance.id);
const monitorReferencesForActiveWorkspaces = allWorkspaceInstances.map((workspaceInstance) => { const monitorReferencesForActiveWorkspaces = allWorkspaceInstances.map((workspaceInstance) => {
return { return {
@@ -171,6 +173,9 @@ export class WorkspaceService {
const workspaceMonitorReferences = allWorkspaceInstances const workspaceMonitorReferences = allWorkspaceInstances
.filter((workspaceInstance) => workspaceInstance !== null) .filter((workspaceInstance) => workspaceInstance !== null)
.filter(
(workspaceInstance) => !workspaceInstance.name.startsWith("special:")
)
.map((workspaceInstance) => { .map((workspaceInstance) => {
return { return {
id: workspaceInstance.monitor?.id, id: workspaceInstance.monitor?.id,
@@ -224,6 +229,9 @@ export class WorkspaceService {
.filter( .filter(
(workspaceInstance) => hyprlandService.focusedMonitor.id === workspaceInstance.monitor?.id, (workspaceInstance) => hyprlandService.focusedMonitor.id === workspaceInstance.monitor?.id,
) )
.filter(
(workspaceInstance) => !workspaceInstance.name.startsWith("special:")
)
.map((workspaceInstance) => workspaceInstance.id); .map((workspaceInstance) => workspaceInstance.id);
const assignedOrOccupiedWorkspaces = activeWorkspaceIds.sort((a, b) => a - b); const assignedOrOccupiedWorkspaces = activeWorkspaceIds.sort((a, b) => a - b);

View File

@@ -1,11 +1,10 @@
.workspaces { .workspaces {
label { label, box {
font-size: 0.2em; font-size: 0.2em;
min-width: $bar-buttons-workspaces-pill-width; min-width: $bar-buttons-workspaces-pill-width;
min-height: $bar-buttons-workspaces-pill-height; min-height: $bar-buttons-workspaces-pill-height;
border-radius: $bar-buttons-workspaces-pill-radius; border-radius: $bar-buttons-workspaces-pill-radius;
transition: 300ms * 0.5; transition: 300ms * 0.5;
background-color: $bar-buttons-workspaces-available;
color: $bar-buttons-workspaces-available; color: $bar-buttons-workspaces-available;
&.occupied { &.occupied {
@@ -58,7 +57,7 @@
} }
.workspace-button { .workspace-button {
&:hover label { &:hover label, box {
color: $bar-buttons-workspaces-hover; color: $bar-buttons-workspaces-hover;
&.default { &.default {