diff --git a/docs/_static/images/text_power_menu.png b/docs/_static/images/text_power_menu.png new file mode 100644 index 00000000..623aba3b Binary files /dev/null and b/docs/_static/images/text_power_menu.png differ diff --git a/docs/manual/how_to/popup.rst b/docs/manual/how_to/popup.rst index 1b2c6b1a..09304210 100644 --- a/docs/manual/how_to/popup.rst +++ b/docs/manual/how_to/popup.rst @@ -35,6 +35,7 @@ Currently, the following controls are provided: - ``PopupText``: a simple text display object - ``PopupImage``: a control to display an image - ``PopupSlider``: a control to draw a line which marks a particular value (e.g. volume level) +- ``PopupCircularProgress``: a control to draw a curved line showing progress etc. - ``PopupWidget``: a control to display a Qtile widget in the popup Configuration options for these controls can be found on @@ -55,7 +56,7 @@ Below is an example of creating a power menu in your ``config.py``. .. code:: python - from qtile_extras.popup.toolkit import ( + from qtile_extras.popup import ( PopupRelativeLayout, PopupImage, PopupText @@ -154,7 +155,7 @@ Below is a quick example for displaying a number of graph widgets in a popup: .. code:: python from libqtile import widget - from qtile_extras.popup.toolkit import ( + from qtile_extras.popup import ( PopupRelativeLayout, PopupWidget ) @@ -216,7 +217,7 @@ be updated in the same call. .. code:: python - from qtile_extras.popup.toolkit import ( + from qtile_extras.popup import ( PopupRelativeLayout, PopupText ) @@ -267,7 +268,7 @@ For example, to make the ``Clock`` widget show the long date when clicked: from libqtile import widget from qtile_extras import widget as extrawidgets - from qtile_extras.popup.toolkit import PopupRelativeLayout, PopupText, PopupWidget + from qtile_extras.popup import PopupRelativeLayout, PopupText, PopupWidget from qtile_extras.widget.mixins import ExtendedPopupMixin @@ -321,4 +322,68 @@ For example, to make the ``Clock`` widget show the long date when clicked: Putting ``extended_clock`` in your bar and clicking on the clock will give you this: -.. image:: /_static/images/extended_popup_clock.png \ No newline at end of file +.. image:: /_static/images/extended_popup_clock.png + + +Building simple text menus +========================== + +The toolkit also contains some basic classes to simplify the creation of text based menus. +The primary use of these classes is to provide context menus for widgets (e.g. ``StatusNotifier``) +but they can also be easily incorporated directly in config files. + +For example, to recreate the power menu above using text, you could define the following: + +.. code:: python + + from libqtile.lazy import lazy + + from qtile_extras.popup import PopupMenu, PopupMenuItem, PopupMenuSeparator + + + @lazy.function + def show_text_power_menu(qtile): + items = [ + PopupMenuItem(text="Power Menu", enabled=False), + PopupMenuSeparator(), + PopupMenuItem( + text="Lock", + mouse_callbacks={ + "Button1": lazy.spawn("/path/to/lock_cmd") + } + ), + PopupMenuItem( + text="Sleep", + mouse_callbacks={ + "Button1": lazy.spawn("/path/to/lock_cmd") + } + ), + PopupMenuItem( + text="Shutdown", + highlight="900", + mouse_callbacks={ + "Button1": lazy.shutdown() + } + ), + ] + menu = PopupMenu.generate(qtile, menuitems=items, border_width=2) + menu.show(centered=True) + + keys = [ + ... + Key([mod, "shift"], "q", show_text_power_menu) + ... + ] + +Pressing ``Mod + shift + B`` will display the following: + +.. image:: /_static/images/text_power_menu.png + +Menu items have a default blue/green highlight but this was overriden to show red for +the shutdown command. + +Note that the menu items can be configured individually. Configuration options for the layout +(border etc.) are passed to the ``generate`` method. + +Configuration options for the menu objects can be found on +:ref:`the reference page `. diff --git a/docs/manual/ref/popup.rst b/docs/manual/ref/popup.rst index 2241d5ae..1b4a4c2b 100644 --- a/docs/manual/ref/popup.rst +++ b/docs/manual/ref/popup.rst @@ -32,4 +32,21 @@ and have each of these react to input events or display information dynamically. :baseclass: qtile_extras.popup.toolkit._PopupWidget :exclude-base: :no-commands: - :show-config: \ No newline at end of file + :show-config: + + +.. _ref-popup-menus: + +Popup Toolkit Menus +=================== + +These are basic text menus. The layout is generated automatically and users are only +required to provide the menu items. + +.. qtile_class:: qtile_extras.popup.menu.PopupMenu + :methods: generate,from_dbus_menu + +.. qtile_class:: qtile_extras.popup.menu.PopupMenuItem + +.. qtile_class:: qtile_extras.popup.menu.PopupMenuSeparator + \ No newline at end of file diff --git a/qtile_extras/popup/menu.py b/qtile_extras/popup/menu.py index 8527b51a..b6a6cefc 100644 --- a/qtile_extras/popup/menu.py +++ b/qtile_extras/popup/menu.py @@ -162,13 +162,13 @@ class PopupMenu(PopupGridLayout): A class for creating menus. The menu should be created via one of two classmethods: - `from_dbus_menu` or `generate`. The former accepts a list of - `DBusMenuItem` objects and the second accepts a list of - `PopupMenuItem` and `PopupMenuSeparator` objects. + ``from_dbus_menu`` or ``generate``. The former accepts a list of + ``DBusMenuItem`` objects and the second accepts a list of + ``PopupMenuItem`` and ``PopupMenuSeparator`` objects. The menu is created as a PopupGridLayout object. Therefore, if - using the `generate` method, object sizes can be changed using - the `row_span` attribute. By default, a text item will be twice + using the ``generate`` method, object sizes can be changed using + the ``row_span`` attribute. By default, a text item will be twice the height of a separator. """ @@ -182,6 +182,12 @@ def __init__(self, qtile, controls, **config): @classmethod def from_dbus_menu(cls, qtile, dbusmenuitems, **config): + """ + Create a ``PopupMenu`` instance a DBus menu. + + The ``dbusmenuitems`` need to be created from ``DBusMenu.parse_menu`` as this + will generate the ``DBusMenuItem`` objects needed to create a menu. + """ menuitems = [] prev_sep = False @@ -227,6 +233,14 @@ def from_dbus_menu(cls, qtile, dbusmenuitems, **config): @classmethod def generate(cls, qtile, menuitems, **config): + """ + Create a ``PopupMenu`` instance from the provided ``menuitems``. + + Users must pass the ``qtile`` instance as well as the list of items. + + ``menuitems`` should be a list of ``PopupMenuItem`` and ``PopupMenuSeparator`` + instances. + """ row_count = 0 for item in menuitems: item.row = row_count