Source code for qtile_expanded.extensions.base_popup

"""
Base Popup class for Qtile Expanded.

This module provides a base class for all popups and a registry to track
all open popups, enabling external control (e.g., via gestures or keybindings).

Features:
- BasePopup: Base class for all popup types
- PopupRegistry: Tracks all open popups
- close_all_popups(): Close all open popups
- is_popup_open(): Check if any popup is open
"""

from libqtile.popup import Popup
from libqtile.log_utils import logger


[docs] class PopupRegistry: """ Registry for tracking all open popups. This singleton class maintains a list of all open popups, allowing external code to check if popups are open and close them programmatically. Usage: from qtile_expanded.extensions.base_popup import PopupRegistry # Check if any popup is open if PopupRegistry.is_popup_open(): print("A popup is open") # Close all popups PopupRegistry.close_all_popups() # Get list of open popups open_popups = PopupRegistry.get_open_popups() """ _instances: list = []
[docs] @classmethod def register(cls, popup) -> None: """Register a popup as open.""" if popup not in cls._instances: cls._instances.append(popup) logger.debug(f"PopupRegistry: Registered popup {popup}")
[docs] @classmethod def unregister(cls, popup) -> None: """Unregister a popup when it's closed.""" if popup in cls._instances: cls._instances.remove(popup) logger.debug(f"PopupRegistry: Unregistered popup {popup}")
[docs] @classmethod def get_open_popups(cls) -> list: """Get list of all open popups.""" return cls._instances.copy()
[docs] @classmethod def is_popup_open(cls) -> bool: """Check if any popup is currently open.""" return len(cls._instances) > 0
[docs] @classmethod def close_all_popups(cls) -> int: """ Close all open popups. Returns: Number of popups closed """ count = 0 for popup in cls._instances[:]: try: if hasattr(popup, 'win') and hasattr(popup.win, 'visible') and popup.win.visible: popup.hide() count += 1 cls.unregister(popup) except Exception as e: logger.warning(f"PopupRegistry: Error closing popup: {e}") logger.debug(f"PopupRegistry: Closed {count} popups") return count
[docs] @classmethod def close_popup(cls, popup) -> bool: """ Close a specific popup if it's open. Args: popup: The popup instance to close Returns: True if the popup was open and closed, False otherwise """ if popup in cls._instances: try: if hasattr(popup, 'win') and hasattr(popup.win, 'visible') and popup.win.visible: popup.hide() cls.unregister(popup) return True except Exception as e: logger.warning(f"PopupRegistry: Error closing popup: {e}") return False
[docs] class BasePopup(Popup): """ Base class for all Qtile Expanded popups. This class extends Qtile's Popup with: - Automatic registration in PopupRegistry when shown - Automatic unregistration when hidden - Support for external close commands (gestures, keybindings) All popup classes should inherit from this class instead of directly from libqtile.popup.Popup. Usage: from qtile_expanded.extensions.base_popup import BasePopup class MyPopup(BasePopup): def __init__(self, qtile, **config): super().__init__(qtile, **config) # Your initialization """
[docs] def __init__(self, qtile, **config): """Initialize the base popup.""" super().__init__(qtile, **config) self._registered = False # Override hide to unregister when closed original_hide = self.hide def hide_with_unregister(): original_hide() self._unregister() self.hide = hide_with_unregister
[docs] def show(self, *args, **kwargs): """Show the popup and register it.""" super().show(*args, **kwargs) self._register()
def _register(self) -> None: """Register this popup in the registry.""" PopupRegistry.register(self) self._registered = True def _unregister(self) -> None: """Unregister this popup from the registry.""" if self._registered: PopupRegistry.unregister(self) self._registered = False
[docs] @classmethod def close_all(cls) -> int: """ Close all popups of this type. Returns: Number of popups closed """ return PopupRegistry.close_all_popups()
[docs] @classmethod def is_any_open(cls) -> bool: """Check if any popup is open.""" return PopupRegistry.is_popup_open()
[docs] def close_all_popups() -> int: """ Close all open popups. This function can be called from anywhere (e.g., gesture handlers, keybindings) to close all open popups. Returns: Number of popups closed Example: from qtile_expanded.extensions.base_popup import close_all_popups # In your Qtile config def close_popups(qtile): count = close_all_popups() if count > 0: print(f"Closed {count} popups") keys = [ Key(["mod1"], "Escape", lazy.function(close_popups)), ] """ return PopupRegistry.close_all_popups()
[docs] def is_popup_open() -> bool: """ Check if any popup is currently open. Returns: True if at least one popup is open, False otherwise Example: from qtile_expanded.extensions.base_popup import is_popup_open if is_popup_open(): print("There is a popup open") """ return PopupRegistry.is_popup_open()
[docs] def get_open_popups() -> list: """ Get list of all currently open popups. Returns: List of open popup instances """ return PopupRegistry.get_open_popups()