terminal-widgets

1. Migration Guide: v1.3 v2.0

Version 2.0 of terminal-widgets introduces a major refactor to centralise state management and improve typing. If you have created custom widgets in ~/.config/twidgets/py_widgets/, you will need to update them to work with the new release.

1.1 Abstract of Changes


1.2 Imports

The imports in your custom widget files need to be cleaned up. UIState, BaseConfig, and standalone helper functions are no longer imported directly from twidgets.core.base.

Old (v1.3):

from twidgets.core.base import Widget, draw_widget, add_widget_content, Config, UIState, BaseConfig, CursesWindowType

New (v2.0):

from twidgets.core.base import Widget, WidgetContainer, Config, CursesWindowType

# Optional: Import CursesColors if you use specific styling
from twidgets.core.base import CursesColors

# Optional: Import CursesKeys if you use specific keyboard or mouse actions
from twidgets.core.base import CursesKeys

1.3 draw function

The draw function signature has changed. Instead of passing ui_state and base_config separately, you now pass a single widget_container.

Old (v1.3):

def draw(widget: Widget, ui_state: UIState, base_config: BaseConfig) -> None:
    draw_widget(widget, ui_state, base_config)
    
    content = ['Hello', 'World']
    add_widget_content(widget, content)

New (v2.0):

def draw(widget: Widget, widget_container: WidgetContainer) -> None:
    # 1. Update draw_widget call
    draw_widget(widget, widget_container) 
    
    content = ['Hello', 'World']
    # 2. Use the widget instance method for adding content
    widget.add_widget_content(content)

Note: If your draw function accepts data from an update function (e.g., info), the signature becomes: def draw(widget: Widget, widget_container: WidgetContainer, info: Any) -> None:

1.4 update function and secrets

If your widget fetches data (APIs, heavy loading), the update function signature has changed. Additionally, accessing secrets is now done through the widget_container.

Old (v1.3):

from twidgets.core.base import ConfigLoader

def update(_widget: Widget, _config_loader: ConfigLoader) -> list[str]:
    api_key = _config_loader.get_secret('MY_KEY')
    ...

New (v2.0):

# ConfigLoader import is likely no longer needed if only used for type hinting secrets
def update(widget: Widget, widget_container: WidgetContainer) -> list[str]:
    # Access config_loader via the container
    api_key = widget_container.config_loader.get_secret('MY_KEY')
    ...

1.5 Advanced Styling (safe_addstr)

If you use safe_addstr for precise text placement, the arguments have changed significantly. It is now a method of widget, and colors/attributes are passed as lists.

Old (v1.3):

from twidgets.core.base import safe_addstr, convert_color_number_to_curses_pair, CursesBold

# ... inside draw ...
safe_addstr(widget, y, x, 'Text', convert_color_number_to_curses_pair(base_config.PRIMARY_PAIR_NUMBER) | CursesBold)

New (v2.0):

from twidgets.core.base import CursesColors

# ... inside draw ...
widget.safe_addstr(y, x, 'Text', 
    [widget_container.base_config.PRIMARY_PAIR_NUMBER], # Pass all numbers (PRIMARY_PAIR_NUMBER, SECONDARY_PAIR_NUMBER etc.) here (as a list)
    [CursesColors.BOLD]                                 # Pass all pairs (BOLD, REVERSE, etc.) here (as a list)
)

1.6 Input Handling and Init

If your widget handles mouse clicks, keyboard presses, or has an init function, update the signatures to accept widget_container.

1.6.1 Mouse Actions

Old (v1.3): def mouse_click_action(widget: Widget, mx: int, my: int, b_state: int, ui_state: UIState):

New (v2.0): def mouse_click_action(widget: Widget, mx: int, my: int, b_state: int, widget_container: WidgetContainer) -> None:

1.6.2 Keyboard Actions

Old (v1.3): def keyboard_press_action(widget: Widget, key: int, ui_state: UIState, base_config: BaseConfig):

New (v2.0): def keyboard_press_action(widget: Widget, key: int, widget_container: WidgetContainer) -> None:

1.6.3 Prompt User Input

Old (v1.3): confirm = prompt_user_input(widget, 'Are you sure?')

New (v2.0): confirm = widget.prompt_user_input('Are you sure?')

1.6.4 Init

Old (v1.3): def init(widget, ui_state, base_config):

New (v2.0): def init(widget: Widget, widget_container: WidgetContainer) -> None:

1.7 Built-in widget locations

All widgets (also built-ins) are now located at ~/.config/twidgets/py_widgets/. This means you will have to run twidgets init if you still want the built-in widgets integrated in your layout.

1.8 Z-index

Widgets now support z-coordinates too. Set them in each .yaml file in ~/.config/twidgets/widgets/ using the key z.

Example:

name: '...'
title: ' ... '
enabled: True
interval: 0
height: 5
width: 30
y: 4
x: 87
z: 0