Skip to main content

Package version

rofi-menu

Rofi allows defining custom modes (see the spec).

This lib is a reference implementation with some extra "sugar".

Features:

  • simple menu definition via python
  • extendable
  • async in first place
  • allows keeping state during rofi session

Simple demo:

custom menu

Requirements

  • rofi >= 1.5.4
  • python >= 3.6

Installation

Using pip

$ pip install rofi-menu

Example

Create a python script which will be used for rofi mode e.g. example.py (don't forget to mark it as executable -- chmod +x ./example.py)

Assuming you installed rofi-menu into a virtual environment (let's say it's ~/.pyenv/versions/rofi/bin/python). Make sure shebang points to the right python executable, e.g. #!/home/user/pyenv/versions/rofi/bin/python.

#!/home/user/.pyenv/versions/rofi/bin/python
import rofi_menu


class ProjectsMenu(rofi_menu.Menu):
    prompt = "Projects"
    items = [
        rofi_menu.BackItem(),
        rofi_menu.ShellItem("Project 1", "code-insiders ~/Develop/project1"),
        rofi_menu.ShellItem("Project 2", "code-insiders ~/Develop/project2"),
        rofi_menu.ShellItem("Project X", "code-insiders ~/Develop/projectx"),
    ]


class LogoutMenu(rofi_menu.Menu):
    prompt = "Logout"
    items = [
        rofi_menu.ShellItem("Yes", "i3-msg exit", flags={rofi_menu.FLAG_STYLE_URGENT}),
        rofi_menu.ExitItem("No", flags={rofi_menu.FLAG_STYLE_ACTIVE}),
    ]


class MainMenu(rofi_menu.Menu):
    prompt = "menu"
    items = [
        rofi_menu.TouchpadItem(),
        rofi_menu.NestedMenu("Projects >", ProjectsMenu()),
        rofi_menu.ShellItem(
            "Downloads (show size)", "du -csh ~/Downloads", show_output=True
        ),
        rofi_menu.NestedMenu("Second monitor", rofi_menu.SecondMonitorMenu()),
        rofi_menu.ShellItem("Lock screen", "i3lock -i ~/.config/i3/bg.png"),
        rofi_menu.ShellItem("Sleep", "systemctl suspend"),
        rofi_menu.NestedMenu("Logout", LogoutMenu()),
    ]


if __name__ == "__main__":
    rofi_menu.run(MainMenu(), rofi_version="1.6")  # change to 1.5 if you use older rofi version

Run it as:

$ rofi -modi mymenu:/path/to/example.py -show mymenu -show-icons

It'll result in

rofi menu

Advanced example

#!/home/user/pyenv/versions/rofi/bin/python
import asyncio
from datetime import datetime
import os

import rofi_menu


class OutputSomeTextItem(rofi_menu.Item):
    """Output arbitrary text on selection"""
    async def on_select(self, meta):
        # any python code
        await asyncio.sleep(0.1)
        return rofi_menu.Operation(rofi_menu.OP_OUTPUT, (
            "💢 simple\n"
            "💥 multi-\n"
            "💫 <b>line</b>\n"
            "💣 <i>text</i>\n"
        ))


class DoAndExitItem(rofi_menu.Item):
    """Do something and exit"""
    async def on_select(self, meta):
        os.system('notify-send msg')
        return rofi_menu.Operation(rofi_menu.OP_EXIT)


class CurrentDatetimeItem(rofi_menu.Item):
    """Show current datetime inside menu item"""
    async def load(self, meta):
        self.state = datetime.now().strftime('%A %d. %B %Y (%H:%M:%S)')

    async def render(self, meta):
        return f"🕑 {self.state}"


class CounterItem(rofi_menu.Item):
    """Increment counter on selection"""
    async def load(self, meta):
        await super().load(meta)
        self.state = self.state or 0
        meta.session.setdefault("counter_total", 0)

    async def on_select(self, meta):
        self.state += 1
        meta.session["counter_total"] += 1
        return await super().on_select(meta)

    async def render(self, meta):
        per_menu_item = self.state
        total = meta.session["counter_total"]
        return f"🏃 Selected #{per_menu_item} time(s) (across menu items #{total})"


class HandleUserInputMenu(rofi_menu.Menu):
    allow_user_input = True

    class CustomItem(rofi_menu.Item):
        async def render(self, meta):
            entered_text = meta.session.get("text", "[ no text ]")
            return f"You entered: {entered_text}"

    items = [CustomItem()]

    async def on_user_input(self, meta):
        meta.session['text'] = meta.user_input
        return rofi_menu.Operation(rofi_menu.OP_REFRESH_MENU)


main_menu = rofi_menu.Menu(
    prompt="menu",
    items=[
        OutputSomeTextItem("Output anything"),
        DoAndExitItem("Do something and exit"),
        CurrentDatetimeItem(),
        CounterItem(),
        CounterItem(),
        rofi_menu.NestedMenu("User input", HandleUserInputMenu()),
    ],
)


if __name__ == "__main__":
    rofi_menu.run(main_menu)

advanced example

TODO

  • documentation of API
  • examples
  • tests

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rofi-menu-0.6.tar.gz (12.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rofi_menu-0.6-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file rofi-menu-0.6.tar.gz.

File metadata

  • Download URL: rofi-menu-0.6.tar.gz
  • Upload date:
  • Size: 12.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.0.10 CPython/3.8.5 Linux/5.8.0-50-generic

File hashes

Hashes for rofi-menu-0.6.tar.gz
Algorithm Hash digest
SHA256 96df3ef2fe622ab65675548b9f4e11e82052c039fbc0a26e4787db59921695be
MD5 d06e98d81cc9e6498c9a60df39de3836
BLAKE2b-256 874f6ca17850ded7e2cc019ac9fe14b9bc24b874b936ec23cc1aacadb0e4423d

See more details on using hashes here.

File details

Details for the file rofi_menu-0.6-py3-none-any.whl.

File metadata

  • Download URL: rofi_menu-0.6-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.0.10 CPython/3.8.5 Linux/5.8.0-50-generic

File hashes

Hashes for rofi_menu-0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 ae9791f6332448876c499a0b011da6c7df595c360110c0557a2b98ef8eb3e412
MD5 2ef92ec665ba13ac6eeaccfb368a4204
BLAKE2b-256 2248d59deea04e60c6ec6b910a4329fc2b30be4085405b86b2b5c3bd7a258664

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.6 This release

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page