From c309a73d2d9821c90864447058b627c02bd82165 Mon Sep 17 00:00:00 2001 From: Jas Singh Date: Sat, 15 Feb 2025 00:01:51 -0800 Subject: [PATCH] Fixed an issue that would cause a hidden bar to unhide when a workspace changed. (#771) * Fixed an issue that would cause a hidden bar to unhide when a workspace is changed. * Remove jsdoc for param that doesn't exist. --- .../commands/windowManagement/index.ts | 3 + src/cli/utils/BarVisibility.ts | 13 +++ src/components/bar/modules/cava/index.tsx | 1 + src/lib/behaviors/autoHide.ts | 105 ++++++++++++++---- src/lib/types/cli.d.ts | 1 + 5 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 src/cli/utils/BarVisibility.ts create mode 100644 src/lib/types/cli.d.ts diff --git a/src/cli/commander/commands/windowManagement/index.ts b/src/cli/commander/commands/windowManagement/index.ts index 2ec7db3..994ba9d 100644 --- a/src/cli/commander/commands/windowManagement/index.ts +++ b/src/cli/commander/commands/windowManagement/index.ts @@ -1,6 +1,7 @@ import { errorHandler } from 'src/lib/utils'; import { Command } from '../../types'; import { App } from 'astal/gtk3'; +import { BarVisibility } from 'src/cli/utils/BarVisibility'; export const windowManagementCommands: Command[] = [ { @@ -46,6 +47,8 @@ export const windowManagementCommands: Command[] = [ App.toggle_window(windowName); + BarVisibility.set(windowName, windowStatus === 'visible'); + return windowStatus; } catch (error) { errorHandler(error); diff --git a/src/cli/utils/BarVisibility.ts b/src/cli/utils/BarVisibility.ts new file mode 100644 index 0000000..0ad871d --- /dev/null +++ b/src/cli/utils/BarVisibility.ts @@ -0,0 +1,13 @@ +import { BarToggleStates } from 'src/lib/types/cli'; + +export class BarVisibility { + private static _toggleStates: BarToggleStates = {}; + + public static get(barName: string): boolean { + return this._toggleStates[barName] ?? true; + } + + public static set(barName: string, isVisible: boolean): void { + this._toggleStates[barName] = isVisible; + } +} diff --git a/src/components/bar/modules/cava/index.tsx b/src/components/bar/modules/cava/index.tsx index 7a216d7..3b1bd62 100644 --- a/src/components/bar/modules/cava/index.tsx +++ b/src/components/bar/modules/cava/index.tsx @@ -39,6 +39,7 @@ export const Cava = (): BarBoxChild => { return blockCharacters[Math.min(index, blockCharacters.length - 1)]; }) .join(spacing); + return valueMap; }, ); diff --git a/src/lib/behaviors/autoHide.ts b/src/lib/behaviors/autoHide.ts index c78d26a..fea4f0c 100644 --- a/src/lib/behaviors/autoHide.ts +++ b/src/lib/behaviors/autoHide.ts @@ -1,50 +1,109 @@ import { bind, Variable } from 'astal'; import { App } from 'astal/gtk3'; import AstalHyprland from 'gi://AstalHyprland?version=0.1'; +import { BarVisibility } from 'src/cli/utils/BarVisibility'; import { forceUpdater } from 'src/components/bar/modules/workspaces/helpers'; import options from 'src/options'; const hyprlandService = AstalHyprland.get_default(); const { autoHide } = options.bar; -const focusedClient = (focusedClient: AstalHyprland.Client): void => { - const fullscreenBinding = bind(focusedClient, 'fullscreen'); +/** + * Sets bar visibility for a specific monitor + * + * @param monitorId - The ID of the monitor + * @param isVisible - Whether the bar should be visible + */ +function setBarVisibility(monitorId: number, isVisible: boolean): void { + const barName = `bar-${monitorId}`; - if (!focusedClient) { + if (BarVisibility.get(barName)) { + App.get_window(barName)?.set_visible(isVisible); + } +} + +/** + * Handles bar visibility when a client's fullscreen state changes + * + * @param client - The Hyprland client that gained focus + */ +function handleFullscreenClientVisibility(client: AstalHyprland.Client): void { + if (!client) { return; } + const fullscreenBinding = bind(client, 'fullscreen'); + Variable.derive([bind(fullscreenBinding)], (isFullScreen) => { if (autoHide.get() === 'fullscreen') { - App.get_window(`bar-${focusedClient.monitor.id}`)?.set_visible(!isFullScreen); + setBarVisibility(client.monitor.id, !isFullScreen); } }); -}; +} -export const initializeAutoHide = (): void => { - Variable.derive([bind(autoHide), bind(forceUpdater), bind(hyprlandService, 'workspaces')], (shouldAutohide) => { - if (shouldAutohide === 'never') { - hyprlandService.get_monitors().forEach((monitor) => { - App.get_window(`bar-${monitor.id}`)?.set_visible(true); - }); +/** + * Shows bars on all monitors + */ +function showAllBars(): void { + const monitors = hyprlandService.get_monitors(); + + monitors.forEach((monitor) => { + if (BarVisibility.get(`bar-${monitor.id}`)) { + setBarVisibility(monitor.id, true); } + }); +} - hyprlandService.get_workspaces().map((workspace) => { - if (autoHide.get() === 'single-window') { - App.get_window(`bar-${workspace.monitor.id}`)?.set_visible(workspace.get_clients().length !== 1); +/** + * Updates bar visibility based on workspace window count + */ +function updateBarVisibilityByWindowCount(): void { + const monitors = hyprlandService.get_monitors(); + const activeWorkspaces = monitors.map((monitor) => monitor.active_workspace); + + activeWorkspaces.forEach((workspace) => { + const hasOneClient = workspace.get_clients().length !== 1; + setBarVisibility(workspace.monitor.id, hasOneClient); + }); +} + +/** + * Updates bar visibility based on workspace fullscreen state + */ +function updateBarVisibilityByFullscreen(): void { + hyprlandService.get_workspaces().forEach((workspace) => { + setBarVisibility(workspace.monitor.id, !workspace.hasFullscreen); + }); +} + +/** + * Initializes the auto-hide behavior for bars + * Manages visibility based on window count, fullscreen state, and user preferences + */ +export function initializeAutoHide(): void { + Variable.derive( + [ + bind(autoHide), + bind(hyprlandService, 'workspaces'), + bind(forceUpdater), + bind(hyprlandService, 'focusedWorkspace'), + ], + (hideMode) => { + if (hideMode === 'never') { + showAllBars(); + } else if (hideMode === 'single-window') { + updateBarVisibilityByWindowCount(); } - }); - }); + }, + ); Variable.derive([bind(hyprlandService, 'focusedClient')], (currentClient) => { - focusedClient(currentClient); + handleFullscreenClientVisibility(currentClient); }); - Variable.derive([bind(autoHide)], (shouldAutohide) => { - if (shouldAutohide === 'fullscreen') { - hyprlandService.get_workspaces().forEach((workspace) => { - App.get_window(`bar-${workspace.monitor.id}`)?.set_visible(!workspace.hasFullscreen); - }); + Variable.derive([bind(autoHide)], (hideMode) => { + if (hideMode === 'fullscreen') { + updateBarVisibilityByFullscreen(); } }); -}; +} diff --git a/src/lib/types/cli.d.ts b/src/lib/types/cli.d.ts new file mode 100644 index 0000000..0e74f46 --- /dev/null +++ b/src/lib/types/cli.d.ts @@ -0,0 +1 @@ +export type BarToggleStates = Record;