Skip to content

Commit

Permalink
Draft version
Browse files Browse the repository at this point in the history
  • Loading branch information
miphreal committed Mar 29, 2020
0 parents commit 66fe7ff
Show file tree
Hide file tree
Showing 16 changed files with 710 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# editorconfig.org
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.{yaml,yml}]
indent_style = space
indent_size = 2
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
*.pyc

# Packages
*.egg
/*.egg-info
/dist/*
build
_build
.cache
*.so

# Installer logs
pip-log.txt

# Unit test / coverage reports
.coverage
.tox
.pytest_cache

.DS_Store
.idea/*
.python-version
.vscode/*

.mypy_cache

.venv
8 changes: 8 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[settings]
default_section=THIRDPARTY
indent=' '
sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
multi_line_output=3
line_length=88
include_trailing_comma=True
use_parentheses=True
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# rofi-menu: lib for building rofi menu via python


39 changes: 39 additions & 0 deletions example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env 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())
176 changes: 176 additions & 0 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[tool.poetry]
name = "rofi-menu"
version = "0.1.0"
description = "Create rofi menus via python"
authors = ["miphreal <[email protected]>"]
license = "MIT"

[tool.poetry.dependencies]
python = "^3.8"

[tool.poetry.dev-dependencies]
black = "^19.10b0"
isort = "^4.3.21"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
4 changes: 4 additions & 0 deletions rofi_menu/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .constants import *
from .contrib import *
from .main import run
from .menu import Menu, NestedMenu, Item, BackItem, ExitItem
11 changes: 11 additions & 0 deletions rofi_menu/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
MENU_ITEM_META_DELIM = "\r!"

FLAG_STYLE_URGENT = "URGENT"
FLAG_STYLE_ACTIVE = "ACTIVE"

OP_OUTPUT = "OUTPUT_MENU"
OP_REFRESH_MENU = "REFRESH_MENU"
OP_BACK_TO_PARENT_MENU = "BACK_TO_PARENT_MENU"
OP_EXIT = "EXIT"

ROOT_MENU_ID = "root"
3 changes: 3 additions & 0 deletions rofi_menu/contrib/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .monitor import SecondMonitorMenu
from .shell import ShellItem
from .touchpad import TouchpadItem
51 changes: 51 additions & 0 deletions rofi_menu/contrib/monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from rofi_menu.menu import NestedMenu, Menu
from .shell import ShellItem


class SecondMonitorMenu(Menu):
prompt = "Second monitor"
secod_monitor_options = [
{
"text": '<span background="green"><b>Off</b></span>',
"command": "xrandr --output {mon1} --auto --output {mon2} --off",
},
{
"text": '<span background="blue"><b>Mirror</b></span>',
"command": "xrandr --output {mon1} --auto --output {mon2} --auto --same-as {mon1}",
},
{
"text": '<span background="gray"><b>Above</b></span>',
"command": "xrandr --output {mon1} --auto --output {mon2} --auto --above {mon1}",
},
{
"text": '<span background="gray"><b>Left</b></span>',
"command": "xrandr --output {mon1} --auto --output {mon2} --auto --left-of {mon1}",
},
{
"text": '<span background="gray"><b>Right</b></span>',
"command": "xrandr --output {mon1} --auto --output {mon2} --auto --right-of {mon1}",
},
{
"text": '<span background="gray"><b>Below</b></span>',
"command": "xrandr --output {mon1} --auto --output {mon2} --auto --below {mon1}",
},
]

def __init__(
self,
prompt="Second monitor",
primary_monitor="eDP1",
secondary_monitor="HDMI1",
):
items = [
ShellItem(
text=option["text"].format(
mon1=primary_monitor, mon2=secondary_monitor
),
command=option["command"].format(
mon1=primary_monitor, mon2=secondary_monitor
),
)
for option in self.secod_monitor_options
]
super().__init__(prompt=prompt, items=items)
32 changes: 32 additions & 0 deletions rofi_menu/contrib/shell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import asyncio

from rofi_menu.constants import OP_EXIT, OP_OUTPUT
from rofi_menu.menu import Item, Operation


class ShellItem(Item):
def __init__(self, text=None, command="echo OK", **kwargs):
self._command = command
self.show_output = kwargs.pop("show_output", False)
self.detached = kwargs.pop("detached", True)
super().__init__(text, **kwargs)

@property
def command(self):
return self._command

async def on_select(self, item_id, meta):
command = f"nohup {self.command}" if self.detached else self.command
proc = await asyncio.create_subprocess_shell(
command,
stdout=(
asyncio.subprocess.PIPE
if self.show_output
else asyncio.subprocess.DEVNULL
),
stderr=asyncio.subprocess.DEVNULL,
)
if self.show_output:
data = await proc.stdout.read()
return Operation(OP_OUTPUT, data.decode("utf-8"))
return Operation(OP_EXIT)
Loading

0 comments on commit 66fe7ff

Please sign in to comment.