123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746 |
- #!/usr/bin/perl
- # Copyright (C) 2010-2023 Daniel "Trizen" Șuteu <echo dHJpemVuQHByb3Rvbm1haWwuY29tCg== | base64 -d>.
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
- # Openbox Menu Generator
- # A fast menu generator for the Openbox Window Manager, with support for icons.
- # Edited on 07 December 2014 by Bob Currey
- # added cmd line option -t "Menu Label Text" with default of "Applications"
- # Name: obmenu-generator
- # License: GPLv3
- # Created: 25 March 2011
- # Edited: 01 September 2023
- # https://github.com/trizen/obmenu-generator
- use 5.014;
- #use strict;
- #use warnings;
- use Linux::DesktopFiles;
- my $pkgname = 'obmenu-generator';
- my $version = '0.93';
- our ($CONFIG, $SCHEMA);
- my $output_h = \*STDOUT;
- my ($pipe, $static, $with_icons, $reload_config, $db_clean, $update_config, $reconf_openbox);
- my $home_dir =
- $ENV{HOME}
- || $ENV{LOGDIR}
- || (getpwuid($<))[7]
- || `echo -n ~`;
- my $xdg_config_home = $ENV{XDG_CONFIG_HOME} || "$home_dir/.config";
- my $xdg_cache_home = $ENV{XDG_CACHE_HOME} || "$home_dir/.cache";
- my $menu_id = "root-menu";
- my $menu_label_text = "Applications";
- my $config_dir = "$xdg_config_home/$pkgname";
- my $cache_dir = "$xdg_cache_home/$pkgname";
- my $schema_file = "$config_dir/schema.pl";
- my $config_file = "$config_dir/config.pl";
- my $openbox_conf = "$xdg_config_home/openbox";
- my $menufile = "$openbox_conf/menu.xml";
- my $cache_db = "$cache_dir/cache.db";
- my $icons_dir = "$cache_dir/icons";
- sub usage {
- print <<"HELP";
- usage: $0 [options]
- menu:
- -p : generate a dynamic menu (pipe)
- -s : generate a static menu
- -i : include icons
- -m <id> : menu id (default: 'root-menu')
- -t <label> : menu label text (default: 'Applications')
- misc:
- -u : update the config file
- -d : regenerate the cache file
- -c : reconfigure openbox automatically
- -R : reconfigure openbox and exit
- -S <file> : absolute path to the schema.pl file
- -C <file> : absolute path to the config.pl file
- -o <file> : absolute path to the menu.xml file
- info:
- -h : print this message and exit
- -v : print version and exit
- examples:
- $0 -p -i # dynamic menu with icons
- $0 -s -c # static menu without icons
- => Config file: $config_file
- => Schema file: $schema_file
- HELP
- exit 0;
- }
- my $config_help = <<"HELP";
- || FILTERING
- | skip_filename_re : Skip a .desktop file if its name matches the regex.
- Name is from the last slash to the end. (e.g.: name.desktop)
- Example: qr/^(?:gimp|xterm)\\b/, # skips 'gimp' and 'xterm'
- | skip_entry : Skip a desktop file if the value from a given key matches the regex.
- Example: [
- {key => 'Name', re => qr/(?:about|terminal)/i},
- {key => 'Exec', re => qr/^xterm/},
- {key => 'OnlyShowIn', re => qr/XFCE/},
- ],
- | substitutions : Substitute, by using a regex, in the values from the desktop files.
- Example: [
- {key => 'Exec', re => qr/xterm/, value => 'tilix', global => 1},
- ],
- || ICON SETTINGS
- | gtk_version : The version of the Gtk library used for resolving the icon paths. (default: 3)
- | gtk_rc_filename : Absolute path to the Gtk configuration file.
- | missing_icon : Use this icon for missing icons (default: gtk-missing-image)
- | icon_size : Preferred size for icons. (default: 48)
- | generic_fallback : Try to shorten icon name at '-' characters before looking at inherited themes. (default: 0)
- | force_icon_size : Always get the icon scaled to the requested size. (default: 0)
- || PATHS
- | desktop_files_paths : Absolute paths which contain .desktop files.
- Example: [
- '/usr/share/applications',
- "\$ENV{HOME}/.local/share/applications",
- glob("\$ENV{HOME}/.local/share/applications/wine/Programs/*"),
- ],
- || NOTES
- | Regular expressions:
- * use qr/.../ instead of '...'
- * use qr/.../i for case insensitive mode
- HELP
- sub remove_database {
- my ($db) = @_;
- foreach my $file ($db, "$db.dir", "$db.pag") {
- unlink($file) if (-e $file);
- }
- }
- if (@ARGV) {
- while (defined(my $arg = shift @ARGV)) {
- if ($arg eq '-i') {
- $with_icons = 1;
- }
- elsif ($arg eq '-p') {
- $pipe = 1;
- }
- elsif ($arg eq '-s') {
- $static = 1;
- }
- elsif ($arg eq '-d') {
- $db_clean = 1;
- remove_database($cache_db);
- }
- elsif ($arg eq '-u') {
- $update_config = 1;
- }
- elsif ($arg eq '-v') {
- print "$pkgname $version\n";
- exit 0;
- }
- elsif ($arg eq '-c') {
- $reconf_openbox = 1;
- }
- elsif ($arg eq '-R') {
- exec 'openbox', '--reconfigure';
- }
- elsif ($arg eq '-S') {
- $schema_file = shift(@ARGV) // die "$0: option '-S' requires an argument!\n";
- }
- elsif ($arg eq '-C') {
- $reload_config = 1;
- $config_file = shift(@ARGV) // die "$0: options '-C' requires an argument!\n";
- }
- elsif ($arg eq '-o') {
- $menufile = shift(@ARGV) // die "$0: option '-o' requires an argument!\n";
- }
- elsif ($arg eq '-m') {
- $menu_id = shift(@ARGV) // die "$0: option '-m' requires an argument!\n";
- }
- elsif ($arg eq '-t') {
- $menu_label_text = shift(@ARGV) // die "$0: option '-t' requires an argument!\n";
- }
- elsif ($arg eq '-h') {
- usage();
- }
- else {
- die "$0: option `$arg' is invalid!\n";
- }
- }
- }
- if (not -d $config_dir) {
- require File::Path;
- File::Path::make_path($config_dir)
- or die "$0: can't create configuration directory `$config_dir': $!\n";
- }
- if (not -d $cache_dir) {
- require File::Path;
- File::Path::make_path($cache_dir)
- or die "$0: can't create cache directory `$cache_dir': $!\n";
- }
- if ($with_icons and not -d $icons_dir) {
- remove_database($cache_db);
- require File::Path;
- File::Path::make_path($icons_dir)
- or warn "$0: can't create icon path `$icons_dir': $!\n";
- }
- my $config_documentation = <<"EOD";
- #!/usr/bin/perl
- # $pkgname - configuration file
- # This file will be updated automatically.
- # Any additional comment and/or indentation will be lost.
- =for comment
- $config_help
- =cut
- EOD
- my %CONFIG = (
- 'Linux::DesktopFiles' => {
- keep_unknown_categories => 1,
- unknown_category_key => 'other',
- skip_entry => undef,
- substitutions => undef,
- skip_filename_re => undef,
- terminalize => 1,
- terminalization_format => q{%s -e '%s'},
- #<<<
- desktop_files_paths => [
- '/usr/share/applications',
- '/usr/local/share/applications',
- '/usr/share/applications/kde4',
- "$home_dir/.local/share/applications",
- ],
- #>>>
- },
- terminal => 'xterm',
- editor => 'geany',
- missing_icon => 'gtk-missing-image',
- gtk_rc_filename => "$home_dir/.config/gtk-3.0/settings.ini",
- icon_size => 48,
- force_icon_size => 0,
- generic_fallback => 0,
- locale_support => 1,
- gtk_version => 3,
- VERSION => $version,
- );
- sub dump_configuration {
- require Data::Dump;
- open my $config_fh, '>', $config_file
- or die "Can't open file '${config_file}' for write: $!";
- my $dumped_config = q{our $CONFIG = } . Data::Dump::dump(\%CONFIG) . "\n";
- $dumped_config =~ s/\Q$home_dir\E/\$ENV{HOME}/g if ($home_dir eq $ENV{HOME});
- print $config_fh $config_documentation, $dumped_config;
- close $config_fh;
- }
- if (not -e $config_file) {
- dump_configuration();
- }
- if (not -e $schema_file) {
- if (-e (my $etc_schema_file = "/etc/xdg/$pkgname/schema.pl")) {
- require File::Copy;
- File::Copy::copy($etc_schema_file, $schema_file)
- or warn "$0: can't copy file `$etc_schema_file' to `$schema_file': $!\n";
- }
- else {
- die "$0: schema file `$schema_file' does not exists!\n";
- }
- }
- # Load the configuration files
- require $schema_file;
- require $config_file if $reload_config;
- # Remove invalid user-defined keys
- my @valid_keys = grep { exists $CONFIG{$_} } keys %$CONFIG;
- @CONFIG{@valid_keys} = @{$CONFIG}{@valid_keys};
- if ($CONFIG{VERSION} != $version) {
- $CONFIG{VERSION} = $version;
- dump_configuration();
- }
- #<<<
- my @desktop_files_paths = do {
- my %seen;
- grep { !$seen{$_}++ } (
- ($ENV{XDG_DATA_DIRS} ? split(/:/, $ENV{XDG_DATA_DIRS}) : ()),
- @{$CONFIG{'Linux::DesktopFiles'}{desktop_files_paths}},
- );
- };
- #>>>
- my $desk_obj = Linux::DesktopFiles->new(
- %{$CONFIG{'Linux::DesktopFiles'}},
- desktop_files_paths => \@desktop_files_paths,
- categories => [map { exists($_->{cat}) ? $_->{cat}[0] : () } @$SCHEMA],
- keys_to_keep => ['Name', 'Exec', 'Path',
- ($with_icons ? 'Icon' : ()),
- (
- ref($CONFIG{'Linux::DesktopFiles'}{skip_entry}) eq 'ARRAY'
- ? (map { $_->{key} } @{$CONFIG{'Linux::DesktopFiles'}{skip_entry}})
- : ()
- ),
- ],
- terminal => $CONFIG{terminal},
- case_insensitive_cats => 1,
- );
- if ($pipe or $static) {
- my $menu_backup = $menufile . '.bak';
- if (not -e $menu_backup and -e $menufile) {
- require File::Copy;
- File::Copy::copy($menufile, $menu_backup);
- }
- if ($static) {
- open $output_h, '>', $menufile
- or die "Can't open file '${menufile}' for write: $!";
- }
- elsif ($pipe) {
- if (not -d $openbox_conf) {
- require File::Path;
- File::Path::make_path($openbox_conf)
- or die "Can't create directory '${openbox_conf}': $!";
- }
- require Cwd;
- my $exec_name = Cwd::abs_path($0);
- if (not -x $exec_name) {
- $exec_name = "$^X $exec_name";
- }
- $with_icons && ($exec_name .= q{ -i});
- open my $fh, '>', $menufile
- or die "Can't open file '${menufile}' for write: $!";
- print $fh <<"PIPE_MENU_HEADER";
- <?xml version="1.0" encoding="utf-8"?>
- <openbox_menu xmlns="https://openbox.org/"
- xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="https://openbox.org/">
- <menu id="$menu_id" label="$pkgname" execute="$exec_name" />
- </openbox_menu>
- PIPE_MENU_HEADER
- close $fh;
- print STDERR <<'EOT';
- :: A dynamic menu has been successfully generated!
- EOT
- exec 'openbox', '--reconfigure';
- }
- }
- my $generated_menu = $static
- ? <<"STATIC_MENU_HEADER"
- <?xml version="1.0" encoding="utf-8"?>
- <openbox_menu xmlns="https://openbox.org/"
- xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="https://openbox.org/">
- <menu id="$menu_id" label="$menu_label_text">
- STATIC_MENU_HEADER
- : "<openbox_pipe_menu>\n";
- sub get_icon_path {
- my ($name) = @_;
- state $gtk = do {
- require Digest::MD5;
- ($CONFIG{gtk_version} == 3)
- ? do {
- eval "use Gtk3";
- 'Gtk3'->init;
- 'Gtk3';
- }
- : do {
- require Gtk2;
- 'Gtk2'->init;
- 'Gtk2';
- };
- };
- state $theme =
- ($gtk eq 'Gtk2')
- ? Gtk2::IconTheme->get_default
- : Gtk3::IconTheme::get_default();
- #<<<
- state $flags = "${gtk}::IconLookupFlags"->new(
- [
- ($CONFIG{force_icon_size} ? 'force-size' : ()),
- ($CONFIG{generic_fallback} ? 'generic-fallback' : ()),
- ]
- );
- #>>>
- foreach my $icon_name ($name, $CONFIG{missing_icon}) {
- #<<<
- my $pixbuf = eval {
- (substr($icon_name, 0, 1) eq '/')
- ? (substr($icon_name, -4) eq '.xpm')
- ? "${gtk}::Gdk::Pixbuf"->new_from_file($icon_name)->scale_simple($CONFIG{icon_size}, $CONFIG{icon_size}, 'hyper')
- : "${gtk}::Gdk::Pixbuf"->new_from_file_at_size($icon_name, $CONFIG{icon_size}, $CONFIG{icon_size})
- : $theme->load_icon($icon_name, $CONFIG{icon_size}, $flags);
- };
- #>>>
- if (defined($pixbuf)) {
- my $md5 = Digest::MD5::md5_hex($pixbuf->get_pixels);
- my $path = "$icons_dir/$md5.png";
- $pixbuf->save($path, 'png') if not -e $path;
- return $path;
- }
- }
- return '';
- }
- # Regenerate the cache db if the config or schema file has been modified
- if (!$db_clean and ((-M $config_file) < (-M $cache_db) or (-M _) > (-M $schema_file))) {
- print STDERR ":: Regenerating the cache DB...\n";
- remove_database($cache_db);
- $db_clean = 1;
- }
- eval { require GDBM_File } // eval { require DB_File };
- dbmopen(my %cache_db, $cache_db, 0777)
- or die "Can't create/access database <<$cache_db>>: $!";
- # Regenerate the icon db if the GTKRC file has been modified
- if ($with_icons) {
- my $gtkrc_mtime = (stat $CONFIG{gtk_rc_filename})[9];
- if ($db_clean) {
- $cache_db{__GTKRC_MTIME__} = $gtkrc_mtime;
- }
- else {
- my $old_mtime = exists($cache_db{__GTKRC_MTIME__}) ? $cache_db{__GTKRC_MTIME__} : -1;
- if ($old_mtime != $gtkrc_mtime) {
- print STDERR ":: Regenerating the cache DB...\n";
- dbmclose(%cache_db);
- remove_database($cache_db);
- dbmopen(%cache_db, $cache_db, 0777)
- or die "Can't create database <<$cache_db>>: $!";
- $cache_db{__GTKRC_MTIME__} = $gtkrc_mtime;
- }
- }
- }
- {
- my %fast_cache;
- sub check_icon {
- $fast_cache{$_[0] // return undef} //= do {
- exists($cache_db{$_[0]})
- ? $cache_db{$_[0]}
- : do { $cache_db{$_[0]} = get_icon_path($_[0]) }
- };
- }
- }
- sub begin_category {
- if ($with_icons and (my $icon_path = check_icon($_[1]))) {
- <<"MENU_WITH_ICON";
- <menu id="${\rand()}" icon="$icon_path" label="$_[0]">
- MENU_WITH_ICON
- }
- else {
- <<"MENU";
- <menu id="${\rand()}" label="$_[0]">
- MENU
- }
- }
- my %categories;
- foreach my $file ($desk_obj->get_desktop_files) {
- my %info = split("\0\1\0", (exists($cache_db{$file}) ? $cache_db{$file} : ''), -1);
- next if exists $info{__IGNORE__};
- my $mtime = (stat $file)[9];
- my $cache_ok = (%info and $info{__MTIME__} == $mtime);
- if ($with_icons and $cache_ok and not exists $info{Icon}) {
- $cache_ok = 0;
- }
- if (not $cache_ok) {
- my $entry = $desk_obj->parse_desktop_file($file) // do {
- $cache_db{$file} = join("\0\1\0", __IGNORE__ => 1);
- next;
- };
- #<<<
- %info = (
- Name => $entry->{Name} // next,
- Exec => $entry->{Exec} // next,
- Path => $entry->{Path} // '',
- (
- $with_icons
- ? (Icon => check_icon($entry->{Icon}) // '')
- : ()
- ),
- __CATEGORIES__ => join(';', @{$entry->{Categories}}),
- __MTIME__ => $mtime,
- );
- #>>>
- # Support for the Path key
- if ($info{Path} ne '') {
- require Encode;
- my $path = Encode::decode_utf8($info{Path});
- my $exec = Encode::decode_utf8($info{Exec});
- $exec = "$^X -e 'chdir(\$ARGV[0]) && exec(\$ARGV[1])' \Q$path\E \Q$exec\E";
- $info{Exec} = Encode::encode_utf8($exec);
- }
- eval {
- state $x = do {
- require Encode;
- require File::DesktopEntry;
- };
- $info{Name} = Encode::encode_utf8(File::DesktopEntry->new($file)->get('Name') // '');
- } if $CONFIG{locale_support};
- state $entities = {
- '&' => '&',
- '"' => '"',
- '_' => '__',
- '<' => '<',
- '>' => '>',
- };
- # Encode XML entities (if any)
- $info{Name} =~ tr/"&_<>//
- && $info{Name} =~ s/([&"_<>])/$entities->{$1}/g;
- $cache_db{$file} = join("\0\1\0", %info);
- }
- foreach my $category (split(/;/, $info{__CATEGORIES__})) {
- push @{$categories{$category}}, \%info;
- }
- }
- foreach my $schema (@$SCHEMA) {
- if (exists $schema->{cat}) {
- exists($categories{my $category = lc($schema->{cat}[0]) =~ tr/_a-z0-9/_/cr}) || next;
- $generated_menu .= begin_category($schema->{cat}[1], ($with_icons ? $schema->{cat}[2] : ())) . join(
- q{},
- map { $_->[1] }
- sort { $a->[0] cmp $b->[0] }
- map { [lc($_), $_] }
- map {
- ($with_icons and $_->{Icon})
- ? <<"ITEM_WITH_ICON"
- <item label="$_->{Name}" icon="$_->{Icon}"><action name="Execute"><command><![CDATA[$_->{Exec}]]></command></action></item>
- ITEM_WITH_ICON
- : <<"ITEM";
- <item label="$_->{Name}"><action name="Execute"><command><![CDATA[$_->{Exec}]]></command></action></item>
- ITEM
- } @{$categories{$category}}
- )
- . qq[ </menu>\n];
- }
- elsif (exists $schema->{item}) {
- my ($command, $label, $icon) = @{$schema->{item}};
- if ($with_icons and (my $icon_path = check_icon($icon))) {
- $generated_menu .= <<"ITEM_WITH_ICON";
- <item label="$label" icon="$icon_path"><action name="Execute"><command><![CDATA[$command]]></command></action></item>
- ITEM_WITH_ICON
- }
- else {
- $generated_menu .= <<"ITEM";
- <item label="$label"><action name="Execute"><command><![CDATA[$command]]></command></action></item>
- ITEM
- }
- }
- elsif (exists $schema->{sep}) {
- $generated_menu .=
- defined($schema->{sep})
- ? qq[ <separator label="$schema->{sep}"/>\n]
- : qq[ <separator/>\n];
- }
- elsif (exists $schema->{beg}) {
- $generated_menu .= begin_category(@{$schema->{beg}});
- }
- elsif (exists $schema->{begin_cat}) {
- $generated_menu .= begin_category(@{$schema->{begin_cat}});
- }
- elsif (exists $schema->{end}) {
- $generated_menu .= qq[ </menu>\n];
- }
- elsif (exists $schema->{end_cat}) {
- $generated_menu .= qq[ </menu>\n];
- }
- elsif (exists $schema->{exit}) {
- my ($label, $icon) = @{$schema->{exit}};
- if ($with_icons and (my $icon_path = check_icon($icon))) {
- $generated_menu .= <<"EXIT_WITH_ICON";
- <item label="$label" icon="$icon_path"><action name="Exit"/></item>
- EXIT_WITH_ICON
- }
- else {
- $generated_menu .= <<"EXIT";
- <item label="$label"><action name="Exit"/></item>
- EXIT
- }
- }
- elsif (exists $schema->{raw}) {
- $generated_menu .= qq[ $schema->{raw}\n];
- }
- elsif (exists $schema->{file}) {
- sysopen(my $fh, $schema->{file}, 0) or die "Can't open file <<$schema->{file}>>: $!";
- sysread($fh, $generated_menu, -s $schema->{file}, length($generated_menu));
- }
- elsif (exists $schema->{pipe}) {
- my ($command, $label, $icon) = @{$schema->{pipe}};
- if ($with_icons and (my $icon_path = check_icon($icon))) {
- $generated_menu .= <<"PIPE_WITH_ICON";
- <menu id="${\rand()}" label="$label" execute="$command" icon="$icon_path"/>
- PIPE_WITH_ICON
- }
- else {
- $generated_menu .= <<"PIPE";
- <menu id="${\rand()}" label="$label" execute="$command"/>
- PIPE
- }
- }
- elsif (exists $schema->{obgenmenu}) {
- my ($name, $icon) = ref($schema->{obgenmenu}) eq 'ARRAY' ? @{$schema->{obgenmenu}} : $schema->{obgenmenu};
- if ($with_icons and (my $icon_path = check_icon($icon))) {
- $generated_menu .= <<"MENU_WITH_ICON";
- <menu id="${\rand()}" label="$name" icon="$icon_path">
- MENU_WITH_ICON
- }
- else {
- $generated_menu .= <<"MENU";
- <menu id="${\rand()}" label="$name">
- MENU
- }
- $generated_menu .= ($with_icons ? <<"ITEMS_WITH_ICONS" : <<"ITEMS");
- <item label="Menu Schema" icon="${\check_icon('text-x-generic')}"><action name="Execute"><command><![CDATA[$CONFIG{editor} $schema_file]]></command></action></item>
- <item label="Menu Config" icon="${\check_icon('text-x-generic')}"><action name="Execute"><command><![CDATA[$CONFIG{editor} $config_file]]></command></action></item>
- <separator/>
- <item label="Generate a static menu" icon="${\check_icon('accessories-text-editor')}"><action name="Execute"><command><![CDATA[obmenu-generator -s -c]]></command></action></item>
- <item label="Generate a static menu with icons" icon="${\check_icon('accessories-text-editor')}"><action name="Execute"><command><![CDATA[obmenu-generator -s -i -c]]></command></action></item>
- <separator/>
- <item label="Generate a dynamic menu" icon="${\check_icon('accessories-text-editor')}"><action name="Execute"><command><![CDATA[obmenu-generator -p]]></command></action></item>
- <item label="Generate a dynamic menu with icons" icon="${\check_icon('accessories-text-editor')}"><action name="Execute"><command><![CDATA[obmenu-generator -p -i]]></command></action></item>
- <separator/>
- <menu id="${\rand()}" label="Openbox" icon="${\check_icon('openbox')}">
- <item label="Openbox Autostart" icon="${\check_icon('text-x-generic')}"><action name="Execute"><command><![CDATA[$CONFIG{editor} $openbox_conf/autostart]]></command></action></item>
- <item label="Openbox RC" icon="${\check_icon('text-x-generic')}"><action name="Execute"><command><![CDATA[$CONFIG{editor} $openbox_conf/rc.xml]]></command></action></item>
- <item label="Openbox Menu" icon="${\check_icon('text-x-generic')}"><action name="Execute"><command><![CDATA[$CONFIG{editor} $openbox_conf/menu.xml]]></command></action></item>
- <item label="Reconfigure" icon="${\check_icon('openbox')}"><action name="Reconfigure"/></item>
- </menu>
- <separator/>
- <item label="Refresh Icon Set" icon="${\check_icon('view-refresh')}"><action name="Execute"><command><![CDATA[obmenu-generator -d]]></command></action></item>
- </menu>
- ITEMS_WITH_ICONS
- <item label="Menu Schema"><action name="Execute"><command><![CDATA[$CONFIG{editor} $schema_file]]></command></action></item>
- <item label="Menu Config"><action name="Execute"><command><![CDATA[$CONFIG{editor} $config_file]]></command></action></item>
- <separator/>
- <item label="Generate a static menu"><action name="Execute"><command><![CDATA[obmenu-generator -s -c]]></command></action></item>
- <item label="Generate a static menu with icons"><action name="Execute"><command><![CDATA[obmenu-generator -s -i -c]]></command></action></item>
- <separator/>
- <item label="Generate a dynamic menu"><action name="Execute"><command><![CDATA[obmenu-generator -p]]></command></action></item>
- <item label="Generate a dynamic menu with icons"><action name="Execute"><command><![CDATA[obmenu-generator -p -i]]></command></action></item>
- <separator/>
- <menu id="${\rand()}" label="Openbox">
- <item label="Openbox Autostart"><action name="Execute"><command><![CDATA[$CONFIG{editor} $openbox_conf/autostart]]></command></action></item>
- <item label="Openbox RC"><action name="Execute"><command><![CDATA[$CONFIG{editor} $openbox_conf/rc.xml]]></command></action></item>
- <item label="Openbox Menu"><action name="Execute"><command><![CDATA[$CONFIG{editor} $openbox_conf/menu.xml]]></command></action></item>
- <item label="Reconfigure Openbox"><action name="Reconfigure" /></item>
- </menu>
- <separator/>
- <item label="Refresh Icon Set"><action name="Execute"><command><![CDATA[obmenu-generator -d]]></command></action></item>
- </menu>
- ITEMS
- }
- else {
- warn "$0: invalid key '", (keys %{$schema})[0], "' in schema file!\n";
- }
- }
- print $output_h $generated_menu, $static
- ? qq[ </menu>\n</openbox_menu>\n]
- : qq[</openbox_pipe_menu>\n];
- dump_configuration() if $update_config;
- if ($static) {
- print STDERR <<'EOT';
- :: A static menu has been successfully generated!
- EOT
- if ($reconf_openbox) {
- exec 'openbox', '--reconfigure';
- }
- }
|