JGMENUTUTORIAL(7)

πŸ¦‹ jgmenututorial(7) β€” the tutorial, but it's a group chat

✨ NAME ✨

jgmenututorial β€” a step-by-step tutorial to jgmenu, taught by someone who is lowkey obsessed with window managers and wants you to be too πŸ’…


🌸 INTRODUCTION 🌸

okay so. this whole tutorial's entire job is to teach you how jgmenu works, but it does it in lessons, like a lil syllabus. no cap. each lesson builds on the last one, bestie, so don't skip around like a gremlin πŸ™ˆ


πŸŽ€ TABLE OF CONTENTS πŸŽ€

  • Lesson 1 - Get started
  • Lesson 2 - Architecture
  • Lesson 3 - Scripting with jgmenu
  • Lesson 4 - Descriptions
  • Lesson 5 - Icons
  • Lesson 6 - Submenus
  • Lesson 7 - XDG Application Menus
  • Lesson 8 - Config Options
  • Lesson 9 - Apprend/Prepend and Separators
  • Lesson 10 - CSV generators
  • Lesson 11 - Search

✨ Lesson 1 - Get started ✨

so after you install jgmenu (slay), you start the whole menu by running this command:

jgmenu_run

and you should get a Linux/BSD system menu showing all your installed applications 🫢 (peep Lesson 7 if you wanna know more about that).

next, make yourself a config file (~/.config/jgmenu/jgmenurc) by running:

jgmenu_run init

the full tea on all the config options lives in jgmenu(1) (jgmenu.1.html) β€” go read it when you're ready πŸ‘‘

also!! if you hop into interactive mode and then select t, you can try out some pre-defined templates/themes:

jgmenu_run init -i

now, there are a small number of config options that might need you to manually step in so that jgmenu actually displays correctly on your system. not many, just these:

position_mode

there are several methods for positioning the menu. try fixed, ipc, center and pointer to see which one works best on your system. full details in jgmenu(1). ✨

if you're using position_mode=fixed, you might need to set these two variables. depending on what window manager and panel you use, jgmenu may be able to automatically find a suitable vertical and horizontal position β€” so try it without setting these variables first, bestie. trust the process πŸ’–

again, depending on your system, you may need to manually specify horizontal and vertical alignment of the menu β€” but same deal, try without first. let it cook πŸ”₯


🌈 Lesson 2 - Architecture 🌈

the design of jgmenu is very modular, which gives you a lot of flexibility in how you use it. it's giving lego but for menus.

when jgmenu is started, two processes are run to produce the menu:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ csv-generator  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        |
        V
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ graphical menu β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

the first process (csv-generator) produces the menu content, whereas the second generates the graphical menu. two icons, two jobs, no overlap πŸ’…

jgmenu_run(1) (jgmenu_run.1.html) is a multi-purpose wrapper script, and what it does is basically this in pseudo code:

if (jgmenu is already running)
        show menu
else
        start a new instance of jgmenu

and that's exactly why it's so good for using with panels and keyboard shortcuts. main character behavior, honestly πŸ‘‘


πŸ’œ Lesson 3 - Scripting with jgmenu πŸ’œ

from this point onwards, we're assuming you understand basic shell usage, including re-direction (like <, >) and piping (like |). if you don't, that's okay, go learn it, come back, i'll wait 🫢

the syntax below (a here-document) is used to denote the creation of a text file from whatever sits between the EOFs. you can of course use your favourite text editor instead β€” no one's stopping you.

cat >file <<EOF
foo
bar
EOF

there are many ways to run jgmenu. in Lesson 1, you saw jgmenu as a long-running application. as we go through the next few lessons we're gonna run jgmenu as a short-lived application instead. that means it starts from scratch every single time it's called. fresh start, no baggage ✨

so let's get back to basics. try this:

echo >foo.txt <<EOF
xterm
firefox
EOF

if you haven't got used to the here-document syntax yet, it just means you put the words xterm and firefox into a text file (which, yes, you could totally have done with a text editor). then run either of these:

cat foo.txt | jgmenu --simple --icon-size=0

jgmenu --vsimple --csv-file="foo.txt"

the option --simple makes jgmenu short-lived and reads menu items from stdin.

the option --icon-size=0 disables icons (and ngl, it doesn't just display them at zero size β€” it simply does not load them at all. iconic).

the command line argument --vsimple is the same as --simple, but it also disables icons and ignores jgmenurc (if it exists). it's the no-thoughts-just-vibes option.

and if you want a menu to be launched by a single script, you could construct it like this:

cat <<EOF >menu.sh
#!/bin/sh
(
printf "foo\n"
printf "bar\n"
) | jgmenu --vsimple
EOF
chmod +x menu.sh
./menu.sh

πŸ¦‹ Lesson 4 - Descriptions πŸ¦‹

so, as you saw in the previous example, each line fed to stdin becomes a menu item. and any line containing two fields separated by a comma gets parsed as description,command. look:

Terminal,xterm
File Manager,pcmanfm

this lets you give a more meaningful description to each menu item. so instead of just screaming xterm at your users, you can say Terminal and look all put-together πŸ’…


πŸ“ Lesson 5 - Icons πŸ“

to display icons, you need to populate the third field. by default, jgmenu will obtain the icon theme from xsettings (if it is running) or tint2rc (if it exists). and when running with the --simple argument, make sure that icon_theme is set to something sensible in your $HOME/.config/jgmenu/jgmenurc. consider the following CSV menu data:

Browser,        firefox,               firefox
File manager,   pcmanfm,               system-file-manager
Terminal,       xterm,                 utilities-terminal
Lock,           i3lock -c 000000,      system-lock-screen
Exit to prompt, openbox --exit,        system-log-out
Reboot,         systemctl -i reboot,   system-reboot
Poweroff,       systemctl -i poweroff, system-shutdown

and in that third field you can also specify the full path if you wish. go wild 🌈


🌸 Lesson 6 - Submenus 🌸

so far we've only looked at producing a single "root" menu. but jgmenu understands a small amount of markup, and it enables submenus by ^tag() and ^checkout(). try this:

Terminal,xterm
File Manager,pcmanfm
Settings,^checkout(settings)

^tag(settings)
Set Background Image,nitrogen

in pseudo-code, you build your CSV file like this:

# the root-menu
item0.0
item0.1
sub1,^checkout(1)
sub2,^checkout(2)

# the first sub-menu
^tag(1)
item1.0
item1.1

# the second sub-menu
^tag(2)
item2.0
item2.1

and psst β€” ^root() can be used instead of ^checkout() in order to open the submenu in the parent window. little detail, big difference πŸ’…


⭐ Lesson 7 - XDG Application Menus ⭐

XDG (freedesktop.org) have defined a Linux/BSD Desktop Menu Specification which is followed by the big Desktop Environments. see menu-spec (http://specifications.freedesktop.org/menu-spec/latest/) for further details. in brief, there are three types of files which define an XDG menu:

XML file describing menu categories and directory structure. located in /etc/xdg/menus/, or XDG_CONFIG_{HOME,DIRS} equivalent.

.directory

describe menu directories. located in /usr/share/desktop-directories/, or XDG_DATA_{HOME,DIRS} equivalent.

.desktop

describe applications and contain most of the information needed to build a menu (e.g. Name, Exec command, Icon and Category). located in /usr/share/applications/, or XDG_DATA_{HOME,DIRS} equivalent.

most desktop applications provide their own associated .desktop files, whereas .menu and .directory files are supplied by menu packages, such as libmenu-cache (LXDE) and libcargon (XFCE).

the jgmenu core module jgmenu-apps(1) (jgmenu-apps.1.html) provides a system menu based on .desktop files and built-in schema data or a specified schema file, rather than system .menu and .directory files. and whilst this deviates from the XDG menu spec, it is much simpler to understand and tweak. it also avoids reliance on menu packages. honestly? worth it 🫢

for strict XDG compliance, the optional module jgmenu-lx(1) (jgmenu-lx.1.html) can be used.

see Lesson 10 for generic instructions on modules.


πŸŽ€ Lesson 8 - Config Options πŸŽ€

in Lesson 1 we discussed the config options position_mode, menu_margin_x, menu_margin_y, menu_halign and menu_valign.

here are a few more options you may wish to explore. for full details, see jgmenu(1) (jgmenu.1.html). ✨

Rofi style:

csv_no_dirs=1
csv_single_window=1
columns=2
menu_width=600
menu_valign=center
menu_halign=center

Synchronize colours, font and icons with tint2 panel:

tint2_look=1

πŸ’– Lesson 9 - Apprend/Prepend and Separators πŸ’–

when using apps, pmenu or lx, you can add menu items to the top and bottom of the root menu by editing append.csv and/or prepend.csv in ~/.config/jgmenu. for example, try the following:

prepend.csv

Browser,      firefox,               firefox
File manager, pcmanfm,               system-file-manager
Terminal,     xterm,                 utilities-terminal
^sep()

append.csv

^sep()
Suspend,      systemctl -i suspend,  system-log-out
Reboot,       systemctl -i reboot,   system-reboot
Poweroff,     systemctl -i poweroff, system-shutdown

in these examples we've used the markup ^sep(), which inserts a horizontal separator line. similarly, ^sep(foo) inserts a text separator displaying foo. cute lil dividers, we love to see it πŸŽ€


πŸ”₯ Lesson 10 - CSV generators πŸ”₯

in previous lessons, we introduced the apps, lx and pmenu modules. these modules are referred to as "CSV generators" and they're invoked like this:

jgmenu_run <command>

built-in "CSV generators" include: apps and ob

optional "CSV generators" include: lx and pmenu

they're documented by a man page or a simple --help message.

man jgmenu-<command>
jgmenu_run <command> --help

here follow some examples of how they can be used.

Specify CSV generator in the config file by setting csv_cmd in ~/.config/jgmenu/jgmenurc:

csv_cmd = pmenu

Specify CSV generator on the command line:

jgmenu --csv-cmd="jgmenu_run pmenu"

Pipe the CSV output to jgmenu (using --simple to read from stdin):

jgmenu_run pmenu | jgmenu --simple

Create a pipemenu using ^pipe() markup. consider this example:

Terminal,xterm
File Manager,pcmanfm
^pipe(jgmenu_run pmenu)

okay bestie this one is so good. jgmenu has search support ✨ and the way you use it is genuinely the easiest thing ever: you just type. That's it. Type while the menu is open and boom, you're searching. no keybind, no incantation, just keystrokes and vibes πŸ’…


πŸŽ€ Dropping a search box in

You can also insert a search box using widgets. For example, add this to ~/.config/jgmenu/prepend.csv:

@search,,3,3,150,20,2,left,top,auto,#000000 0,Type to Search
fr fr though, make sure you adjust your menu padding accordingly, otherwise your cute little search box is gonna be overlapping things like an uninvited guest at the function 😭 For example:
menu_padding_top=24

A search can also be invoked by associating a widget with a ^filter() command. Obsessed with the flexibility ngl 🫢


πŸ‘‘ AUTHORS πŸ‘‘

  • Johan Malm. β€” periodt. the name on the page, the icon behind the whole thing πŸ’–

and that's a wrap on the whole tutorial, bestie!! πŸŽ‰ this page is JGMENUTUTORIAL(7), dated 21 February, 2020 β€” go forth and slay your menus, ily, mwah πŸ’‹πŸ¦‹πŸŒΈ