# How to Toggle Hiding of Targets with Filters Set to Off in tui-logger

> Learn how to toggle the visibility of tui-logger targets with filters set to Off using the Space key. Easily manage your log output for better debugging.

- Repository: [gin66/tui-logger](https://github.com/gin66/tui-logger)
- Tags: how-to-guide
- Published: 2026-03-02

---

**Press the Space key (or programmatically invoke `TuiWidgetEvent::SpaceKey`) to toggle the visibility of log targets whose filter is set to `LevelFilter::Off` in the tui-logger widget.**

The `gin66/tui-logger` crate provides interactive log filtering for Rust terminal user interfaces. When your application configures `LevelFilter::Off` for specific modules, you can declutter the target list by toggling the **Hide Off** flag, which removes those disabled entries from view without changing their underlying filter configuration.

## How the Hide-Off Mechanism Works

`tui-logger` maintains two distinct visibility toggles. **Hide Off** controls whether targets with `LevelFilter::Off` appear in the list, while **Hide Target** collapses the entire target column.

| Toggle | Behavior | Default Key |
|--------|------------|-------------|
| **Hide Off** | Omits targets where `LevelFilter == Off` | <kbd>Space</kbd> |
| **Hide Target** | Hides the entire target column, showing only logs | <kbd>h</kbd> (`HideKey`) |

The **Hide Off** state is stored in the `hide_off` field of `TuiWidgetInnerState`. When you trigger a `SpaceKey` event, the state machine flips this boolean flag (`self.hide_off ^= true`). Both the standalone target widget and the composite smart widget read this flag during render to skip drawing filtered-off targets.

## Implementation in the Source Code

The toggle logic spans three core files in `src/widget/`. Understanding these locations helps when customizing behavior or debugging visibility issues.

### State Transition in [`src/widget/inner.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/inner.rs)

The `TuiWidgetState` handle processes input events in [`inner.rs`](https://github.com/gin66/tui-logger/blob/main/inner.rs). When it receives `TuiWidgetEvent::SpaceKey`, it toggles the internal flag:

```rust
// src/widget/inner.rs, lines 86-88
SpaceKey => {
    self.hide_off ^= true;
}

```

This mutation affects all widgets sharing the same state handle. The event enum itself is defined earlier in the same file at lines 45-58.

### Target Widget Filtering in [`src/widget/target.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/target.rs)

The `TuiLoggerTargetWidget` iterates through registered targets and applies the hide-off logic before rendering. If the flag is enabled and a target's filter equals `LevelFilter::Off`, the iterator skips that entry:

```rust
// src/widget/target.rs, lines 152-155
for (t, levelfilter) in targets.iter() {
    if hide_off && levelfilter == &LevelFilter::Off {
        continue;               // skip targets filtered Off
    }
    self.targets.push(t.clone());
}

```

This ensures the UI list stays synchronized with the toggle state.

### Smart Widget Layout in [`src/widget/smart.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/smart.rs)

The composite smart widget also respects `hide_off` when calculating column widths. It filters the target list during layout to avoid allocating space for hidden entries:

```rust
// src/widget/smart.rs, lines 62-66
for (t, levelfilter) in targets.iter() {
    if hide_off && levelfilter == &LevelFilter::Off {
        continue;
    }
    width = width.max(t.graphemes(true).count())
}

```

This prevents layout jitter when toggling the visibility of off-filtered targets.

## Practical Usage Examples

You can trigger the toggle either through built-in key handling or direct API calls.

### Handling Keyboard Input

If you delegate input to `tui-logger`'s state machine, map the Space key to `TuiWidgetEvent::SpaceKey`:

```rust
use tui_logger::{TuiWidgetState, TuiWidgetEvent};
use crossterm::event::{self, Event, KeyCode};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let state = TuiWidgetState::new();

    loop {
        if let Event::Key(key) = event::read()? {
            match key.code {
                KeyCode::Char(' ') => {
                    // Toggle hiding of Off-filtered targets
                    state.transition(TuiWidgetEvent::SpaceKey);
                }
                KeyCode::Char('h') => {
                    // Toggle visibility of the entire target column
                    state.transition(TuiWidgetEvent::HideKey);
                }
                _ => {}
            }
        }
        
        // Render widgets using the shared state...
    }
}

```

### Programmatic Control

To toggle the setting without user input, invoke the transition directly on your `TuiWidgetState` instance:

```rust
let state = TuiWidgetState::new();

// Hide targets with LevelFilter::Off
state.transition(tui_logger::TuiWidgetEvent::SpaceKey);

// Show them again later
state.transition(tui_logger::TuiWidgetEvent::SpaceKey);

```

This approach works well when saving or restoring UI preferences from a configuration file.

## Summary

- The **Space** key toggles `hide_off` in `TuiWidgetInnerState`, controlling whether targets with `LevelFilter::Off` appear in the list.
- The implementation resides in [`src/widget/inner.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/inner.rs) (state), [`src/widget/target.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/target.rs) (rendering), and [`src/widget/smart.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/smart.rs) (layout).
- Call `state.transition(TuiWidgetEvent::SpaceKey)` to trigger the toggle programmatically.
- This feature is distinct from the **Hide Target** toggle (<kbd>h</kbd> key), which hides the entire column rather than filtering individual entries.

## Frequently Asked Questions

### What is the default keyboard shortcut to hide targets with filters set to Off?

The default shortcut is the **Space** bar. When the tui-logger widget has focus, pressing Space generates a `TuiWidgetEvent::SpaceKey` that flips the `hide_off` boolean flag, immediately hiding or showing targets where the filter equals `LevelFilter::Off`.

### How do I toggle hiding of off-filtered targets without keyboard input?

Use the programmatic API. Obtain a `TuiWidgetState` handle and call `state.transition(TuiWidgetEvent::SpaceKey)`. This mutates the internal `hide_off` flag exactly as if the user pressed Space, allowing you to control visibility from configuration files or automated UI states.

### Does toggling Hide Off affect the smart widget's column layout?

Yes. The smart widget defined in [`src/widget/smart.rs`](https://github.com/gin66/tui-logger/blob/main/src/widget/smart.rs) checks `hide_off` during its width-calculation phase (lines 62-66). When the flag is enabled, the widget excludes off-filtered targets from the width calculation, preventing the layout from reserving space for invisible entries.

### What is the difference between the Space key and the 'h' key in tui-logger?

The **Space** key toggles **Hide Off**, which filters the list to exclude individual targets with `LevelFilter::Off`. The **'h'** key (mapped to `HideKey`) toggles **Hide Target**, which collapses the entire target column to show only the log output, regardless of individual filter settings.