Rofi based application launcher menu with categories

Rofi is a great piece of software, it is light, fast and pretty. I've been using it as an application launcer for a long time. Unfortunately it lacks applications categories menu.

There is full featured morc_menu with categories, but it is not very pretty. So I borrowed some ideas from it and wrote a script with rofi.

Rofi can search applications by category, so I used that feature and managed to add application categories (kind of) to rofi.

2018-03-23-113726_1366x768_scrot

2018-03-23-113736_1366x768_scrot

Script is here

@Chrysostomus, maybe something like that will fit bspwm-minimal?

7 Likes

Sure! Also, morc_menu could be used with rofi. However, that would mean no icons.

Maybe a menu with some top level items + application categories? Like

Terminal
Filemanager
Browser
[categories]
Search
Settings
Exit

That could be quite awesome. Thank you for the idea and the script!

1 Like

With Nerd fonts it is possible to add icons to the top level menu

Good idea! I would like to have arrow or some other indicator to the right of the app categories to show that they have submenus. I think I will have some time to work on this on Monday morning.

Terminal
Filemanager
Browser
AudioVideo    >
Development   >
Documentation >
Education     >
Graphics      >
Network       >
Office        >
System        >
Utility       >
Settings      >
Exit
1 Like

2018-03-23-234436_1920x1080_scrot

Added custom items to the top level menu. Having some trouble with

  • Using spaces in item names (shift in line 84)
  • Adding icons to application categories (maybe a sed pipe at the end of $present?)

EDIT: got icons added to categories:

2018-03-24-001738_1920x1080_scrot

It messes up the y offset calculation though. Maybe I should just use mouselocation with xdotool, since I would like to use it anyway as desktop menu too.

EDIT: Hacked the height, this is what I got now:

#!/bin/dash

Y_OFFSET=1	# vertical position in lines
MAX_LINES=20
DISABLE_CAT_INPUTLINE="#mainbox {children: [ listview ];}"	# unset it to have input line on categories
# DISABLE_CAT_INPUTLINE=""

THEME="	#window {
		location: northwest;
		anchor: northwest;
		y-offset: ${Y_OFFSET}em;}
	#listview {
		fixed-height: false;
		lines: $MAX_LINES;
		dynamic: true;}"
ALL_CAT=" Applications"
TITLE="Menu:"

# new line separated list
desired='Favorites
Settings
Development 
Documentation
Education
System
Network
Utility
Graphics
Office
AudioVideo
Accessories
Multimedia
Internet'

present=$(grep Categories /usr/share/applications/*.desktop \
	| cut -d'=' -f2 \
	| sed 's/;/\n/g' \
	| LC_COLLATE=POSIX sort --ignore-case --unique \
	| grep "$desired" -F -x - \
	| sed -e 's/Settings/ Settings/g' -e 's/Development/ Development/g' -e 's/AudioVideo/ AudioVideo/g' -e 's/Documentation/ Documentation/g' -e 's/Office/ Office/g' -e 's/System/漣 System/g' -e 's/Utility/ Utility/g' -e 's/Accessories/ Accessories/g' -e 's/Multimedia/ Multimedia/g' -e 's/Education/拾 Education/g' -e 's/Internet/ Internet/g' -e 's/Graphics/ Graphics/g' -e 's/Network/ Network/g')

menulist=" Terminal
 Filemanager
 Browser
$ALL_CAT
$present
 Search"

# determine max category name length

set -- $menulist
maxlength=1
while [ $# -gt 0 ] ; do
	if [ ${#1} -gt $maxlength ] ; then
		maxlength=${#1}
	fi
	shift
done
 
maxlength=$(($maxlength+8))
#maxlength=18
while true; do
	category=$(echo "$menulist" \
		| rofi 	-dmenu \
			-i \
			-no-custom \
			-config "~/.config/rofi/config-monocle.rasi" \
			-select "$category" \
			-p "$TITLE" \
			-theme-str "$THEME
				#window {
					width: ${maxlength}ch;
					x-offset: 0;}
					$DISABLE_CAT_INPUTLINE" \
		| awk '{print $2}')

	if [ -z "$category" ] ; then
		exit
	fi

	# determine vertical position of submenu
	yoffset=$Y_OFFSET
	set -- $menulist
	while [ "$category" != "$1" ] ; do
		yoffset=$(($yoffset+1))
		shift
	done
		yoffset=$(($yoffset/2+1))
	
	if [ "$category" = "$ALL_CAT" ] ; then
		category=""
	elif [ "$category" = "Terminal" ] ; then
		exec default-terminal &
		exit
	elif [ "$category" = "Browser" ] ; then
		exec default-browser &
		exit
	elif [ "$category" = "Filemanager" ] ; then
		xdg-open ~ &
		exit
	elif [ "$category" = "Search" ] ; then
		rofi-finder.sh &
		exit
	fi

	sleep 0.15	# pause to avoid instant menu closing with mouse
	
	command=$(rofi	-modi drun \
			-show drun \
			-drun-match-fields categories,name \
			-run-command "echo {cmd}" \
			-filter "$category " \
			-no-sidebar-mode \
			-config "~/.config/rofi/config-monocle.rasi" \
			-theme-str "$THEME
				#window {
					width: 40ch;
					x-offset: ${maxlength}ch;
					y-offset: ${yoffset}em;}")

	if [ -n "$command" ] ; then
		eval "$command" &
		exit
	fi
done
configuration {
    modi: 				"windowcd";
    me-select-entry:	"MouseSecondary";
    me-accept-entry:	"MousePrimary";
    scroll-method:      1;
    display-windowcd:   "Window: ";
    show-icons:         true;
    window-format:		"{c} - {t}";
}

* {
    background:                  #292f34FF;
    background-color:            #00000000;
    foreground:                  #F6F9FFFF;
    selected:                    #1ABB9BFF;

    active-background:           #3A464BFF;
    urgent-background:           #800000FF;
    urgent-foreground:           @foreground;
    selected-urgent-background:  @urgent-foreground;
    selected-urgent-foreground:  @urgent-background;

    font:                        "xos4 Terminus 22px";
    text-color:                  @foreground;

    border:                      0px;
    padding:                     0px;
    spacing:                     0px;
}
window {
    location:         north;
    y-offset:         25px;
    width:            33%;
    background-color: @background;
    padding:          4px;
}
listview {
    lines:        17;
    fixed-height: false;
    spacing:      3px;
    scrollbar:    false;
}
element.normal.active,
element.alternate.active {
    background-color: @active-background;
}
element.selected {
    background-color: @selected;
}
element.normal.urgent,
element.alternate.urgent {
    background-color: @urgent-background;
    text-color:       @urgent-foreground;
}
element.selected.urgent {
    background-color: @selected-urgent-background;
    text-color:       @selected-urgent-foreground;
}
1 Like

Maybe it will help to add this before set -- $menulist:

IFS='
'

After a lot of tinkering I've got this:

2018-03-25-015151_1366x768_scrot

2018-03-25-015214_1366x768_scrot

2018-03-25-015245_1366x768_scrot

New script
https://github.com/kainonergon/scripts/blob/master/rofimenu

Rofi theme
https://github.com/kainonergon/scripts/blob/master/rofimenu.rasi

Works with bash, but with dash it hangs. Still can not find the reason.
Using rofi with custom modi has a lot of nice opportunities, but I could not find a way how to set selected row. It is easy with rofi -dmenu, and it would be usefull to set when browsing categories.

5 Likes

I guess I need to use wait or trap command somewhere. Or maybe I'll have to split the script into several files.

Wow, this is some sweet stuff!

I think I could convert my fork to a desktop menu that spawns on the cursor and use this new version for the limepanel menu. Gotta go to work, but I sure am excited about this thing :smiley:

3 Likes

I think bash is fast enough for this. Porting it to dash is not strictly necessary (though potentially fun).

Do you mind if I package these as part of rootmenu/limepanel?

2 Likes

Here is a version that spawns on cursor:

2018-03-25-175416_1920x1080_scrot

2 Likes

I wrote it to work supposedly on dash, without any bash specific features like arrays. I guess dash prints some error messages where bash can do right thing without errors. If so, rofi gets all script output and tries to use it as a list and calls script. Infinite loop and it hangs. I'l try to look into what goes from the script to rofi and check if that is true.

Sure you can package it. I think it needs proper config file like limepanel

it is interesting to see you use the "desktop run" mode (with icons) of rofi more and more.

personally, i find myself using it less and less.
the reason is simple: i also want to use my custom commands in rofi. custom commands can only be run in the "run" mode. first, i have tried to use the combi mode (with "run" and "drun"), but rofi's behavior (especially sorting) was not to my satisfaction no matter what i tried.

currently, i use "run" mode by default and a calculator. i have removed "combi" mode completely. the "drun" and "window" modes are still there but i have not used them for weeks.
the only downside to using "run" mode by default are a lack of icons and some unintuitive program names, such as "lowriter" instead of "libre office writer".

@kainonergon
currently it looks likethis [ direct run was fine, after logout and login ], the menu window [blank part] shadow ! any further tweaking needed ?
rofimenu-shadowissue

I use dmenu_recency for this use case. It remembers my custom commands, is faster and has better behaviour for the tab key.

2 Likes

2018-03-25-210539_1920x1080_scrot

I'm wondering if the black area in the sidebar could be made transparent.

i was facing similar issue... [as displayed in the shat above]
i resolved this by editing bspwm autostart like this...

....
....
# autostart programs
compton -b --shadow-exclude 'argb' &
....
...
2 Likes

Rofi has only one rectangular window. I set rofi theme to make transparent lower left part, but shadow is set by compositor. Do you use compton? I think it has settings to disable shadows on certain windows.

That requires compositor. I use xcompmgr without shadows. Without compositor that lower left area can be set to the same background color. Or height of lines on the left side can be set to fill all rofi window.

I've added default config files.

@Chrysostomus
i use both [ to play with diff wms ]. i did come across THIS LINK and felt compton is better ? though i am not sure on how expensive they are in individual level on the resource. just felt i ll share here :slight_smile:

EDIT :slight_smile:
STARTING XCOMPMGR AFTER A DELAY also resolves the issue. just tried it...
LINK

# autostart apps
sleep 20s && xcompmgr -n &
.....

Forum kindly sponsored by