Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PopupMenu: add make_generators method #409

Merged
merged 1 commit into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
2025-01-02: [FEATURE] More methods for generating `PopupMenu` objects
2024-12-26: [BUGFIX] Fix control highlight border in popup toolkit
2024-12-23: [FEATURE] Add ability to mask icons in `StatusNotifier` widget
2024-12-11: [BREAKING CHANGE] `dbus-next` dependency has been replaced with `dbus-fast`. Update to latest qtile is also required.
Expand Down
56 changes: 56 additions & 0 deletions docs/manual/how_to/popup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -385,5 +385,61 @@ 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.

Alternatively, the ``PopupMenu.make_generators`` method can be used to apply a config to menu items
and the layout. It returns three functions which are used to create menu items, separators and the layout.
For example, to recreate the text menu above with a custom theme, you could do the following:

.. code:: python

from libqtile.lazy import lazy

from qtile_extras.popup import PopupMenu


# Define config for menu and create functions to generate menu
menu_config = {
"foreground": "0ff",
"foreground_disabled": "666",
"foreground_highlighted": "fff",
"highlight": "900",
"border_width": 2
}

item, separator, generate = PopupMenu.make_generators(**menu_config)


@lazy.function
def show_text_power_menu(qtile):
items = [
item(text="Power Menu", enabled=False),
separator(),
item(
text="Lock",
mouse_callbacks={
"Button1": lazy.spawn("/path/to/lock_cmd")
}
),
item(
text="Sleep",
mouse_callbacks={
"Button1": lazy.spawn("/path/to/lock_cmd")
}
),
item(
text="Shutdown",
mouse_callbacks={
"Button1": lazy.shutdown()
}
),
]
menu = generate(qtile, menuitems=items)
menu.show(centered=True)

keys = [
...
Key([mod, "shift"], "q", show_text_power_menu)
...
]

Configuration options for the menu objects can be found on
:ref:`the reference page <ref-popup-menus>`.
2 changes: 1 addition & 1 deletion docs/manual/ref/popup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ These are basic text menus. The layout is generated automatically and users are
required to provide the menu items.

.. qtile_class:: qtile_extras.popup.menu.PopupMenu
:methods: generate,from_dbus_menu
:methods: generate,from_dbus_menu,make_generators

.. qtile_class:: qtile_extras.popup.menu.PopupMenuItem

Expand Down
32 changes: 32 additions & 0 deletions qtile_extras/popup/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,38 @@ def __init__(self, qtile, controls, **config):
PopupGridLayout.__init__(self, qtile, controls=controls, **config)
self.add_defaults(PopupMenu.defaults)

@staticmethod
def make_generators(qtile=None, **config):
"""
Returns three functions (``make_popupmenuitem``, ``make_popupmenuseparator`` and
``generate_menu``) to help creation of menus with custom configs.

``make_popupmenuitem`` and ``make_popupmenuseparator`` create those items but with
the supplied config already applied to them. Config values can still be overriden
on an item-by-item basis.

``generate_menu`` creates the menu with the supplied config.

The ``qtile`` object must be passed to either the ``make_generators`` method or the
``generate_menu`` function.
"""
_qtile = qtile

def make_popupmenuitem(text, **itemconfig):
cfg = {**config, **itemconfig}
return PopupMenuItem(text=text, **cfg)

def make_popupmenuseparator(**itemconfig):
cfg = {**config, **itemconfig}
return PopupMenuSeparator(**cfg)

def generate_menu(qtile=None, menuitems=list(), **menuconfig):
qt = _qtile or qtile
cfg = {**config, **menuconfig}
return PopupMenu.generate(qt, menuitems=menuitems, **cfg)

return make_popupmenuitem, make_popupmenuseparator, generate_menu

@classmethod
def from_dbus_menu(cls, qtile, dbusmenuitems, **config):
"""
Expand Down
Loading