pax_global_header00006660000000000000000000000064147261313630014520gustar00rootroot0000000000000052 comment=13ea04faa008634fcdd8b63f952d07547df10e8c jgmenu-4.5.0/000077500000000000000000000000001472613136300130135ustar00rootroot00000000000000jgmenu-4.5.0/.clang-format000066400000000000000000000351371472613136300153770ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0 # # clang-format configuration file. Intended for clang-format >= 4. # # For more information, see: # # Documentation/process/clang-format.rst # https://clang.llvm.org/docs/ClangFormat.html # https://clang.llvm.org/docs/ClangFormatStyleOptions.html # --- AccessModifierOffset: -4 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false #AlignEscapedNewlines: Left # Unknown to clang-format-4.0 AlignOperands: true AlignTrailingComments: false AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: false BinPackArguments: true BinPackParameters: true BraceWrapping: AfterClass: false AfterControlStatement: false AfterEnum: false AfterFunction: true AfterNamespace: true AfterObjCDeclaration: false AfterStruct: false AfterUnion: false #AfterExternBlock: false # Unknown to clang-format-5.0 BeforeCatch: false BeforeElse: false IndentBraces: false #SplitEmptyFunction: true # Unknown to clang-format-4.0 #SplitEmptyRecord: true # Unknown to clang-format-4.0 #SplitEmptyNamespace: true # Unknown to clang-format-4.0 BreakBeforeBinaryOperators: None BreakBeforeBraces: Custom #BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0 BreakBeforeTernaryOperators: false BreakConstructorInitializersBeforeComma: false #BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0 BreakAfterJavaFieldAnnotations: false BreakStringLiterals: false ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' #CompactNamespaces: false # Unknown to clang-format-4.0 ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerIndentWidth: 8 ContinuationIndentWidth: 8 Cpp11BracedListStyle: false DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false #FixNamespaceComments: false # Unknown to clang-format-4.0 # Taken from: # git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ \ # | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \ # | sort | uniq ForEachMacros: - 'apei_estatus_for_each_section' - 'ata_for_each_dev' - 'ata_for_each_link' - '__ata_qc_for_each' - 'ata_qc_for_each' - 'ata_qc_for_each_raw' - 'ata_qc_for_each_with_internal' - 'ax25_for_each' - 'ax25_uid_for_each' - '__bio_for_each_bvec' - 'bio_for_each_bvec' - 'bio_for_each_integrity_vec' - '__bio_for_each_segment' - 'bio_for_each_segment' - 'bio_for_each_segment_all' - 'bio_list_for_each' - 'bip_for_each_vec' - 'blkg_for_each_descendant_post' - 'blkg_for_each_descendant_pre' - 'blk_queue_for_each_rl' - 'bond_for_each_slave' - 'bond_for_each_slave_rcu' - 'bpf_for_each_spilled_reg' - 'btree_for_each_safe128' - 'btree_for_each_safe32' - 'btree_for_each_safe64' - 'btree_for_each_safel' - 'card_for_each_dev' - 'cgroup_taskset_for_each' - 'cgroup_taskset_for_each_leader' - 'cpufreq_for_each_entry' - 'cpufreq_for_each_entry_idx' - 'cpufreq_for_each_valid_entry' - 'cpufreq_for_each_valid_entry_idx' - 'css_for_each_child' - 'css_for_each_descendant_post' - 'css_for_each_descendant_pre' - 'device_for_each_child_node' - 'drm_atomic_crtc_for_each_plane' - 'drm_atomic_crtc_state_for_each_plane' - 'drm_atomic_crtc_state_for_each_plane_state' - 'drm_atomic_for_each_plane_damage' - 'drm_connector_for_each_possible_encoder' - 'drm_for_each_connector_iter' - 'drm_for_each_crtc' - 'drm_for_each_encoder' - 'drm_for_each_encoder_mask' - 'drm_for_each_fb' - 'drm_for_each_legacy_plane' - 'drm_for_each_plane' - 'drm_for_each_plane_mask' - 'drm_for_each_privobj' - 'drm_mm_for_each_hole' - 'drm_mm_for_each_node' - 'drm_mm_for_each_node_in_range' - 'drm_mm_for_each_node_safe' - 'flow_action_for_each' - 'for_each_active_drhd_unit' - 'for_each_active_iommu' - 'for_each_available_child_of_node' - 'for_each_bio' - 'for_each_board_func_rsrc' - 'for_each_bvec' - 'for_each_card_components' - 'for_each_card_links' - 'for_each_card_links_safe' - 'for_each_card_prelinks' - 'for_each_card_rtds' - 'for_each_card_rtds_safe' - 'for_each_cgroup_storage_type' - 'for_each_child_of_node' - 'for_each_clear_bit' - 'for_each_clear_bit_from' - 'for_each_cmsghdr' - 'for_each_compatible_node' - 'for_each_component_dais' - 'for_each_component_dais_safe' - 'for_each_comp_order' - 'for_each_console' - 'for_each_cpu' - 'for_each_cpu_and' - 'for_each_cpu_not' - 'for_each_cpu_wrap' - 'for_each_dev_addr' - 'for_each_dma_cap_mask' - 'for_each_dpcm_be' - 'for_each_dpcm_be_rollback' - 'for_each_dpcm_be_safe' - 'for_each_dpcm_fe' - 'for_each_drhd_unit' - 'for_each_dss_dev' - 'for_each_efi_memory_desc' - 'for_each_efi_memory_desc_in_map' - 'for_each_element' - 'for_each_element_extid' - 'for_each_element_id' - 'for_each_endpoint_of_node' - 'for_each_evictable_lru' - 'for_each_fib6_node_rt_rcu' - 'for_each_fib6_walker_rt' - 'for_each_free_mem_range' - 'for_each_free_mem_range_reverse' - 'for_each_func_rsrc' - 'for_each_hstate' - 'for_each_if' - 'for_each_iommu' - 'for_each_ip_tunnel_rcu' - 'for_each_irq_nr' - 'for_each_link_codecs' - 'for_each_lru' - 'for_each_matching_node' - 'for_each_matching_node_and_match' - 'for_each_memblock' - 'for_each_memblock_type' - 'for_each_memcg_cache_index' - 'for_each_mem_pfn_range' - 'for_each_mem_range' - 'for_each_mem_range_rev' - 'for_each_migratetype_order' - 'for_each_msi_entry' - 'for_each_msi_entry_safe' - 'for_each_net' - 'for_each_netdev' - 'for_each_netdev_continue' - 'for_each_netdev_continue_rcu' - 'for_each_netdev_feature' - 'for_each_netdev_in_bond_rcu' - 'for_each_netdev_rcu' - 'for_each_netdev_reverse' - 'for_each_netdev_safe' - 'for_each_net_rcu' - 'for_each_new_connector_in_state' - 'for_each_new_crtc_in_state' - 'for_each_new_mst_mgr_in_state' - 'for_each_new_plane_in_state' - 'for_each_new_private_obj_in_state' - 'for_each_node' - 'for_each_node_by_name' - 'for_each_node_by_type' - 'for_each_node_mask' - 'for_each_node_state' - 'for_each_node_with_cpus' - 'for_each_node_with_property' - 'for_each_of_allnodes' - 'for_each_of_allnodes_from' - 'for_each_of_cpu_node' - 'for_each_of_pci_range' - 'for_each_old_connector_in_state' - 'for_each_old_crtc_in_state' - 'for_each_old_mst_mgr_in_state' - 'for_each_oldnew_connector_in_state' - 'for_each_oldnew_crtc_in_state' - 'for_each_oldnew_mst_mgr_in_state' - 'for_each_oldnew_plane_in_state' - 'for_each_oldnew_plane_in_state_reverse' - 'for_each_oldnew_private_obj_in_state' - 'for_each_old_plane_in_state' - 'for_each_old_private_obj_in_state' - 'for_each_online_cpu' - 'for_each_online_node' - 'for_each_online_pgdat' - 'for_each_pci_bridge' - 'for_each_pci_dev' - 'for_each_pci_msi_entry' - 'for_each_populated_zone' - 'for_each_possible_cpu' - 'for_each_present_cpu' - 'for_each_prime_number' - 'for_each_prime_number_from' - 'for_each_process' - 'for_each_process_thread' - 'for_each_property_of_node' - 'for_each_registered_fb' - 'for_each_reserved_mem_region' - 'for_each_rtd_codec_dai' - 'for_each_rtd_codec_dai_rollback' - 'for_each_rtdcom' - 'for_each_rtdcom_safe' - 'for_each_set_bit' - 'for_each_set_bit_from' - 'for_each_sg' - 'for_each_sg_dma_page' - 'for_each_sg_page' - 'for_each_sibling_event' - 'for_each_subelement' - 'for_each_subelement_extid' - 'for_each_subelement_id' - '__for_each_thread' - 'for_each_thread' - 'for_each_zone' - 'for_each_zone_zonelist' - 'for_each_zone_zonelist_nodemask' - 'fwnode_for_each_available_child_node' - 'fwnode_for_each_child_node' - 'fwnode_graph_for_each_endpoint' - 'gadget_for_each_ep' - 'genradix_for_each' - 'genradix_for_each_from' - 'hash_for_each' - 'hash_for_each_possible' - 'hash_for_each_possible_rcu' - 'hash_for_each_possible_rcu_notrace' - 'hash_for_each_possible_safe' - 'hash_for_each_rcu' - 'hash_for_each_safe' - 'hctx_for_each_ctx' - 'hlist_bl_for_each_entry' - 'hlist_bl_for_each_entry_rcu' - 'hlist_bl_for_each_entry_safe' - 'hlist_for_each' - 'hlist_for_each_entry' - 'hlist_for_each_entry_continue' - 'hlist_for_each_entry_continue_rcu' - 'hlist_for_each_entry_continue_rcu_bh' - 'hlist_for_each_entry_from' - 'hlist_for_each_entry_from_rcu' - 'hlist_for_each_entry_rcu' - 'hlist_for_each_entry_rcu_bh' - 'hlist_for_each_entry_rcu_notrace' - 'hlist_for_each_entry_safe' - '__hlist_for_each_rcu' - 'hlist_for_each_safe' - 'hlist_nulls_for_each_entry' - 'hlist_nulls_for_each_entry_from' - 'hlist_nulls_for_each_entry_rcu' - 'hlist_nulls_for_each_entry_safe' - 'i3c_bus_for_each_i2cdev' - 'i3c_bus_for_each_i3cdev' - 'ide_host_for_each_port' - 'ide_port_for_each_dev' - 'ide_port_for_each_present_dev' - 'idr_for_each_entry' - 'idr_for_each_entry_continue' - 'idr_for_each_entry_ul' - 'inet_bind_bucket_for_each' - 'inet_lhash2_for_each_icsk_rcu' - 'key_for_each' - 'key_for_each_safe' - 'klp_for_each_func' - 'klp_for_each_func_safe' - 'klp_for_each_func_static' - 'klp_for_each_object' - 'klp_for_each_object_safe' - 'klp_for_each_object_static' - 'kvm_for_each_memslot' - 'kvm_for_each_vcpu' - 'list_for_each' - 'list_for_each_codec' - 'list_for_each_codec_safe' - 'list_for_each_entry' - 'list_for_each_entry_continue' - 'list_for_each_entry_continue_rcu' - 'list_for_each_entry_continue_reverse' - 'list_for_each_entry_from' - 'list_for_each_entry_from_rcu' - 'list_for_each_entry_from_reverse' - 'list_for_each_entry_lockless' - 'list_for_each_entry_rcu' - 'list_for_each_entry_reverse' - 'list_for_each_entry_safe' - 'list_for_each_entry_safe_continue' - 'list_for_each_entry_safe_from' - 'list_for_each_entry_safe_reverse' - 'list_for_each_prev' - 'list_for_each_prev_safe' - 'list_for_each_safe' - 'llist_for_each' - 'llist_for_each_entry' - 'llist_for_each_entry_safe' - 'llist_for_each_safe' - 'media_device_for_each_entity' - 'media_device_for_each_intf' - 'media_device_for_each_link' - 'media_device_for_each_pad' - 'mp_bvec_for_each_page' - 'mp_bvec_for_each_segment' - 'nanddev_io_for_each_page' - 'netdev_for_each_lower_dev' - 'netdev_for_each_lower_private' - 'netdev_for_each_lower_private_rcu' - 'netdev_for_each_mc_addr' - 'netdev_for_each_uc_addr' - 'netdev_for_each_upper_dev_rcu' - 'netdev_hw_addr_list_for_each' - 'nft_rule_for_each_expr' - 'nla_for_each_attr' - 'nla_for_each_nested' - 'nlmsg_for_each_attr' - 'nlmsg_for_each_msg' - 'nr_neigh_for_each' - 'nr_neigh_for_each_safe' - 'nr_node_for_each' - 'nr_node_for_each_safe' - 'of_for_each_phandle' - 'of_property_for_each_string' - 'of_property_for_each_u32' - 'pci_bus_for_each_resource' - 'ping_portaddr_for_each_entry' - 'plist_for_each' - 'plist_for_each_continue' - 'plist_for_each_entry' - 'plist_for_each_entry_continue' - 'plist_for_each_entry_safe' - 'plist_for_each_safe' - 'pnp_for_each_card' - 'pnp_for_each_dev' - 'protocol_for_each_card' - 'protocol_for_each_dev' - 'queue_for_each_hw_ctx' - 'radix_tree_for_each_slot' - 'radix_tree_for_each_tagged' - 'rbtree_postorder_for_each_entry_safe' - 'rdma_for_each_port' - 'resource_list_for_each_entry' - 'resource_list_for_each_entry_safe' - 'rhl_for_each_entry_rcu' - 'rhl_for_each_rcu' - 'rht_for_each' - 'rht_for_each_from' - 'rht_for_each_entry' - 'rht_for_each_entry_from' - 'rht_for_each_entry_rcu' - 'rht_for_each_entry_rcu_from' - 'rht_for_each_entry_safe' - 'rht_for_each_rcu' - 'rht_for_each_rcu_from' - '__rq_for_each_bio' - 'rq_for_each_bvec' - 'rq_for_each_segment' - 'scsi_for_each_prot_sg' - 'scsi_for_each_sg' - 'sctp_for_each_hentry' - 'sctp_skb_for_each' - 'shdma_for_each_chan' - '__shost_for_each_device' - 'shost_for_each_device' - 'sk_for_each' - 'sk_for_each_bound' - 'sk_for_each_entry_offset_rcu' - 'sk_for_each_from' - 'sk_for_each_rcu' - 'sk_for_each_safe' - 'sk_nulls_for_each' - 'sk_nulls_for_each_from' - 'sk_nulls_for_each_rcu' - 'snd_array_for_each' - 'snd_pcm_group_for_each_entry' - 'snd_soc_dapm_widget_for_each_path' - 'snd_soc_dapm_widget_for_each_path_safe' - 'snd_soc_dapm_widget_for_each_sink_path' - 'snd_soc_dapm_widget_for_each_source_path' - 'tb_property_for_each' - 'tcf_exts_for_each_action' - 'udp_portaddr_for_each_entry' - 'udp_portaddr_for_each_entry_rcu' - 'usb_hub_for_each_child' - 'v4l2_device_for_each_subdev' - 'v4l2_m2m_for_each_dst_buf' - 'v4l2_m2m_for_each_dst_buf_safe' - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' - 'xa_for_each' - 'xa_for_each_marked' - 'xa_for_each_start' - 'xas_for_each' - 'xas_for_each_conflict' - 'xas_for_each_marked' - 'zorro_for_each_dev' #IncludeBlocks: Preserve # Unknown to clang-format-5.0 IncludeCategories: - Regex: '.*' Priority: 1 IncludeIsMainRegex: '(Test)?$' IndentCaseLabels: false #IndentPPDirectives: None # Unknown to clang-format-5.0 IndentWidth: 8 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: Inner #ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0 ObjCBlockIndentWidth: 8 ObjCSpaceAfterProperty: true ObjCSpaceBeforeProtocolList: true # Taken from git's rules #PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0 PenaltyBreakBeforeFirstCallParameter: 30 PenaltyBreakComment: 10 PenaltyBreakFirstLessLess: 0 PenaltyBreakString: 10 PenaltyExcessCharacter: 100 PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right ReflowComments: false SortIncludes: false #SortUsingDeclarations: false # Unknown to clang-format-4.0 SpaceAfterCStyleCast: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true #SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0 #SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0 SpaceBeforeParens: ControlStatements #SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0 SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInContainerLiterals: false SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Cpp03 TabWidth: 8 UseTab: Always ... jgmenu-4.5.0/.gitattributes000066400000000000000000000001231472613136300157020ustar00rootroot00000000000000scripts/checkpatch.pl linguist-vendored scripts/checkbashisms.pl linguist-vendored jgmenu-4.5.0/.gitignore000066400000000000000000000002761472613136300150100ustar00rootroot00000000000000*.o *.a jgmenu jgmenu-ob jgmenu-lx jgmenu-socket jgmenu-i18n jgmenu-greeneye jgmenu-obtheme jgmenu-apps jgmenu-config README.html config.mk valgrind.log binsiz.log .d/ checkdeps tags .tmp-* jgmenu-4.5.0/.travis.yml000066400000000000000000000004551472613136300151300ustar00rootroot00000000000000language: c dist: jammy os: linux compiler: - gcc - clang sudo: true addons: apt: packages: - libxrandr-dev - libpango1.0-dev - checkinstall - clang - gcc script: - ./configure --prefix=/usr - make - make test - sudo checkinstall --install=no -y jgmenu-4.5.0/AUTHORS.md000066400000000000000000000021611472613136300144620ustar00rootroot00000000000000Authors who have contributed more than a few of lines of code to at least two files in the src/ directory include: [@johanmalm](https://github.com/johanmalm) - main author [@o9000](https://github.com/o9000) - wrote the pmenu module - produced the xsettings client and xpm loader - provided much advice on early design choices - provided a lot of technical guidance on icon related code, inter-process communication (IPC), the main loop select() and self-pipe constructs, and more (see git log for full details) There many who have contributed in other ways including, but not limited to: [@Vladimir-csp](https://github.com/Vladimir-csp) - has contributed a great deal with bug reports and general helpful suggestions (including the `lx` module) - advice on XDG compliance [@johnraff](https://github.com/johnraff) - lots of support with the openbox (ob) module - packaging [@Misko-2083](https://github.com/Misko-2083) - various contrib/ packages Members of the Arch, ArchLabs, BunsenLabs, FreeBSD communities have also helped with testing, documentation, ideas and inspiration to keep this project going. jgmenu-4.5.0/CONTRIBUTING.md000066400000000000000000000206541472613136300152530ustar00rootroot00000000000000# Contributing - [Introduction](#introduction) - [Reporting issues and bugs](#reporting-issues-and-bugs) - [Debugging](#debugging) - [Upversion](#upversion) - [Add new config variables](#add-new-config-variables) - [Testing](#testing) - [Architecture](#architecture) - [Grammar and Language](#grammar-and-language) - [Git](#git) - [Overview of src/ files](#overview-of-src-files) - [Stack Traces](#stack-traces) ## Introduction First of all, thanks for contributing or considering to contribute. We have two high level development rules: - Friendship, ideas and code are valued in said order - There are no deadlines ## Reporting issues and bugs Reporting issues and bugs is a very helpful contribution. The preferred route for reporting these is to raise github issues, but we are happy with any method including forums threads and e-mails. If you are able to help resolve them, that is also greatly appreciated. It would be useful if you could simply start by describing what you did and what happened. It may help if you could also do the following: 1. Run jgmenu from the terminal and copy/paste any output 2. Provide the output of `jgmenu --version` 3. Provide the output of `type jgmenu` (i.e. the location of the binary) 4. Provide the command you used to run jgmenu 5. Provide the config file 6. Provide some basic information about your system (e.g. distribution, window manager, composite manager) 7. Run `jgmenu_run init -i` then choose 'check' and report any warnings ## Debugging This list is by no means exhaustive, but may provide some ideas for things to try. 1. Make use of the modular design of jgmenu to isolate the root cause. For example, if you are using jgmenu with the 'lx' module, run `jgmenu_run lx > foo` and analyse the output. Then try `jgmenu --csv-file=foo`. This approach might help find the root cause of the issue. 2. If the menu data is causing the issue (e.g. foo above), try to comment out a section at a time or write a script to cycle through individual items. The command line option --die-when-loaded can be useful for this. 3. If using the 'pmenu' module, `jgmenu_run pmenu` will output the .desktop file corresponding to each menu item. This can be useul to analyse specific items. 4. strace can be used to understand what what system calls are made. For example, to analyse which .desktop files were opened, try: `strace -f -o foo jgmenu_run lx ; grep '.desktop' foo` If you experience a crash, `strace` can also be particularly useful for analysing which system calls were made, including their return values. 5. Revert to a default configuration file and gradually change options until the bug occurs. 6. The file ./scripts/enable-error-messages.sh contains a number of environment variables which can be set for verbose output relating to specific topics. ## Upversion - update `default_version` in scripts/version-gen.sh - run `dch` and update debian/changelog - create docs/relnotes/X.Y.txt - update NEWS.md - add and commit the above files - git tag -a 'vX.Y' (using the release notes as the commit message) ## Add new config variables Any new config variables need to be added to the following: - config.c - config.h - src/jgmenu-config.c - docs/manual/jgmenu.1.md ## Testing - `make ex` to launch a few menus specifically designed to test various features. - `make check` to check coding style and perform some static analysis on all files in `src/`. Files can be checked on an individual basis by running `./scripts/check ` - `make test` to run unit tests ## Architecture `jgmenu_run ` is a wrapper script which calls `jgmenu-`. This architecture is inspired by git and has a number of advantages over putting all `jgmenu-` in `$prefix/bin`: - It ensures that the correct module is called if multiple version of jgmenu are installed on the system. - It avoids putting programs, that are not meant to be called by the user, in `$prefix/bin`. - It saves the user having to remember script file extensions whilst making it simple for the developer to know which are binary, shell, python, etc. ## Grammar and Language jgmenu is always written with a lowercase "j". It should be obvious from the context if we refer to the entire application or just the binary file. The language used in documentation shall follow British English rules. Although, for variable names and configuration options, US spelling is used (e.g. color and center) ## Git Keep commit messages lines to 74 characters. ## Overview of src/ files jgmenu.c - x11-ui.c - interface with X11 - icon.c - load icons * cache.c - manage icon cache on harddisk * icon-find.c - find icons * xpm-loader.c - load xpm icons (png/svg use cairo) - config.c - read config file - geometry.c - calculate positions and dimensions - filter.c - search support - theme.c + font.c - set icon theme and font from xsettings, tint2rc, etc * xsettings-helper.c - read xsettings variables * gtkconf.c - read gtk3.0 config file variables jgmenu-apps.c - desktop.c - parse desktopp files jgmenu-ob.c ## Stack traces If jgmenu crashes with the message 'Segmentation fault' or 'Abort', a stack trace (also known as backtrace) is often the most useful starting point. A stack trace tells us where the program stopped and how that point was reached through all the functions up to main(). A useful stack trace provides filenames and line numbers. You can provide a stack trace using one of the methods listed below. Method 1 - ASAN AddressSanitizer (ASAN) is a tool that detects memory error bugs and has been implemented in GCC since v4.8. It is invoked by simply compiling and linking with `--fsanitize=address` flag. This method is the easiest if you are prepared to compile jgmenu. You might balk at this, but jgmenu is very fast and simple to build, compared to many other software packages. See INSTALL.md for details of build dependencies and then take the following steps and report the output. git clone https://github.com/johanmalm/jgmenu cd jgmenu make ASAN=1 ./jgmenu The `ASAN=1` variable enables ASAN and sets some flags for a useful stack trace. Upon a crash, you will see something like this: #0 0x4a1ad2 in build_tree /home/johan/src/jgmenu/jgmenu.c:1099 #1 0x4aa077 in main /home/johan/src/jgmenu/jgmenu.c:2441 #2 0xb686d285 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18285) #3 0x499a70 (/home/johan/src/jgmenu/jgmenu+0xba70) Method 2 - gdb In order to get a useful stack trace with gdb, you need binaries with debug symbols. Release packages have generally been 'stripped' of these, so you have two options: - Install a package with debug symbols (e.g. jgmenu-dbgsym on BunsenLabs Linux). This option has the advantage of not needing to build the binaries. - Compile with `-g` and `-Og' flags as a minimum. jgmenu CFLAGS are set in `Makefile.inc` There are two ways of producing a stack trace with gdb. Either run the programme in gdb and trigger the crash; gdb jgmenu (gdb) handle SIG64 noprint nostop # or similar (gdb) run # wait for crash (gdb) backtrace or analyse a core dump after a crash. gdb (gdb) backtrace When using the `gdb jgmenu` approach, be aware that jgmenu grabs the keyboard and pointer, so interaction with gdb is not straight forward. If you get it wrong, you may need to log into a different tty (e.g. ctrl+alt+F2) and `killall jgmenu ; killall xterm` (or whatever terminal you use). With both approaches, remember that the jgmenu package contains many binary files, so it's important to run gdb on the one with the issue. For example, if the 'ob' modules caused a segfault and core dump, you need to run gdb jgmenu-ob In order to use the `gdb ` method, your system needs to be configured to core dump and you need the filename and location of the core dump file. Consult your OS/distribution documentation for details on this. The segfault/abort error message will indicate if the core has been dumped, e.g: `Segmentation fault (core dumped)`. If you system has not been setup to core dump, you can use the command `ulimit -c unlimited` to force a core dump in a specific shell session. In this scenario, the core will be dumped in the current working directory. Method 3 - coredumpctl If your system is set up to core dump and you have coredumpctl installed, you can run the following and include the output in your bug report. sudo coredumpctl info jgmenu jgmenu-4.5.0/INSTALL.md000066400000000000000000000062141472613136300144460ustar00rootroot00000000000000Install ======= - [Install from repos](#install-from-repos) - [Build and install in $HOME directory](#build-and-install-in-home-directory) - [System wide installation](#system-wide-installation) - [Build a Debian package](#build-a-debian-package) - [Dependencies](#dependencies) - [Build Options](#build-options) Install from repos ------------------ [Repology](https://repology.org/metapackage/jgmenu/versions) [![Packaging status](https://repology.org/badge/vertical-allrepos/jgmenu.svg)](https://repology.org/project/jgmenu/versions) Build and install in $HOME directory ------------------------------------ This is for users who: - wish to use/test a feature/fix which is not yet in the latest version in their repo. - wish to experiement with the code or contribute code - use a distro without jgmenu in their repo and run a single-user system - do not like to or are not permitted to use sudo ```bash git clone https://github.com/johanmalm/jgmenu.git cd jgmenu ./configure --prefix=$HOME --with-lx --with-pmenu make make install ``` Make sure you have `$HOME/bin` in your `$PATH`. If you have another version of jgmenu installed on your system, please run `hash -r` and then `type jgmenu` to make sure the correct one will be launched The Makefile contains an uninstall target. As I am not brave enough to write 'sudo rm -rf...', it only works when prefix=$HOME. It is advisable to use a package manager for installations outside of the $HOME directory. To uninstall jgmenu, run ```bash make uninstall ``` For subsequent updates, do: ```bash make uninstall make clean git pull make make install ``` System wide installation ------------------------ By default, `make install` installs jgmenu to /usr/local/{bin,lib/jgmenu,share/man} Use `./configure --prefix` to specify a different target location. For example: ```bash ./configure --prefix=/usr sudo make install ``` Build a Debian package ---------------------- A debian package can be built as follows: ``` dpkg-buildpackage -tc -b -us -uc ``` Then install the .deb package with ``` sudo dpkg -i ../jgmenu_.deb ``` Dependencies ------------ ## src/ programs - jgmenu required: * libx11, libxrandr, cairo, pango, glib-2.0 optional: * librsvg-2.0 - apps * Nothing - not even a menu package :) - ob * libxml2 ## contrib/ programs - lx * glib-2.0, libmenu-cache (>=1.1.0) * A `menu package` such as lxmenu-data or gnome-menus. Xfce's libgarcon-common does not yet work with lx. - pmenu * python3 * A `menu package` is optional. If none is installed, all applications will be shown in the menu's root directory. - xfce-panel * xfce4-panel ## Other - A Composite Manager such as `compton` is required to enable transparency. Most Desktop Environments already have one installed. - To build the man pages, you need to have `pandoc` installed. However, as many users do not have this package, the man pages are commited in the git repo (i.e. you only need pandoc if you want to contribute to or change the man pages.) Build Options ------------- In addition to `prefix`, there are a number of build variables which can be defined. Run `./configure --help` for further details. jgmenu-4.5.0/LICENSE000066400000000000000000000432541472613136300140300ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. jgmenu-4.5.0/Makefile000066400000000000000000000124761472613136300144650ustar00rootroot00000000000000# # Define ASAN=1 to enable AddressSanitizer # Define RSVG=1 to enable SVG icon support # # Define VERBOSE=1 for a more verbose compilation # # Define CONTRIB_DIRS to include any contrib/ packages you wish to include # The following are supported: CONTRIB_DIRS="xfce4-panel gtktheme lx" # VER = $(shell ./scripts/version-gen.sh) -include config.mk include Makefile.inc jgmenu: CFLAGS += `pkg-config cairo pango pangocairo $(RSVG_LIB) --cflags` $(RSVG_FLAGS) jgmenu-ob: CFLAGS += `xml2-config --cflags` jgmenu-obtheme: CFLAGS += `xml2-config --cflags` jgmenu-config: CFLAGS += `pkg-config --cflags glib-2.0` jgmenu-apps: CFLAGS += `pkg-config --cflags glib-2.0` jgmenu: LIBS += `pkg-config x11 xrandr cairo pango pangocairo $(RSVG_LIB) --libs` $(RSVG_FLAGS) jgmenu: LIBS += -pthread -lpng jgmenu-ob: LIBS += `xml2-config --libs` jgmenu-obtheme: LIBS += `xml2-config --libs` jgmenu-config: LIBS += `pkg-config --libs glib-2.0` jgmenu-apps: LIBS += `pkg-config --libs glib-2.0` LDFLAGS += $(LIBS) DEPDIR := .d $(shell mkdir -p $(DEPDIR) >/dev/null) DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td SCRIPTS_LIBEXEC = src/jgmenu-init.sh \ src/jgmenu-unity-hack.py \ src/jgmenu-themes.sh \ src/jgmenu-hide-app.sh PROGS_LIBEXEC = jgmenu-ob jgmenu-socket jgmenu-i18n jgmenu-greeneye \ jgmenu-obtheme jgmenu-apps jgmenu-config PROGS = jgmenu $(PROGS_LIBEXEC) all: config_mk $(PROGS) @for dir in $(CONTRIB_DIRS); do \ $(MAKE) -C contrib/$$dir || exit 1; \ done config_mk: @if test ! -e config.mk; then \ echo "fatal: you have not run ./configure"; \ exit 1; \ fi @: jgmenu: jgmenu.o x11-ui.o config.o util.o geometry.o isprog.o sbuf.o \ icon-find.o icon.o xpm-loader.o xdgdirs.o xsettings.o \ xsettings-helper.o filter.o compat.o lockfile.o argv-buf.o t2conf.o \ ipc.o unix_sockets.o bl.o cache.o back.o terminal.o restart.o \ theme.o gtkconf.o font.o args.o widgets.o pm.o socket.o workarea.o \ charset.o hooks.o spawn.o jgmenu-ob: jgmenu-ob.o util.o sbuf.o i18n.o hashmap.o jgmenu-socket: jgmenu-socket.o util.o sbuf.o unix_sockets.o socket.o compat.o jgmenu-i18n: jgmenu-i18n.o i18n.o hashmap.o util.o sbuf.o jgmenu-greeneye: jgmenu-greeneye.o compat.o util.o sbuf.o jgmenu-apps: jgmenu-apps.o compat.o util.o sbuf.o desktop.o charset.o \ xdgdirs.o argv-buf.o dirs.o lang.o fmt.o i18n.o hashmap.o isprog.o jgmenu-obtheme: jgmenu-obtheme.o util.o sbuf.o compat.o set.o jgmenu-config: jgmenu-config.o util.o sbuf.o compat.o set.o spawn.o $(PROGS): $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) %.o : src/%.c %.o : src/%.c $(DEPDIR)/%.d $(QUIET_CC)$(CC) $(DEPFLAGS) $(CFLAGS) -c $< @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@ $(DEPDIR)/%.d: ; .PRECIOUS: $(DEPDIR)/%.d install: $(PROGS) @install -d $(DESTDIR)$(bindir) @install -m755 jgmenu src/jgmenu_run $(DESTDIR)$(bindir) @install -d $(DESTDIR)$(libexecdir)/jgmenu @install -m755 $(PROGS_LIBEXEC) $(SCRIPTS_LIBEXEC) $(DESTDIR)$(libexecdir)/jgmenu @./scripts/set-exec-path.sh $(DESTDIR)$(bindir)/jgmenu_run $(libexecdir)/jgmenu @$(MAKE) --no-print-directory -C docs/manual/ prefix=$(prefix) install @install -d $(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/ @install -d $(DESTDIR)$(datarootdir)/applications/ @install -m644 ./data/jgmenu.svg $(DESTDIR)$(datarootdir)/icons/hicolor/scalable/apps/ @install -m644 ./data/jgmenu.desktop $(DESTDIR)$(datarootdir)/applications/ @for dir in $(CONTRIB_DIRS); do \ $(MAKE) -C contrib/$$dir install || exit 1; \ done # We are not brave enough to uninstall in /usr/, /usr/local/ etc uninstall: ifneq ($(prefix),$(HOME)) @$(error uninstall only works if prefix=$(HOME)) endif @rm -f ~/bin/jgmenu @rm -f ~/bin/jgmenu_run @rm -rf ~/lib/jgmenu/ @-rmdir ~/lib 2>/dev/null || true @rm -f ~/share/man/man1/jgmenu* @rm -f ~/share/man/man7/jgmenu* @-rmdir ~/share/man/man1 2>/dev/null || true @-rmdir ~/share/man/man7 ~/share/man ~/share 2>/dev/null || true @rm -f ~/.local/share/icons/hicolor/scalable/apps/jgmenu.svg @rm -f ~/.local/share/applications/jgmenu.desktop @-rmdir ~/.local/share/applications 2>/dev/null || true @-rmdir ~/.local/share/icons/hicolor/scalable/apps 2>/dev/null || true @-rmdir ~/.local/share/icons/hicolor/scalable 2>/dev/null || true @-rmdir ~/.local/share/icons/hicolor 2>/dev/null || true @-rmdir ~/.local/share/icons 2>/dev/null || true @for dir in $(CONTRIB_DIRS); do \ $(MAKE) -C contrib/$$dir uninstall || exit 1; \ done clean: @$(RM) $(PROGS) *.o *.a $(DEPDIR)/*.d @$(RM) -r .d/ @$(MAKE) --no-print-directory -C tests/ clean @$(MAKE) --no-print-directory -C tests/helper/ clean @for dir in $(CONTRIB_DIRS); do \ $(MAKE) -C contrib/$$dir clean || exit 1; \ done distclean: clean @$(RM) config.mk clang-format-tmpfile test: @$(MAKE) --no-print-directory -C tests/helper/ all @$(MAKE) --no-print-directory -C tests/ all prove: @$(MAKE) --no-print-directory -C tests/helper/ all @$(MAKE) --no-print-directory -C tests/ prove ex: @$(MAKE) --no-print-directory -C examples/ all check: @./scripts/check src/*.sh src/*.c src/*.h print-%: @echo '$*=$($*)' SRCS = $(patsubst ./%,%,$(shell find ./src -maxdepth 1 -name '*.c' -print)) include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS)))) .PHONY: all install uninstall clean distclean test prove ex check jgmenu-4.5.0/Makefile.inc000066400000000000000000000021771472613136300152320ustar00rootroot00000000000000RM ?= rm -f prefix ?= /usr/local bindir ?= $(prefix)/bin libdir ?= $(prefix)/lib # www.gnu.org/prep/standards/html_node/Directory-Variables.html specifies that # libexecdir should point to $(exec_prefix)/libexec, but for backward # compatibility, we're just making it the same $libdir. That's what it's set # to on Arch and Debian anyway. libexecdir ?= $(prefix)/lib ifeq ($(prefix),$(HOME)) datarootdir= $(prefix)/.local/share else datarootdir= $(prefix)/share endif CFLAGS += -g -Wall -Os -std=gnu99 CFLAGS += -Wextra -Wdeclaration-after-statement -Wno-format-zero-length \ -Wold-style-definition -Woverflow -Wpointer-arith \ -Wstrict-prototypes -Wunused -Wvla -Wunused-result CFLAGS += -Wno-unused-parameter -Wno-expansion-to-defined CFLAGS += -DVERSION='"$(VER)"' ifdef ASAN ASAN_FLAGS = -O0 -fsanitize=address -fno-common -fno-omit-frame-pointer -rdynamic CFLAGS += $(ASAN_FLAGS) LDFLAGS += $(ASAN_FLAGS) -fuse-ld=gold endif ifdef RSVG RSVG_LIB = librsvg-2.0 RSVG_FLAGS = -DRSVG=1 endif ifndef VERBOSE QUIET_CC = @echo ' CC '$@; QUIET_LINK = @echo ' LINK '$@; endif MAKEFLAGS += --no-print-directory jgmenu-4.5.0/NEWS.md000066400000000000000000000010441472613136300141100ustar00rootroot00000000000000# Release Notes ## All releases [docs/relnotes/](docs/relnotes/) ## Recent releases | Date | Release Notes | |------------|-----------------------------------| | 2024-12-06 | [v4.5.0](docs/relnotes/4.5.0.txt) | | 2022-10-30 | [v4.4.1](docs/relnotes/4.4.1.txt) | | 2021-09-16 | [v4.4.0](docs/relnotes/4.4.0.txt) | | 2021-01-02 | [v4.3.0](docs/relnotes/4.3.0.txt) | | 2020-05-19 | [v4.2.1](docs/relnotes/4.2.1.txt) | | 2020-05-06 | [v4.2.0](docs/relnotes/4.2.0.txt) | | 2020-03-02 | [v4.1.0](docs/relnotes/4.1.0.txt) | jgmenu-4.5.0/README.md000066400000000000000000000031031472613136300142670ustar00rootroot00000000000000

jgmenu
jgmenu

A simple X11 menu

[Install] [Release Notes] [Website] [Screenshots]

`jgmenu` is simple, independent and contemporary-looking X11 menu, designed for scripting, modding and tweaking. It is hackable and has a simple code base. It does not depend on any toolkits such as GTK and Qt, but uses cairo and pango to render the menu. It can optionally use some appearance settings from XSettings, tint2 and GTK. It can display the following types of menu (or any combination of): - bespoke menu using a jgmenu flavoured CSV format - application menu (XDG compatible) with localisation support - pipe menus - openbox XML menu including openbox pipe-menus It has UTF-8 search support. Video (13:43) showing advanced jgmenu usage on Mabox jgmenu # Versioning We use [semver 2.0.0](http://www.semver.org) jgmenu-4.5.0/TODO.md000066400000000000000000000000661472613136300141040ustar00rootroot00000000000000See [roadmap](https://jgmenu.github.io/roadmap.html) jgmenu-4.5.0/configure000077500000000000000000000061531472613136300147270ustar00rootroot00000000000000#!/bin/sh config_mk="config.mk" enable_asan=f prefix="/usr/local" with_xfce4_panel_applet=f with_gtktheme=f with_lx=f with_pmenu=f usage_message="Usage: ./configure Produce a config.mk file to be sourced by Makefile --with-xfce4-panel-applet Include xfce4-panel-applet. This has quite different runtime dependencies, so consider building separately. --with-gtktheme Include gtktheme module --with-lx Include lx module --with-pmenu Include pmenu module --all, -a Include all contrib/ packages above --dev, -d Same as --all, but also with ASAN and prefix=\$HOME --enable-asan Enable address sanitizer (only during development) --disable-svg Disable SVG icon support --prefix= Install architecture-independent files in \$prefix (e.g. --prefix=\$HOME') --libdir= Specify libdir (\$prefix/lib by default) --libexecdir= Specify libexecdir (\$prefix/lib by default) " print_ok_fail () { # Usage: print_ok_fail ... # 0=ok; 1-127=fail status=$1 shift if [ "$status" = "0" ]; then printf '%b\n' "[ OK ] $*" else printf '%b\n' "[FAIL] $*" exit 1 fi } check_bin () { type "$*" >/dev/null 2>&1 print_ok_fail $? $* } check_lib () { pkg-config "$*" >/dev/null 2>&1 print_ok_fail $? $* } check_core_dependencies () { for b in "pkg-config" "xml2-config"; do check_bin "$b" done for l in "x11" "xrandr" "cairo" "pango" "pangocairo" "glib-2.0"; do check_lib "$l" done if [ "$disable_svg" != "t" ]; then check_lib "librsvg-2.0" fi } add () { printf '%b\n' "$*" >>"$config_mk" } add_modules () { add "prefix = $prefix" test -z "$libdir" || add "libdir = $libdir" test -z "$libexecdir" || add "libexecdir = $libexecdir" if [ "$disable_svg" != "t" ]; then add "RSVG=1" fi if [ "$enable_asan" = "t" ]; then add "ASAN=1" fi if [ "$with_xfce4_panel_applet" = "t" ]; then check_lib "libxfce4panel-2.0" add "CONTRIB_DIRS += xfce4-panel" fi if [ "$with_gtktheme" = "t" ]; then add "CONTRIB_DIRS += gtktheme" fi if [ "$with_lx" = "t" ]; then check_lib "libmenu-cache >= 1.1.0" add "CONTRIB_DIRS += lx" fi if [ "$with_pmenu" = "t" ]; then add "CONTRIB_DIRS += pmenu" fi } with_all () { with_xfce4_panel_applet=t with_gtktheme=t with_lx=t with_pmenu=t } main () { for arg do opt=${arg%%=*} var=${arg#*=} case "$opt" in --prefix) prefix="$var" ;; --libdir) libdir="$var" ;; --libexecdir) libexecdir="$var" ;; --with-xfce4-panel-applet) with_xfce4_panel_applet=t ;; --with-gtktheme) with_gtktheme=t ;; --with-lx) with_lx=t ;; --with-pmenu) with_pmenu=t ;; --enable-asan) enable_asan=t ;; --disable-svg) disable_svg=t ;; -a|--all) with_all ;; -d|--dev) with_all enable_asan=t prefix=${HOME} ;; -h|--help) printf '%b' "$usage_message"; exit 1 ;; *) printf '%b\n' "warn: unknown option $opt" >&2 ;; esac done rm -rf $config_mk add "# Generated by configure script" check_core_dependencies add_modules } main "$@" jgmenu-4.5.0/contrib/000077500000000000000000000000001472613136300144535ustar00rootroot00000000000000jgmenu-4.5.0/contrib/README.md000066400000000000000000000014541472613136300157360ustar00rootroot00000000000000contrib/ software ================= The tools and helpers in this directory: - are stand-alone, hopefully interesting and sometimes experimental; - are included in the git-repo to give users easier access to them; - have sometimes been entirely contributed by others; - are not installed by default, but can optionally be added to `make && make install` (those that are considered mature enough, can be given as options to the configure script - e.g. --with-lx) - may have completely different dependencies to the core jgmenu application (e.g. ff-bookmarks depends on sqlite3 and arguably also firefox/iceweasel); - do not always adhere to the jgmenu coding guidelines. Although I will try to maintain this code, my main focus will remain on the jgmenu app itself (the code in the src/ directory). jgmenu-4.5.0/contrib/bookmarks/000077500000000000000000000000001472613136300164435ustar00rootroot00000000000000jgmenu-4.5.0/contrib/bookmarks/jgmenu-ff-bookmarks.sh000077500000000000000000000035431472613136300226530ustar00rootroot00000000000000#!/bin/sh # Inspired-by: # - https://forum.archlabslinux.com/t/jgmenu-bookmarks/696 # - https://blog.sleeplessbeastie.eu/2014/01/02/how-to-open-firefox-bookmarks-from-openbox-menu/ # If you use iceweasel, set JGMENU_BROWSER=iceweasel before running script : ${JGMENU_BROWSER="firefox"} database=$(find ~/.mozilla/${JGMENU_BROWSER}/ -name "places.sqlite") submenus=$(mktemp) usage () { printf "%b\n" "\ usage: jgmenu_run ff-bookmarks\n\ Generate jgmenu flavoured CSV menu data for firefox/iceweasel bookmarks" } check_dependency () { if ! type "$1" >/dev/null 2>&1 then printf "%b\n" "'$1' is required to run module [ff-bookmarks]" exit 1 fi } process_bookmarks () { query="select b.title, p.url from moz_bookmarks as b left outer join \ moz_places as p on b.fk=p.id where b.type = 1 and p.hidden=0 \ and b.title not null and parent=$1" sqlite3 -separator ^ "$database" "$query" | while IFS=^ read title url do test -z "$title" && title=$url echo "$title, firefox $url" >>$submenus done } process_folders () { query="select id, title from moz_bookmarks where parent=$1 and type=2 \ and (select count(*) from moz_bookmarks as b2 where \ b2.parent=moz_bookmarks.id)>0" sqlite3 -separator ^ "$database" "$query" | while IFS=^ read id title do test -z "$title" && title="(no title)" echo "$title,^checkout($title)" echo "$title,^tag($title)" >>$submenus process_folders $id process_bookmarks $id done } if test "$1" = "--help" then usage exit 0 fi check_dependency ${JGMENU_BROWSER} check_dependency sqlite3 # unfiled bookmarks root="(select id from moz_bookmarks where rtrim(guid,'_')='unfiled')" process_bookmarks "$root" # filed bookmarks root="(select id from moz_bookmarks where rtrim(guid,'_')='menu')" process_bookmarks "$root" process_folders "$root" cat $submenus rm -f $submenus jgmenu-4.5.0/contrib/compton/000077500000000000000000000000001472613136300161325ustar00rootroot00000000000000jgmenu-4.5.0/contrib/compton/jgmenu-compton.sh000077500000000000000000000004031472613136300214300ustar00rootroot00000000000000#!/bin/sh value=$(grep "^menu-opacity" ~/.config/compton.conf) value=${value#*=} value=${value%;} : $(( value *= 100 )) printf '%b\n' "Set menu background to 000000 $value" jgmenu_run config -s ~/.config/jgmenu/jgmenurc -k color_menu_bg -v "000000 $value" jgmenu-4.5.0/contrib/gtktheme/000077500000000000000000000000001472613136300162635ustar00rootroot00000000000000jgmenu-4.5.0/contrib/gtktheme/Makefile000066400000000000000000000003771472613136300177320ustar00rootroot00000000000000-include ../../config.mk include ../../Makefile.inc gtktheme: @: install: @install -d $(DESTDIR)$(libexecdir)/jgmenu @install -m775 jgmenu-gtktheme.py $(DESTDIR)$(libexecdir)/jgmenu uninstall: @rm -f $(libexecdir)/jgmenu/jgmenu-gtktheme.py clean: jgmenu-4.5.0/contrib/gtktheme/jgmenu-gtktheme.py000077500000000000000000000060321472613136300217340ustar00rootroot00000000000000#!/usr/bin/env python3 # Copyright (C) @Misko_2083 2019 # Copyright (C) Johan Malm 2019 """ Parse gtk theme and set some key/value pairs in jgmenurc """ import os import sys import shlex import subprocess try: import gi except ImportError: print("[gtktheme] fatal: require python3-gi") sys.exit(1) gi.require_version("Gtk", "3.0") from gi.repository import Gtk def run(command): """ run a command """ proc = subprocess.Popen(shlex.split(command)) proc.wait() def fmt(s): """ ensure string is at least two characters long """ if len(s) == 0: return "00" elif len(s) == 1: return "0{}".format(s) return s def rgb2hex(line): """ convert rgb values to a 6-digit hex string """ s = line.split("rgb(") rgb = s[-1].replace(");", "").split(",") r = hex(int(rgb[0]))[2:] g = hex(int(rgb[1]))[2:] b = hex(int(rgb[2]))[2:] return "{}{}{}".format(fmt(r), fmt(g), fmt(b)) def setconfig(key, value): """ set key/value pain in ~/.config/jgmenu/jgmenurc """ filename = os.environ["HOME"] + "/.config/jgmenu/jgmenurc" value = "#{} 100".format(value) print("[gtktheme] {} = {}".format(key, value)) cmd = "jgmenu_run config -s {} -k {} -v '{}'".format(filename, key, value) run(cmd) def process_line(line): """ process one line """ if "background-color" in line: setconfig("color_menu_bg", rgb2hex(line)) setconfig("color_title_bg", rgb2hex(line)) setconfig("color_title_border", rgb2hex(line)) def cache(themename): """ save the theme-name to XDG_CACHE_HOME/jgmenu/.last-gtktheme or ~/.cache/jgmenu/.last-gtktheme if it doesn't exist """ print("themename={}".format(themename)) home = os.environ["HOME"] directory = os.getenv("XDG_CACHE_HOME", home + "/.cache") + "/jgmenu" if not os.path.exists(directory): os.mkdir(directory) f = open(directory + "/.last-gtktheme", "w") f.write(themename) f.close() def main(): """ main """ gset = Gtk.Settings.get_default() themename = gset.get_property("gtk-theme-name") cache(themename) prefdark = gset.get_property("gtk-application-prefer-dark-theme") css = Gtk.CssProvider.get_named(themename).to_string() # print(css) # exit(1) lines = css.split("\n") # parse some @define-color lines for line in lines: if "@define-color" not in line: break if "theme_text_color" in line: setconfig("color_norm_fg", rgb2hex(line)) setconfig("color_title_fg", rgb2hex(line)) if "theme_selected_bg_color" in line: setconfig("color_sel_bg", rgb2hex(line)) if "theme_selected_fg_color" in line: setconfig("color_sel_fg", rgb2hex(line)) # parse the menu { } section inside = False for line in lines: if "menu {" in line: inside = True continue if inside: if "{" in line: inside = False break process_line(line) if __name__ == '__main__': main() jgmenu-4.5.0/contrib/lx/000077500000000000000000000000001472613136300150765ustar00rootroot00000000000000jgmenu-4.5.0/contrib/lx/Makefile000066400000000000000000000007441472613136300165430ustar00rootroot00000000000000-include ../../config.mk include ../../Makefile.inc CFLAGS += `pkg-config --cflags glib-2.0 libmenu-cache` LDFLAGS += `pkg-config --libs glib-2.0 libmenu-cache` path = ../../src/ src = util.c sbuf.c xdgdirs.c argv-buf.c back.c fmt.c jgmenu-lx: jgmenu-lx.c $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $^ $(addprefix $(path),$(src)) -I$(path) $(LDFLAGS) install: @install -d $(DESTDIR)$(libexecdir)/jgmenu @install -m755 jgmenu-lx $(DESTDIR)$(libexecdir)/jgmenu clean: @rm -f jgmenu-lx jgmenu-4.5.0/contrib/lx/TODO000066400000000000000000000016041472613136300155670ustar00rootroot00000000000000* Support i18n for prepend.csv and append.csv * Use desktop specific flags * Add 'comment' to `csv_name_format` (%c) * Triple quote all variables if they contain commas (not just name and exec) * Apply `csv_name_format` to directories too * Fix bug: `JGMENU_NO_DIRS=1` with append and prepend doesn't work * If no menu file or no root dir, write tempfile with <All />. This allows lx to run even if no menu package exists (albeit without directories). * Read the above temp file if "--no-dir" specified (puts item in alphabetical order without having to do a qsort) * Deal with xfce-applications.menu. Currently libmenu-cache can't read it because the root-item has the wrong name. * Support `JGMENU_SINGLE_WINDOW=1` * Check that .desktop files are not Unicode in order to avoid segfault (add unit test) * Write some unit tests (incl. nested menus) * Cope with desktop-file without exec field jgmenu-4.5.0/contrib/lx/jgmenu-lx.c000066400000000000000000000126631472613136300171600ustar00rootroot00000000000000#include #include #include #include #include #include #include "sbuf.h" #include "util.h" #include "list.h" #include "back.h" #include "xdgdirs.h" #include "fmt.h" struct menu { struct sbuf buf; struct menu *parent; struct list_head list; }; static struct list_head menu; static struct menu *cur; static int no_dirs; static int no_pend; /* no append or prepend */ static void append(void) { static int done; if (done || no_pend) return; cat("~/.config/jgmenu/append.csv"); done = 1; } static void print_menu(void) { struct menu *m; if (!no_pend) cat("~/.config/jgmenu/prepend.csv"); list_for_each_entry(m, &menu, list) { sbuf_replace(&m->buf, "&", "&"); printf("%s", m->buf.buf); append(); } } static struct menu *menu_add(struct menu *parent) { struct menu *m; m = xmalloc(sizeof(struct menu)); sbuf_init(&m->buf); m->parent = parent; list_add_tail(&m->list, &menu); return m; } static void process_dir(MenuCacheApp *app) { static char unique_number[8]; static int nr; if (no_dirs) { cur = menu_add(cur); return; } snprintf(unique_number, sizeof(unique_number), "%d", nr); sbuf_addstr(&cur->buf, menu_cache_item_get_name(MENU_CACHE_ITEM(app))); sbuf_addstr(&cur->buf, ",^checkout("); sbuf_addstr(&cur->buf, menu_cache_item_get_id(MENU_CACHE_ITEM(app))); sbuf_addstr(&cur->buf, unique_number); sbuf_addstr(&cur->buf, "),"); sbuf_addstr(&cur->buf, menu_cache_item_get_icon(MENU_CACHE_ITEM(app))); sbuf_addstr(&cur->buf, "\n"); cur = menu_add(cur); sbuf_addstr(&cur->buf, menu_cache_item_get_name(MENU_CACHE_ITEM(app))); sbuf_addstr(&cur->buf, ",^tag("); sbuf_addstr(&cur->buf, menu_cache_item_get_id(MENU_CACHE_ITEM(app))); sbuf_addstr(&cur->buf, unique_number); sbuf_addstr(&cur->buf, ")\n"); sbuf_addstr(&cur->buf, back_string()); sbuf_addstr(&cur->buf, ",^back(),go-previous\n"); ++nr; } static void add_metadata(const char * const *categories) { const char **c = (const char **)categories; int i; for (i = 0; c && c[i]; i++) { sbuf_addstr(&cur->buf, "#"); sbuf_addstr(&cur->buf, c[i]); } } static void strip_exec_field_codes(char **exec) { char *p; if (!**exec || !*exec) return; for (p = *exec; *p; p++) { if (*p == '%') { *p = ' '; ++p; if (*p == '\0') break; if (*p != '%') *p = ' '; } } rtrim(exec); } /* * For some reason libmenu-cache does not escape the backslack in 'C:\' * so we have to manually intervene and esacpe it. */ static void ugly_hack(struct sbuf *exec) { sbuf_replace(exec, ":\\", ":\\\\"); } static void process_app(MenuCacheApp *app) { /* TODO: Check visibility flag here too */ struct sbuf exec; static struct sbuf s; static int inited; if (!inited) { sbuf_init(&s); inited = 1; } /* name */ fmt_name(&s, menu_cache_item_get_name(MENU_CACHE_ITEM(app)), menu_cache_app_get_generic_name(MENU_CACHE_APP(app))); if (strchr(s.buf, ',')) sbuf_addstr(&cur->buf, "\"\"\""); sbuf_addstr(&cur->buf, s.buf); if (strchr(s.buf, ',')) sbuf_addstr(&cur->buf, " \"\"\""); sbuf_addstr(&cur->buf, ","); /* command */ sbuf_init(&exec); if (menu_cache_app_get_use_terminal(app)) sbuf_addstr(&cur->buf, "^term("); sbuf_cpy(&exec, (char *)menu_cache_app_get_exec(MENU_CACHE_APP(app))); if (strchr(exec.buf, ',')) sbuf_addstr(&cur->buf, "\"\"\""); ugly_hack(&exec); strip_exec_field_codes(&exec.buf); sbuf_addstr(&cur->buf, exec.buf); if (strchr(exec.buf, ',')) sbuf_addstr(&cur->buf, " \"\"\""); sbuf_rtrim(&cur->buf); if (menu_cache_app_get_use_terminal(app)) sbuf_addstr(&cur->buf, ")"); sbuf_addstr(&cur->buf, ","); xfree(exec.buf); /* icon */ sbuf_addstr(&cur->buf, menu_cache_item_get_icon(MENU_CACHE_ITEM(app))); sbuf_addstr(&cur->buf, ","); /* working directory */ sbuf_addstr(&cur->buf, menu_cache_app_get_working_dir(MENU_CACHE_APP(app))); sbuf_addstr(&cur->buf, ","); /* metadata */ add_metadata(menu_cache_app_get_categories(MENU_CACHE_APP(app))); sbuf_addstr(&cur->buf, "\n"); } static void traverse(MenuCacheDir *dir) { GSList *l = NULL; for (l = menu_cache_dir_get_children(dir); l; l = l->next) { switch ((guint)menu_cache_item_get_type(MENU_CACHE_ITEM(l->data))) { case MENU_CACHE_TYPE_DIR: process_dir(l->data); traverse(MENU_CACHE_DIR(l->data)); cur = cur->parent; break; case MENU_CACHE_TYPE_SEP: if (!no_dirs) sbuf_addstr(&cur->buf, "^sep()\n"); break; case MENU_CACHE_TYPE_APP: process_app(l->data); } } } static void set_if_unset_xdg_menu_prefix(void) { struct sbuf f; char *p, *q; if (getenv("XDG_MENU_PREFIX")) return; sbuf_init(&f); xdgdirs_find_menu_file(&f); if (!f.len) die("cannot find a menu file"); p = strrchr(f.buf, '/'); BUG_ON(!p); p++; q = strchr(p, '-'); BUG_ON(!q); q++; *q = '\0'; setenv("XDG_MENU_PREFIX", p, 1); } int main(int argc, char **argv) { MenuCache *cache; MenuCacheDir *rootdir; INIT_LIST_HEAD(&menu); cur = menu_add(NULL); setlocale(LC_ALL, ""); if (getenv("JGMENU_NO_DIRS")) no_dirs = 1; if (getenv("JGMENU_NO_PEND")) no_pend = 1; set_if_unset_xdg_menu_prefix(); cache = menu_cache_lookup_sync("applications.menu"); if (!cache) die("cannot connect to menu-cache"); rootdir = menu_cache_dup_root_dir(cache); if (!rootdir) die("no lx menu root directory"); if (!g_slist_length(menu_cache_dir_get_children(rootdir))) die("lx menu is empty"); traverse(rootdir); menu_cache_item_unref(MENU_CACHE_ITEM(rootdir)); menu_cache_unref(cache); print_menu(); return 0; } jgmenu-4.5.0/contrib/mate-panel/000077500000000000000000000000001472613136300164765ustar00rootroot00000000000000jgmenu-4.5.0/contrib/mate-panel/Makefile000066400000000000000000000006001472613136300201320ustar00rootroot00000000000000MATE_APPLET_DIR = /usr/share/mate-panel/applets SERVICE_DIR = /usr/share/dbus-1/services BINDIR = $(HOME)/bin install: install -d $(MATE_APPLET_DIR) install -m644 org.mate.panel.JgMenuApplet.mate-panel-applet $(MATE_APPLET_DIR) install -d $(SERVICE_DIR) install -m644 org.mate.panel.applet.JgMenuAppletFactory.service $(SERVICE_DIR) install -m755 mate-jgmenu.py /home/johan/bin jgmenu-4.5.0/contrib/mate-panel/README000066400000000000000000000002131472613136300173520ustar00rootroot00000000000000https://forums.bunsenlabs.org/viewtopic.php?pid=88137#p88137 Depends on: - mate-panel - lib-matepanel-applet-dev - python3-setproctitle jgmenu-4.5.0/contrib/mate-panel/mate-jgmenu.py000077500000000000000000000061361472613136300212720ustar00rootroot00000000000000#!/usr/bin/env python3 # Copyright (C) @Misko_2083 2019 import gi gi.require_version("Gtk", "3.0") gi.require_version("Gdk", "3.0") gi.require_version('MatePanelApplet', '4.0') from gi.repository import Gtk, Gdk from gi.repository import MatePanelApplet from gi.repository.GdkPixbuf import Pixbuf import os import shlex import subprocess import setproctitle # Rename the process setproctitle.setproctitle('mate-jgmenu') class JgMenu(MatePanelApplet.Applet): def __init__(self, applet): self.applet_fill(applet) def execute(self, command): subprocess.Popen(shlex.split(command), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) def applet_fill(self, applet): # you can use this path with gio/gsettings settings_path = applet.get_preferences_path() applet.set_border_width(0) self.button = Gtk.Button(border_width=0) try: pixbuf = Gtk.IconTheme.get_default().load_icon("start-here", applet.get_size(), 0) button_icon = Gtk.Image.new_from_pixbuf(pixbuf) except: button_icon = Gtk.Label("jgmenu") self.button.add(button_icon) # Disable label to show icon # self.button.set_label("jgmenu") self.button.connect("clicked", self.on_toggle, self.button, applet) self.applet = applet self.applet.add(self.button) toplevel = self.button.get_toplevel() self.applet.show_all() def on_toggle(self, button, applet, data=None): # make sure we're in ipc mode - won't touch jgmenurc if already in ipc self.execute("jgmenu_run config -s {} -k position_mode -v ipc".format(os.environ["HOME"] + '/.config/jgmenu/jgmenurc')) rect = button.get_allocation() main_window = self.button.get_toplevel() [val, button_x1, button_y1] = main_window.get_window().get_origin() button_x2 = button_x1 + rect.width button_y2 = button_y1 + rect.height button_y1=0 orientation = self.applet.get_orient() # Cheeky hack to watch a few variables f = open("/home/johan/mate-temp", 'w') f.write("x={} ".format(button_x2)) f.write("y={} ".format(button_y2)) f.write("\n") f.close() os.environ["TINT2_BUTTON_PANEL_X1"] = "0" os.environ["TINT2_BUTTON_PANEL_Y1"] = "0" os.environ["TINT2_BUTTON_PANEL_X2"] = "1024" os.environ["TINT2_BUTTON_PANEL_Y2"] = "{}".format(button_y2) os.environ["TINT2_BUTTON_ALIGNED_X1"] = "{}".format(button_x1) os.environ["TINT2_BUTTON_ALIGNED_Y1"] = "{}".format(button_y2) os.environ["TINT2_BUTTON_ALIGNED_X2"] = "{}".format(button_x2) os.environ["TINT2_BUTTON_ALIGNED_Y2"] = "{}".format(button_y2) self.execute("jgmenu_run") def applet_factory(applet, iid, data): if iid != "JgMenuApplet": return False JgMenu(applet) return True if __name__ == "__main__": MatePanelApplet.Applet.factory_main("JgMenuAppletFactory", True, MatePanelApplet.Applet.__gtype__, applet_factory, None) jgmenu-4.5.0/contrib/mate-panel/org.mate.panel.JgMenuApplet.mate-panel-applet000066400000000000000000000003761472613136300271000ustar00rootroot00000000000000[Applet Factory] Id=JgMenuAppletFactory Location=/home/johan/bin/mate-jgmenu.py Name=JGmenu Applet Factory Description=A JGmenu Applet Factory [JgMenuApplet] Name=JGMENU Description=A JGMENU Launcher Icon=mate MateComponentId=OAFIID:MATE_JgMenuApplet; jgmenu-4.5.0/contrib/mate-panel/org.mate.panel.applet.JgMenuAppletFactory.service000066400000000000000000000001441472613136300300370ustar00rootroot00000000000000[D-BUS Service] Name=org.mate.panel.applet.JgMenuAppletFactory Exec=/home/johan/bin/mate-jgmenu.py jgmenu-4.5.0/contrib/places/000077500000000000000000000000001472613136300157225ustar00rootroot00000000000000jgmenu-4.5.0/contrib/places/jgmenu-places.sh000077500000000000000000000014231472613136300210130ustar00rootroot00000000000000#!/bin/sh # # Inspired by the {a,b}l-places-pipemenu scripts found in # ArchLabs and BunsenLabs # : ${JGMENU_RESOURCE_OPENER=xdg-open} path=${1:-$HOME} path=${path%/} test -d "$path" || { echo "$0: '$path' is not a directory" >&2 ; exit 1 ; } for i in $path/* do test -e "$i" || continue shortname=${i##*/} if test -d "$i" then directories_menu="${directories_menu} ${shortname},^pipe(jgmenu_run places ${path}/${shortname})" else files_menu="$files_menu ${shortname},${JGMENU_RESOURCE_OPENER} ${path}/${shortname}" fi done printf "%b\n" "Browse here...,${JGMENU_RESOURCE_OPENER} ${path}" printf "%b\n" "^sep()" printf "%b\n" "${directories_menu}" printf "%b\n" "${files_menu}" if test -z "${directories_menu}" && test -z "${files_menu}" then printf "%b\n" '' fi jgmenu-4.5.0/contrib/pmenu/000077500000000000000000000000001472613136300155775ustar00rootroot00000000000000jgmenu-4.5.0/contrib/pmenu/Makefile000066400000000000000000000003571472613136300172440ustar00rootroot00000000000000-include ../../config.mk include ../../Makefile.inc pmenu: @: install: @install -d $(DESTDIR)$(libexecdir)/jgmenu @install -m775 jgmenu-pmenu.py $(DESTDIR)$(libexecdir)/jgmenu uninstall: @rm -f $(libexecdir)/jgmenu-pmenu.py clean: jgmenu-4.5.0/contrib/pmenu/jgmenu-pmenu.py000077500000000000000000000420271472613136300205700ustar00rootroot00000000000000#!/usr/bin/env python3 # # License: GPLv2 # # Copyright (C) 2016-2017 Ovidiu M # Copyright (C) 2017-2019 Johan Malm # import argparse import gettext import locale import os import sys strings = { "Back": "Back", "Back[am]": "ወደ ኋላ", "Back[ar]": "إلى الخلف", "Back[ast]": "Atrás", "Back[be]": "Назад", "Back[bg]": "Назад", "Back[bn]": "পূর্ববর্তী", "Back[ca]": "Endarrere", "Back[cs]": "Zpět", "Back[da]": "Tilbage", "Back[de]": "Zurück", "Back[el]": "Πίσω", "Back[eo]": "Malantaŭen", "Back[es]": "Atrás", "Back[et]": "Tagasi", "Back[eu]": "Atzera", "Back[fa_IR]": "بازگشت", "Back[fi]": "Edellinen", "Back[fr]": "Précédent", "Back[gl]": "Recuar", "Back[he]": "אחורה", "Back[hr]": "Natrag", "Back[hu]": "Vissza", "Back[id]": "Kembali", "Back[is]": "Til baka", "Back[it]": "Indietro", "Back[ja]": "戻る", "Back[kk]": "Артқа", "Back[ko]": "뒤로", "Back[lt]": "Atgal", "Back[lv]": "Atpakaļ", "Back[ms]": "Undur", "Back[nb]": "Tilbake", "Back[nl]": "Terug", "Back[nn]": "Tilbake", "Back[oc]": "Precedent", "Back[pa]": "ਪਿੱਛੇ", "Back[pl]": "Wstecz", "Back[pt_BR]": "Voltar", "Back[pt]": "Recuar", "Back[ro]": "Înapoi", "Back[ru]": "Назад", "Back[sk]": "Späť", "Back[sq]": "Prapa", "Back[sr]": "Назад", "Back[sv]": "Bakåt", "Back[te]": "వెనుకకు", "Back[th]": "ถอยกลับ", "Back[tr]": "Geri", "Back[ug]": "ئارقىسىغا", "Back[uk]": "Назад", "Back[ur_PK]": "پیچھے", "Back[ur]": "پیچھے", "Back[vi]": "Quay lui", "Back[zh_CN]": "后退", "Back[zh_HK]": "往前", "Back[zh_TW]": "往前", "Other": "Other", "Other[af]": "Ander", "Other[ar]": "أخرى", "Other[as]": "অন্যান্য", "Other[ast]": "Otres", "Other[be]": "Іншыя", "Other[be@latin]": "Inšyja", "Other[bg]": "Други", "Other[bn]": "অন্যান্য", "Other[bn_IN]": "অন্যান্য", "Other[br]": "All", "Other[ca]": "Altres", "Other[cs]": "Ostatní", "Other[cy]": "Eraill", "Other[da]": "Andre", "Other[de]": "Sonstige", "Other[dz]": "གཞན།", "Other[el]": "Άλλα", "Other[en_CA]": "Other", "Other[en_GB]": "Other", "Other[eo]": "Alia", "Other[es]": "Otras", "Other[es_VE]": "Otras", "Other[et]": "Muu", "Other[eu]": "Bestelakoak", "Other[fa]": "غیره", "Other[fi]": "Muut", "Other[fr]": "Autre", "Other[frp]": "Autres", "Other[fur]": "Altri", "Other[ga]": "Eile", "Other[gl]": "Outros", "Other[gn]": "Amboae", "Other[gu]": "અન્ય", "Other[he]": "אחר", "Other[hi]": "अन्य", "Other[hr]": "Ostalo", "Other[hu]": "Egyéb", "Other[hy]": "Այլ", "Other[id]": "Lainnya", "Other[io]": "Altra", "Other[is]": "Aðrir", "Other[it]": "Altro", "Other[ja]": "その他", "Other[ka]": "სხვა", "Other[kk]": "Басқалар", "Other[ko]": "기타", "Other[ku]": "Yên din", "Other[ky]": "Башкалар", "Other[lt]": "Kitos", "Other[lv]": "Citas programmas", "Other[mai]": "आन", "Other[mg]": "Hafa", "Other[mk]": "Други", "Other[ml]": "മറ്റുളളവ", "Other[mn]": "Бусад", "Other[mr]": "अन्य", "Other[ms]": "Lain-lain", "Other[nb]": "Annet", "Other[ne]": "अन्य", "Other[nl]": "Overig", "Other[nn]": "Andre", "Other[oc]": "Autre", "Other[or]": "ଅନ୍ଯାନ୍ଯ", "Other[pa]": "ਹੋਰ", "Other[pl]": "Inne", "Other[ps]": "نور", "Other[pt]": "Outras", "Other[pt_BR]": "Outros", "Other[ro]": "Altele", "Other[ru]": "Прочие", "Other[rw]": "Ikindi", "Other[si]": "වෙනත්", "Other[sk]": "Ostatné", "Other[sl]": "Drugo", "Other[sq]": "Tjetër", "Other[sr]": "Остало", "Other[sr@latin]": "Ostalo", "Other[sv]": "Övriga", "Other[ta]": "மற்றவை", "Other[te]": "ఇతర", "Other[th]": "อื่นๆ", "Other[tr]": "Diğer", "Other[ug]": "باشقىلار", "Other[uk]": "Інші", "Other[ur]": "دیگر", "Other[ur_PK]": "دیگر", "Other[uz@cyrillic]": "Бошқа", "Other[vi]": "Khác", "Other[xh]": "Ezinye", "Other[zh_CN]": "其它", "Other[zh_HK]": "其它", "Other[zh_TW]": "其它" } # Computes a list of the current locale names, in most specific to least specific order. # The empty string is always the last element. def get_current_locale_names(): # E.g. "en_US" lang = locale.getlocale()[0] or "en_US" # ["en", "US"] lang_parts = lang.split("_") locale_names = [""] for i in range(len(lang_parts)): locale_names.append("_".join(lang_parts[:i+1])) # ["en_US", "en", ""] locale_names = list(reversed(locale_names)) return locale_names def internationalized(entry): # Now entry is a dict of tag -> value, with tag like "Name", "Name[en]", "Name[en_US]" # We modify it so that the value of "Name" is replaced with the value of the most specific tag # that matches the current locale. # We create a two-level tree: # tag => name, suffix => value # Where name is the tag name (e.g. "Name") and suffix is the tag's locale (e.g. "en_US" or ""). tree = {} for tag in entry: if "[" in tag: name, suffix = tag.replace("]", "").split("[", 1) else: name = tag suffix = "" if name not in tree: tree[name] = {} tree[name][suffix] = entry[tag] # Collapse into a tag => value dict, using the most specific matching suffix. # Keep the old names in keys with the value "_pmenu_raw_" + tag locale_names = get_current_locale_names() entry = {} for name in tree: if "" in tree[name]: entry["_pmenu_raw_" + name] = tree[name][""] for suffix in locale_names: if suffix in tree[name]: entry[name] = tree[name][suffix] if not suffix and entry[name]: entry[name] = _(entry[name]) break return entry # Reference: http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html # Loads a Desktop Entry file into a dictionary key -> value # A special key "_path" stores the path of the file def read_desktop_entry(path): entry = {} try: with open(path, "r", encoding="utf-8") as f: lines = f.read().split("\n") inside = False for line in lines: if line.startswith("["): inside = line == "[Desktop Entry]" continue if inside: if "=" in line: k, v = line.split("=", 1) if k == "NoDisplay" and v == "true": return {} entry[k] = v except UnicodeDecodeError: print("warn: ignoring '{}' as it is unicode (utf-8 needed)".format(path), file=sys.stderr) except: print("warn: error reading '{}'".format(path), file=sys.stderr) entry["_path"] = path return internationalized(entry) # Reference: http://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html # Reference: http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html def get_setting_locations(): locations = [] locations.append(os.path.expanduser("~/.local/share")) if "XDG_DATA_DIRS" in os.environ: dirs = os.environ["XDG_DATA_DIRS"] if dirs: dirs = dirs.split(":") for d in dirs: while d.endswith("/"): d = d[:-1] if d not in locations: locations.append(d) locations.append("/usr/share") locations.append("/usr/local/share") return locations # Loads all Desktop Entry files with type "Directory" into a dictionary name -> entry # Reference: http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html def load_categories(): categories = {} for d in get_setting_locations(): d = d + "/desktop-directories/" for (dirpath, dirnames, filenames) in os.walk(d): for filename in filenames: entry = read_desktop_entry(os.path.join(dirpath, filename)) if "_pmenu_raw_Name" in entry and "Type" in entry and entry["Type"] == "Directory": categories[normalize_category(entry["_pmenu_raw_Name"])[-1]] = entry if "Other" not in categories: categories["Other"] = {"Name": strings["Other"], "Icon": "applications-other", "_path": "auto-generated"} return categories # Returns a list of alternate, more generic categories for a given category name # Reference: http://standards.freedesktop.org/menu-spec/latest/apas02.html def normalize_category(c): if c in ["Network", "Email", "Dialup", "InstantMessaging", "Chat", "IRCClient", "Feed", "FileTransfer", "HamRadio", "News", "P2P", "RemoteAccess", "Telephony", "TelephonyTools", "VideoConference", "WebBrowser"]: return [c, "Internet"] if c in ["Game", "ActionGame", "AdventureGame", "ArcadeGame", "BoardGame", "BlocksGame", "CardGame", "KidsGame", "LogicGame", "RolePlaying", "Shooter", "Simulation", "SportsGame", "StrategyGame", "Sports", "Amusement"]: return [c, "Games"] if c in ["Utility", "TextTool", "TextTools", "Archiving", "Compression", "FileTool", "FileTools", "Calculator", "Clock", "TextEditor"]: return [c, "Accessories", "Utilities"] if c in ["Building", "Debugger", "IDE", "GUIDesigner", "Profiling", "RevisionControl", "Translation", "WebDevelopment", "ParallelComputing", "Database", "ArtificialIntelligence"]: return [c, "Development"] if c in ["Calendar", "ContactManagement", "Dictionary", "Chart", "Finance", "FlowChart", "PDA", "ProjectManagement", "Presentation", "Spreadsheet", "WordProcessor", "Publishing", "Viewer"]: return [c, "Office"] if c in ["2DGraphics", "VectorGraphics", "RasterGraphics", "3DGraphics", "Scanning", "OCR", "Photography", "ImageProcessing"]: return [c, "Graphics"] if c in ["AudioVideo", "Player", "Audio", "Video", "Midi", "Mixer", "Sequencer", "Tuner", "TV", "AudioVideoEditing", "Recorder", "DiscBurning", "Adult"]: return [c, "Multimedia", "Sound & Video"] if c in ["Construction", "Astronomy", "Biology", "Chemistry", "ComputerScience", "DataVisualization", "Economy", "Electricity", "Geography", "Geology", "Geoscience", "Maps", "Math", "NumericalAnalysis", "MedicalSoftware", "Physics", "Robotics", "Electronics", "Engineering"]: return [c, "Science"] if c in ["Literature", "Art", "Languages", "History", "Humanities", "Spirituality"]: return [c, "Education", "Science"] if c in ["Emulator", "FileManager", "TerminalEmulator", "Filesystem", "Monitor"]: return [c, "System"] if c in ["Settings", "Security", "Accessibility"]: return [c, "Preferences"] return [c] # Returns a list of suggested categories for a given application name (useful if no category is specified or found) def suggest_categories(app_name): app_name = app_name.lower() if "network" in app_name or "google" in app_name or "cisco" in app_name or "mail" in app_name or "youtube" in app_name: return normalize_category("Network") return ["Other"] def get_cmd(app): if "Exec" in app: cmd = "" if "Path" in app and app["Path"]: cmd += "cd " + app["Path"] + ";" exe = "" percent = False for c in app["Exec"]: if not percent: if c == "%": percent = True else: exe += c else: if c == "%": exe += c percent = False else: pass cmd += exe if "Terminal" in app and app["Terminal"] == "true": cmd = "^term(" + cmd.strip() + ")" return cmd return None # Returns the start menu hierarchy and the main application categories # The menu is a dictionary category-name -> list of application entries # The categories are in the same form as returned by load_categories() def load_applications(hide_dirs): if hide_dirs: menu = [] else: menu = {} categories = load_categories() all_filenames = [] # keep track of filenames to respect user overrides for d in get_setting_locations(): d = d + "/applications/" for (dirpath, dirnames, filenames) in os.walk(d): for filename in filenames: if filename in all_filenames: continue all_filenames.append(filename) entry = read_desktop_entry(os.path.join(dirpath, filename)) cmd = get_cmd(entry) if "Type" in entry and entry["Type"] == "Application" and cmd: entry["cmd"] = cmd if "Name" not in entry: entry["Name"] = filename.replace(".desktop", "") entry["Name"] = entry["Name"][:1].upper() + entry["Name"][1:] if hide_dirs: menu.append(entry) continue app_categories = [] if "Categories" in entry: app_categories = [s.strip() for s in entry["Categories"].split(";") if s.strip()] app_categories.append("") added = False for c in app_categories: options = [] if c: if c not in categories: options = normalize_category(c) else: options = [c] else: try: options = suggest_categories(entry["_pmenu_raw_Name"]) except: print("warn: no 'Name' key in file '{}'".format(entry["_path"]), file=sys.stderr) for o in options: if o in categories: if o not in menu: menu[o] = [] menu[o].append(entry) added = True break if added: break if not hide_dirs: for c in menu: menu[c] = sorted(menu[c], key=lambda item: item["Name"]) if hide_dirs: return menu else: return menu, categories def cat_file(path): if path and os.path.isfile(path): with open(path, encoding='utf-8') as data_file: print(data_file.read()) def escape_markup(s): return s.replace("&", "&") # Creates the menu with directories def create_menu(arg_append_file, arg_prepend_file): single_window = os.getenv("JGMENU_SINGLE_WINDOW") # print("jgmenu,^tag(pmenu)") cat_file(arg_prepend_file) tree, categories = load_applications(False) # If no menu-package exists, just dump the apps in the menu-root if len(categories) <= 1: for app in tree['Other']: icon = app["Icon"] if "Icon" in app else "" print(escape_markup(app["Name"]) + "," + app["cmd"] + "," + icon) cat_file(arg_append_file) print("warn: no menu package found; displaying apps without directories", file=sys.stderr) return for c in sorted(tree): category = categories[c] icon = category["Icon"] if "Icon" in category else "folder" try: if single_window: print(escape_markup(category["Name"]) + ",^root(" + category["Name"] + ")," + icon) else: print(escape_markup(category["Name"]) + ",^checkout(" + category["Name"] + ")," + icon) except: print("warn: category problem", file=sys.stderr) cat_file(arg_append_file) for c in sorted(tree): category = categories[c] print("") print("#", category["_path"]) print("submenu,^tag(" + category["Name"] + ")") print(strings["Back"] + ",^back(),go-previous") for app in tree[c]: icon = app["Icon"] if "Icon" in app else "application-x-executable" print("#", app["_path"]) print(escape_markup(app["Name"]) + "," + app["cmd"] + "," + icon) # Creates menu without directories def create_menu_no_dirs(arg_append_file, arg_prepend_file): cat_file(arg_prepend_file) menu = load_applications(True) for app in sorted(menu, key=lambda k: k['Name']): icon = app["Icon"] if "Icon" in app else "application-x-executable" print("#", app["_path"]) print(escape_markup(app["Name"]) + "," + app["cmd"] + "," + icon) cat_file(arg_append_file) def setup_gettext(): global _ try: gettext.translation("gnome-menus-3.0", languages=get_current_locale_names()).install() except: try: gettext.translation("gnome-menus", languages=get_current_locale_names()).install() except: pass try: _("") except: def _(s): return s def main(): global strings parser = argparse.ArgumentParser(prog="jgmenu_run pmenu") parser.add_argument("--append-file", help="Path to menu file to append to the root menu", metavar="FILE") parser.add_argument("--prepend-file", help="Path to menu file to prepend to the root menu", metavar="FILE") parser.add_argument("--locale", help="Use a custom locale (e.g. 'en_US.UTF-8'; available locales can be shown " + "by running 'locale -a')", default="") args = parser.parse_args() if args.append_file: append_file = args.append_file else: append_file = os.getenv("HOME") + "/.config/jgmenu/append.csv" if args.prepend_file: prepend_file = args.prepend_file else: prepend_file = os.getenv("HOME") + "/.config/jgmenu/prepend.csv" try: locale.setlocale(locale.LC_ALL, args.locale) except: print("Warning: setting locale failed! Use an available locale as listed by 'locale -a'.", file=sys.stderr) setup_gettext() strings = internationalized(strings) if os.getenv("JGMENU_NO_DIRS"): create_menu_no_dirs(append_file, prepend_file) else: create_menu(append_file, prepend_file) if __name__ == '__main__': main() jgmenu-4.5.0/contrib/tasks/000077500000000000000000000000001472613136300156005ustar00rootroot00000000000000jgmenu-4.5.0/contrib/tasks/jgmenu-tasks.sh000077500000000000000000000037771472613136300205650ustar00rootroot00000000000000#!/bin/bash # # Copyright (C) Bunsenlabs' misko_2083 # Copied with permission from # https://forums.bunsenlabs.org/viewtopic.php?pid=68098#p68098 # # This script requires imagemagick, xprop, xdotool and wmctrl # # Temp dir to store the icons TMPDIR=$(mktemp -d /tmp/XXXXXX) trap "rm -rf $TMPDIR" EXIT # With process substitution output from "wmctrl -l" is redirected to file descriptor 3 # while loop reads "win_id" and "display" variables from file descriptor 3 while read -r win_id display text <&3 do # filter windows with win_id that has X window properties of type normal or dialog if xprop -id $win_id | grep -e "^_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL" \ -e "^_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DIALOG" &>/dev/null then # Get WM_CLASS X window property wm_class=$(xprop -id $win_id WM_CLASS | awk -F'"' '{print $4}') if hash convert &>/dev/null;then # Convert icon to pam then use imagemagic to convert to png xprop -notype 32c -id $win_id _NET_WM_ICON \ | perl -0777 -pe '@_=/\d+/g; printf "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", splice@_,0,2; $_=pack "N*", @_; s/(.)(...)/$2$1/gs' \ | convert pam:- $TMPDIR/$wm_class.png 2>/dev/null fi # if WM_CLASS is a "Wrapper" if [[ "${wm_class}" == "Wrapper" ]] then # Get WM_CLASS X window property _NET_WM_NAME wm_class=$(xprop -id $win_id _NET_WM_NAME | awk -F '"' '{print $2}') echo "\"\"\"$display $text\"\"\",xdotool windowactivate $win_id,xfwm4" else # print echo "\"\"\"$display $text\"\"\",xdotool windowactivate $win_id,$TMPDIR/$wm_class.png" fi fi done 3< <(wmctrl -l | awk '{print $1,$2,substr($0, index($0,$4), 28)}') | jgmenu --simple --at-pointer # Close file descriptor 3 exec 3<&- exit jgmenu-4.5.0/contrib/unicode-icons/000077500000000000000000000000001472613136300172125ustar00rootroot00000000000000jgmenu-4.5.0/contrib/unicode-icons/jgmenu-unicode-icons.sh000077500000000000000000000042141472613136300235740ustar00rootroot00000000000000#!/bin/bash # This is a template script that makes it easy to generate a menu with hand-picked # Unicode glyphs (from Font Awesome and the like) acting as icons, with # their size and alignment being separated from actual labels. # The script should be set as a CSV source in the jgmenurc config file, # i.e.: csv_cmd = bash ~/.config/jgmenu/jgmenu-unicode-icons.sh readonly defaultIconFont="FontAwesome" readonly defaultIconSize="15px" readonly defaultIconLeftOffset="0px" readonly defaultIconRightOffset="6px" readonly defaultIconVerticalOffset="-2px" formatSpacing() { local output output+="" for i in $(seq 1 ${1::-2}); do output+=" " done output+="" echo -n "$output" } formatIconAndLabel() { local icon="$1" local iconFont="$2" # optional local iconSize="$3" # optional local iconLeftOffset="$4" # optional local iconRightOffset="$5" # optional local iconVerticalOffset="$6" # optional local label="$7" [[ -z "$iconFont" ]] && iconFont="$defaultIconFont" [[ -z "$iconSize" ]] && iconSize="$defaultIconSize" [[ -z "$iconLeftOffset" ]] && iconLeftOffset="$defaultIconLeftOffset" [[ -z "$iconRightOffset" ]] && iconRightOffset="$defaultIconRightOffset" [[ -z "$iconVerticalOffset" ]] && iconVerticalOffset="$defaultIconVerticalOffset" local iconRise=$(echo "${iconVerticalOffset::-2} * 0.0625 * 10000 / 1" | bc) local output output+="$(formatSpacing $iconLeftOffset)" output+="$icon" output+="$(formatSpacing $iconRightOffset)" output+="$label" echo -n "$output" } echo -n "\ $(formatIconAndLabel "" "" "" "" "" "" "Example label 1"), example_command_1 $(formatIconAndLabel "" "" "" "" "" "" "Example label 2"), example_command_2 $(formatIconAndLabel "" "" "" "" "7px" "" "Example label 3"), example_command_3 $(formatIconAndLabel "" "" "" "5px" "10px" "" "Example label 4"), example_command_4 " # Note: The default values of horizontal icon offsets for the 3rd and 4th entry # have been overriden. That's because glyphs used in these entries have variable width. jgmenu-4.5.0/contrib/xdg/000077500000000000000000000000001472613136300152355ustar00rootroot00000000000000jgmenu-4.5.0/contrib/xdg/.gitignore000066400000000000000000000000131472613136300172170ustar00rootroot00000000000000jgmenu-xdg jgmenu-4.5.0/contrib/xdg/Makefile000066400000000000000000000004411472613136300166740ustar00rootroot00000000000000CC = gcc CFLAGS = -g -Wall CFLAGS += `xml2-config --cflags` LIBS += `xml2-config --libs` path = ../../src/ src = util.c sbuf.c xdgdirs.c argv-buf.c charset.c compat.c jgmenu-xdg: jgmenu-xdg.c xdgapps.c $(CC) $(CFLAGS) -o $@ $^ $(addprefix $(path),$(src)) -I$(path) $(LIBS) jgmenu-4.5.0/contrib/xdg/jgmenu-xdg.c000066400000000000000000000240371472613136300174540ustar00rootroot00000000000000/* * jgmenu-xdg.c * * Parses XML .menu file and outputs a csv formatted jgmenu file * * See this spec for further details: * https://specifications.freedesktop.org/menu-spec/menu-spec-1.0.html * * Generate jgmenu flavoured CSV menu data for an XDGish menu * * `jgmenu_run xdg` \[--no-dirs] \[<*.menu file*>] * * `jgmenu_run xdg` generates jgmenu flavoured CSV menu data for a menu * based on XML .menu files loosely in accordance with the XDG spec: * * http://standards.freedesktop.org/menu-spec/ * http://standards.freedesktop.org/basedir-spec/ * http://standards.freedesktop.org/desktop-entry-spec/ * http://standards.freedesktop.org/desktop-entry-spec/ * * `jgmenu_run xdg` is a very simple XDG implementation. * It understands the XML elements <*Menu*>, <*Name*>, <*Directory*> * and <*Include*><*And*><*Category*>, but ignores everything else. * * The .menu file is sought in `${XDG_CONFIG_DIRS:-/etc/xdg}` with * user configuration override in `${XDG_CONFIG_HOME:-$HOME/.config}` * * `$XDG_MENU_PREFIX` can be used to specity a .menu file. For example * `$XDG_MENU_PREFIX=lxde-` will load lxde-applications.menu * This can be useful if there are several .menu files on the system. * * \--no-dirs * : ignore .menu and .directory files */ #include #include #include #include #include #include "xdgapps.h" #include "util.h" #include "sbuf.h" #include "xdgdirs.h" #define DEBUG_PRINT_XML_NODES 0 /* * In jgmenu-speak: * - A "node" is a root-menu or a submenu. * It corresponds roughly to an XML element. * - An "item" is a individual menu entry (with name, command and icon) * These are defined by "categories", .desktop-files, etc */ struct jgmenu_node { char *name; char *tag; char *directory; int level; struct jgmenu_node *parent; struct list_head category_includes; struct list_head category_excludes; struct list_head categories; struct list_head desktop_files; struct list_head menu_items; struct list_head list; }; struct jgmenu_item { char *name; char *cmd; char *icon_name; struct list_head list; }; static LIST_HEAD(jgmenu_nodes); static struct jgmenu_node *current_jgmenu_node; static void print_menu_item(struct jgmenu_item *item) { printf("%s,", item->name); if (item->cmd) printf("%s", item->cmd); if (item->icon_name) printf(",%s", item->icon_name); printf("\n"); } static void print_csv_menu(void) { struct jgmenu_node *n; struct jgmenu_item *item; list_for_each_entry(n, &jgmenu_nodes, list) { if (list_empty(&n->menu_items)) continue; if (!n->parent) { cat("~/.config/jgmenu/prepend.csv"); } else { printf("%s,^tag(%s)\n", n->name, n->tag); printf("Go back,^back(),folder\n"); } /* Print directories first */ list_for_each_entry(item, &n->menu_items, list) if (item->cmd && !strncmp(item->cmd, "^checkout", 9)) print_menu_item(item); /* Then all other items */ list_for_each_entry(item, &n->menu_items, list) if (!item->cmd || strncmp(item->cmd, "^checkout", 9)) print_menu_item(item); printf("\n"); if (!n->parent) cat("~/.config/jgmenu/append.csv"); } } static void init_jgmenu_item(struct jgmenu_item *item) { item->name = NULL; item->cmd = NULL; item->icon_name = NULL; } static void add_item_to_jgmenu_node(struct jgmenu_node *node, struct desktop_file_data *data) { struct jgmenu_item *item; item = xmalloc(sizeof(struct jgmenu_item)); init_jgmenu_item(item); if (data->name) item->name = strdup(data->name); if (data->exec) item->cmd = strdup(strstrip(data->exec)); if (data->icon) item->icon_name = strdup(data->icon); list_add_tail(&item->list, &node->menu_items); } static void add_dir_to_jgmenu_node(struct jgmenu_node *parent, const char *name, const char *tag) { struct jgmenu_item *item; struct sbuf s; if (!name || !tag) die("no name or tag specified in add_dir_to_jgmenu_node()"); if (!parent) return; sbuf_init(&s); sbuf_addstr(&s, "^checkout("); sbuf_addstr(&s, tag); sbuf_addstr(&s, ")"); item = xmalloc(sizeof(struct jgmenu_item)); init_jgmenu_item(item); item->name = strdup(name); item->cmd = strdup(s.buf); item->icon_name = strdup("folder"); list_add_tail(&item->list, &parent->menu_items); } /* TODO: This needs to be changed to categories rather than category_includes */ static void process_categories_and_populate_desktop_files(void) { struct jgmenu_node *jgmenu_node; struct desktop_file_data *desktop_file; struct sbuf *cat; list_for_each_entry(jgmenu_node, &jgmenu_nodes, list) { list_for_each_entry(cat, &jgmenu_node->category_includes, list) { xdgapps_filter_desktop_files_on_category(cat->buf); list_for_each_entry(desktop_file, &desktop_files_filtered, filtered_list) add_item_to_jgmenu_node(jgmenu_node, desktop_file); } } } /* * For each directory within a , a menu item is added to the * _parent_ jgmenu node. This is slighly counter intuitive, but it's just * how it is. * * TODO: Throw error if .directory file does not exist */ static void process_directory_files(void) { struct jgmenu_node *jgmenu_node; struct directory_file_data *directory_file; list_for_each_entry(jgmenu_node, &jgmenu_nodes, list) { if (list_empty(&jgmenu_node->menu_items)) continue; list_for_each_entry(directory_file, &directory_files, list) if (!strcmp(directory_file->filename, jgmenu_node->directory)) add_dir_to_jgmenu_node(jgmenu_node->parent, jgmenu_node->name, jgmenu_node->tag); } } static void add_data_to_jgmenu_node(const char *xml_node_name, const char *content) { struct jgmenu_node *jgmenu_node; struct sbuf *category; jgmenu_node = current_jgmenu_node; /* TODO: Lots to be added here */ /* TODO: Check for tag duplicates */ if (!strcasecmp(xml_node_name, "Name")) { jgmenu_node->name = strdup(content); jgmenu_node->tag = strdup(content); } else if (!strcasecmp(xml_node_name, "Directory")) { jgmenu_node->directory = strdup(content); } else if (!strcasecmp(xml_node_name, "Include.And.Category")) { category = xmalloc(sizeof(struct sbuf)); sbuf_init(category); sbuf_addstr(category, content); list_add_tail(&category->list, &jgmenu_node->category_includes); } if (DEBUG_PRINT_XML_NODES) printf("%d-%s: %s\n", jgmenu_node->level, xml_node_name, content); } static void create_new_jgmenu_node(struct jgmenu_node *parent, int level) { struct jgmenu_node *node; if (DEBUG_PRINT_XML_NODES) printf("---\n"); node = xcalloc(1, sizeof(struct jgmenu_node)); node->name = NULL; node->tag = NULL; node->directory = NULL; node->level = level; if (parent) node->parent = parent; else node->parent = NULL; INIT_LIST_HEAD(&node->category_includes); INIT_LIST_HEAD(&node->category_excludes); INIT_LIST_HEAD(&node->categories); INIT_LIST_HEAD(&node->desktop_files); INIT_LIST_HEAD(&node->menu_items); list_add_tail(&node->list, &jgmenu_nodes); current_jgmenu_node = node; } static int level(xmlNode *node) { int level = 0; for (;;) { node = node->parent; if (!node || !node->name) return level; if (!strcasecmp((char *)node->name, "Menu")) ++level; } } /* * Gives the node name back to the parent "Menu" element. * For example, it would convert * to * "Include.And.Category" */ static void get_full_node_name(struct sbuf *node_name, xmlNode *node) { int ismenu; if (!strcmp((char *)node->name, "text")) { node = node->parent; if (!node || !node->name) { fprintf(stderr, "warning: node is root\n"); return; } } ismenu = !strcmp((char *)node->name, "Menu"); for (;;) { if (!ismenu) sbuf_prepend(node_name, (char *)node->name); node = node->parent; if (!node || !node->name) return; ismenu = !strcmp((char *)node->name, "Menu"); if (!ismenu) sbuf_prepend(node_name, "."); } } static void process_node(xmlNode *node) { struct sbuf node_name; /* * Just filtering out a lot of rubbish here for the time being. * We will need to check for etc. */ if (!node->content) return; sbuf_init(&node_name); get_full_node_name(&node_name, node); if (node_name.len && strlen(strstrip((char *)node->content))) add_data_to_jgmenu_node(node_name.buf, strstrip((char *)node->content)); free(node_name.buf); } static void revert_to_parent(void) { if (current_jgmenu_node && current_jgmenu_node->parent) current_jgmenu_node = current_jgmenu_node->parent; } /* * n->next refers to siblings * n->children is obviously the children */ static void xml_tree_walk(xmlNode *node) { xmlNode *n; for (n = node; n; n = n->next) { if (!strcasecmp((char *)n->name, "Menu")) { create_new_jgmenu_node(current_jgmenu_node, level(n)); xml_tree_walk(n->children); revert_to_parent(); continue; } if (!strcasecmp((char *)n->name, "Comment")) continue; process_node(n); xml_tree_walk(n->children); } } static void parse_xml(const char *filename) { xmlDoc *d = xmlReadFile(filename, NULL, 0); if (!d) die("error reading file '%s'\n", filename); xml_tree_walk(xmlDocGetRootElement(d)); xmlFreeDoc(d); xmlCleanupParser(); } static void print_desktop_files(void) { struct desktop_file_data *f; cat("~/.config/jgmenu/prepend.csv"); list_for_each_entry(f, &desktop_files_all, full_list) if (f->name) printf("%s,%s,%s\n", f->name, f->exec, f->icon); cat("~/.config/jgmenu/append.csv"); } int main(int argc, char **argv) { struct sbuf filename; int i; int no_dirs = 0; sbuf_init(&filename); LIBXML_TEST_VERSION /* Create lists of .desktop- and .directory files */ xdgapps_init_lists(); i = 1; while (i < argc) { if (argv[i][0] != '-') sbuf_cpy(&filename, argv[i]); else if (!strncmp(argv[i], "--no-dirs", 9)) no_dirs = 1; else die("unknown option '%s'", argv[i]); i++; } if (no_dirs) { print_desktop_files(); goto out; } if (!filename.len) xdgdirs_find_menu_file(&filename); if (!filename.len) die("cannot find menu-file"); info("parsing menu file '%s'", filename.buf); parse_xml(filename.buf); process_categories_and_populate_desktop_files(); process_directory_files(); print_csv_menu(); out: xfree(filename.buf); return 0; } jgmenu-4.5.0/contrib/xdg/t0007-xdgapps.c000066400000000000000000000007721472613136300176250ustar00rootroot00000000000000#include #include "../xdgapps.h" #include "../sbuf.h" #include "../list.h" int main(int argc, char **argv) { struct desktop_file_data *desktop_file; xdgapps_init_lists(); /* list_for_each_entry(desktop_file, &desktop_files_all, full_list) */ printf("Development:\n"); xdgapps_filter_desktop_files_on_category("Development"); list_for_each_entry(desktop_file, &desktop_files_filtered, filtered_list) printf("%s,%s,%s\n", desktop_file->name, desktop_file->exec, desktop_file->icon); } jgmenu-4.5.0/contrib/xdg/xdgapps.c000066400000000000000000000100101472613136300170370ustar00rootroot00000000000000/* * xdgapps.c creates cache for .desktop- and .directory-files */ #include #include #include #include #include "xdgapps.h" #include "xdgdirs.h" #include "util.h" #include "sbuf.h" #include "list.h" #include "charset.h" #include "compat.h" struct list_head desktop_files_all; struct list_head desktop_files_filtered; struct list_head directory_files; /* "${HOME}/.local/share", "/usr/share", etc. */ static struct list_head xdg_data_dirs; static int parse_directory_file(FILE *fp, const char *filename) { char line[BUFSIZ]; char *p; struct directory_file_data *tmp; tmp = xcalloc(1, sizeof(struct directory_file_data)); tmp->filename = strdup(filename); while (fgets(line, sizeof(line), fp)) { if (line[0] == '\0') continue; p = strrchr(line, '\n'); if (!p) continue; *p = '\0'; if (!utf8_validate(line, p - &line[0])) return -1; if (!strncmp("Name=", line, 5)) tmp->name = strdup(line + 5); else if (!strncmp("Icon=", line, 5)) tmp->icon = strdup(line + 5); } list_add_tail(&tmp->list, &directory_files); return 0; } static int parse_desktop_file(FILE *fp) { char line[BUFSIZ]; char *p; struct desktop_file_data *tmp; tmp = xcalloc(1, sizeof(struct desktop_file_data)); while (fgets(line, sizeof(line), fp)) { if (line[0] == '\0') continue; p = strrchr(line, '\n'); if (!p) continue; *p = '\0'; if (!utf8_validate(line, p - &line[0])) return -1; /* A bit crude, but prevents loading other Exec values */ if ((line[0] == '[') && strcmp(line, "[Desktop Entry]")) break; if (!strncmp("Name=", line, 5)) tmp->name = strdup(line + 5); else if (!strncmp("Exec=", line, 5)) tmp->exec = strdup(line + 5); else if (!strncmp("Icon=", line, 5)) tmp->icon = strdup(line + 5); else if (!strncmp("Categories=", line, 11)) tmp->categories = strdup(line + 11); } /* Remove %U, %f, etc at the end of Exec cmd */ if (tmp->exec) { p = strchr(tmp->exec, '%'); if (p) *p = '\0'; } list_add_tail(&tmp->full_list, &desktop_files_all); return 0; } static void process_file(char *filename, const char *path, int isdir) { FILE *fp; char fullname[4096]; int ret; size_t len; len = strlen(path); strlcpy(fullname, path, sizeof(fullname)); strlcpy(fullname + len, filename, sizeof(fullname) - len); fp = fopen(fullname, "r"); if (!fp) { warn("could not open file %s", filename); return; } if (isdir) ret = parse_directory_file(fp, filename); else ret = parse_desktop_file(fp); fclose(fp); if (ret < 0) warn("file '%s' is not utf-8 compatible", filename); } /* * isdir=0 will process .desktop files * isdir=1 will process .directory files */ static void populate_desktop_and_directory_lists(const char *path, int isdir) { struct dirent *entry; DIR *dp; dp = opendir(path); if (!dp) return; while ((entry = readdir(dp))) { if (!strncmp(entry->d_name, ".", 1) || !strncmp(entry->d_name, "..", 2)) continue; process_file(entry->d_name, path, isdir); } closedir(dp); } void xdgapps_init_lists(void) { struct sbuf *dir; struct sbuf s; INIT_LIST_HEAD(&desktop_files_all); INIT_LIST_HEAD(&desktop_files_filtered); INIT_LIST_HEAD(&directory_files); INIT_LIST_HEAD(&xdg_data_dirs); xdgdirs_get_datadirs(&xdg_data_dirs); sbuf_init(&s); list_for_each_entry(dir, &xdg_data_dirs, list) { sbuf_cpy(&s, dir->buf); sbuf_addstr(&s, "/applications/"); populate_desktop_and_directory_lists(s.buf, 0); } list_for_each_entry(dir, &xdg_data_dirs, list) { sbuf_cpy(&s, dir->buf); sbuf_addstr(&s, "/desktop-directories/"); populate_desktop_and_directory_lists(s.buf, 1); } } void xdgapps_filter_desktop_files_on_category(const char *category) { struct desktop_file_data *a, *pos; list_for_each_entry_safe(pos, a, &desktop_files_filtered, filtered_list) list_del(&pos->filtered_list); list_for_each_entry(a, &desktop_files_all, full_list) { if (!a->name || !a->categories) continue; if (strstr(a->categories, category)) list_add_tail(&a->filtered_list, &desktop_files_filtered); } } jgmenu-4.5.0/contrib/xdg/xdgapps.h000066400000000000000000000010641472613136300170550ustar00rootroot00000000000000#ifndef XDGAPPS_H #define XDGAPPS_H #include "list.h" struct desktop_file_data { char *name; char *exec; char *icon; char *categories; struct list_head full_list; struct list_head filtered_list; }; struct directory_file_data { char *filename; char *name; char *icon; struct list_head list; }; extern struct list_head desktop_files_all; extern struct list_head desktop_files_filtered; extern struct list_head directory_files; void xdgapps_init_lists(void); void xdgapps_filter_desktop_files_on_category(const char *category); #endif /* XDGAPPS_H */ jgmenu-4.5.0/contrib/xfce4-panel/000077500000000000000000000000001472613136300165615ustar00rootroot00000000000000jgmenu-4.5.0/contrib/xfce4-panel/.gitignore000066400000000000000000000000151472613136300205450ustar00rootroot00000000000000libjgmenu.so jgmenu-4.5.0/contrib/xfce4-panel/Makefile000066400000000000000000000014651472613136300202270ustar00rootroot00000000000000-include ../../config.mk include ../../Makefile.inc libdir ?= `pkg-config --variable=libdir libxfce4panel-2.0` LIBDIR = $(DESTDIR)$(libdir)/xfce4/panel/plugins PLUGIN_DIR = $(DESTDIR)$(prefix)/share/xfce4/panel/plugins CFLAGS += -Wno-strict-prototypes -Wno-declaration-after-statement CFLAGS += -s -shared -fPIC CFLAGS += `pkg-config --cflags libxfce4panel-2.0` LDFLAGS += `pkg-config --libs libxfce4panel-2.0` xfce4-panel: libjgmenu.so libjgmenu.so: jgmenu-applet.c $(QUIET_CC)$(CC) $(CFLAGS) -o libjgmenu.so jgmenu-applet.c $(LDFLAGS) install: @install -d $(LIBDIR) @install -m644 libjgmenu.so $(LIBDIR) @install -d $(PLUGIN_DIR) @install -m644 jgmenu-applet.desktop $(PLUGIN_DIR) uninstall: @rm -f $(LIBDIR)/libjgmenu.so @rm -f $(PLUGIN_DIR)/jgmenu-applet.desktop clean: @rm -f libjgmenu.so jgmenu-4.5.0/contrib/xfce4-panel/README000066400000000000000000000002061472613136300174370ustar00rootroot00000000000000On debian, install libgtk-3-dev xfce4-panel-dev Launch at button with xfce4-panel --plugin-event=jgmenu-applet:popup:bool:false jgmenu-4.5.0/contrib/xfce4-panel/jgmenu-applet.c000066400000000000000000000232411472613136300214770ustar00rootroot00000000000000/* * Copyright © 2019 misko_2083 * * Distributed under terms of the GPL2 license. */ #include #include #define DEFAULT_ICON_NAME "jgmenu" #define DEFAULT_TOOLTIP_MESSAGE "Applications Menu" #define DEFAULT_TITLE "jgmenu" #define DEFAULT_RUN_COMMAND "jgmenu_run" #define DEFAULT_RUN_COMMAND_AT_POINTER "jgmenu --at-pointer" #define XFCE_PLUGIN_VERSION "0.1" typedef struct _JgmenuPlugin { XfcePanelPlugin *plugin; GtkWidget *button; GtkWidget *icon; gchar *icon_name; } JgmenuPlugin; static const char jgmenu_plugin_copyright[] = "Copyright \xc2\xa9 2019 Miloš Pavlović (plugin)\n" "Copyright \xc2\xa9 Johan Malm (jgmenu)\n"; static void jgmenu_about(XfcePanelPlugin *plugin) { const gchar *auth[] = { "Miloš Pavlović", NULL }; GdkPixbuf *icon; icon = xfce_panel_pixbuf_from_source("jgmenu", NULL, 32); gtk_show_about_dialog(NULL, "logo", icon, "license", xfce_get_license_text(XFCE_LICENSE_TEXT_GPL), "version", XFCE_PLUGIN_VERSION, "program-name", "jgmenu-applet", "comments", _("Starts Jgmenu"), "website", "https://github.com/johanmalm/jgmenu", "copyright", _(jgmenu_plugin_copyright), "authors", auth, NULL); if (icon) g_object_unref(G_OBJECT(icon)); } static char **extend_env(int coordinate, char *variable, char **envp) { envp = g_environ_setenv(envp, variable, g_strdup_printf("%" G_GINT16_FORMAT, coordinate), FALSE); return envp; } static void button_clicked(GtkWidget *button, XfcePanelPlugin *plugin) { gint x, y, panel_w, panel_h, button_width, button_height; gint panel_x1 = 0, panel_x2 = 0, panel_y1 = 0, panel_y2 = 0, button_x1 = 0, button_x2 = 0, button_y1 = 0, button_y2 = 0; GdkRectangle extents; GdkWindow *window; GtkAllocation allocation; GdkScreen *screen; gint screen_width, screen_height; gchar **envp; screen = gdk_screen_get_default(); if (!screen) { fprintf(stderr, "xfce4-plugin: gdk_screen_get_default() failed"); return; } screen_width = gdk_screen_get_width(screen); screen_height = gdk_screen_get_height(screen); screen_width = screen_width / 2; screen_height = screen_height / 2; /* get parent window */ window = gtk_widget_get_parent_window(button); /* parent's top-left screen coordinates */ gdk_window_get_root_origin(window, &x, &y); /* parent's width and height */ panel_w = gdk_window_get_width(window); panel_h = gdk_window_get_height(window); /* parent's extents (including decorations) */ gdk_window_get_frame_extents(window, &extents); gtk_widget_get_allocation(button, &allocation); /* calculating x (assuming: left border size == right border size) */ x = x + (extents.width - panel_w) / 2 + allocation.x; /* calculating y (assuming: left border size == right border size == bottom border size) */ y = y + (extents.height - panel_h) - (extents.width - panel_w) / 2 + allocation.y; button_width = allocation.width; button_height = allocation.height; /* Panel Position */ XfceScreenPosition position; position = xfce_panel_plugin_get_screen_position(plugin); if (xfce_screen_position_is_horizontal(position)) { /* horizontal */ if (xfce_screen_position_is_top(position)) { /* top panel position */ panel_x1 = extents.x; panel_x2 = extents.x + panel_w; panel_y1 = extents.y + panel_h; panel_y2 = panel_y1; button_x1 = x; button_x2 = x + button_width; button_y1 = y + button_height; button_y2 = y + button_height; } if (xfce_screen_position_is_bottom(position)) { /* bottom */ panel_x1 = extents.x; panel_x2 = extents.x + panel_w; panel_y1 = extents.y; panel_y2 = extents.y; button_x1 = x; button_x2 = x + button_width; button_y1 = y; button_y2 = y; } if (xfce_screen_position_is_floating(position)) { /* floating */ if (extents.y > screen_height) { /* bottom */ panel_x1 = extents.x; panel_x2 = extents.x + panel_w; panel_y1 = extents.y; panel_y2 = extents.y; button_x1 = x; button_x2 = x + button_width; button_y1 = y; button_y2 = y; } else { /* top */ panel_x1 = extents.x; panel_x2 = extents.x + panel_w; panel_y1 = extents.y + panel_h; panel_y2 = panel_y1; button_x1 = x; button_x2 = x + button_width; button_y1 = y + button_height; button_y2 = y + button_height; } } } else { /* vertical */ if (xfce_screen_position_is_left(position)) { /* left */ panel_x1 = extents.x + panel_w; panel_x2 = extents.x + panel_w; panel_y1 = extents.y; panel_y2 = extents.y + panel_h; button_x1 = x + button_width; button_x2 = button_x1; button_y1 = y; button_y2 = y + button_height; } if (xfce_screen_position_is_right(position)) { /* right */ panel_x1 = extents.x; panel_x2 = extents.x; panel_y1 = extents.y; panel_y2 = extents.y + panel_h; button_x1 = x; button_x2 = x; button_y1 = y; button_y2 = y + button_height; } if (xfce_screen_position_is_floating(position)) { /* floating */ if (extents.x > screen_width) { /* right */ panel_x1 = extents.x; panel_x2 = extents.x; panel_y1 = extents.y; panel_y2 = extents.y + panel_h; button_x1 = x; button_x2 = x; button_y1 = y; button_y2 = y + button_height; } else { /* left */ panel_x1 = extents.x + panel_w; panel_x2 = extents.x + panel_w; panel_y1 = extents.y; panel_y2 = extents.y + panel_h; button_x1 = x + button_width; button_x2 = button_x1; button_y1 = y; button_y2 = y + button_height; } } } envp = g_get_environ(); envp = g_environ_unsetenv(envp, "TINT2_BUTTON_ALIGNED_X1"); envp = g_environ_unsetenv(envp, "TINT2_BUTTON_ALIGNED_X2"); envp = g_environ_unsetenv(envp, "TINT2_BUTTON_ALIGNED_Y1"); envp = g_environ_unsetenv(envp, "TINT2_BUTTON_ALIGNED_Y2"); envp = g_environ_unsetenv(envp, "TINT2_BUTTON_PANEL_X1"); envp = g_environ_unsetenv(envp, "TINT2_BUTTON_PANEL_X2"); envp = g_environ_unsetenv(envp, "TINT2_BUTTON_PANEL_Y1"); envp = g_environ_unsetenv(envp, "TINT2_BUTTON_PANEL_Y2"); if (button_x1 >= 0) { envp = extend_env(button_x1, "TINT2_BUTTON_ALIGNED_X1", envp); envp = extend_env(button_x2, "TINT2_BUTTON_ALIGNED_X2", envp); envp = extend_env(button_y1, "TINT2_BUTTON_ALIGNED_Y1", envp); envp = extend_env(button_y2, "TINT2_BUTTON_ALIGNED_Y2", envp); envp = extend_env(panel_x1, "TINT2_BUTTON_PANEL_X1", envp); envp = extend_env(panel_x2, "TINT2_BUTTON_PANEL_X2", envp); envp = extend_env(panel_y1, "TINT2_BUTTON_PANEL_Y1", envp); envp = extend_env(panel_y2, "TINT2_BUTTON_PANEL_Y2", envp); } /* * Set IPC mode to ensure jgmenu reads the above environment variables * The jgmenurc config file will only be updated if not already in IPC * mode */ gchar *command_setup[] = { "jgmenu_run", "config", "-s", "~/.config/jgmenu/jgmenurc", "-k", "position_mode", "-v", "ipc", NULL }; gchar *command[] = { DEFAULT_RUN_COMMAND, NULL }; GError *error = NULL; g_spawn_sync(".", command_setup, envp, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, NULL, &error); if (error) g_warning("unable to launch: %s", error->message); g_spawn_async(".", command, envp, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error); if (error) g_warning("unable to launch: %s", error->message); g_strfreev(envp); } static JgmenuPlugin *jgmenu_init(XfcePanelPlugin *plugin) { JgmenuPlugin *jgmenu = g_slice_new0(JgmenuPlugin); jgmenu->plugin = plugin; jgmenu->icon_name = g_strdup(DEFAULT_ICON_NAME); jgmenu->button = xfce_panel_create_button(); gtk_widget_show(jgmenu->button); g_signal_connect(G_OBJECT(jgmenu->button), "clicked", G_CALLBACK(button_clicked), plugin); gtk_widget_set_tooltip_text(GTK_WIDGET(jgmenu->button), DEFAULT_TOOLTIP_MESSAGE); jgmenu->icon = xfce_panel_image_new_from_source(jgmenu->icon_name); gtk_widget_show(jgmenu->icon); gtk_container_add(GTK_CONTAINER(jgmenu->button), jgmenu->icon); return jgmenu; } static void jgmenu_free(XfcePanelPlugin *plugin, JgmenuPlugin *jgmenu) { gtk_widget_destroy(jgmenu->button); gtk_widget_destroy(jgmenu->icon); g_slice_free(JgmenuPlugin, jgmenu); } static gboolean jgmenu_size_changed(XfcePanelPlugin *plugin, gint size, JgmenuPlugin *jgmenu) { size = size / xfce_panel_plugin_get_nrows(plugin); gtk_widget_set_size_request(GTK_WIDGET(plugin), size, size); return TRUE; } static gboolean jgmenu_remote(XfcePanelPlugin *plugin, gchar *name, GValue *value, JgmenuPlugin *jgmenu) { g_return_val_if_fail(!value || G_IS_VALUE(value), FALSE); if (strcmp(name, "popup") == 0) { if (value && G_VALUE_HOLDS_BOOLEAN(value) && g_value_get_boolean(value) && gtk_widget_get_visible(GTK_WIDGET(plugin))) { /* popup here at mouse pointer */ GError *error = NULL; g_spawn_command_line_async(DEFAULT_RUN_COMMAND_AT_POINTER, &error); if (error) g_warning("unable to launch: %s", error->message); } else { /* popup here, where X is an internal id * xfce4-panel --plugin-event=jgmenu-applet-X:popup:bool:false */ button_clicked(jgmenu->button, plugin); } return TRUE; } return FALSE; } static void jgmenu_construct(XfcePanelPlugin *plugin) { JgmenuPlugin *jgmenu; jgmenu = jgmenu_init(plugin); gtk_container_add(GTK_CONTAINER(plugin), jgmenu->button); xfce_panel_plugin_add_action_widget(plugin, jgmenu->button); xfce_panel_plugin_menu_show_about(plugin); g_signal_connect(G_OBJECT(plugin), "free-data", G_CALLBACK(jgmenu_free), jgmenu); g_signal_connect(G_OBJECT(plugin), "size-changed", G_CALLBACK(jgmenu_size_changed), jgmenu); g_signal_connect(G_OBJECT(plugin), "remote-event", G_CALLBACK(jgmenu_remote), jgmenu); g_signal_connect(G_OBJECT(plugin), "about", G_CALLBACK(jgmenu_about), jgmenu); } XFCE_PANEL_PLUGIN_REGISTER(jgmenu_construct); jgmenu-4.5.0/contrib/xfce4-panel/jgmenu-applet.desktop000066400000000000000000000002641472613136300227260ustar00rootroot00000000000000[Xfce Panel] Type=X-XFCE-PanelPlugin Encoding=UTF-8 Name=jgmenu Comment=Applications Menu Icon=jgmenu X-XFCE-Module=jgmenu X-XFCE-Internal=true X-XFCE-Unique=false X-XFCE-API=2.0 jgmenu-4.5.0/data/000077500000000000000000000000001472613136300137245ustar00rootroot00000000000000jgmenu-4.5.0/data/jgmenu.desktop000066400000000000000000000007211472613136300166040ustar00rootroot00000000000000[Desktop Entry] Type=Application Encoding=UTF-8 Name=jgmenu GenericName=Application Menu GenericName[ru]=Меню приложений GenericName[sv]=Program Meny Comment=Displays menu for launching installed applications Comment[ru]=Отображает меню для запуска установленных приложений Comment[sv]=Visar meny för installerade program Exec=jgmenu_run Terminal=false Icon=jgmenu Categories=System StartupNotify=false jgmenu-4.5.0/data/jgmenu.svg000066400000000000000000000055001472613136300157320ustar00rootroot00000000000000 image/svg+xml jgmenu-4.5.0/data/schema000066400000000000000000000016331472613136300151120ustar00rootroot00000000000000Name=Accessories Name[sv]=Tillbehör Icon=applications-accessories Categories=Accessibility;Core;Utility; Name=Development Name[sv]=Utveckling Icon=applications-development Categories=Development; Name=Education Name[sv]=Utbildning Icon=applications-science Categories=Education; Name=Games Name[sv]=Spel Icon=applications-games Categories=Game; Name=Graphics Name[sv]=Grafik Icon=applications-graphics Categories=Graphics; Name=Multimedia Name[sv]=Multimedia Icon=applications-multimedia Categories=Audio;Video;AudioVideo; Name=Internet Name[sv]=Internet Icon=applications-internet Categories=Network; Name=Office Name[sv]=Kontorsprogram Icon=applications-office Categories=Office; Name=Other Name[sv]=Övrigt Icon=applications-other Name=Settings Name[sv]=Inställningar Icon=preferences-desktop Categories=Settings;Screensaver; Name=System Name[sv]=System Icon=applications-system Categories=Emulator;System; jgmenu-4.5.0/debian/000077500000000000000000000000001472613136300142355ustar00rootroot00000000000000jgmenu-4.5.0/debian/.gitignore000066400000000000000000000006601472613136300162270ustar00rootroot00000000000000README.Debian README.source docs files init.d.ex jgmenu-doc.docs jgmenu-doc.install jgmenu.cron.d.ex jgmenu.debhelper.log jgmenu.default.ex jgmenu.doc-base.EX jgmenu.postinst.debhelper jgmenu.prerm.debhelper jgmenu.substvars manpage.1.ex manpage.sgml.ex manpage.xml.ex menu.ex package-doc.docs package-doc.install package.cron.d.ex package.default.ex package.doc-base.EX postinst.ex postrm.ex preinst.ex prerm.ex rules.dh7 watch.ex jgmenu-4.5.0/debian/changelog000066400000000000000000000033731472613136300161150ustar00rootroot00000000000000jgmenu (4.5.0-1) unstable; urgency=medium * New upstream release -- Johan Malm Tue, 10 Dec 2024 21:29:31 +0000 jgmenu (4.4.1-1) unstable; urgency=medium * New upstream release -- Johan Malm Sun, 30 Oct 2022 13:36:33 +0000 jgmenu (4.4.0-1) unstable; urgency=medium * New upstream release -- Johan Malm Thu, 16 Sep 2021 18:33:07 +0100 jgmenu (4.3.0-1) unstable; urgency=medium * New upstream release -- Johan Malm Sat, 02 Jan 2021 14:48:01 +0000 jgmenu (4.2.1-1) unstable; urgency=medium * New upstream release -- Johan Malm Tue, 19 May 2020 22:04:21 +0100 jgmenu (4.2.0-1) unstable; urgency=medium * New upstream release -- Johan Malm Wed, 06 May 2020 19:54:30 +0100 jgmenu (4.1.0-1) unstable; urgency=medium * New upstream release -- Johan Malm Mon, 02 Mar 2020 21:21:52 +0000 jgmenu (4.0.2-1) unstable; urgency=medium * New upstream release -- Johan Malm Sun, 02 Feb 2020 21:28:47 +0000 jgmenu (4.0.1-1) unstable; urgency=medium * New upstream release -- Johan Malm Sun, 19 Jan 2020 21:08:29 +0000 jgmenu (4.0-1) unstable; urgency=medium * New upstream release * Add configure script * Move pmenu and lx to contrib/ -- Johan Malm Sun, 05 Jan 2020 15:10:51 +0000 jgmenu (3.5-1) unstable; urgency=medium * New upstream release * Split into packages jgmenu and jgmenu-xfce4-panel-applet -- Johan Malm Mon, 21 Oct 2019 21:30:56 +0100 jgmenu (3.4-1) unstable; urgency=medium * New upstream release * Add CONTRIB_DIRS packages -- Johan Malm Sat, 05 Oct 2019 11:59:11 +0100 jgmenu-4.5.0/debian/compat000066400000000000000000000000031472613136300154340ustar00rootroot0000000000000010 jgmenu-4.5.0/debian/control000066400000000000000000000016531472613136300156450ustar00rootroot00000000000000Source: jgmenu Maintainer: Johan Malm Section: x11 Priority: optional Standards-Version: 4.3.0 Homepage: https://jgmenu.github.io/ Build-Depends: debhelper (>= 10), libx11-dev, libxrandr-dev, libcairo2-dev, libpango1.0-dev, librsvg2-dev (>=2.46), libxml2-dev, libglib2.0-dev, libmenu-cache-dev, pkg-config, libxfce4panel-2.0-dev Package: jgmenu Architecture: any Multi-Arch: foreign Depends: ${shlibs:Depends}, ${misc:Depends}, python3, python3-gi, x11-xserver-utils Suggests: lxmenu-data Description: Simple X11 menu A stand-alone, contemporary-looking menu application for Linux and BSD. Independent of window manager and panel. Designed for customisation, scripting, modding and tweaking Package: jgmenu-xfce4-panel-applet Section: x11 Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends}, jgmenu (>= 3.5) Description: xfce4-panel applet for jgmenu An xfce4-panel applet for jgmenu jgmenu-4.5.0/debian/copyright000066400000000000000000000020301472613136300161630ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Source: https://github.com/johanmalm/jgmenu.git Files: * Copyright: 2014-2019 Johan Malm 2016-2017 Ovidiu M License: GPL-2 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation, 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. . On Debian systems, the full text of the GNU General Public License 2 can be found in `/usr/share/common-licenses/GPL-2'. jgmenu-4.5.0/debian/jgmenu-xfce4-panel-applet.install000066400000000000000000000000421472613136300224750ustar00rootroot00000000000000usr/lib/xfce4/* usr/share/xfce4/* jgmenu-4.5.0/debian/jgmenu.dirs000066400000000000000000000000731472613136300164050ustar00rootroot00000000000000/usr/bin /usr/lib /usr/share/man/man1 /usr/share/man/man7 jgmenu-4.5.0/debian/jgmenu.install000066400000000000000000000000531472613136300171100ustar00rootroot00000000000000usr/bin/* usr/lib/jgmenu/* usr/share/man/* jgmenu-4.5.0/debian/rules000077500000000000000000000004531472613136300153170ustar00rootroot00000000000000#!/usr/bin/make -f export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/buildflags.mk %: dh $@ override_dh_auto_configure: ./configure \ --prefix=/usr \ --with-lx \ --with-xfce4-panel-applet \ --with-gtktheme \ --with-pmenu jgmenu-4.5.0/debian/source/000077500000000000000000000000001472613136300155355ustar00rootroot00000000000000jgmenu-4.5.0/debian/source/format000066400000000000000000000000141472613136300167430ustar00rootroot000000000000003.0 (quilt) jgmenu-4.5.0/docs/000077500000000000000000000000001472613136300137435ustar00rootroot00000000000000jgmenu-4.5.0/docs/coding_style000066400000000000000000000036271472613136300163610ustar00rootroot00000000000000Coding Style ============ C programs ---------- - Use C99 without GNU extensions. We compile with -std=gnu99 to support list.h, but otherwise stay clear of GNU tricks. - Kernel coding style (https://www.kernel.org/doc/Documentation/CodingStyle) applies with the following exceptions: - Points which are kernel specific (e.g. kmalloc) - Lines can be up to 120 characters (although 80 is better) - Use scripts/checkpatch-wrapper.sh to check code. Shell scripts ------------- - Use tabs for indentation - Write <, >, <<, >> with space before, but no space after. E.g. cat <"${file}" - Use $( ) instead of `` - Use ${ } for variables - Use 'type ' to check if command is installed - Write "if", "for" and "while" structures with "then"/"do" on the next line (not with semicolon on the same line). E.g. if test -f foo.sh then do something fi for i in a b c do echo ${i} done - For short constructs, it is okay to use use && and || instead of if-statements. E.g: test -e foo || die "cannot find foo" type special_command || die "cannot find program `special_command`" - Use ./* rather than ls/$(ls) for lor loops for i in ./* do echo $i done - Use "test" instead of [ ] or [[ ]] E.g. test -n "${x}" && test "${a}" = "${b}" - Use $(( )) to perform maths operations instead of "let" or "expr". E.g: : $(( a += 5)) - Write functions like this my_function () { some code } - Quote variables except in for-loops and in $(( )) ### Stay POSIX friendly: - Don't use bash specific features such as arrays and [[ ]] - Avoid non-POSIX re-directions such as '&>', '>&-', '|&', etc For example, to re-direct both stdout and stderr to /dev/null, do: command >/dev/null 2>&1 - Don't use echo -e "foo", instead use printf "%b\n" "foo" - Don't use sed -i, it is not POSIX - Don't use curly brace globbing such as "ls *.{c,h}" jgmenu-4.5.0/docs/default.csv000066400000000000000000000023221472613136300161030ustar00rootroot00000000000000# # This menu was specifically designed for my particular setup on Arch Linux # when I first started writing jgmenu. It is only an example and is not # designed to work on other OSs/WMs/setups. # Web Browser,firefox,firefox File Manager,pcmanfm,system-file-manager Terminal,xterm,utilities-terminal Music Player,pgrep mpd || mpd; xterm -e 'ncmpcpp',multimedia-player Lock,i3lock -c 000000,system-lock-screen Run,dmenu_run -fn "-*-dejavu sans-medium-r-*-*-*-*-*-*-*-*-*-*",system-run Settings and Admin,^checkout(settings),folder Exit,^checkout(exit),system-shutdown ^tag(settings) Wifi,xterm -e 'sudo wifi-menu',network-wireless Sound,pavucontrol,multimedia-volume-control Printers,firefox http://localhost:631/admin,printer Background image,nitrogen ~/bg/,preferences-desktop-wallpaper Colour Picker,yad --color --button=OK --undecorated --center,color-picker Keyboard Layout,^checkout(keyboard) Update system,xterm -e 'sudo pacman -Syyu; bash',system-software-update ^tag(keyboard) British,setxkbmap -layout gb Swedish,setxkbmap -layout se ^tag(exit) Exit to prompt,openbox --exit,system-log-out Suspend,systemctl -i suspend,system-log-out Reboot,systemctl -i reboot,system-reboot Poweroff,systemctl -i poweroff,system-shutdown jgmenu-4.5.0/docs/manual/000077500000000000000000000000001472613136300152205ustar00rootroot00000000000000jgmenu-4.5.0/docs/manual/.gitignore000066400000000000000000000000071472613136300172050ustar00rootroot00000000000000*.html jgmenu-4.5.0/docs/manual/Makefile000066400000000000000000000012061472613136300166570ustar00rootroot00000000000000man1pages = jgmenu.1 jgmenu_run.1 jgmenu-pmenu.1 jgmenu-lx.1 jgmenu-ob.1 \ jgmenu-apps.1 jgmenu-i18n.1 man7pages = jgmenututorial.7 jgmenuunicode.7 manpages = $(man1pages) $(man7pages) prefix ?= /usr/local mandir ?= $(prefix)/share/man man1dir = $(mandir)/man1 man7dir = $(mandir)/man7 all: $(manpages) $(manpages): % : %.md @echo " PANDOC " $^ @pandoc -s -t man $^ -o $@ @sed -i 's/\\\\\\\\/\\\\/' $@ install: @install -d -m 755 $(DESTDIR)$(man1dir) @install -d -m 755 $(DESTDIR)$(man7dir) @install -m 644 $(man1pages) $(DESTDIR)$(man1dir) @install -m 644 $(man7pages) $(DESTDIR)$(man7dir) clean: @rm -f $(manpages) jgmenu-4.5.0/docs/manual/README000066400000000000000000000006331472613136300161020ustar00rootroot00000000000000The man pages are commited in order to save you installing pandoc if you haven't got it. Any changes are to be made to the md files. Set text width to 69 for consistent formatting on 80x25 and bigger. Use non-breaking spaces (\u00A0) at the beginning of lines if indentation is required in a non-"code" area, for example the "usage" lines under SYNOPSIS. In vim, this is achieved by ^KNS or ^K jgmenu-4.5.0/docs/manual/jg.css000066400000000000000000000015641472613136300163400ustar00rootroot00000000000000body { margin: auto; padding-right: 1em; padding-left: 1em; max-width: 44em; color: black; font-family: Ubuntu, Verdana, sans-serif; font-size: 100%; line-height: 140%; color: #333; } b { color:#502000; } i { color:#006000; } pre { border: 1px dotted gray; background-color: #ececec; color: #111111; padding: 0.7em; } code { font-family: monospace; background-color: #ececec; color: #111111; } h1 a, h2 a, h3 a, h4 a, h5 a { text-decoration: none; color: #7a5ada; } h1, h2, h3, h4, h5 { font-family: verdana; font-weight: bold; border-bottom: 1px solid black; color: #113366; } h1 { color:#A00000; font-size: 130%; } h2 { color:#A00000; font-size: 110%; } h3 { color:#600000; font-size: 95%; } h4 { font-size: 90%; font-style: italic; } h5 { font-size: 90%; font-style: italic; } dt code { font-weight: bold; } dd p { margin-top: 0; } jgmenu-4.5.0/docs/manual/jgmenu-apps.1000066400000000000000000000065631472613136300175420ustar00rootroot00000000000000.\" Automatically generated by Pandoc 3.1.6 .\" .\" Define V font for inline verbatim, using C font in formats .\" that render this, and otherwise B font. .ie "\f[CB]x\f[]"x" \{\ . ftr V B . ftr VI BI . ftr VB B . ftr VBI BI .\} .el \{\ . ftr V CR . ftr VI CI . ftr VB CB . ftr VBI CBI .\} .TH "JGMENU-APPS" "1" "14 January, 2024" "" "" .hy .SH NAME .PP jgmenu-apps - generate jgmenu flavoured CSV menu data .SH SYNOPSIS .PP \f[V]jgmenu_run apps\f[R] [--help]\ [--no-append]\ [--no-prepend] .PD 0 .P .PD [--append-file <\f[I]file\f[R]>] [--prepend-file <\f[I]file\f[R]>] .SH DESCRIPTION .PP \f[V]jgmenu_run apps\f[R] generates jgmenu flavoured CSV menu data for system applications using built-in schema data or a specified schema file to map categories to directories, rather than system .directory files. .PP A schema is searched for in the following locations and order: .IP \[bu] 2 \f[V]$XDG_CONFIG_HOME/jgmenu/schema\f[R] .PD 0 .P .PD .IP \[bu] 2 \f[V]$HOME/.config/jgmenu/schema\f[R] .PD 0 .P .PD .IP \[bu] 2 \f[V]$XDG_CONFIG_DIRS/jgmenu/schema\f[R] .PD 0 .P .PD .IP \[bu] 2 \f[V]/etc/xdg/jgmenu/schema\f[R] .PP The root menu is appended and/or prepended by the contents of the files \f[V]$HOME/.config/jgmenu/{append,prepend}.csv\f[R] if they exist. .PP Applications which do not belong in any of the categories in the schema file, are placed in `Other' (which is the one with no Categories= field) .PP Example schema file: .IP .nf \f[C] Name=Accessories Name[sv]=Tillbehör Icon=applications-accessories Categories=Accessibility;Core;Utility; Name=Development Name[sv]=Utveckling Icon=applications-development Categories=Development; Name=Education Name[sv]=Utbildning Icon=applications-science Categories=Education; Name=Games Name[sv]=Spel Icon=applications-games Categories=Game; Name=Graphics Name[sv]=Grafik Icon=applications-graphics Categories=Graphics; Name=Multimedia Name[sv]=Multimedia Icon=applications-multimedia Categories=Audio;Video;AudioVideo; Name=Internet Name[sv]=Internet Icon=applications-internet Categories=Network; Name=Office Name[sv]=Kontorsprogram Icon=applications-office Categories=Office; Name=Other Name[sv]=Övrigt Icon=applications-other Name=Settings Name[sv]=Inställningar Icon=preferences-desktop Categories=Settings;Screensaver; Name=System Name[sv]=System Icon=applications-system Categories=Emulator;System; \f[R] .fi .SH OPTIONS .TP \f[V]--help\f[R] Show help message and exit .TP \f[V]--no-prepend\f[R] Do not output \[ti]/.config/jgmenu/prepend.csv before root menu .TP \f[V]--no-append\f[R] Do not output \[ti]/.config/jgmenu/append.csv after root menu .TP \f[V]--append-file \f[R] Specify menu file to append to the root menu. Use $HOME/.config/jgmenu/append.csv by default. .TP \f[V]--prepend-file \f[R] Specify menu file to prepend to the root menu. Use $HOME/.config/jgmenu/prepend.csv by default. .SH ENVIRONMENT VARIABLES .TP \f[V]JGMENU_SINGLE_WINDOW\f[R] If set, \f[V]\[ha]checkout()\f[R] items will be replaced by \f[V]\[ha]root()\f[R] .TP \f[V]JGMENU_NO_DIRS\f[R] If set, applications will be listed without a directory structure .TP \f[V]JGMENU_NO_PEND\f[R] Do not read append.csv or prepend.csv .TP \f[V]JGMENU_NAME_FORMAT\f[R] See \f[V]csv_name_format\f[R] in jgmenu(1) .TP \f[V]JGMENU_NO_DUPLICATES\f[R] See \f[V]csv_no_duplicates\f[R] in jgmenu(1) .TP \f[V]JGMENU_I18N\f[R] See \f[V]csv_i18n\f[R] in jgmenu(1) and jgmenu-i18n(1) .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenu-apps.1.md000066400000000000000000000054341472613136300201350ustar00rootroot00000000000000% JGMENU-APPS(1) % Johan Malm % 14 January, 2024 # NAME jgmenu-apps - generate jgmenu flavoured CSV menu data # SYNOPSIS `jgmenu_run apps` \[\--help] \[\--no-append] \[\--no-prepend] \[\--append-file <*file*>] \[\--prepend-file <*file*>] # DESCRIPTION `jgmenu_run apps` generates jgmenu flavoured CSV menu data for system applications using built-in schema data or a specified schema file to map categories to directories, rather than system .directory files. A schema is searched for in the following locations and order: - `$XDG_CONFIG_HOME/jgmenu/schema` - `$HOME/.config/jgmenu/schema` - `$XDG_CONFIG_DIRS/jgmenu/schema` - `/etc/xdg/jgmenu/schema` The root menu is appended and/or prepended by the contents of the files `$HOME/.config/jgmenu/{append,prepend}.csv` if they exist. Applications which do not belong in any of the categories in the schema file, are placed in 'Other' (which is the one with no Categories= field) Example schema file: ``` Name=Accessories Name[sv]=Tillbehör Icon=applications-accessories Categories=Accessibility;Core;Utility; Name=Development Name[sv]=Utveckling Icon=applications-development Categories=Development; Name=Education Name[sv]=Utbildning Icon=applications-science Categories=Education; Name=Games Name[sv]=Spel Icon=applications-games Categories=Game; Name=Graphics Name[sv]=Grafik Icon=applications-graphics Categories=Graphics; Name=Multimedia Name[sv]=Multimedia Icon=applications-multimedia Categories=Audio;Video;AudioVideo; Name=Internet Name[sv]=Internet Icon=applications-internet Categories=Network; Name=Office Name[sv]=Kontorsprogram Icon=applications-office Categories=Office; Name=Other Name[sv]=Övrigt Icon=applications-other Name=Settings Name[sv]=Inställningar Icon=preferences-desktop Categories=Settings;Screensaver; Name=System Name[sv]=System Icon=applications-system Categories=Emulator;System; ``` # OPTIONS `--help` : Show help message and exit `--no-prepend` : Do not output ~/.config/jgmenu/prepend.csv before root menu `--no-append` : Do not output ~/.config/jgmenu/append.csv after root menu `--append-file ` : Specify menu file to append to the root menu. Use $HOME/.config/jgmenu/append.csv by default. `--prepend-file ` : Specify menu file to prepend to the root menu. Use $HOME/.config/jgmenu/prepend.csv by default. # ENVIRONMENT VARIABLES `JGMENU_SINGLE_WINDOW` : If set, `^checkout()` items will be replaced by `^root()` `JGMENU_NO_DIRS` : If set, applications will be listed without a directory structure `JGMENU_NO_PEND` : Do not read append.csv or prepend.csv `JGMENU_NAME_FORMAT` : See `csv_name_format` in jgmenu(1) `JGMENU_NO_DUPLICATES` : See `csv_no_duplicates` in jgmenu(1) `JGMENU_I18N` : See `csv_i18n` in jgmenu(1) and jgmenu-i18n(1) jgmenu-4.5.0/docs/manual/jgmenu-i18n.1000066400000000000000000000042361472613136300173510ustar00rootroot00000000000000.\" Automatically generated by Pandoc 2.2.1 .\" .TH "JGMENU\-I18N" "1" "15 February, 2020" "" "" .hy .SH NAME .PP jgmenu\-i18n \- support translation of jgmenu flavoured CSV menu data .SH SYNOPSIS .PP jgmenu_run i18n <\f[I]translation\-file\f[]> .PP jgmenu_run i18n \-\-init [<\f[I]translation\-file\f[]>] .SH DESCRIPTION .PP \f[C]jgmenu_run\ i18n\f[] reads jgmenu flavoured CSV menu data from stdin and either translates it, or creates a po style translation file .PP The <\f[I]translation\-file\f[]> argument can be a file or directory. If it is the latter, translation files will be searched for in this directory based on the environment variable $LANG, which will be assumed to be in the format \f[C]ll_CC.UTF8\f[] where \f[C]ll\f[] is an ISO 639 two\-letter language code and \f[C]CC\f[] is an ISO 3166 two\-letter country code. Files named \f[C]ll_CC\f[] and \f[C]ll\f[] will be used in said order. .SH OPTIONS .TP .B \f[C]\-\-init\f[] Create a template po style translation file with blank msgid entries .RS .RE .SH EXAMPLES .SS Create translation file template for manual translation .PP Modules jgmenu\-apps(1) and jgmenu\-ob(1) have built\-in i18n support. In order to use this features, a translation file is required. Here follow examples of how a translation file can be created: .PP Example 1. .IP .nf \f[C] jgmenu_run\ ob\ |\ jgmenu_run\ i18n\ \-\-init\ >sv \f[] .fi .PP Example 2. .IP .nf \f[C] jgmenu_run\ i18n\ \-\-init\ sv \f[] .fi .PP The result of the above commands would be a skeleton translation file (\f[C]sv\f[] in this case) containing entries like this: .IP .nf \f[C] msgid\ "Web\ Browser" msgstr\ "" \f[] .fi .PP Manually translate the empty msgstr fields. .SS Use translation file .PP If using modules jgmenu\-apps(1) or jgmenu\-ob(1), just set \f[C]csv_i18n\f[] in jgmenurc to directly point to a translation\-file or a directory containing translation files. .PP In special circumstances, you may wish to include i18n in command plumbing. Here follow an example of how this could be constructed: .IP .nf \f[C] \ \\ \ \ \ \ |\ jgmenu_run\ i18n\ \ \\ \ \ \ \ |\ jgmenu\ \-\-vsimple \f[] .fi .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenu-i18n.1.md000066400000000000000000000035311472613136300177450ustar00rootroot00000000000000% JGMENU-I18N(1) % Johan Malm % 15 February, 2020 # NAME jgmenu-i18n - support translation of jgmenu flavoured CSV menu data # SYNOPSIS jgmenu_run i18n <*translation-file*> jgmenu_run i18n \--init \[<*translation-file*>] # DESCRIPTION `jgmenu_run i18n` reads jgmenu flavoured CSV menu data from stdin and either translates it, or creates a po style translation file The <*translation-file*> argument can be a file or directory. If it is the latter, translation files will be searched for in this directory based on the environment variable $LANG, which will be assumed to be in the format `ll_CC.UTF8` where `ll` is an ISO 639 two-letter language code and `CC` is an ISO 3166 two-letter country code. Files named `ll_CC` and `ll` will be used in said order. # OPTIONS `--init` : Create a template po style translation file with blank msgid entries # EXAMPLES ## Create translation file template for manual translation Modules jgmenu-apps(1) and jgmenu-ob(1) have built-in i18n support. In order to use this features, a translation file is required. Here follow examples of how a translation file can be created: Example 1. jgmenu_run ob | jgmenu_run i18n --init >sv Example 2. jgmenu_run i18n --init sv The result of the above commands would be a skeleton translation file (`sv` in this case) containing entries like this: msgid "Web Browser" msgstr "" Manually translate the empty msgstr fields. ## Use translation file If using modules jgmenu-apps(1) or jgmenu-ob(1), just set `csv_i18n` in jgmenurc to directly point to a translation-file or a directory containing translation files. In special circumstances, you may wish to include i18n in command plumbing. Here follow an example of how this could be constructed: \ | jgmenu_run i18n \ | jgmenu --vsimple jgmenu-4.5.0/docs/manual/jgmenu-lx.1000066400000000000000000000016251472613136300172140ustar00rootroot00000000000000.\" Automatically generated by Pandoc 2.2.1 .\" .TH "JGMENU\-LX" "1" "29 September, 2019" "" "" .hy .SH NAME .PP jgmenu\-lx \- generate jgmenu flavoured CSV menu data .SH SYNOPSIS .PP \f[C]jgmenu_run\ lx\f[] .SH DESCRIPTION .PP \f[C]jgmenu_run\ lx\f[] generates jgmenu flavoured CSV menu data for freedesktop.org defined application menus, using LXDE's libmenu\-cache. .SH ENVIRONMENT VARIABLES .TP .B \f[C]XDG_MENU_PREFIX\f[] This can be used to specity a .menu file. For example, \f[C]XDG_MENU_PREFIX=lxde\-\f[] will load lxde\-applications.menu .RS .RE .TP .B \f[C]JGMENU_NO_DIRS\f[] If set, applications will be listed without a directory structure .RS .RE .TP .B \f[C]JGMENU_NO_PEND\f[] Do not read append.csv or prepend.csv .RS .RE .TP .B \f[C]JGMENU_NAME_FORMAT\f[] See \f[C]csv_name_format\f[] in jgmenu(1) .RS .RE .SH KNOWN ISSUES .PP xfce\-applications.menu is not parsed correctly. .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenu-lx.1.md000066400000000000000000000013351472613136300176110ustar00rootroot00000000000000% JGMENU-LX(1) % Johan Malm % 29 September, 2019 # NAME jgmenu-lx - generate jgmenu flavoured CSV menu data # SYNOPSIS `jgmenu_run lx` # DESCRIPTION `jgmenu_run lx` generates jgmenu flavoured CSV menu data for freedesktop.org defined application menus, using LXDE's libmenu-cache. # ENVIRONMENT VARIABLES `XDG_MENU_PREFIX` : This can be used to specity a .menu file. For example, `XDG_MENU_PREFIX=lxde-` will load lxde-applications.menu `JGMENU_NO_DIRS` : If set, applications will be listed without a directory structure `JGMENU_NO_PEND` : Do not read append.csv or prepend.csv `JGMENU_NAME_FORMAT` : See `csv_name_format` in jgmenu(1) # KNOWN ISSUES xfce-applications.menu is not parsed correctly. jgmenu-4.5.0/docs/manual/jgmenu-ob.1000066400000000000000000000020011472613136300171560ustar00rootroot00000000000000.\" Automatically generated by Pandoc 2.2.1 .\" .TH "JGMENU\-OB" "1" "3 December, 2019" "" "" .hy .SH NAME .PP jgmenu\-ob \- convert openbox menu data to jgmenu flavoured CSV .SH SYNOPSIS .PP \f[C]jgmenu_run\ ob\f[] [\-\-tag=<\f[I]tag\f[]>] [\-\-cmd=<\f[I]cmd\f[]> | <\f[I]file\f[]>] .SH DESCRIPTION .PP \f[C]jgmenu_run\ ob\f[] converts openbox XML menu data to jgmenu flavoured CSV. If no \f[C]\f[] or \f[C]\-\-cmd=\f[] is specified, \f[C]~/.config/openbox/menu.xml\f[] or \f[C]/etc/xdg/openbox/menu.xml\f[] will be used if they exist, giving higher precedence to the former. .SH OPTIONS .TP .B \f[C]\f[] Specify openbox XML file. .RS .RE .TP .B \f[C]\-\-cmd=\f[] Specify command to produce openbox XML menu data. .RS .RE .TP .B \f[C]\-\-tag=\f[] Specify value of root \f[C]^tag()\f[]. This can be useful for pipemenus to avoid clashing tag\-names .RS .RE .SH ENVIRONMENT VARIABLES .TP .B \f[C]JGMENU_I18N\f[] See \f[C]csv_i18n\f[] in jgmenu(1) and jgmenu\-i18n(1) .RS .RE .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenu-ob.1.md000066400000000000000000000014241472613136300175650ustar00rootroot00000000000000% JGMENU-OB(1) % Johan Malm % 3 December, 2019 # NAME jgmenu-ob - convert openbox menu data to jgmenu flavoured CSV # SYNOPSIS `jgmenu_run ob` \[\--tag=<*tag*>] \[\--cmd=<*cmd*> | <*file*>] # DESCRIPTION `jgmenu_run ob` converts openbox XML menu data to jgmenu flavoured CSV. If no `` or `--cmd=` is specified, `~/.config/openbox/menu.xml` or `/etc/xdg/openbox/menu.xml` will be used if they exist, giving higher precedence to the former. # OPTIONS `` : Specify openbox XML file. `--cmd=` : Specify command to produce openbox XML menu data. `--tag=` : Specify value of root `^tag()`. This can be useful for pipemenus to avoid clashing tag-names # ENVIRONMENT VARIABLES `JGMENU_I18N` : See `csv_i18n` in jgmenu(1) and jgmenu-i18n(1) jgmenu-4.5.0/docs/manual/jgmenu-pmenu.1000066400000000000000000000036331472613136300177160ustar00rootroot00000000000000.\" Automatically generated by Pandoc 2.2.1 .\" .TH "JGMENU\-PMENU" "1" "29 September, 2019" "" "" .hy .SH NAME .PP jgmenu\-pmenu \- generate jgmenu flavoured CSV menu data .SH SYNOPSIS .PP \f[C]jgmenu_run\ pmenu\f[] [\-h | \[en]help] [\[en]append\-file <\f[I]FILE\f[]>] .PD 0 .P .PD \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\[en]prepend\-file <\f[I]FILE\f[]>] [\[en]locale <\f[I]LOCALE\f[]>] .SH DESCRIPTION .PP Generates jgmenu flavoured CSV menu data based on .desktop and \&.directory files found on the system, but ignores any .menu files. Instead of the structure specified in the .menu file, it simply maps each \[lq].desktop\[rq] application onto one of the \[lq].directory\[rq] categories. If a matching \[lq].directory\[rq] category does not exist, it tries to cross\-reference \[lq]additional categories\[rq] to \[lq]related categories\[rq] in accordance with the XDG menu\-spec. This is a generic approach which avoids Desktop Environment specific rules defined in the .menu file. It ensures that all .desktop files are included in the menu. .PP The root menu is appended/prepended by the contents of the following files if they exist: .IP \[bu] 2 \f[C]~/.config/jgmenu/append.csv\f[] .IP \[bu] 2 \f[C]~/.config/jgmenu/prepend.csv\f[] .SH OPTIONS .TP .B \f[C]\-h\f[], \f[C]\-\-help\f[] Show this help message and exit .RS .RE .TP .B \f[C]\-\-append\-file\ FILE\f[] Path to menu file to append to the root menu .RS .RE .TP .B \f[C]\-\-prepend\-file\ FILE\f[] Path to menu file to prepend to the root menu .RS .RE .TP .B \f[C]\-\-locale\ LOCALE\f[] Use a custom locale (e.g. \f[C]en_US.UTF\-8\f[]). Available locales can be shown by running \f[C]locale\ \-a\f[]. .RS .RE .SH ENVIRONMENT VARIABLES .TP .B \f[C]JGMENU_SINGLE_WINDOW\f[] If set, \f[C]^checkout()\f[] items will be replaced by \f[C]^root()\f[] .RS .RE .TP .B \f[C]JGMENU_NO_DIRS\f[] If set, applications will be listed without a directory structure .RS .RE .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenu-pmenu.1.md000066400000000000000000000030651472613136300203140ustar00rootroot00000000000000% JGMENU-PMENU(1) % Johan Malm % 29 September, 2019 # NAME jgmenu-pmenu - generate jgmenu flavoured CSV menu data # SYNOPSIS `jgmenu_run pmenu` \[-h | --help] \[--append-file <*FILE*>]                  \[--prepend-file <*FILE*>] \[--locale <*LOCALE*>] # DESCRIPTION Generates jgmenu flavoured CSV menu data based on .desktop and .directory files found on the system, but ignores any .menu files. Instead of the structure specified in the .menu file, it simply maps each ".desktop" application onto one of the ".directory" categories. If a matching ".directory" category does not exist, it tries to cross-reference "additional categories" to "related categories" in accordance with the XDG menu-spec. This is a generic approach which avoids Desktop Environment specific rules defined in the .menu file. It ensures that all .desktop files are included in the menu. The root menu is appended/prepended by the contents of the following files if they exist: - `~/.config/jgmenu/append.csv` - `~/.config/jgmenu/prepend.csv` # OPTIONS `-h`, `--help` : Show this help message and exit `--append-file FILE` : Path to menu file to append to the root menu `--prepend-file FILE` : Path to menu file to prepend to the root menu `--locale LOCALE` : Use a custom locale (e.g. `en_US.UTF-8`). Available locales can be shown by running `locale -a`. # ENVIRONMENT VARIABLES `JGMENU_SINGLE_WINDOW` : If set, `^checkout()` items will be replaced by `^root()` `JGMENU_NO_DIRS` : If set, applications will be listed without a directory structure jgmenu-4.5.0/docs/manual/jgmenu.1000066400000000000000000000723111472613136300165730ustar00rootroot00000000000000.\" Automatically generated by Pandoc 3.1.11.1 .\" .TH "JGMENU" "1" "2 January, 2021" "" "" .SH NAME jgmenu \- A simple X11 menu .SH SYNOPSIS jgmenu\ [\-\-no\-spawn]\ [\-\-checkout=<\f[I]tag\f[R]>]\ [\-\-config\-file=<\f[I]file\f[R]>] .PD 0 .P .PD \ \ \ \ \ \ \ [\-\-icon\-size=<\f[I]size\f[R]>] [\-\-at\-pointer] [\-\-hide\-on\-startup] .PD 0 .P .PD \ \ \ \ \ \ \ [\-\-simple] [\-\-vsimple] [\-\-csv\-file=<\f[I]file\f[R]>] .PD 0 .P .PD \ \ \ \ \ \ \ [\-\-csv\-cmd=<\f[I]command\f[R]>] [\-\-die\-when\-loaded] .PD 0 .P .PD \ \ \ \ \ \ \ [\-\-center] [\-\-persistent] .PP Use these commands to get started .TP \f[CR]jgmenu_run\f[R] Launch menu .TP \f[CR]jgmenu_run init\f[R] Create config file \[ti]/.config/jgmenu/jgmenurc .TP \f[CR]jgmenu_run init \-i\f[R] Interactive setup .TP \f[CR]man jgmenututorial\f[R] Step\-by\-step tutorial .SH DESCRIPTION \f[CR]jgmenu\f[R] is a simple menu for Linux/BSD. It reads CSV menu data from a file and generates a graphical menu on an X11 window. .SS Fields Each line of CSV menu data is parsed into the following fields using comma as a field separator: .IP "(1)" 4 description .PD 0 .P .PD .IP "(2)" 4 command .PD 0 .P .PD .IP "(3)" 4 icon .PD 0 .P .PD .IP "(4)" 4 working directory .PD 0 .P .PD .IP "(5)" 4 metadata .PP For example: .IP .EX printf \[dq]Terminal,xterm\[rs]\[rs]nWeb Browser,firefox\[dq] | jgmenu \-\-vsimple .EE .SS Special Characters at beginning of line .TP \f[CR]#\f[R] Ignore line .TP \f[CR].\f[R] A line beginning with a dot followed by a space, will source the file specified by the string following the dot .TP \f[CR]\[at]\f[R] Treat as widget .SS Special Characters in fields .TP \f[CR],\f[R] As commas are used as field separators, individual fields can only contain commas if they are triple quoted. For example: .RS .PP foo,\[lq]\[lq]\[lq]\[ha]pipe(find . \-printf `%f,display %p,%p\[rs]n')\[rq]\[lq]\[rq] .RE .TP \f[CR]< > &\f[R] The description field is parsed as pango markup, so \f[CR]<\f[R], \f[CR]>\f[R], and \f[CR]&\f[R] need to be escaped as \f[CR]<\f[R], \f[CR]>\f[R], and \f[CR]&\f[R] respectively. .TP \f[CR]\[dq]\f[R] Unlike most CSV implementations, a single instance of a double quote (\f[CR]\[dq]\f[R]) is not considered a special character. The reason for this is to let users write commands with double quotes without having to escape them. .TP \f[CR]\[dq]\[dq]\[dq]\f[R] Use three quotes \f[CR]\[dq]\[dq]\[dq]\f[R] to begin and to end a fully quoted value. The primary use case for this is when a comma is needed within a value. .SS Markup The syntax \[ha]foo(bar) is used to carry out action \f[CR]foo\f[R] with argument \f[CR]bar\f[R]. We refer to \f[CR]bar\f[R] as the \f[CR]inner value\f[R]. .PP The following markup is supported in the \f[CR]description\f[R] field .TP \f[CR]sep()\f[R] Define a separator. If an inner value is provided, the separator will appear as a title. If no inner value is provided, the separator will simply be a horizontal line .PP The following markup is supported in the \f[CR]command\f[R] field .TP \f[CR]\[ha]tag()\f[R] Define the beginning of a new menu structure node. .RS .PP The lines following \f[CR]\[ha]tag(whatever)\f[R] will not show in the top level menu, but can be opened by using \f[CR]\[ha]checkout()\f[R] or \f[CR]\[ha]root()\f[R]. .IP .EX item0.0 item0.1 submenu1,\[ha]checkout(1) submenu2,\[ha]root(2) \[ha]tag(1) item1.0 item1.1 \[ha]tag(2) item2.0 item2.1 .EE .RE .TP \f[CR]\[ha]checkout()\f[R] Open the tag specified by the inner value as a submenu in a new window .TP \f[CR]\[ha]root()\f[R] Open the tag specified by the inner value in the root window, replacing the current menu .TP \f[CR]\[ha]sub()\f[R] Draw a submenu arrow. This can be useful for creating submenus with \f[CR]stay_alive=0\f[R]. For example: .RS .IP .EX item0.0 item0.1 submenu1,\[ha]sub(echo \[dq]item1.0\[dq] | jgmenu \-\-simple) .EE .RE .TP \f[CR]\[ha]back()\f[R] Check\-out parent menu .TP \f[CR]\[ha]term()\f[R] Run program in terminal .TP \f[CR]\[ha]pipe()\f[R] Execute sub\-process and checkout a menu based on its stdout. .TP \f[CR]\[ha]filter()\f[R] Invoke search .TP \f[CR]\[ha]quit()\f[R] Quit .SS Icons Icons will be displayed if the third field is populated, for example: .IP .EX Terminal,xterm,utilities\-terminal Firefox,firefox,firefox .EE .SH OPTIONS .TP \f[CR]\-\-no\-spawn\f[R] Redirect command to stdout rather than execute it. .TP \f[CR]\-\-checkout=\f[R] Checkout submenu on startup. .TP \f[CR]\-\-config\-file=\f[R] Read config file. .TP \f[CR]\-\-icon\-size=\f[R] Specify icon size (22 by default). If set to 0, icons will not be loaded. .TP \f[CR]\-\-at\-pointer\f[R] Launch menu at mouse pointer. .TP \f[CR]\-\-hide\-on\-startup\f[R] Start menu is hidden state. .TP \f[CR]\-\-simple\f[R] Ignore tint2 settings; Run in short\-lived mode (i.e.\ exit after mouse click or enter/escape); read menu items from \f[CR]stdin\f[R]. .TP \f[CR]\-\-vsimple\f[R] Same as \f[CR]\-\-simple\f[R], but also disables icons and ignores jgmenurc. .TP \f[CR]\-\-csv\-file=\f[R] Specify menu file (in jgmenu flavoured CSV format). If file cannot be opened, input is reverted to \f[CR]stdin\f[R]. .TP \f[CR]\-\-csv\-cmd=\f[R] Specify command to produce menu data, for example \f[CR]jgmenu_run pmenu\f[R] .TP \f[CR]\-\-die\-when\-loaded\f[R] Open menu and then exit(0). Useful for debugging and testing. .TP \f[CR]\-\-center\f[R] Center align menu horizontally and vertically. .TP \f[CR]\-\-persistent\f[R] Same as the persistent config option. See config option section below for details. .SH USER INTERFACE .TP \f[CR]Up\f[R], \f[CR]Down\f[R] Select previous/next item .TP \f[CR]Left\f[R]. \f[CR]Right\f[R] Move to parent/sub menu .TP \f[CR]PgUp\f[R], \f[CR]PgDn\f[R] Scroll up/down .TP \f[CR]Home\f[R], \f[CR]End\f[R] Select first/last item .TP \f[CR]Enter\f[R] Select an item or open a submenu .TP \f[CR]F5\f[R] Restart .TP \f[CR]F8\f[R] Print node tree to stderr .TP \f[CR]F9\f[R] exit(1) .TP \f[CR]F10\f[R] exit(0) .TP \f[CR]Backspace\f[R] Return to parent menu .PP Type any string to invoke a search. Words separated by space will be searched for using \f[CR]OR\f[R] logic (i.e.\ the match of either word is sufficient to display an item). .SH WIDGETS Lines beginning with `\[at]' in jgmenu flavoured CSV files are parsed in accordance with the following syntax: .IP .EX \[at]type,action,x,y,w,h,r,halign,valign,fgcol,bgcol,content .EE .TP \f[CR]type\f[R] The widget type, which can be one of the following: .RS .TP \f[CR]rect\f[R] Rectangle with a 1px thick border drawn using \f[CR]fgcol\f[R] .TP \f[CR]search\f[R] Search box showing the current filter (what the user has typed) or the specified \f[CR]text\f[R] if no filter has been invoked. .TP \f[CR]icon\f[R] Icon .RE .TP \f[CR]action\f[R] The action to take when selected. This can either be a shell command or a menu action such \f[CR]\[ha]root()\f[R]. .TP \f[CR]x\f[R], \f[CR]y\f[R] Horizontal and vertical margin of widget .TP \f[CR]w\f[R], \f[CR]h\f[R] Width and height of widget .TP \f[CR]r\f[R] Corner radius .TP \f[CR]fgcol\f[R], \f[CR]bgcol\f[R] Foreground and background colours using syntax \f[CR]rrggbb #aa\f[R] \f[CR]fgcol\f[R] accepts \f[CR]auto\f[R] to use the jgmenurc\[cq]s \f[CR]color_norm_fg\f[R] .TP \f[CR]content\f[R] \f[CR]icon_path\f[R] for \f[CR]icon\f[R] widgets \f[CR]text\f[R] for all other widget types .TP \f[CR]halign\f[R], \f[CR]valign\f[R] Horizontal and vertical alignment of widget. This has not yet been implemented, but defaults to \f[CR]top\f[R] and \f[CR]left\f[R] .SH CONFIGURATION FILE If no file is specified using the \[en]config\-file= option, the XDG Base Directory Specification is adhered to. I.e: .IP \[bu] 2 Global config in \f[CR]${XDG_CONFIG_DIRS:\-/etc/xdg}\f[R] .PD 0 .P .PD .IP \[bu] 2 User config override in \f[CR]${XDG_CONFIG_HOME:\-$HOME/.config}\f[R] .PP For most users \[ti]/.config/jgmenu/jgmenurc is appropriate. .PP Global config variables are set in the following order (i.e.\ bottom of list has higher precedence): .IP \[bu] 2 built\-in defaults (config.c) .PD 0 .P .PD .IP \[bu] 2 tint2rc config file (can be specified by \f[CR]TINT2_CONFIG\f[R] environment variable) .PD 0 .P .PD .IP \[bu] 2 jgmenurc config file (can be specified by \[en]config\-file=) .PD 0 .P .PD .IP \[bu] 2 command line arguments .SS Syntax Lines beginning with \f[CR]#\f[R] are ignored. .PP All other lines are recognised as setting variables in the format .IP .EX key = value .EE .PP White spaces are mostly ignored. .SS Values Unless otherwise specified, values as treated as simple strings. .PP Here follow some specific types: .TP \f[CR]boolean\f[R] When a variable takes a boolean value, only 0 and 1 are accepted. 0 means false; 1 means true. .TP \f[CR]integer\f[R] When a variable takes an integer value, only numerical values are accepted. The only valid characters are digits (0\-9) and minus\-sign. All integer variables relating to geometry and position are interpreted as pixel values unless otherwise specified. .TP \f[CR]color\f[R] When a variable takes a color value, only the syntax \f[CR]#rrggbb aaa\f[R] is recognised, where \f[CR]rr\f[R], \f[CR]gg\f[R] and \f[CR]bb\f[R] represent hexadecimal values (00\-ff) for the colours red, green and blue respectively; and \f[CR]aaa\f[R] stands for the alpha channel value expressed as a percentage (0\-100) (i.e.\ 100 means no transparency and 0 means fully transparent.) For example \f[CR]#ff0000 100\f[R] represents red with no transparency, whereas \f[CR]#000088 50\f[R] means dark blue with 50% transparency. .TP \f[CR]pathname\f[R] When a variable takes a pathname value, it is evaluated as a string. If the first character is tilde (\[ti]), it will be replaced by the the environment variable $HOME just as a shell would expand it. .SS Variables .TP \f[CR]verbosity\f[R] = \f[B]integer\f[R] (default 0) General verbosity: (0) warnings only; (1) basic info; (2) more info; (3) max info .RS .PP Additional specific topics: (4) IPC .PP Note: Some IPC messages need environment variable \f[CR]JGMENU_VERBOSITY=4\f[R] too .RE .TP \f[CR]stay_alive\f[R] = \f[B]boolean\f[R] (default 1) If set to 1, the menu will \[lq]hide\[rq] rather than \[lq]exit\[rq] when the following events occur: clicking on menu item; clicking outside the menu; pressing escape. When in the hidden mode, a USR1 signal will \[lq]un\-hide\[rq] the menu. .TP \f[CR]persistent\f[R] = \f[B]boolean\f[R] (default 0) If set to 1, the menu will not exit nor hide when the following events occur: clicking on menu item; clicking outside the menu; pressing escape. Use in conjunction with the \[ha]quit() markup. .TP \f[CR]hide_on_startup\f[R] = \f[B]boolean\f[R] (default 0) If set to 1, jgmenu start in \[lq]hidden\[rq] mode. This is useful for starting jgmenu during the boot process and then sending a \f[CR]killall \-SIGUSR1 jgmenu\f[R] to show the menu. .TP \f[CR]csv_cmd\f[R] = \f[B]string\f[R] (default \f[CR]apps\f[R]) Defines the command to produce the jgmenu flavoured CSV for \f[CR]jgmenu\f[R]. Accpetable keyword include apps, pmenu, lx, and ob. If a value is given other than these keywords, it will be executed in a shell (so be careful!). If left blank, jgmenu will read from \f[CR]stdin\f[R]. Examples: .RS .IP .EX csv_cmd = lx csv_cmd = jgmenu_run lx \-\-no\-dirs csv_cmd = cat \[ti]/mymenu.csv .EE .RE .TP \f[CR]tint2_look\f[R] = \f[B]boolean\f[R] (default 0) Read tint2rc and parse config options for colours,\ dimensions and alignment. .TP \f[CR]position_mode\f[R] = (fixed | ipc | pointer | center) (default fixed) Define menu positioning mode. .RS .TP \f[CR]fixed\f[R] Align to \f[CR]margin_{x,y}\f[R] and respect \f[CR]_NET_WORKAREA\f[R]. .TP \f[CR]ipc\f[R] Use IPC to read environment variables set by panel. See Inter\-Process Communication for further info. .TP \f[CR]pointer\f[R] Launch at pointer whilst respecting both \f[CR]_NET_WORKAREA\f[R] and \f[CR]edge_snap_x\f[R]. .TP \f[CR]center\f[R] Launch at center of screen and ignore \f[CR]_NET_WORKAREA\f[R]. Take precedence over \f[CR]menu_{v,h}align\f[R]. .RE .TP \f[CR]edge_snap_x\f[R] = \f[B]integer\f[R] (default 30) Specify the distance (in pixels) from the left hand edge, within which the menu will snap to the edge. Note that this only applies in \f[CR]at_pointer\f[R] mode. .TP \f[CR]terminal_exec\f[R] = \f[B]string\f[R] (default x\-terminal\-emulator) Define terminal to use for commands with \[ha]term() markup .TP \f[CR]terminal_args\f[R] = \f[B]string\f[R] (default \-e) The values of these two variables are used to build a string to launch programs requiring a terminal to run. With the default values, the string would become: \f[CR]x\-terminal\-emulator \-e \[aq]some_command with arguments\[aq]\f[R]. \f[CR]terminal_args\f[R] must finish with \f[CR]\-e\f[R] or equivalent, where \f[CR]\-e\f[R] refers to the meaning of \f[CR]\-e\f[R] in \f[CR]xterm \-e\f[R]. .TP \f[CR]monitor\f[R] = \f[B]integer\f[R] (default 0) Specify a particular monitor as an index starting from 1. If 0, the menu will be launched on the monitor where the mouse is. .TP \f[CR]hover_delay\f[R] = \f[B]integer\f[R] (default 100) Time (in milliseconds) from hovering over an item until a submenu is opened. .TP \f[CR]hide_back_items\f[R] = \f[B]boolean\f[R] (default 1) If enabled, all \[ha]back() items will be suppressed. As a general rule, it should be set to 1 for a multi\-window menu, and 0 when in single\-window mode. .TP \f[CR]columns\f[R] = \f[B]integer\f[R] (default 1) Number of columns in which to show menu items .TP \f[CR]tabs\f[R] = \f[B]integer\f[R] (default 120) Specify the position is pixels of the first tab .TP \f[CR]menu_margin_x\f[R] = \f[B]integer\f[R] (default 0) Distance between the menu (=X11 window) and the edge of the screen. See note on \f[CR]_NET_WORKAREA\f[R] under \f[CR]menu_{v,h}align\f[R] variables. .TP \f[CR]menu_margin_y\f[R] = \f[B]integer\f[R] (default 0) Vertical equilvalent of \f[CR]menu_margin_x\f[R] .TP \f[CR]menu_width\f[R] = \f[B]integer\f[R] (default 200) Minimum menu width of the menu. The menu width will adjust to the longest item in the current (sub)menu. If a filter is applied (e.g.\ by the user typing) the menu width will not adjust. .TP \f[CR]menu_height_min\f[R] = \f[B]integer\f[R] (default 0) Set the minimum height of the root menu. If \f[CR]menu_height_min\f[R] and \f[CR]menu_height_max\f[R] these are set to the same value, the menu height will be fixed at that value. If set to zero, they will be ignored. .TP \f[CR]menu_height_max\f[R] = \f[B]integer\f[R] (default 0) Minimum height of the root menu. See \f[CR]menu_height_min\f[R] .TP \f[CR]menu_height_mode\f[R] = (static | dynamic) (default static) Mode of menu height .RS .TP \f[CR]static\f[R] Height of the initial root menu will be used for any subsequent \f[CR]\[ha]root()\f[R] action .TP \f[CR]dynamic\f[R] Root menu height will be re\-calculated every time a new tag is opened using \f[CR]\[ha]root()\f[R]. .RE .TP \f[CR]menu_padding_top\f[R] = \f[B]integer\f[R] (default 5) Distance between top border and item/widget .TP \f[CR]menu_padding_right\f[R] = \f[B]integer\f[R] (default 5) Distance between right border and item/widget .TP \f[CR]menu_padding_bottom\f[R] = \f[B]integer\f[R] (default 5) Distance between bottom border and item/widget .TP \f[CR]menu_padding_left\f[R] = \f[B]integer\f[R] (default 5) Distance between left border and item/widget .TP \f[CR]menu_radius\f[R] = \f[B]integer\f[R] (default 1) Radius of rounded corners of menu .TP \f[CR]menu_border\f[R] = \f[B]integer\f[R] (default 0) Thickness of menu border .TP \f[CR]menu_halign\f[R] = (left | right | center) (default left) Horizontal alignment of menu. If not set, jgmenu will try to guess the alignment reading \f[CR]_NET_WORKAREA\f[R], which is a freedesktop EWMH root window property. Not all Window Managers and Panels respect \f[CR]_NET_WORKAREA\f[R]. The following do: openbox, xfwm4, tint2 and polybar. The following do NOT: awesome, i3, bspwm and plank .TP \f[CR]menu_valign\f[R] = (top | bottom | center) (default bottom) Vertical alignment of menu. See \f[CR]menu_halign\f[R]. .TP \f[CR]menu_gradient_pos\f[R] = (none | top | right | bottom | left | top_left | top_right | bottom_left | bottom_right ) (default none) Start position of menu window gradient. The end position is at the opposite side or corner. Colors color_menu_bg and color_menu_bg_to specify the start (from) and finish (to). .TP \f[CR]sub_spacing\f[R] = \f[B]integer\f[R] (default 1) Horizontal space between windows. A negative value results in each submenu window overlapping its parent window. .TP \f[CR]sub_padding_top\f[R] = \f[B]integer\f[R] (default auto) Same as \f[CR]menu_padding_top\f[R] but applies to submenu windows only. It understands the keyword \f[CR]auto\f[R] which means that the smallest of the four \f[CR]menu_padding_*\f[R] variables will be used. .TP \f[CR]sub_padding_right\f[R] = \f[B]integer\f[R] (default auto) See \f[CR]sub_padding_top\f[R] .TP \f[CR]sub_padding_bottom\f[R] = \f[B]integer\f[R] (default auto) See \f[CR]sub_padding_top\f[R] .TP \f[CR]sub_padding_left\f[R] = \f[B]integer\f[R] (default auto) See \f[CR]sub_padding_top\f[R] .TP \f[CR]sub_hover_action\f[R] = \f[B]integer\f[R] (default 1) Open submenu when hovering over item (only works in multi\-window mode). .TP \f[CR]item_margin_x\f[R] = \f[B]integer\f[R] (default 3) Horizontal distance between items and the edge of the menu. .TP \f[CR]item_margin_y\f[R] = \f[B]integer\f[R] (default 3) Vertical distance between items and the edge of the menu. .TP \f[CR]item_height\f[R] = \f[B]integer\f[R] (default 25) Height of menu items. .TP \f[CR]item_padding_x\f[R] = \f[B]integer\f[R] (default 4) Horizontal distance between item edge and its content (e.g.\ text or icon) .TP \f[CR]item_radius\f[R] = \f[B]integer\f[R] (default 1) Radius of rounded corners of items .TP \f[CR]item_border\f[R] = \f[B]integer\f[R] (default 0) Thickness of item border .TP \f[CR]item_halign\f[R] = (left | right) (default left) Horizontal alignment of menu items. If set to \f[CR]right\f[R], the option \f[CR]arrow_string\f[R] should be changed too. .TP \f[CR]sep_height\f[R] = \f[B]integer\f[R] (default 5) Height of separator without text (defined by \[ha]sep()). Separators with text use \f[CR]item_height\f[R] .TP \f[CR]sep_halign\f[R] = (left | center | right) (default left) Horizontal alignment of separator text .TP \f[CR]sep_markup\f[R] = \f[B]string\f[R] (unset by default) If specified, \f[CR]foo\f[R] will be passed to pango for \[ha]sep(foo). .RS .PP See the following link for pango attributes: \c .UR https://docs.gtk.org/Pango/pango_markup.html .UE \c .PP Keywords include (but are not limited to): .IP \[bu] 2 font .IP \[bu] 2 size (x\-small, small, medium, large, x\-large) \-\ style (normal, oblique, italic) .IP \[bu] 2 weight (ultralight, light, normal, bold, ultrabold, heavy .IP \[bu] 2 foreground (using format #rrggbb or a colour name) .IP \[bu] 2 underline (none, single, double) .PP Example: .IP .EX sep_markup = font=\[dq]Sans Italic 12\[dq] foreground=\[dq]blue\[dq] .EE .RE .TP \f[CR]font\f[R] = \f[B]string\f[R] (unset by default) Font description for menu items. \f[CR]font\f[R] accepts a string such as \f[CR]Cantarell 10\f[R] or \f[CR]UbuntuCondensed 11\f[R]. The font description without a specified size unit is interpreted as \f[CR]points\f[R]. If \f[CR]px\f[R] is added, it will be read as pixels.\ Using \[lq]points\[rq] enables consistency with other applications. .TP \f[CR]font_fallback\f[R] = \f[B]string\f[R] (default xtg) Same as \f[CR]icon_theme_fallback\f[R], except that the xsettings variable \f[CR]Gtk/FontName\f[R] is read. .TP \f[CR]icon_size\f[R] = \f[B]integer\f[R] (default 22) Size of icons in pixels. If set to 0, icons will be disabled. .TP \f[CR]icon_text_spacing\f[R] = \f[B]integer\f[R] (default 10) Distance between icon and text within a menu item .TP \f[CR]icon_norm_alpha\f[R] = \f[B]integer\f[R] (default 100) Opacity of menu item icons, expressed as a percentage (0\-100). .TP \f[CR]icon_sel_alpha\f[R] = \f[B]integer\f[R] (default 100) Opacity of the currently selected menu item\[cq]s icon, expressed as a percentage (0\-100). .TP \f[CR]icon_theme\f[R] = \f[B]string\f[R] (unset by default) Name of icon theme. E.g. \f[CR]Adwaita\f[R], \f[CR]breeze\f[R], \f[CR]Paper\f[R], \f[CR]Papirus\f[R] and \f[CR]Numix\f[R]. See \f[CR]ls /usr/share/icons/\f[R] (or similar) for available icon themes on your system. .TP \f[CR]icon_theme_fallback\f[R] = \f[B]string\f[R] (default xtg) Fallback sources of the icon theme in order of precedence, where the left\-most letter designates the source with highest precedence. The following characters are acceptable: \f[CR]x=xsettings Net/IconThemeName\f[R]; \f[CR]t=tint2\f[R]; \f[CR]g=gtk3.0\f[R]. \f[CR]icon_theme\f[R] takes priority if set. In order to increase consistency with tint2, xsettings variables will only be read if the tint2rc variable \f[CR]launcher_icon_theme_override\f[R] is \f[CR]0\f[R]. .TP \f[CR]arrow_string\f[R] = \f[B]string\f[R] (default ▸) String to be used to indicate that an item will open submenu. See jgmenuunicode(7) for examples .TP \f[CR]arrow_width\f[R] = \f[B]integer\f[R] (default 15) Width allowed for \f[CR]arrow_string\f[R]. Set to 0 to hide arrow. .TP \f[CR]search_empty_string\f[R] = \f[B]string\f[R] (default \f[CR]\f[R]) String to show when no entries match a search. .TP \f[CR]color_menu_bg\f[R] = \f[B]color\f[R] (default #000000 100) Background colour of menu window. If gradients are enabled, this will be the `from' color. .TP \f[CR]color_menu_bg_to\f[R] = \f[B]color\f[R] (default #000000 100) Background `to' colour of menu window \- for use with gradients .TP \f[CR]color_menu_border\f[R] = \f[B]color\f[R] (default #eeeeee 8) Border colour of menu window .TP \f[CR]color_norm_bg\f[R] = \f[B]color\f[R] (default #000000 0) Background colour of menu items, except the one currently selected. .TP \f[CR]color_norm_fg\f[R] = \f[B]color\f[R] (default #eeeeee 100) Font (foreground) colour of menu items, except the one currently selected. .TP \f[CR]color_sel_bg\f[R] = \f[B]color\f[R] (default #ffffff 20) Background color of the currently selected menu item. .TP \f[CR]color_sel_fg\f[R] = \f[B]color\f[R] (default #eeeeee 100) Font (foreground) color of the currently selected menu item. .TP \f[CR]color_sel_border\f[R] = \f[B]color\f[R] (default #eeeeee 8) Border color of the currently selected menu item. .TP \f[CR]color_sep_fg\f[R] = \f[B]color\f[R] (default #ffffff 20) Font (foreground) colour of separators without text .TP \f[CR]color_title_fg\f[R] = \f[B]color\f[R] (default #eeeeee 50) Font (foreground) colour of separators with text. The font colour can be overridden by \f[CR]sep_markup\f[R] .TP \f[CR]color_title_bg\f[R] = \f[B]color\f[R] (default #000000 0) Background colour of separators with text. .TP \f[CR]color_title_border\f[R] = \f[B]color\f[R] (default #000000 0) Border colour of separators with text. .TP \f[CR]color_scroll_ind\f[R] = \f[B]color\f[R] (default #eeeeee 40) Colour of scroll indicator lines (which show if there are menu items above or below those which are visible). .SS CSV generator variables The following variables begin with \f[CR]csv_\f[R] which denotes that they set environment variables which are used by the CSV generators. .TP \f[CR]csv_name_format\f[R] = \f[B]string\f[R] (default \f[CR]%n (%g)\f[R]) Defines the format of the \f[CR]name\f[R] field for CSV generators. Supported by apps and lx. It understands the following two fields: .RS .TP \f[CR]%n\f[R] Application name .TP \f[CR]%g\f[R] Application generic name. If a \f[CR]generic name\f[R] does not exist or is the same as the \f[CR]name\f[R], \f[CR]%n\f[R] will be used without any formatting. .RE .TP \f[CR]csv_single_window\f[R] = \f[B]boolean\f[R] (default 0) If set, csv\-generators will output \[ha]root() instead of \[ha]checkout(). This results in a single window menu, where submenus appear in the same window. This is supported by apps and pmenu. .TP \f[CR]csv_no_dirs\f[R] = \f[B]boolean\f[R] (default 0) If set, csv\-generators will output applications without any directory structure. This is supported by apps, pmenu and lx. .TP \f[CR]csv_i18n\f[R] = \f[B]string\f[R] (no default) Look for a translation file in the specified file or directory. See \[ga]jgmenu\-i18n(1) for further details. Supported by apps and ob. .TP \f[CR]csv_no_duplicates\f[R] = \f[B]boolean\f[R] (default 0) Restrict applications to appear in one directory only. Supported by apps. .SH Inter\-Process Communication (IPC) IPC can be used to align jgmenu to a panel launcher in real\-time. This is currently supported by tint2 and xfce\-panel. It works as follows: .PP \f[CR]jgmenu_run\f[R] reads the environment variables listed below and passes them via a unix socket to the long\-running instance of jgmenu. .PP If \f[CR]position_mode=ipc\f[R], jgmenu aligns to these variables every times it is launched. .PP The following four environment variables define the extremities of the panel: \f[CR]TINT2_BUTTON_PANEL_X1\f[R], \f[CR]TINT2_BUTTON_PANEL_X2\f[R], \f[CR]TINT2_BUTTON_PANEL_Y1\f[R], \f[CR]TINT2_BUTTON_PANEL_Y2\f[R]. .IP .EX (X1,Y1) ╔══════════════════════╗ ║ panel ║ ╚══════════════════════╝ (X2,Y2) .EE .PP The following environment variables define the position of the launcher. These are interpreted differently depending on panel alignment. .PP In the case of a horizontal panel: .IP \[bu] 2 \f[CR]TINT2_BUTTON_ALIGNED_X1\f[R] and \f[CR]TINT2_BUTTON_ALIGNED_X2\f[R] define the launcher button\[cq]s horizontal extremities to align to. .IP \[bu] 2 \f[CR]TINT2_BUTTON_ALIGNED_Y1\f[R] and \f[CR]TINT2_BUTTON_ALIGNED_Y2\f[R] define the edge of the panel to align to. These shall be the same. .PP In the case or a vertical panel, the same rules apply with X and Y reversed. .PP If the above variables are not set, \f[CR]menu_margin_x\f[R] and \f[CR]menu_margin_y\f[R] are used. .SH DIAGRAMS .SS General Notes .TP \f[CR]margin\f[R] Refers to space outside an object .TP \f[CR]padding\f[R] Refers to space inside an object (between border and content) .SS Vertical Menu .IP .EX ╔════════════════════════╗ ║ 1 ║ ╟────────────────────────╢ ║ 2 ║ ╟────────────────────────╢ ║ item ║ ╟────────────────────────╢ ║ 2 ║ ╟────────────────────────╢ ║ item ║ ╟────────────────────────╢ ║ 2 ║ ╟────────────────────────╢ ║ 3 ║ ╚════════════════════════╝ 1. menu_padding_top 2. item_margin_y 3. menu_padding_bottom .EE .SS Horizontal Menu .IP .EX ╔═╤═╤════════════════╤═╤═╗ ║ │ │ │ │ ║ ║ │ ├────────────────┤ │ ║ ║ │ │icon text >│ │ ║ ║ │ ├────────────────┤ │ ║ ║2│1│ │1│3║ ║ │ ├────┬─┬───────┬─┤ │ ║ ║ │ │ 4 │5│ │6│ │ ║ ║ │ ├────┴─┴───────┴─┤ │ ║ ║ │ │ │ │ ║ ║ │ │ │ │ ║ ╚═╧═╧════════════════╧═╧═╝ 1. item_margin_x 2. padding_left 3. padding_right 4. icon_size 5. icon_to_text_spacing 6. arrow_width .EE .SS External to menu .IP .EX screen ╔════════════════════════╗ ║ 2 ║ ║ ┌──────┐ ║ ║ │ root │ ┌──────┐ ║ ║1│ menu │ │ sub │ ║ ║ │ │3│ menu │ ║ ║ └──────┘ │ │ ║ ║ └──────┘ ║ ║ ║ ║ ║ ║ ║ ╚════════════════════════╝ 1. menu_margin_x 2. menu_margin_y 3. sub_spacing .EE .SH HOOKS A hook in jgmenu is a rule which optionally triggers a command and then performs a restart if a file or directory has has changed since the last time the instance of jgmenu was mapped (=made visible \- normally by running jgmenu_run). .PP Hooks are specified in the file $HOME/.config/jgmenu/hooks are take the format .IP .EX , .EE .PP For example, to synchronise with the GTK theme, use this hook: .IP .EX \[ti]/.config/gtk\-3.0/settings.ini,jgmenu_run gtktheme .EE .PP Leave the \f[CR]\f[R] empty to just restart. .PP A number of restart\-hooks are built\-in by default, for example \[ti]/.config/jgmenu/{jgmenurc,append.csv,prepend.csv} and /usr/share/applications. .PP To list all the built\-in hooks, use the keyword \f[CR]print\f[R] in the hook file (on a line on its own). In order to remove all the built\-in hooks, use the keyword \f[CR]clear\f[R]. .SH STARTUP SCRIPT Unless the \f[CR]\-\-vsimple\f[R] argument is used, the file \[ti]/.config/jgmenu/startup is executed on initial startup. .SH SEE ALSO .IP \[bu] 2 \f[CR]jgmenu_run(1)\f[R] .IP \[bu] 2 \f[CR]jgmenututorial(7)\f[R] .IP \[bu] 2 \f[CR]jgmenuunicode(7)\f[R] .PP The jgmenu source code and documentation can be downloaded from \c .UR https://github.com/johanmalm/jgmenu/ .UE \c .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenu.1.md000066400000000000000000000644261472613136300172020ustar00rootroot00000000000000% JGMENU(1) % Johan Malm % 2 January, 2021 # NAME jgmenu - A simple X11 menu # SYNOPSIS jgmenu \[\--no-spawn] \[\--checkout=<*tag*>] \[\--config-file=<*file*>]        \[\--icon-size=<*size*>] \[\--at-pointer] \[\--hide-on-startup]        \[\--simple] \[\--vsimple] \[\--csv-file=<*file*>]        \[\--csv-cmd=<*command*>] \[\--die-when-loaded]        \[\--center] \[\--persistent] Use these commands to get started `jgmenu_run` : Launch menu `jgmenu_run init` : Create config file ~/.config/jgmenu/jgmenurc `jgmenu_run init -i` : Interactive setup `man jgmenututorial` : Step-by-step tutorial # DESCRIPTION `jgmenu` is a simple menu for Linux/BSD. It reads CSV menu data from a file and generates a graphical menu on an X11 window. ## Fields Each line of CSV menu data is parsed into the following fields using comma as a field separator: (1) description (2) command (3) icon (4) working directory (5) metadata For example: printf "Terminal,xterm\\nWeb Browser,firefox" | jgmenu --vsimple ## Special Characters at beginning of line `#` : Ignore line `. ` : A line beginning with a dot followed by a space, will source the file specified by the string following the dot `@` : Treat as widget ## Special Characters in fields `,` : As commas are used as field separators, individual fields can only contain commas if they are triple quoted. For example: foo,"""^pipe(find . -printf '%f,display %p,%p\\n')""" `< > &` : The description field is parsed as pango markup, so `<`, `>`, and `&` need to be escaped as `<`, `>`, and `&` respectively. `"` : Unlike most CSV implementations, a single instance of a double quote (`"`) is not considered a special character. The reason for this is to let users write commands with double quotes without having to escape them. `"""` : Use three quotes `"""` to begin and to end a fully quoted value. The primary use case for this is when a comma is needed within a value. ## Markup The syntax ^foo(bar) is used to carry out action `foo` with argument `bar`. We refer to `bar` as the `inner value`. The following markup is supported in the `description` field `sep()` : Define a separator. If an inner value is provided, the separator will appear as a title. If no inner value is provided, the separator will simply be a horizontal line The following markup is supported in the `command` field `^tag()` : Define the beginning of a new menu structure node. The lines following `^tag(whatever)` will not show in the top level menu, but can be opened by using `^checkout()` or `^root()`. item0.0 item0.1 submenu1,^checkout(1) submenu2,^root(2) ^tag(1) item1.0 item1.1 ^tag(2) item2.0 item2.1 `^checkout()` : Open the tag specified by the inner value as a submenu in a new window `^root()` : Open the tag specified by the inner value in the root window, replacing the current menu `^sub()` : Draw a submenu arrow. This can be useful for creating submenus with `stay_alive=0`. For example: item0.0 item0.1 submenu1,^sub(echo "item1.0" | jgmenu --simple) `^back()` : Check-out parent menu `^term()` : Run program in terminal `^pipe()` : Execute sub-process and checkout a menu based on its stdout. `^filter()` : Invoke search `^quit()` : Quit ## Icons Icons will be displayed if the third field is populated, for example: Terminal,xterm,utilities-terminal Firefox,firefox,firefox # OPTIONS `--no-spawn` : Redirect command to stdout rather than execute it. `--checkout=` : Checkout submenu on startup. `--config-file=` : Read config file. `--icon-size=` : Specify icon size (22 by default). If set to 0, icons will not be loaded. `--at-pointer` : Launch menu at mouse pointer. `--hide-on-startup` : Start menu is hidden state. `--simple` : Ignore tint2 settings; Run in short-lived mode (i.e. exit after mouse click or enter/escape); read menu items from `stdin`. `--vsimple` : Same as `--simple`, but also disables icons and ignores jgmenurc. `--csv-file=` : Specify menu file (in jgmenu flavoured CSV format). If file cannot be opened, input is reverted to `stdin`. `--csv-cmd=` : Specify command to produce menu data, for example `jgmenu_run pmenu` `--die-when-loaded` : Open menu and then exit(0). Useful for debugging and testing. `--center` : Center align menu horizontally and vertically. `--persistent` : Same as the persistent config option. See config option section below for details. # USER INTERFACE `Up`, `Down` : Select previous/next item `Left`. `Right` : Move to parent/sub menu `PgUp`, `PgDn` : Scroll up/down `Home`, `End` : Select first/last item `Enter` : Select an item or open a submenu `F5` : Restart `F8` : Print node tree to stderr `F9` : exit(1) `F10` : exit(0) `Backspace` : Return to parent menu Type any string to invoke a search. Words separated by space will be searched for using `OR` logic (i.e. the match of either word is sufficient to display an item). # WIDGETS {#widgets} Lines beginning with '@' in jgmenu flavoured CSV files are parsed in accordance with the following syntax: @type,action,x,y,w,h,r,halign,valign,fgcol,bgcol,content `type` : The widget type, which can be one of the following: `rect` : Rectangle with a 1px thick border drawn using `fgcol` `search` : Search box showing the current filter (what the user has typed) or the specified `text` if no filter has been invoked. `icon` : Icon `action` : The action to take when selected. This can either be a shell command or a menu action such `^root()`. `x`, `y` : Horizontal and vertical margin of widget `w`, `h` : Width and height of widget `r` : Corner radius `fgcol`, `bgcol` : Foreground and background colours using syntax `rrggbb #aa` `fgcol` accepts `auto` to use the jgmenurc's `color_norm_fg` `content` : `icon_path` for `icon` widgets `text` for all other widget types `halign`, `valign` : Horizontal and vertical alignment of widget. This has not yet been implemented, but defaults to `top` and `left` # CONFIGURATION FILE If no file is specified using the --config-file= option, the XDG Base Directory Specification is adhered to. I.e: - Global config in `${XDG_CONFIG_DIRS:-/etc/xdg}` - User config override in `${XDG_CONFIG_HOME:-$HOME/.config}` For most users ~/.config/jgmenu/jgmenurc is appropriate. Global config variables are set in the following order (i.e. bottom of list has higher precedence): - built-in defaults (config.c) - tint2rc config file (can be specified by `TINT2_CONFIG` environment variable) - jgmenurc config file (can be specified by --config-file=) - command line arguments ## Syntax Lines beginning with `#` are ignored. All other lines are recognised as setting variables in the format key = value White spaces are mostly ignored. ### Values Unless otherwise specified, values as treated as simple strings. Here follow some specific types: `boolean` : When a variable takes a boolean value, only 0 and 1 are accepted. 0 means false; 1 means true. `integer` : When a variable takes an integer value, only numerical values are accepted. The only valid characters are digits (0-9) and minus-sign. All integer variables relating to geometry and position are interpreted as pixel values unless otherwise specified. `color` : When a variable takes a color value, only the syntax `#rrggbb aaa` is recognised, where `rr`, `gg` and `bb` represent hexadecimal values (00-ff) for the colours red, green and blue respectively; and `aaa` stands for the alpha channel value expressed as a percentage (0-100) (i.e. 100 means no transparency and 0 means fully transparent.) For example `#ff0000 100` represents red with no transparency, whereas `#000088 50` means dark blue with 50% transparency. `pathname` : When a variable takes a pathname value, it is evaluated as a string. If the first character is tilde (~), it will be replaced by the the environment variable $HOME just as a shell would expand it. ## Variables `verbosity` = __integer__ (default 0) : General verbosity: (0) warnings only; (1) basic info; (2) more info; (3) max info Additional specific topics: (4) IPC Note: Some IPC messages need environment variable `JGMENU_VERBOSITY=4` too `stay_alive` = __boolean__ (default 1) : If set to 1, the menu will "hide" rather than "exit" when the following events occur: clicking on menu item; clicking outside the menu; pressing escape. When in the hidden mode, a USR1 signal will "un-hide" the menu. `persistent` = __boolean__ (default 0) : If set to 1, the menu will not exit nor hide when the following events occur: clicking on menu item; clicking outside the menu; pressing escape. Use in conjunction with the ^quit() markup. `hide_on_startup` = __boolean__ (default 0) : If set to 1, jgmenu start in "hidden" mode. This is useful for starting jgmenu during the boot process and then sending a `killall -SIGUSR1 jgmenu` to show the menu. `csv_cmd` = __string__ (default `apps`) : Defines the command to produce the jgmenu flavoured CSV for `jgmenu`. Accpetable keyword include apps, pmenu, lx, and ob. If a value is given other than these keywords, it will be executed in a shell (so be careful!). If left blank, jgmenu will read from `stdin`. Examples: csv_cmd = lx csv_cmd = jgmenu_run lx --no-dirs csv_cmd = cat ~/mymenu.csv `tint2_look` = __boolean__ (default 0) : Read tint2rc and parse config options for colours, dimensions and alignment. `position_mode` = (fixed | ipc | pointer | center) (default fixed) : Define menu positioning mode. `fixed` : Align to `margin_{x,y}` and respect `_NET_WORKAREA`. `ipc` : Use IPC to read environment variables set by panel. See [Inter-Process Communication](#ipc) for further info. `pointer` : Launch at pointer whilst respecting both `_NET_WORKAREA` and `edge_snap_x`. `center` : Launch at center of screen and ignore `_NET_WORKAREA`. Take precedence over `menu_{v,h}align`. `edge_snap_x` = __integer__ (default 30) : Specify the distance (in pixels) from the left hand edge, within which the menu will snap to the edge. Note that this only applies in `at_pointer` mode. `terminal_exec` = __string__ (default x-terminal-emulator) : Define terminal to use for commands with ^term() markup `terminal_args` = __string__ (default -e) : The values of these two variables are used to build a string to launch programs requiring a terminal to run. With the default values, the string would become: `x-terminal-emulator -e 'some_command with arguments'`. `terminal_args` must finish with `-e` or equivalent, where `-e` refers to the meaning of `-e` in `xterm -e`. `monitor` = __integer__ (default 0) : Specify a particular monitor as an index starting from 1. If 0, the menu will be launched on the monitor where the mouse is. `hover_delay` = __integer__ (default 100) : Time (in milliseconds) from hovering over an item until a submenu is opened. `hide_back_items` = __boolean__ (default 1) : If enabled, all ^back() items will be suppressed. As a general rule, it should be set to 1 for a multi-window menu, and 0 when in single-window mode. `columns` = __integer__ (default 1) : Number of columns in which to show menu items `tabs` = __integer__ (default 120) : Specify the position is pixels of the first tab `menu_margin_x` = __integer__ (default 0) : Distance between the menu (=X11 window) and the edge of the screen. See note on `_NET_WORKAREA` under `menu_{v,h}align` variables. `menu_margin_y` = __integer__ (default 0) : Vertical equilvalent of `menu_margin_x` `menu_width` = __integer__ (default 200) : Minimum menu width of the menu. The menu width will adjust to the longest item in the current (sub)menu. If a filter is applied (e.g. by the user typing) the menu width will not adjust. `menu_height_min` = __integer__ (default 0) : Set the minimum height of the root menu. If `menu_height_min` and `menu_height_max` these are set to the same value, the menu height will be fixed at that value. If set to zero, they will be ignored. `menu_height_max` = __integer__ (default 0) : Minimum height of the root menu. See `menu_height_min` `menu_height_mode` = (static | dynamic) (default static) : Mode of menu height `static` : Height of the initial root menu will be used for any subsequent `^root()` action `dynamic` : Root menu height will be re-calculated every time a new tag is opened using `^root()`. `menu_padding_top` = __integer__ (default 5) : Distance between top border and item/widget `menu_padding_right` = __integer__ (default 5) : Distance between right border and item/widget `menu_padding_bottom` = __integer__ (default 5) : Distance between bottom border and item/widget `menu_padding_left` = __integer__ (default 5) : Distance between left border and item/widget `menu_radius` = __integer__ (default 1) : Radius of rounded corners of menu `menu_border` = __integer__ (default 0) : Thickness of menu border `menu_halign` = (left | right | center) (default left) : Horizontal alignment of menu. If not set, jgmenu will try to guess the alignment reading `_NET_WORKAREA`, which is a freedesktop EWMH root window property. Not all Window Managers and Panels respect `_NET_WORKAREA`. The following do: openbox, xfwm4, tint2 and polybar. The following do NOT: awesome, i3, bspwm and plank `menu_valign` = (top | bottom | center) (default bottom) : Vertical alignment of menu. See `menu_halign`. `menu_gradient_pos` = (none | top | right | bottom | left | top_left | top_right | bottom_left | bottom_right ) (default none) : Start position of menu window gradient. The end position is at the opposite side or corner. Colors color_menu_bg and color_menu_bg_to specify the start (from) and finish (to). `sub_spacing` = __integer__ (default 1) : Horizontal space between windows. A negative value results in each submenu window overlapping its parent window. `sub_padding_top` = __integer__ (default auto) : Same as `menu_padding_top` but applies to submenu windows only. It understands the keyword `auto` which means that the smallest of the four `menu_padding_*` variables will be used. `sub_padding_right` = __integer__ (default auto) : See `sub_padding_top` `sub_padding_bottom` = __integer__ (default auto) : See `sub_padding_top` `sub_padding_left` = __integer__ (default auto) : See `sub_padding_top` `sub_hover_action` = __integer__ (default 1) : Open submenu when hovering over item (only works in multi-window mode). `item_margin_x` = __integer__ (default 3) : Horizontal distance between items and the edge of the menu. `item_margin_y` = __integer__ (default 3) : Vertical distance between items and the edge of the menu. `item_height` = __integer__ (default 25) : Height of menu items. `item_padding_x` = __integer__ (default 4) : Horizontal distance between item edge and its content (e.g. text or icon) `item_radius` = __integer__ (default 1) : Radius of rounded corners of items `item_border` = __integer__ (default 0) : Thickness of item border `item_halign` = (left | right) (default left) : Horizontal alignment of menu items. If set to `right`, the option `arrow_string` should be changed too. `sep_height` = __integer__ (default 5) : Height of separator without text (defined by ^sep()). Separators with text use `item_height` `sep_halign` = (left | center | right) (default left) : Horizontal alignment of separator text `sep_markup` = __string__ (unset by default) : If specified, `foo` will be passed to pango for ^sep(foo). See the following link for pango attributes: [https://docs.gtk.org/Pango/pango_markup.html](https://docs.gtk.org/Pango/pango_markup.html) Keywords include (but are not limited to): - font - size (x-small, small, medium, large, x-large) - style (normal, oblique, italic) - weight (ultralight, light, normal, bold, ultrabold, heavy - foreground (using format #rrggbb or a colour name) - underline (none, single, double) Example: sep_markup = font="Sans Italic 12" foreground="blue" `font` = __string__ (unset by default) : Font description for menu items. `font` accepts a string such as `Cantarell 10` or `UbuntuCondensed 11`. The font description without a specified size unit is interpreted as `points`. If `px` is added, it will be read as pixels. Using "points" enables consistency with other applications. `font_fallback` = __string__ (default xtg) : Same as `icon_theme_fallback`, except that the xsettings variable `Gtk/FontName` is read. `icon_size` = __integer__ (default 22) : Size of icons in pixels. If set to 0, icons will be disabled. `icon_text_spacing` = __integer__ (default 10) : Distance between icon and text within a menu item `icon_norm_alpha` = __integer__ (default 100) : Opacity of menu item icons, expressed as a percentage (0-100). `icon_sel_alpha` = __integer__ (default 100) : Opacity of the currently selected menu item's icon, expressed as a percentage (0-100). `icon_theme` = __string__ (unset by default) : Name of icon theme. E.g. `Adwaita`, `breeze`, `Paper`, `Papirus` and `Numix`. See `ls /usr/share/icons/` (or similar) for available icon themes on your system. `icon_theme_fallback` = __string__ (default xtg) : Fallback sources of the icon theme in order of precedence, where the left-most letter designates the source with highest precedence. The following characters are acceptable: `x=xsettings Net/IconThemeName`; `t=tint2`; `g=gtk3.0`. `icon_theme` takes priority if set. In order to increase consistency with tint2, xsettings variables will only be read if the tint2rc variable `launcher_icon_theme_override` is `0`. `arrow_string` = __string__ (default ▸) : String to be used to indicate that an item will open submenu. See jgmenuunicode(7) for examples `arrow_width` = __integer__ (default 15) : Width allowed for `arrow_string`. Set to 0 to hide arrow. `search_empty_string` = __string__ (default ``) : String to show when no entries match a search. `color_menu_bg` = __color__ (default #000000 100) : Background colour of menu window. If gradients are enabled, this will be the 'from' color. `color_menu_bg_to` = __color__ (default #000000 100) : Background 'to' colour of menu window - for use with gradients `color_menu_border` = __color__ (default #eeeeee 8) : Border colour of menu window `color_norm_bg` = __color__ (default #000000 0) : Background colour of menu items, except the one currently selected. `color_norm_fg` = __color__ (default #eeeeee 100) : Font (foreground) colour of menu items, except the one currently selected. `color_sel_bg` = __color__ (default #ffffff 20) : Background color of the currently selected menu item. `color_sel_fg` = __color__ (default #eeeeee 100) : Font (foreground) color of the currently selected menu item. `color_sel_border` = __color__ (default #eeeeee 8) : Border color of the currently selected menu item. `color_sep_fg` = __color__ (default #ffffff 20) : Font (foreground) colour of separators without text `color_title_fg` = __color__ (default #eeeeee 50) : Font (foreground) colour of separators with text. The font colour can be overridden by `sep_markup` `color_title_bg` = __color__ (default #000000 0) : Background colour of separators with text. `color_title_border` = __color__ (default #000000 0) : Border colour of separators with text. `color_scroll_ind` = __color__ (default #eeeeee 40) : Colour of scroll indicator lines (which show if there are menu items above or below those which are visible). ## CSV generator variables The following variables begin with `csv_` which denotes that they set environment variables which are used by the CSV generators. `csv_name_format` = __string__ (default `%n (%g)`) : Defines the format of the `name` field for CSV generators. Supported by apps and lx. It understands the following two fields: `%n` : Application name `%g` : Application generic name. If a `generic name` does not exist or is the same as the `name`, `%n` will be used without any formatting. `csv_single_window` = __boolean__ (default 0) : If set, csv-generators will output ^root() instead of ^checkout(). This results in a single window menu, where submenus appear in the same window. This is supported by apps and pmenu. `csv_no_dirs` = __boolean__ (default 0) : If set, csv-generators will output applications without any directory structure. This is supported by apps, pmenu and lx. `csv_i18n` = __string__ (no default) : Look for a translation file in the specified file or directory. See `jgmenu-i18n(1) for further details. Supported by apps and ob. `csv_no_duplicates` = __boolean__ (default 0) : Restrict applications to appear in one directory only. Supported by apps. # Inter-Process Communication (IPC) {#ipc} IPC can be used to align jgmenu to a panel launcher in real-time. This is currently supported by tint2 and xfce-panel. It works as follows: `jgmenu_run` reads the environment variables listed below and passes them via a unix socket to the long-running instance of jgmenu. If `position_mode=ipc`, jgmenu aligns to these variables every times it is launched. The following four environment variables define the extremities of the panel: `TINT2_BUTTON_PANEL_X1`, `TINT2_BUTTON_PANEL_X2`, `TINT2_BUTTON_PANEL_Y1`, `TINT2_BUTTON_PANEL_Y2`. ``` (X1,Y1) ╔══════════════════════╗ ║ panel ║ ╚══════════════════════╝ (X2,Y2) ``` The following environment variables define the position of the launcher. These are interpreted differently depending on panel alignment. In the case of a horizontal panel: - `TINT2_BUTTON_ALIGNED_X1` and `TINT2_BUTTON_ALIGNED_X2` define the launcher button's horizontal extremities to align to. - `TINT2_BUTTON_ALIGNED_Y1` and `TINT2_BUTTON_ALIGNED_Y2` define the edge of the panel to align to. These shall be the same. In the case or a vertical panel, the same rules apply with X and Y reversed. If the above variables are not set, `menu_margin_x` and `menu_margin_y` are used. # DIAGRAMS {#diagrams} ## General Notes `margin` : Refers to space outside an object `padding` : Refers to space inside an object (between border and content) ## Vertical Menu ``` ╔════════════════════════╗ ║ 1 ║ ╟────────────────────────╢ ║ 2 ║ ╟────────────────────────╢ ║ item ║ ╟────────────────────────╢ ║ 2 ║ ╟────────────────────────╢ ║ item ║ ╟────────────────────────╢ ║ 2 ║ ╟────────────────────────╢ ║ 3 ║ ╚════════════════════════╝ 1. menu_padding_top 2. item_margin_y 3. menu_padding_bottom ``` ## Horizontal Menu ``` ╔═╤═╤════════════════╤═╤═╗ ║ │ │ │ │ ║ ║ │ ├────────────────┤ │ ║ ║ │ │icon text >│ │ ║ ║ │ ├────────────────┤ │ ║ ║2│1│ │1│3║ ║ │ ├────┬─┬───────┬─┤ │ ║ ║ │ │ 4 │5│ │6│ │ ║ ║ │ ├────┴─┴───────┴─┤ │ ║ ║ │ │ │ │ ║ ║ │ │ │ │ ║ ╚═╧═╧════════════════╧═╧═╝ 1. item_margin_x 2. padding_left 3. padding_right 4. icon_size 5. icon_to_text_spacing 6. arrow_width ``` ## External to menu ``` screen ╔════════════════════════╗ ║ 2 ║ ║ ┌──────┐ ║ ║ │ root │ ┌──────┐ ║ ║1│ menu │ │ sub │ ║ ║ │ │3│ menu │ ║ ║ └──────┘ │ │ ║ ║ └──────┘ ║ ║ ║ ║ ║ ║ ║ ╚════════════════════════╝ 1. menu_margin_x 2. menu_margin_y 3. sub_spacing ``` # HOOKS A hook in jgmenu is a rule which optionally triggers a command and then performs a restart if a file or directory has has changed since the last time the instance of jgmenu was mapped (=made visible - normally by running jgmenu_run). Hooks are specified in the file $HOME/.config/jgmenu/hooks are take the format , For example, to synchronise with the GTK theme, use this hook: ~/.config/gtk-3.0/settings.ini,jgmenu_run gtktheme Leave the `` empty to just restart. A number of restart-hooks are built-in by default, for example ~/.config/jgmenu/{jgmenurc,append.csv,prepend.csv} and /usr/share/applications. To list all the built-in hooks, use the keyword `print` in the hook file (on a line on its own). In order to remove all the built-in hooks, use the keyword `clear`. # STARTUP SCRIPT Unless the `--vsimple` argument is used, the file ~/.config/jgmenu/startup is executed on initial startup. # SEE ALSO - `jgmenu_run(1)` - `jgmenututorial(7)` - `jgmenuunicode(7)` The jgmenu source code and documentation can be downloaded from [https://github.com/johanmalm/jgmenu/](https://github.com/johanmalm/jgmenu/) jgmenu-4.5.0/docs/manual/jgmenu_run.1000066400000000000000000000021711472613136300174540ustar00rootroot00000000000000.\" Automatically generated by Pandoc 2.2.1 .\" .TH "JGMENU_RUN" "1" "3 December, 2019" "" "" .hy .SH NAME .PP \f[C]jgmenu_run\f[] \- A wrapper for jgmenu .SH SYNOPSIS .PP \f[C]jgmenu_run\f[] .PD 0 .P .PD \f[C]jgmenu_run\f[] <\f[I]command\f[]> .PD 0 .P .PD \f[C]jgmenu_run\f[] <\f[I]option\f[]> .SH DESCRIPTION .PP Use without \f[C]command\f[] or \f[C]option\f[] to launch menu. If an instance of jgmenu is already running, this will be mapped (=made visible), otherwise a new instances will be started. .PP Use with \f[C]command\f[] to call any programe in $libexecdir/jgmenu which containis executable programs designed to be run by jgmenu rather than directly by users. .SH OPTIONS .TP .B \f[C]\-\-help\f[] Print help message .RS .RE .TP .B \f[C]\-\-exec\-path\f[] Print path to $libexecdir/jgmenu which is where jgmenu commands are installed. .RS .RE .SH EXAMPLES .PP Launch menu .IP .nf \f[C] jgmenu_run \f[] .fi .PP Run the following to see all \f[C]jgmenu_run\f[] commands: .IP .nf \f[C] ls\ $(jgmenu_run\ \-\-exec\-path) \f[] .fi .SH SEE ALSO .IP \[bu] 2 \f[C]jgmenu(1)\f[] .IP \[bu] 2 \f[C]jgmenututorial(7)\f[] .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenu_run.1.md000066400000000000000000000015361472613136300200570ustar00rootroot00000000000000% JGMENU_RUN(1) % Johan Malm % 3 December, 2019 # NAME `jgmenu_run` - A wrapper for jgmenu # SYNOPSIS `jgmenu_run` `jgmenu_run` <*command*> `jgmenu_run` <*option*> # DESCRIPTION Use without `command` or `option` to launch menu. If an instance of jgmenu is already running, this will be mapped (=made visible), otherwise a new instances will be started. Use with `command` to call any programe in $libexecdir/jgmenu which containis executable programs designed to be run by jgmenu rather than directly by users. # OPTIONS `--help` : Print help message `--exec-path` : Print path to $libexecdir/jgmenu which is where jgmenu commands are installed. # EXAMPLES {#examples} Launch menu jgmenu_run Run the following to see all `jgmenu_run` commands: ls $(jgmenu_run --exec-path) # SEE ALSO - `jgmenu(1)` - `jgmenututorial(7)` jgmenu-4.5.0/docs/manual/jgmenututorial.7000066400000000000000000000272701472613136300203710ustar00rootroot00000000000000.\" Automatically generated by Pandoc 2.2.1 .\" .TH "JGMENUTUTORIAL" "7" "21 February, 2020" "" "" .hy .SH NAME .PP jgmenututorial \- A step\-by\-step tutorial to jgmenu .SH INTRODUCTION .PP This tutorial aims to explain the usage of jgmenu through a set of lessons. .SH TABLE OF CONTENTS .IP \[bu] 2 Lesson 1\ \- Get started .PD 0 .P .PD .IP \[bu] 2 Lesson 2\ \- Architecture .PD 0 .P .PD .IP \[bu] 2 Lesson 3\ \- Scripting with jgmenu .PD 0 .P .PD .IP \[bu] 2 Lesson 4\ \- Descriptions .PD 0 .P .PD .IP \[bu] 2 Lesson 5\ \- Icons .PD 0 .P .PD .IP \[bu] 2 Lesson 6\ \- Submenus .PD 0 .P .PD .IP \[bu] 2 Lesson 7\ \- XDG Application Menus .PD 0 .P .PD .IP \[bu] 2 Lesson 8\ \- Config Options .PD 0 .P .PD .IP \[bu] 2 Lesson 9\ \- Apprend/Prepend and Separators .PD 0 .P .PD .IP \[bu] 2 Lesson 10 \- CSV generators .PD 0 .P .PD .IP \[bu] 2 Lesson 11 \- Search .SH Lesson 1 \- Get started .PP After installing jgmenu, start the menu by running the following command .IP .nf \f[C] jgmenu_run \f[] .fi .PP You should see a Linux/BSD system menu showing installed applications. See lesson 7 for further details. .PP Create a config file (\f[C]~/.config/jgmenu/jgmenurc\f[]) by running .IP .nf \f[C] jgmenu_run\ init \f[] .fi .PP Full details of config options are covered in jgmenu(1) (jgmenu.1.html). .PP By entering the interactive mode and then selecting `t', you can try some pre\-defined templates/themes. .IP .nf \f[C] jgmenu_run\ init\ \-i \f[] .fi .PP There are a small number of configuration options which may need manual intervention in order for jgmenu to display correctly on your system. .TP .B \f[C]position_mode\f[] There are several methods for positioning the menu. Try \f[C]fixed\f[], \f[C]ipc\f[], \f[C]center\f[] and \f[C]pointer\f[] to see what works best on your system. See jgmenu(1) for full details. .RS .RE .TP .B \f[C]menu_margin_x\f[] and \f[C]menu_margin_y\f[] If your are using \f[C]position_mode=fixed\f[], you may 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 without setting these variables first. .RS .RE .TP .B \f[C]menu_halign\f[] and \f[C]menu_valign\f[] Again, depending on your system, you may need to manually specify horizontal and vertical alignment of the menu, but try without first. .RS .RE .SH Lesson 2 \- Architecture .PP The design of jgmenu is very modular, providing a lot of flexibility in how it is used. .PP When jgmenu is started, two processes are run to produce the menu. .IP .nf \f[C] ┌────────────────┐ │\ csv\-generator\ \ │ └────────────────┘ \ \ \ \ \ \ \ \ | \ \ \ \ \ \ \ \ V ┌────────────────┐ │\ graphical\ menu\ │ └────────────────┘ \f[] .fi .PP The first process (csv\-generator) produces the menu content, whereas the second generates the graphical menu. .PP jgmenu_run(1) (jgmenu_run.1.html) is a multi\-purpose wrapper script which does the following is pseudo code: .IP .nf \f[C] if\ (jgmenu\ is\ already\ running) \ \ \ \ \ \ \ \ show\ menu else \ \ \ \ \ \ \ \ start\ a\ new\ instance\ of\ jgmenu \f[] .fi .PP This makes it suitable for using with panels and keyboard shortcuts. .SH Lesson 3 \- Scripting with jgmenu .PP From this point onwards, it is assumed that you understand basic shell usage including re\-direction (e.g. <, >) and piping (e.g. |). .PP The syntax below (here\-document) is used to denote the creation of a text file from whatever is between the EOFs. You can of course use your favourite text editor instead. .IP .nf \f[C] cat\ >file\ <foo.txt\ <menu.sh #!/bin/sh ( printf\ "foo\\n" printf\ "bar\\n" )\ |\ jgmenu\ \-\-vsimple EOF chmod\ +x\ menu.sh \&./menu.sh \f[] .fi .SH Lesson 4 \- Descriptions .PP As you saw in the previous example, each line fed to \f[C]stdin\f[] becomes a menu item. Any line containing two fields separated by a comma is parsed as \f[C]description\f[],\f[C]command\f[]. Consider the following CSV menu data: .IP .nf \f[C] Terminal,xterm File\ Manager,pcmanfm \f[] .fi .PP This lets you give a more meaningful description to each menu item. .SH Lesson 5 \- Icons .PP 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). When running with the \[en]simple argument, make sure that \f[C]icon_theme\f[] is set to something sensible in your $HOME/.config/jgmenu/jgmenurc. Consider the following CSV menu data: .IP .nf \f[C] 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 \f[] .fi .PP In the third field you can also specify the full path if you wish. .SH Lesson 6 \- Submenus .PP So far we have looked at producing a single \[lq]root\[rq] menu only. jgmenu understands a small amount of markup and enables submenus by ^tag() and ^checkout(). Try this: .IP .nf \f[C] Terminal,xterm File\ Manager,pcmanfm Settings,^checkout(settings) ^tag(settings) Set\ Background\ Image,nitrogen \f[] .fi .PP In pseudo\-code, build your CSV file as follows: .IP .nf \f[C] #\ 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 \f[] .fi .PP \f[C]^root()\f[] can be used instead of \f[C]^checkout()\f[] in order to open the submenu in the parent window. .SH Lesson 7 \- XDG Application Menus .PP 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: .TP .B \f[C]\&.menu\f[] XML file describing menu categories and directory structure. Located in \f[C]/etc/xdg/menus/\f[], or XDG_CONFIG_{HOME,DIRS} equivalent. .RS .RE .TP .B \f[C]\&.directory\f[] Describe menu directories. Located in \f[C]/usr/share/desktop\-directories/\f[], or XDG_DATA_{HOME,DIRS} equivalent. .RS .RE .TP .B \f[C]\&.desktop\f[] Describe applications and contain most of the information needed to build a menu (e.g. \f[C]Name\f[], \f[C]Exec\ command\f[], \f[C]Icon\f[] and \f[C]Category\f[]) Located in \f[C]/usr/share/applications/\f[], or XDG_DATA_{HOME,DIRS} equivalent. .RS .RE .PP Most desktop applications provided their own associated .desktop files, whereas .menu and .directory files are supplied by menu packages, such as libmenu\-cache (LXDE) and libcargon (XFCE). .PP 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. Whilst this deviates from XDG menu spec, it is much simpler to understand and tweak. It also avoids reliance on menu packages. .PP For strict XDG compliance, the optional module jgmenu\-lx(1) (jgmenu-lx.1.html) can be used. .PP See Lesson 10 for generic instructions on modules. .SH Lesson 8 \- Config Options .PP In lesson 1 we discussed config options \f[C]position_mode\f[], \f[C]menu_margin_x\f[], \f[C]menu_margin_y\f[], \f[C]menu_halign\f[] and \f[C]menu_valign\f[]. .PP Here follow a few more options you may wish to explore. For full details, see jgmenu(1) (jgmenu.1.html). .PP Rofi style: .IP .nf \f[C] csv_no_dirs=1 csv_single_window=1 columns=2 menu_width=600 menu_valign=center menu_halign=center \f[] .fi .PP Synchronize colours, font and icons with tint2 panel .IP .nf \f[C] tint2_look=1 \f[] .fi .SH Lesson 9 \- Apprend/Prepend and Separators .PP When using \f[C]apps\f[], \f[C]pmenu\f[] or \f[C]lx\f[], 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: .PP prepend.csv .IP .nf \f[C] Browser,\ \ \ \ \ \ firefox,\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ firefox File\ manager,\ pcmanfm,\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ system\-file\-manager Terminal,\ \ \ \ \ xterm,\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ utilities\-terminal ^sep() \f[] .fi .PP append.csv .IP .nf \f[C] ^sep() Suspend,\ \ \ \ \ \ systemctl\ \-i\ suspend,\ \ system\-log\-out Reboot,\ \ \ \ \ \ \ systemctl\ \-i\ reboot,\ \ \ system\-reboot Poweroff,\ \ \ \ \ systemctl\ \-i\ poweroff,\ system\-shutdown \f[] .fi .PP In these example we have used the markup ^sep(), which inserts a horizontal separator line. Similarly, ^sep(foo) inserts a text separator displaying \[lq]foo\[rq] .SH Lesson 10 \- CSV generators .PP In previous lessons, we introduced the \f[C]apps\f[], \f[C]lx\f[] and \f[C]pmenu\f[]. These modules are referred to as \[lq]CSV generators\[rq] and are invoked as follows: .IP .nf \f[C] jgmenu_run\ \f[] .fi .PP Built\-in \[lq]CSV generators\[rq] include: \f[C]apps\f[] and \f[C]ob\f[] .PP Optional \[lq]CSV generators\[rq] include: \f[C]lx\f[] and \f[C]pmenu\f[] .PP They are documented by a man page or a simple \[en]help message. .IP .nf \f[C] man\ jgmenu\- jgmenu_run\ \ \-\-help \f[] .fi .PP Here follow some examples of how they can be used. .PP Specify CSV generator in the config file by setting \f[C]csv_cmd\f[] in \f[C]~/.config/jgmenu/jgmenurc\f[] .IP .nf \f[C] csv_cmd\ =\ pmenu \f[] .fi .PP Specify CSV generator on the command line .IP .nf \f[C] jgmenu\ \-\-csv\-cmd="jgmenu_run\ pmenu" \f[] .fi .PP Pipe the CSV output to jgmenu (using \f[C]\-\-simple\f[] to read from\ \f[C]stdin\f[]) .IP .nf \f[C] jgmenu_run\ pmenu\ |\ jgmenu\ \-\-simple \f[] .fi .PP Create a pipemenu using ^pipe() markup. Consider this example .IP .nf \f[C] Terminal,xterm File\ Manager,pcmanfm ^pipe(jgmenu_run\ pmenu) \f[] .fi .SH Lesson 11 \- Search .PP jgmenu has search support, which can be invoked by just typing when the menu is open. .PP A search box can be inserted using widgets. For example, add this to ~/.config/jgmenu/prepend.csv: .IP .nf \f[C] \@search,,3,3,150,20,2,left,top,auto,#000000\ 0,Type\ to\ Search \f[] .fi .PP Make sure you adjust menu padding accordingly, for example .IP .nf \f[C] menu_padding_top=24 \f[] .fi .PP A search can also be invoked by associating a widget with a ^filter() command. .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenututorial.7.md000066400000000000000000000247471472613136300207760ustar00rootroot00000000000000% JGMENUTUTORIAL(7) % Johan Malm % 21 February, 2020 # NAME jgmenututorial - A step-by-step tutorial to jgmenu # INTRODUCTION This tutorial aims to explain the usage of jgmenu through a set of lessons. # TABLE OF CONTENTS - [Lesson 1 - Get started](#lesson1) - [Lesson 2 - Architecture](#lesson2) - [Lesson 3 - Scripting with jgmenu](#lesson3) - [Lesson 4 - Descriptions](#lesson4) - [Lesson 5 - Icons](#lesson5) - [Lesson 6 - Submenus](#lesson6) - [Lesson 7 - XDG Application Menus](#lesson7) - [Lesson 8 - Config Options](#lesson8) - [Lesson 9 - Apprend/Prepend and Separators](#lesson9) - [Lesson 10 - CSV generators](#lesson10) - [Lesson 11 - Search](#lesson11) # Lesson 1 - Get started {#lesson1} After installing jgmenu, start the menu by running the following command jgmenu_run You should see a Linux/BSD system menu showing installed applications. See [lesson 7](#lesson7) for further details. Create a config file (`~/.config/jgmenu/jgmenurc`) by running jgmenu_run init Full details of config options are covered in [jgmenu(1)](jgmenu.1.html). By entering the interactive mode and then selecting 't', you can try some pre-defined templates/themes. jgmenu_run init -i There are a small number of configuration options which may need manual intervention in order for jgmenu to display correctly on your system. `position_mode` : There are several methods for positioning the menu. Try `fixed`, `ipc`, `center` and `pointer` to see what works best on your system. See jgmenu(1) for full details. `menu_margin_x` and `menu_margin_y` : If your are using `position_mode=fixed`, you may 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 without setting these variables first. `menu_halign` and `menu_valign` : Again, depending on your system, you may need to manually specify horizontal and vertical alignment of the menu, but try without first. # Lesson 2 - Architecture {#lesson2} The design of jgmenu is very modular, providing a lot of flexibility in how it is used. 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. [jgmenu_run(1)](jgmenu_run.1.html) is a multi-purpose wrapper script which does the following is pseudo code: if (jgmenu is already running) show menu else start a new instance of jgmenu This makes it suitable for using with panels and keyboard shortcuts. # Lesson 3 - Scripting with jgmenu {#lesson3} From this point onwards, it is assumed that you understand basic shell usage including re-direction (e.g. \<, >) and piping (e.g. |). The syntax below (here-document) is used to denote the creation of a text file from whatever is between the EOFs. You can of course use your favourite text editor instead. cat >file <foo.txt <menu.sh #!/bin/sh ( printf "foo\\n" printf "bar\\n" ) | jgmenu --vsimple EOF chmod +x menu.sh ./menu.sh # Lesson 4 - Descriptions {#lesson4} As you saw in the previous example, each line fed to `stdin` becomes a menu item. Any line containing two fields separated by a comma is parsed as `description`,`command`. Consider the following CSV menu data: Terminal,xterm File Manager,pcmanfm This lets you give a more meaningful description to each menu item. # Lesson 5 - Icons {#lesson5} 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). 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 In the third field you can also specify the full path if you wish. # Lesson 6 - Submenus {#lesson6} So far we have looked at producing a single "root" menu only. jgmenu understands a small amount of markup and 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, build your CSV file as follows: # 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 `^root()` can be used instead of `^checkout()` in order to open the submenu in the parent window. # Lesson 7 - XDG Application Menus {#lesson7} 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: `.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 provided 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. Whilst this deviates from XDG menu spec, it is much simpler to understand and tweak. It also avoids reliance on menu packages. For strict XDG compliance, the optional module [jgmenu-lx(1)](jgmenu-lx.1.html) can be used. See [Lesson 10](#lesson10) for generic instructions on modules. # Lesson 8 - Config Options {#lesson8} In lesson 1 we discussed config options `position_mode`, `menu_margin_x`, `menu_margin_y`, `menu_halign` and `menu_valign`. Here follow 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 {#lesson9} 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 example we have used the markup ^sep(), which inserts a horizontal separator line. Similarly, ^sep(foo) inserts a text separator displaying "foo" # Lesson 10 - CSV generators {#lesson10} In previous lessons, we introduced the `apps`, `lx` and `pmenu`. These modules are referred to as "CSV generators" and are invoked as follows: jgmenu_run Built-in "CSV generators" include: `apps` and `ob` Optional "CSV generators" include: `lx` and `pmenu` They are documented by a man page or a simple --help message. man jgmenu- jgmenu_run --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) # Lesson 11 - Search {#lesson11} jgmenu has search support, which can be invoked by just typing when the menu is open. A search box can be inserted 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 Make sure you adjust menu padding accordingly, for example menu_padding_top=24 A search can also be invoked by associating a widget with a ^filter() command. jgmenu-4.5.0/docs/manual/jgmenuunicode.7000066400000000000000000000050721472613136300201500ustar00rootroot00000000000000.\" Automatically generated by Pandoc 2.10.1 .\" .TH "JGMENUUNICODE" "7" "7 October, 2020" "" "" .hy .SH NAME .PP jgmenuunicode - An overview of jgmenu unicode usage .SH INTRODUCTION .PP Unicode characters can be displayed by jgmenu. They can be used in: .IP \[bu] 2 CSV data .PD 0 .P .PD .IP \[bu] 2 Widgets .PD 0 .P .PD .IP \[bu] 2 Config file .PP Throughout this document, unicode code points will be referred to by writing \f[C]u+\f[R] followed by their hexadecimal number. In examples, u+1234 will be used. .SH UNICODE CHARACTERS IN TERMINAL .PP Terminals handle unicode differently. For full support, avoid xterm and urxvt, and opt for something libvte based such as sakura or gnome-terminal. In a terminal, you can produce a unicode character by issuing .IP .nf \f[C] printf \[aq]%b\[aq] \[aq]\[rs]\[rs]u1234\[aq] \f[R] .fi .PP In libvte terminals, you can press ctrl+shift+u and then enter the hex sequence. .SH UNICODE CHARACTERS IN VIM .PP Whilst in insert mode, press ctrl+V and then type u1234. .PP Use the command \f[C]ga\f[R] to show the hex value of the character under the cursor. .SH VARIATION SELECTORS .PP Some unicode characters can be rendered as either emoji or text. Special invisible unicode characters called variation selectors can be used to force either presentation. Append with the text presentation selector (u+fe0e) or emoji presentation selector (u+fe0f), to force text or emoji respectively. For example: .PP u+1f50d u+fe0f \[u1F50D] .PD 0 .P .PD u+1f50d u+fe0e \[u1F50D]\[uFE0E] .SH USEFUL CHARACTERS FOR BUILDING MENUS .SS SEARCH .PP u+2315 \[u2315] .PD 0 .P .PD u+26b2 \[u26B2] .PD 0 .P .PD u+1c04 \[u1C04] .SS ARROWS .PP u+2192 \[->] .PD 0 .P .PD u+203a \[fc] .PD 0 .P .PD u+25b6 \[u25B6] .PD 0 .P .PD u+2794 \[u2794] .PD 0 .P .PD u+2799 \[u2799] .PD 0 .P .PD u+279b \[u279B] .PD 0 .P .PD u+279c \[u279C] .PD 0 .P .PD u+279d \[u279D] .PD 0 .P .PD u+279e \[u279E] .PD 0 .P .PD u+279f \[u279F] .PD 0 .P .PD u+27a0 \[u27A0] .PD 0 .P .PD u+27a1 \[u27A1] .PD 0 .P .PD u+27a2 \[u27A2] .PD 0 .P .PD u+27a3 \[u27A3] .PD 0 .P .PD u+27a4 \[u27A4] .PD 0 .P .PD u+27a5 \[u27A5] .PD 0 .P .PD u+27a6 \[u27A6] .PD 0 .P .PD u+21a6 \[u21A6] .PD 0 .P .PD u+21d2 \[rA] .PD 0 .P .PD u+21dd \[u21DD] .PD 0 .P .PD u+21e2 \[u21E2] .PD 0 .P .PD u+21e5 \[u21E5] .PD 0 .P .PD u+21e8 \[u21E8] .PD 0 .P .PD u+21fe \[u21FE] .PD 0 .P .PD u+27ad \[u27AD] .PD 0 .P .PD u+27ae \[u27AE] .PD 0 .P .PD u+27af \[u27AF] .PD 0 .P .PD u+27b1 \[u27B1] .PD 0 .P .PD u+27b2 \[u27B2] .PD 0 .P .PD u+27ba \[u27BA] .PD 0 .P .PD u+27bc \[u27BC] .PD 0 .P .PD u+27bd \[u27BD] .PD 0 .P .PD u+27be \[u27BE] .SH AUTHORS Johan Malm. jgmenu-4.5.0/docs/manual/jgmenuunicode.7.md000066400000000000000000000034631472613136300205510ustar00rootroot00000000000000% JGMENUUNICODE(7) % Johan Malm % 7 October, 2020 # NAME jgmenuunicode - An overview of jgmenu unicode usage # INTRODUCTION Unicode characters can be displayed by jgmenu. They can be used in: - CSV data - Widgets - Config file Throughout this document, unicode code points will be referred to by writing `u+` followed by their hexadecimal number. In examples, u+1234 will be used. # UNICODE CHARACTERS IN TERMINAL Terminals handle unicode differently. For full support, avoid xterm and urxvt, and opt for something libvte based such as sakura or gnome-terminal. In a terminal, you can produce a unicode character by issuing printf '%b' '\\u1234' In libvte terminals, you can press ctrl+shift+u and then enter the hex sequence. # UNICODE CHARACTERS IN VIM Whilst in insert mode, press ctrl+V and then type u1234. Use the command `ga` to show the hex value of the character under the cursor. # VARIATION SELECTORS Some unicode characters can be rendered as either emoji or text. Special invisible unicode characters called variation selectors can be used to force either presentation. Append with the text presentation selector (u+fe0e) or emoji presentation selector (u+fe0f), to force text or emoji respectively. For example: u+1f50d u+fe0f 🔍 u+1f50d u+fe0e 🔍︎ # USEFUL CHARACTERS FOR BUILDING MENUS ## SEARCH u+2315 ⌕ u+26b2 ⚲ u+1c04 ᰄ ## ARROWS u+2192 → u+203a › u+25b6 ▶ u+2794 ➔ u+2799 ➙ u+279b ➛ u+279c ➜ u+279d ➝ u+279e ➞ u+279f ➟ u+27a0 ➠ u+27a1 ➡ u+27a2 ➢ u+27a3 ➣ u+27a4 ➤ u+27a5 ➥ u+27a6 ➦ u+21a6 ↦ u+21d2 ⇒ u+21dd ⇝ u+21e2 ⇢ u+21e5 ⇥ u+21e8 ⇨ u+21fe ⇾ u+27ad ➭ u+27ae ➮ u+27af ➯ u+27b1 ➱ u+27b2 ➲ u+27ba ➺ u+27bc ➼ u+27bd ➽ u+27be ➾ jgmenu-4.5.0/docs/notes_on_icons000066400000000000000000000020001472613136300166750ustar00rootroot00000000000000NOTES ON ICONS ============== The main loop kicks off two threads to load icons, - the first for the root menu; - the second for the rest (this one starts when the first is finished.) This allows the root-menu to be displayed quickly whilst the rest is loaded in the background. When jgmenu if first run, icon 'cache' is created in the path specified in the XDG_CACHE_HOME environment variable. If this variable is unset, it default back on '~/.cache/jgmenu/icons/'. The cache consists of symlinks pointing to icons which match the name, size and theme. For example: folder -> /usr/share/icons/Adwaita/22x22/places/folder.png On subsequence runs, icon.c reads the symlinks, thus avoiding expensive operations searching for icons. The file index.theme contains the icon theme and size associated with the symlinks. If either of these is changed in the jgmenu config, the cache will be re-created on the next run. If an icon cannot be found during the cache creation, an empty file is created instead of the symlink. jgmenu-4.5.0/docs/relnotes/000077500000000000000000000000001472613136300155765ustar00rootroot00000000000000jgmenu-4.5.0/docs/relnotes/0.2.1.txt000066400000000000000000000004301472613136300167720ustar00rootroot00000000000000jgmenu v0.2.1 release notes ========================= Updates since v0.2 -------------------- - Makefile tidy-up to make packaging easier - Set ~/.config/jgmenu/jgmenurc as the default config file if no --config-file= is specified - Set more neutral default colours jgmenu-4.5.0/docs/relnotes/0.2.txt000066400000000000000000000012111472613136300166310ustar00rootroot00000000000000jgmenu v0.2 release notes ========================= Updates since v0.1.2 -------------------- - Enabled window transparency and rounded corners. - Added various config file options including colour, margin, padding, radius and border thickness. - Added options for max/min number of "visible" menu items. Also added --fixed-items=N command line option. - Enabled vertical scrolling. - Enabled xdg parsing functionality (to show default Linux desktop menu). - Added ability to check if a program is installed. - Added --checkout= and --parent= options. - Added ^sub() markup for drawing submenu arrow. jgmenu-4.5.0/docs/relnotes/0.3.1.txt000066400000000000000000000005531472613136300170010ustar00rootroot00000000000000jgmenu v0.3.1 release notes =========================== Updates since v0.3 ------------------ - Added initial support for icon cache. This is currently just in the form of symlinks, but it does speed up the loading of icons when jgmenu is started. - Added support for xpm icons. - Improved icon-find.c search algorithms and fixed some bugs. jgmenu-4.5.0/docs/relnotes/0.3.txt000066400000000000000000000010621472613136300166360ustar00rootroot00000000000000jgmenu v0.3 release notes ========================= Updates since v0.2.2 -------------------- - Added icon support (issue #5) The icons are loaded under a worker thread which notifies the main- loop through a "self-pipe" and a select() call - Added xdgicon.c which finds suitable icon based on theme, name and size (including any parent themes specified in index.theme) - Added config options: icon_size show_title icon_theme - Changed the scrolling behaviour to feel more intuitive (issue #4) - Fixed various bugs (incl issue #1) jgmenu-4.5.0/docs/relnotes/0.4.1.txt000066400000000000000000000002261472613136300167770ustar00rootroot00000000000000jgmenu v0.4.1 release notes =========================== Updates since v0.4 ------------------ - Added menu alignment support - Fixed some bugs jgmenu-4.5.0/docs/relnotes/0.4.2.txt000066400000000000000000000004671472613136300170070ustar00rootroot00000000000000jgmenu v0.4.2 release notes =========================== Updates since v0.4.1 -------------------- - Added support for loading xpm icons without using gtk3 - Added gnome-menus (et al) to dependencies in README.md - Made jgmenu-parse-pmenu.py compatible with python2 and 3 (previously just python2) jgmenu-4.5.0/docs/relnotes/0.4.3.txt000066400000000000000000000005101472613136300167750ustar00rootroot00000000000000jgmenu v0.4.3 release notes =========================== Updates since v0.4.2 -------------------- - Added config options "arrow_show" and "arrow_string" for manipulating submenu arrows. - Changed "jgmenu_run csv" usage to jgmenu_run csv [] [] and added options --add-pmenu and --add-xdg. jgmenu-4.5.0/docs/relnotes/0.4.4.txt000066400000000000000000000004611472613136300170030ustar00rootroot00000000000000jgmenu v0.4.4 release notes =========================== Updates since v0.4.3 -------------------- - Added option to launch menu at pointer - Added search support (just start typing when in menu) - Added script to create .desktop file - Added support for "backspace" to go back to parent menu jgmenu-4.5.0/docs/relnotes/0.4.5.txt000066400000000000000000000030021472613136300167760ustar00rootroot00000000000000jgmenu v0.4.5 release notes =========================== Updates since v0.4.4 -------------------- - Updated documentation, particularly README.md Added JGMENUTUTORIAL(7) and JGMENU-CONFIG(1) - Added support for openbox menus (`jgmenu_run ob`) Pipe-menus are faked (by spawning a new menu), but work reasonably well. - pmenu: Added internationalization support. The menu should now appear in your language. (Thanks o9000) - Added append and prepend support to pmenu (to add items to the root-menu) `jgmenu_run parse-pmenu` now understands --append-file= and --prepend-file= `jgmenu_run pmenu` passes on the following if they exist: $HOME/.config/jgmenu/{append.csv,prepend.csv} - Added --no-dirs options to `jgmenu_run parse-xdg`. With --no-dirs, the .menu and .directory files are ignored. The output will be a plain list of all applications (derived from .desktop files) without any ^tag() and ^checkout() markup. - Changed installation paths in the Makefile. "jgmenu" and "jgmenu_run" remain in $(bindir). All other executable programmes are installed in $(libexecdir) as they are run by other programs rather than the user. - Added 'jgmenu_run init' This command creates a ~/.config/jgmenu/jgmenurc if one does not exist. If a jgmenurc already exists, the `init` command updates it with any missing variables. - Added separator support (although it's still a bit experimental) Use ^sep() in first field of jgmenu-CSV jgmenu-4.5.0/docs/relnotes/0.4.txt000066400000000000000000000012761472613136300166460ustar00rootroot00000000000000jgmenu v0.4 release notes ========================= Updates since v0.3.1 -------------------- - Added man pages - Added support for obtaining theme and font details from the xsettings-daemon. - Re-factored jgmenu_run and added/improved the following commands: - csv - pmenu: Copied from https://gitlab.com/o9000/pmenu.git - cache: Now runs without having to specify menu-file; and reads the icon-theme from xsettings or jgmenurc. - xdg: Improved, but still very experimental - Two config options were added (both are set to 0 be default) - ignore_xsettings - ignore_icon_cache (by default, icon-cache will be used if it exists in ~/.local/share/icons/jgmenu-cache/) jgmenu-4.5.0/docs/relnotes/0.5.1.txt000066400000000000000000000025221472613136300170010ustar00rootroot00000000000000jgmenu v0.5.1 release notes =========================== Updates since v0.5 ------------------ - Changed the following to be default behaviours: - Read tint2rc and apply config settings - Start jgmenu as a long-running application ('stay_alive') - Added the following config options (see JGMENU-CONFIG(1)): - tint2_look - tint2_button - tint2_rules - Added the following command line options (see JGMENU(1)): --simple --vsimple - Removed the command line option '--stay-alive' (regression warning!) as it's now the default mode - Lots of minor fixes and improvements to pmenu - Added tint2 compatibility mode which reads tint2rc file and sets colours and dimensions. Global config variables are set in the following order (i.e. bottom of list has higher precedence): - default (config.c) - jgmenurc (or as specified by --config-file=) - command line arguments - tint2rc Although jgmenurc can overrule tint2rc by setting "tint2_rules = 0" - Added tint2 button support using a UNIX socket. This reads environment position variables from tint2 and aligns jgmenu to them. - Improved UI - for example: - escape key clear search - react to mouse-button release instead of mouse-button press - left arrow reverts to parent menu - right arrow goes to submenu - Improved 'Back' (icon and translation) jgmenu-4.5.0/docs/relnotes/0.5.2.txt000066400000000000000000000015651472613136300170100ustar00rootroot00000000000000jgmenu v0.5.2 release notes =========================== Updates since v0.5.1 -------------------- - Add XDG menu parser based on libmenu-cache. This needs libglib2.0-dev and libmenu-cache-dev to build. If anyone feels that they don't want these dependencies, I can easily #ifdef them out. Try it using the command `jgmenu_run lx`. Thank you @Vladimir-csp for suggesting it. - Create icon cache on the fly (see docs/notes_on_icons for further details). With this improvement, the command `jgmenu_run cache` is no longer required and has therefore been removed. - Improved tint2 integration by parsing font and icon-theme. - Remove the following config options (regression): - ignore_icon_cache - show_title - color_noprog_fg - color_title_bg - Remove "title" support. This functionality will be replaced later using a more flexible approach. jgmenu-4.5.0/docs/relnotes/0.5.txt000066400000000000000000000022141472613136300166400ustar00rootroot00000000000000jgmenu v0.5 release notes ========================= Updates since v0.4.5 -------------------- - Added support for the following: - items with different heights (e.g. ^sep()) - automatic detection of menu width - separator with text - Added these config options: - color_menu_border - color_sel_border - sep_height - color_sep_fg - csv_cmd - This is the first time we've done some regression. The following config items were removed: - max_items (does not make sense with variable height) - min_items (as above) - Added support for "stay_alive" mode and added config options - stay_alive - hide_on_startup and associated command line arguments - --stay-alive - --hide-on-startup - Significantly improved icon lookup performance (thanks o9000) - Simplified jgmenu_run usage. If no argument is specified, jgmenu_run now does one of the following: - Shows the menu if an instance of jgmenu is already running - Starts jgmenu in 'stay-alive' mode (i.e. as a long-running application) using pmenu unless otherwise specified by 'csv_cmd' in jgmenurc - Added the "start" and "restart" commands to jgmenu_run jgmenu-4.5.0/docs/relnotes/0.6.1.txt000066400000000000000000000002471472613136300170040ustar00rootroot00000000000000jgmenu v0.6.1 release notes =========================== Updates since v0.6 ------------------ - Allow CFLAGS and LDFLAGS to be pre-set (e.g. with hardening flags) jgmenu-4.5.0/docs/relnotes/0.6.txt000066400000000000000000000021421472613136300166410ustar00rootroot00000000000000jgmenu v0.6 release notes ========================= Updates since v0.5.2 -------------------- - Add support for 'Terminal=true' applications - Read TINT2_CONFIG environment variable to establish which tint2 config file to use - Support non-English search - Filter out duplicate entries and ^back() items from search - Add support for parsing gtk3.0 config file for font and icon-theme - Take into account item_padding_x when positioning icons - Draw non-square icons correctly - Change font and icon-theme fallbacks - Improve menu width calculation based on item text - Add the following config options (see JGMENU-CONFIG(1)): menu_padding_top menu_padding_right menu_padding_bottom menu_padding_left terminal_exec terminal_args arrow_width icon_text_spacing font_fallback icon_theme_fallback item_halign - Remove the following config options: arrow_show ignore_xsettings search_all_items - Add the following command line options (see JGMENU(1)): --csv-file --csv-cmd - Remove the following command line options from 'jgmenu_run csv' --add-pmenu --add-xdg jgmenu-4.5.0/docs/relnotes/0.7.1.txt000066400000000000000000000001711472613136300170010ustar00rootroot00000000000000jgmenu v0.7.1 release notes =========================== Updates since v0.7 ------------------ - Fix triple quote bug jgmenu-4.5.0/docs/relnotes/0.7.2.txt000066400000000000000000000003521472613136300170030ustar00rootroot00000000000000jgmenu v0.7.2 release notes =========================== Updates since v0.7.1 -------------------- - Fix bug relating to multi-window mode - Add debian packaging files - Set WM_NAME and WM_CLASS - Remove jgmenu-restart.sh jgmenu-4.5.0/docs/relnotes/0.7.3.txt000066400000000000000000000005461472613136300170110ustar00rootroot00000000000000jgmenu v0.7.3 release notes =========================== Updates since v0.7.2 -------------------- - Fix multi-window bugs - remember scroll position - take into account window focus when responding to XEvent - stop timer on hide - Exclude ^pipe() items from search - Add sub_hover_action config option - Improve jgmenu-init.sh jgmenu-4.5.0/docs/relnotes/0.7.4.txt000066400000000000000000000001611472613136300170030ustar00rootroot00000000000000jgmenu v0.7.4 release notes =========================== Updates since v0.7.3 -------------------- - Fix bugs jgmenu-4.5.0/docs/relnotes/0.7.5.txt000066400000000000000000000006501472613136300170070ustar00rootroot00000000000000jgmenu v0.7.5 release notes =========================== Updates since v0.7.4 -------------------- * jgmenu-parse-xdg.c: support standard XDG-based configuration i.e. - global configuration in ${XDG_CONFIG_DIRS:-/etc/xdg} - user configuration override in ${XDG_CONFIG_HOME:-$HOME/.config} * jgmenu-parse-xdg.c: support {pre,ap}pend.csv files * Support colon separated directory lists in XDG environment variables jgmenu-4.5.0/docs/relnotes/0.7.6.txt000066400000000000000000000016471472613136300170170ustar00rootroot00000000000000jgmenu v0.7.6 release notes =========================== Updates since v0.7.5 -------------------- NOTE: The CLI has changed. Please set csv_cmd in the config file rather than running 'jgmenu_run lx|pmenu|xdg|ob'. If you prefer to run without a config file, use --csv-cmd= (see man-pages for further info). * Remove jgmenu-{pmenu,lx,xdg,ob}* and replace with corresponding jgmenu-parse-{pmenu,lx,xdg,ob}* CSV commands. * Remove jgmenu-{xsettings,icon-find,csv,config,start}* as they have become redundant. * Read from 'csv_cmd' rather than stdin by default. This means that 'jgmenu' can be run directly from the command line without arguments, piping or re-direction. stdin will be read if - run in --simple and --vsimple mode; - the config option 'csv_cmd' is empty. * Understand csv_cmd keywords: pmenu, xdg, lx and ob. * Add monitor config option. * Fix multi-screen positioning bugs. jgmenu-4.5.0/docs/relnotes/0.7.txt000066400000000000000000000012031472613136300166370ustar00rootroot00000000000000jgmenu v0.7 release notes ========================= Updates since v0.6.1 -------------------- - Add multi-window mode where submenus open in new window - Support standard XDG-based config. Global config is read from ${XDG_CONFIG_DIRS:-/etc/xdg} with an optional user config override in ${XDG_CONFIG_HOME:-$HOME/.config} - Add the following config options: multi_window sub_padding_{top,bottom,left,right} sub_spacing - Remove the following config options: tint2_rules tint2_button - Add pipemenu support using ^pipe() in the command field. - Add triple quote syntax to enable commas in fields (see JGMENU(1)) jgmenu-4.5.0/docs/relnotes/0.8.1.txt000066400000000000000000000017211472613136300170040ustar00rootroot00000000000000jgmenu v0.8.1 release notes =========================== Updates since v0.8 ------------------ * Fix bug reported on some tiling managers (e.g. dwm, bspwm) whereby menu is obscured by other windows (issue #51) * Survive unicode .desktop files (issue #46) * Fix unix socket bug which was present when using a tint2 launcher or button in combination with config options at_pointer=1 or tint2_look=0 * Add support for opening and closing jgmenu using openbox root window mouse clicks passed through tint2 panel (issue #21) * Check png headers before attempting load images (issue #50) * Confine menu to workarea when launching from panel/dock area (i.e. align menu to edge of panel/dock) (issue #21) * lx: support name format for "name" and "generic name" (issue #10) This requires libmenu-cache >=v1.1; use NO_LX=1 to to build without Add config option 'csv_name_format' * Add auto dependency generation (-MMD -MP) to Makefile jgmenu-4.5.0/docs/relnotes/0.8.2.txt000066400000000000000000000005051472613136300170040ustar00rootroot00000000000000jgmenu v0.8.2 release notes =========================== Updates since v0.8.1 -------------------- * Check libmenu-cache version during build. Do not compile lx if libmenu-cache >~/.config/jgmenu/prepend.csv Places,^pipe(jgmenu_run ob --cmd=al-places-pipemenu) EOF * Add 'ff-bookmarks' CSV generator (for firefox bookmarks) * Add jgmenututorial(7) lesson 10 on CSV generators * Add icon (jgmenu.svg) - thanks ArchLabs team for the inspiration * Simplify jgmenu.desktop * Reduce default mouseover hover timer from 250ms to 100ms Also, add config option 'hover_delay' for anyone wishing to tweak further. * Make pmenu handle missing menu package. If no menu-package exists, all apps are put in the menu's root * Add 'tasks' module (written-by: @Misko-2083) This is not yet included in the Makefile, but has been added to the repo as an interesting tool for the time being. * Makefile: handle missing dependencies better (incl libmenu-cache) * Give jgmenurc higher precedence than _NET_WORKAREA * Various minor bug fixes and updates to man pages. jgmenu-4.5.0/docs/relnotes/1.0.txt000066400000000000000000000005251472613136300166370ustar00rootroot00000000000000jgmenu v1.0 release notes ========================= Updates since v0.9.1 -------------------- * Auto-refresh on configuration change or application (un)installation * Set sub menu padding automatically, based on the smallest padding value of the the root menu * Remove config option color_menu_fg (as it was not is use anyway) jgmenu-4.5.0/docs/relnotes/1.1.txt000066400000000000000000000005221472613136300166350ustar00rootroot00000000000000jgmenu v1.1 release notes ========================= Updates since v1.0 ------------------ * Add ^root() markup * Add config options: - csv_single_window - hide_back_items * Add 'places' module * Make super-key hide/exit menu * Make init-script non-interactive by default (use -i to enter interactive mode) jgmenu-4.5.0/docs/relnotes/1.2.1.txt000066400000000000000000000002241472613136300167740ustar00rootroot00000000000000jgmenu v1.2.1 release notes =========================== Updates since v1.2 ------------------ * Fix bug related to finding monitors with xrandr jgmenu-4.5.0/docs/relnotes/1.2.txt000066400000000000000000000031621472613136300166410ustar00rootroot00000000000000jgmenu v1.2 release notes ========================= Updates since v1.1 ------------------ * Add config options - 'csv_no_dirs' - create a menu without a directory structure (i.e. not nested). This option applies to the lx and pmenu modules. - 'menu_height_min', 'menu_height_max' - set the min and max height of the root menu. - 'menu_height_mode' which can be either 'static' or 'dynamic'. 'dynamic' is a new mode in which the menu height is re-calculated every time the root menu is redefined using ^root() (issue #57) A single window menu, with the height adjusting to the space required by the items, can be achieved with the following configuration: csv_cmd = pmenu menu_height_mode = dynamic hide_back_items = 0 csv_single_window = 1 * Support the keyword 'center' for menu alignment (using menu_valign and menu_halign) Try this for a launcher: tint2_look = 0 csv_cmd = pmenu menu_halign = center menu_valign = center menu_height_min = 500 menu_height_max = 500 csv_no_dirs = 1 * x11-ui.c: replace xinerama with xrandr as xinerama has been reported to segfault with some new graphics cards (issue #60) (Suggested-by: @vaygr) * widgets: select on mouseover and enable left-click (if action has been specified) * init: add bunsenlabs_helium template (Provided-by: @johnraff) * Unselect items when mouse moves away from them * Exclude "hide-on-startup" option when restarting jgmenu-4.5.0/docs/relnotes/1.3.txt000066400000000000000000000006471472613136300166470ustar00rootroot00000000000000jgmenu v1.3 release notes ========================= Updates since v1.2.1 -------------------- * Add "columns" config option * Account for long labels. When searching or using columns less wide than the description, an ellipsis (...) is added to curtail the label at the correct width. Thanks @Vladimir-csp for suggesting this. (issue #59) * Fix pipemenu bug which sometimes caused undefined behaviour jgmenu-4.5.0/docs/relnotes/1.4.1.txt000066400000000000000000000001621472613136300167770ustar00rootroot00000000000000jgmenu v1.4.1 release notes =========================== Updates since v1.4 ------------------ * Fix tag issue jgmenu-4.5.0/docs/relnotes/1.4.txt000066400000000000000000000014231472613136300166410ustar00rootroot00000000000000jgmenu v1.4 release notes ========================= Updates since v1.3 ------------------ * Improve openbox module (with support from @johnraff) - Handle openbox reconfigure and restart actions correctly - Check ~/.config/openbox/menu.xml on awake and reload on change - Set $PWD correctly when executing --cmd command * Add --center argument * Fix sticky submenu bug (with thanks to @johnraff) * Re-enable build on OpenBSD by removing calls to timer_create() * Enable pango markup for text * Add config options "sep_halign" and "sep_markup" * pmenu: do not show entries with NoDisplay=true in .desktop file. Reported by ArchLabs Linux forum members Xase and sikkdays (the issue specifically related to multiple entries showing for krita) jgmenu-4.5.0/docs/relnotes/1.5.txt000066400000000000000000000011101472613136300166330ustar00rootroot00000000000000jgmenu v1.5 release notes ========================= Updates since v1.4.1 -------------------- * Improve openbox module - Allow commas in label attribute (issue #66) - Tabulate first occurance of 4+ spaces to allow better formatting of BunsenLabs' bl-kb (list of keyboard shortcuts) - Support icons (issue #65) - Support tag (issue #65) - Improve openbox pipemenu speed performance - Parse tags - Clean up to give clear ASAN warnings * Progress i18n - Add --init option * Add 'tags' config option jgmenu-4.5.0/docs/relnotes/1.6.txt000066400000000000000000000037151472613136300166510ustar00rootroot00000000000000jgmenu v1.6 release notes ========================= Updates since v1.5 ------------------ * Resolve '\n' characters in item names (to give new line characters) As a result, when using the lx module, a '\n' can be included in csv_name_format in jgmenurc to span several lines. For example: csv_name_format = %n\n%g * Amend CSV API to include 'working directory' and 'metadata' field #4 - working_dir (also implemented in spawn()) field #5 - metadata (not yet used) * Improvements to lx module - Allow commas in 'name' and 'command' fields (issue #49) Suggested-by @Vladimir-csp - Add working_dir to output, taking the value from the .desktop files' 'Path=' field (issue #49). Suggested-by @Vladimir-csp * Improvements to openbox module - Support icons with pipe-menu entries (issue #69) Suggested-by: @semeion - Use /etc/xdg/openbox/menu.xml as fallback if no file is specified and $HOME/.config/openbox/menu.xml does not exist. - Add experimental i18n support. This is not yet documented, but can be used by taking the followint steps (replacing sv with whatever is appropriate for you): (a) Run `jgmenu_run ob | jgmenu_run i18n --init >sv` (b) Translate entries in file 'sv' (c) Run 'JGMENU_I18N=sv jgmenu' (with csv_cmd=ob in jgmenurc) It is enough to point the environment variable JGMENU_I18N to a directory containing the translation file, in which case the value of $LANG will be used to find the right file. See 'jgmenu_run i18n --help' for more details * Improvements to pmenu module - Fix markup bug, which sometimes results in breakage (apologies) (issue #71) Reported-by: @eoli3n * A number of minor fixes, most notably: - Escape markup characters in "" string to show correctly - Set menu width correctly taking into account pango markup jgmenu-4.5.0/docs/relnotes/2.0.txt000066400000000000000000000066121472613136300166430ustar00rootroot00000000000000jgmenu v2.0 release notes ========================= Updates since v1.6 ------------------ New features * Support ^filter() markup, whereby ^filter(foo) in the command field invokes a search for the inner value 'foo' * filter: support multi-word search. Words separated by a space will be treated as separate strings and searched for on an OR logic basis. A standalone '*' matches everything * Improve widgets API and fix minor issues - add @text type (to insert text) - draw @rect fill and border in correct order, i.e. border on top of fill - when drawing selection borders, use color_sel_border rather than color_sel_fg * lx: output application categories as metadata Categories as taken from the desktop files' "Categories" field and each category is prepended by a '#' For example, xterm.desktop contains the line Categories=System;TerminalEmulator; The fifth CSV field therefore becomes "#System#TerminalEmulator" * Add the following config options - 'color_scroll_ind' to enable setting the colour of the lines indicating that menu items exist outside those which are visible. - 'csv_i18n' to specify translation file/directory for the ob module * Add greeneye module 'jgmenu_run greeneye' outputs a config file and widget lines for a menu with the following layout: +----------------+-----------------------+ | | a - search box | | |-----------------------| | | | | b - categories | | | | c - applications | | | | | | | +----------------+-----------------------+ Example usage jgmenu_run greeneye --config >$HOME/.config/jgmenu/jgmenurc jgmenu_run greeneye --widgets >$HOME/.config/jgmenu/prepend.csv Prepare for OpenBSD port * util.c: remove strcat() (commit 38e4e11a) * xsettings.c:231: use snprintf() (commit 26ea4c2d) * init: replace "tar -T" as it is not POSIX (commit 4ad9fcff) Fix bugs and issues * Fix KeyError bug in pmenu module (commit 3b4ba92) * Handle missing xsettings variables. If xsettings is running but does not contain Gtk/FontName or Net/IconThemeName, we proceed to the next icon/theme fallback. * i18n: support dirirectory name without '/' at end * ob: quote output correctly (issue #76). This avoids causing a crash when opening directory names with spaces when using bl-places-pipemenu. Reported-by: @johnraff * debian/rules: omit broken dh_auto_clean target (and add some buildflags). Provided-by: @2ion Cody clean up. The changes below break backward compatibility, although it is believed that the majority of users will not notices these changes. * Retire 'xdg' module (now in noncore/). Its functionality is covered by pmenu and lx. * Do not install 'ff-bookmarks' and 'places', just leave them in noncore/ for reference or manual install. These are not considered part of the core application and are too time-consuming to maintain across OSs. * Tidy up init module - remove {ap,pre}pend.csv files when setting new theme - remove tint2 related code (because it seems simplier to just handle jgmenu config files) jgmenu-4.5.0/docs/relnotes/2.1.txt000066400000000000000000000041011472613136300166330ustar00rootroot00000000000000jgmenu v2.1 release notes ========================= Updates since v2.0 ------------------ * The following improvements were made to 'jgmenu' (the binary) - Hide separators when searching - Make ^filter() happily co-exist with type-to-search, by clearing any ^filer() invocation on type-to-search. So, for example, if ^filter(#Network) has been applied and the user then starts typing, '#Network' is cleared. - Survive bad ^pipe() - i.e. one that returns error or no items - Make checkout_tag() survive invalid tag by simply reverting to the first menu item. This means that we now also sensibly handle --checkout=foo where foo does not exist. (Reported-by: @johnraff) - Check that pipe-menu tags are unique before loading. Trying deal with duplicate tags after the node structure has been created does not work, because we cannot tell which ^tag() correspond to which ^checkout(). - Add config option 'edge_snap_x'. Snap to left hand edge if within specified distance from it. Note that this option is only applicable in at_pointer mode. * 'config' module - Simplify command 'amend' and also add --dryrun option to check for missing items, but without modifying jgmenurc - Add command 'create' to create a new config file (jgmenurc) based on built-in default values. * 'ob' module - Cope with commas in all fields (thanks @johnraff) * 'init' module - Add greeneye to the built-in themes Try greeneye with `jgmenu init --theme=greeneye` * Add sharness (https://github.com/chriscool/sharness) and modify current unit-tests to run with it (Thanks @chriscool et al) * Cleanup - Remove redundant/superseded code, scripts, examples and tests - Lots of minor coding style and flawfinder fixes - Simplify Makefile - Move 'init' and 'config' from noncore/ to src/ - Make sure self_pipe is cleared in hide_menu() and positively check that menu is not hidden when opening a submenu. jgmenu-4.5.0/docs/relnotes/2.2.1.txt000066400000000000000000000002461472613136300170010ustar00rootroot00000000000000jgmenu v2.2.1 release notes =========================== Updates since v2.2 ------------------ * Fix init module bug which prevents config file from being created jgmenu-4.5.0/docs/relnotes/2.2.txt000066400000000000000000000015241472613136300166420ustar00rootroot00000000000000jgmenu v2.2 release notes ========================= Updates since v2.1 ------------------ * Fix --hide-on-startup bug * Add 'obtheme' module which: - Reads content of in openbox's rc.xml - Finds and parses the associated openbox-3/themerc file - Sets the corresponding jgmenurc key/value pairs Thanks to @hhhorb for suggesting this * Improvements to 'init' module: - add --apply-obtheme (as a wrapper for the new obtheme module) - use pmenu if ob does not exist for lab themes - add "missing" option to interactive mode - do not launch jgmenu on theme change - only backup when needed * Add config options color_title_{fg,bg,border} (where title refers to a separator with text) * tests/helper/Makefile: disable ASAN by default (issue #84) jgmenu-4.5.0/docs/relnotes/3.0.txt000066400000000000000000000040671472613136300166460ustar00rootroot00000000000000jgmenu v3.0 release notes ========================= Updates since v2.2.1 -------------------- * This release has a MAJOR bump as we have changed a few things in a non-backward compatible way. - The menu background colour is set to have no transparency by default (alpha changed from 85% to 100%) - tint2_look is set to 0 (false) by default. Although the alignment with tint2's config file can be convenient, it has caused confusion for a number of users. - The config module has been re-written in C (previously python). It has very similar functionality, but slighly different command line options. It is predominantly an internal command used by 'init', so most users should not notice a difference. * Support scroll past top/bottom when using keyboard arrows (issue #90). When scrolling past the last item, the selection moves to the top, and vice versa. Suggested-by: @hhhorb * Add lithium-rc1 theme * Teach widgets module to accept keyword "auto" for fgcol. If "auto" is specified instead of a "#rrggbb aa" value, the jgmenurc config file color_norm_fg value will be used. This is useful if you want widget text to take on the same colour as ordinary menu items. * Give menu items higher Z-order priority than widgets * Support movement betweeen widgets and items using keyboard. Simply press the button to toggle between the two. The 'greeneye' theme is a good place to try this out. * Use apps module in greeneye theme rather than lx. This enables users without the lx module to try it. The apps module will be a pmenu successor. Although it is not quite ready yet, it is good enough for this. * In the pmenu module, respect override .desktop files (issue #86). We now do not show .desktop files with the same filenames more than once. We look for .desktop files in "~/.local/share" and "$XDG_DATA_DIRS" before "/usr/share" and "/usr/local/share". * Lots of minor improvements, tweaks and fixes. See git log for full details. jgmenu-4.5.0/docs/relnotes/3.1.txt000066400000000000000000000007301472613136300166400ustar00rootroot00000000000000jgmenu v3.1 release notes ========================= Updates since v3.0 ------------------ * In obtheme module, support openbox config file (rc.xml) user override by setting environment variable JGMENU_RCXML. For example: JGMENU_RCXML=$HOME/.config/openbox/bl-rc.xml jgmenu_run obtheme jgmenurc JGMENU_RCXML=$HOME/.config/openbox/bl-rc.xml jgmenu init --apply-obtheme * Minor updates to man pages * Fix incorrect relative path in unit test t1201-lx.t jgmenu-4.5.0/docs/relnotes/3.2.txt000066400000000000000000000011521472613136300166400ustar00rootroot00000000000000jgmenu v3.2 release notes ========================= Updates since v3.1 ------------------ * Fix incorrect selection after clearing a filter resulting in * Update debian/ file and modify unit test t1201-lx.t to enable clean run with pbuilder * Add jgmenu-hide-app.sh. Run `jgmenu_run hide-app foo.desktop` to hide application foo from menu generated by lx module * Resolve config file csv_cmd value `apps` to `jgmenu_run apps`, so that user only needs to specify `csv_cmd = apps` to use apps module * Add xfce4-panel plugin. Written-by @Misko-2083 (Not installed by default) jgmenu-4.5.0/docs/relnotes/3.3.txt000066400000000000000000000005011472613136300166360ustar00rootroot00000000000000jgmenu v3.3 release notes ========================= Updates since v3.2 ------------------ * In the obtheme module, add support for parsing BunsenLabs Lithium's `bl-rc.xml` to obtain the current openbox theme, thereby supporting `jgmenu init --apply-obtheme` without having to set an environment variable. jgmenu-4.5.0/docs/relnotes/3.4.txt000066400000000000000000000074251472613136300166530ustar00rootroot00000000000000jgmenu v3.4 release notes ========================= Note to package maintainers: * To include the latest contrib/ packages, run the following: make CONTRIB_DIRS="xfce4-panel gtktheme" make CONTRIB_DIRS="xfce4-panel gtktheme" install * The xfce4-panel plugin requires libgtk-3-dev and xfce4-panel-dev to build. Run-time dependencies are only needed if the packages are run. They do not affect jgmenu and its core modules in any way. Updates since v3.3 ------------------ * Add xfce4-panel plugin. Written-by: @Misko_2083 * Add mate-panel plugin. This contrib/ package is still in early development. Written-by: @Misko_2083 * Add the following themes: col3 and the latest bunsenlabs_lithium * Man pages have seen the following improvements: - Better html support and available at https://jgmenu.github.io/ - A new jgmenuunicode(7) guide - jgmenu(1) details on IPC variables, widgets and special pango markup characters (thanks @johnraff) * Support sourcing of CSV files. Suggested-by: @johnraff Use the following syntax to include other files from CSV files . Tilde (~) is expanded, but not environment variables. * In jgmenu, improve handling of tags. - Remove ^checkout() items without matching tags. This permits the default prepend.csv and append.csv files to include ^checkout() items which only appear if an optional package providing a sourced csv file is installed. Suggested-by: @johnraff - Die on duplicate tags - Survive missing tags when actioning ^checkout() and ^pipe(). Reported-by: @johnraff * Improve apps module by filtering out duplicate .desktop files. For example if foo.desktop exists in ~/.local/share/applications/, then ignore foo.desktopp in /usr/share/applications/ * Improve lx modules by ensuring tag names are unique * Improve ob module by - Escaping < and > to support pango markup - Fixing pipemenu inline menu bug. Reported-by: @johnraff * Add .clang-format and a wrapper to cope with foreach iterators * Minor fixes: - Survive unsupported locale (issue #96). If setlocale(LC_ALL, "") fails, use fallback 'C' locale - x11-ui.c: don't pull for XRandR hardware changes. Calling XRRGetScreenResources() pulls for hardware changes which on some systems freezes the screen for a few hundred milliseconds, so use XRRGetScreenResourcesCurrent() instead to avoid that. Written-by: @Roliga - Set arrow colour of selected item to color_sel_fg to match font colour (issue #99) - Fix border misalignment to ensure rounded corners are pixel perfect * Add config option `verbosity`. See jgmenu(1) for details. * Add config option `position_mode` and remove `at_pointer` `position_mode` can be one of pointer, ipc, fixed or center. See jgmenu(1) for full details. Backward compatibility is maintained by repecting at_pointer=1 * Improve `jgmenu_run config` command by: - Creating config file if missing. Avoid failure of `jgmenu_run config -s -k -v ` if config file does not exist (by creating one). - Only setting key/value pair if new value is different. This avoids writing to jgmenurc file unnecessarily. - Amending missing items more intelligently by commenting out new key/value pairs * Add contrib/jgmenu-gtktheme.py. Written by @Misko-2083 This is still a basic implementation which only sets color_menu_bg, color_norm_fg, color_sel_bg and color_sel_fg If your package maintainer has included this contrib/ package, try it out with: jgmenu init --apply-gtktheme * debian/control: install xfce4-panel and gtktheme plugins by default jgmenu-4.5.0/docs/relnotes/3.5.txt000066400000000000000000000003711472613136300166450ustar00rootroot00000000000000jgmenu v3.5 release notes ========================= Updates since v3.4 ------------------ * debian/: split into two packages - jgmenu and jgmenu-xfce4-panel-applet * Add col2 theme * Some minor fixes - see git commit log for full details. jgmenu-4.5.0/docs/relnotes/4.0.1.txt000066400000000000000000000007711472613136300170040ustar00rootroot00000000000000jgmenu v4.0.1 release notes =========================== Updates since v4.0 ------------------ * Issue #108. Show menu on correct monitor in IPC mode (position_mode=ipc) Before this fix, the menu would always appear on the monitor from which it was first launched. Thanks @atmenta for identifying the bug and providing a solution. * Fix segfault bug in jgmenu-apps on OpenBSD. Thanks Scott H for helping resolve this. * Update lithium theme to reflect introduction of apps module jgmenu-4.5.0/docs/relnotes/4.0.2.txt000066400000000000000000000004411472613136300167770ustar00rootroot00000000000000jgmenu v4.0.2 release notes =========================== Updates since v4.0.1 -------------------- * sbuf.c: fix bug which could result in segfault. * x11-ui.c: support unusual color-depths required by applications such as x2go (issue #111). Thanks to s-rod for reporting this. jgmenu-4.5.0/docs/relnotes/4.0.txt000066400000000000000000000056411472613136300166460ustar00rootroot00000000000000jgmenu v4.0 release notes ========================= Note to package maintainers: * A configure script has been added, and pmenu+lx have been moved to contrib/. For backward compatibility run the command below before `make`, changing prefix to suit your system: ./configure --prefix=/usr --with-lx --with-pmenu Run `./configure -h` for further help Updates since v3.5 ------------------ * Add apps module - a replacement for pmenu and the default menu generator from v4.0 (hence major bump). It has the following features and advantages: * It uses built-in schema data or a specified schema file (for user override) to map categories to directories. * It provides a directory structure without the requirement for a menu package such as lxmenu-data or libgarcon-common, thus making it more likely to work out-of-the-box on many systems. * It is written in C and is faster than both pmenu and lx. * It is easier to extend and maintain compared with pmenu * It supports localized directory and application names * It avoids the mind-boggling (in my opinion) mapping relationships betweeen /etc/xdg/menus/* and /usr/share/desktop-directories/* files. For those who want a fully XDG compliant menu, the lx module is still supported. * It avoids a number of pmenu and lx issues which are difficult to solve. For example: (a) lx cache refresh sometimes does not happen until the second read. Whilst I feel that I ought to try to fix this bug, any changes to libmenu-cache would take a long time to appear in some repositories. (b) Both pmenu and lx are affected by having more than one menu package installed, which appears to be common on systems which use applications from different Desktop Environments. (c) libmenu-cache does not like the xfce menu package. * Support csv_no_dirs, csv_single_window and csv_name_format, making it on par with other CSV generators * Move pmenu and lx modules to contrib/ to make maintenance and packaging easier. * jgmenu.c: hide 'last selection border' (issue #103). Thanks @Roliga for pointing this out. * Update man pages and usage() to prefer `jgmenu_run init` over `jgmenu init` * Add banned.h to make audits easier * Add scripts/pbuild to simplify building deb packages with pbuilder. Thanks @johnraff for supplying this. * Add configure script in order to (a) make contrib/ packages easier to manange; and (b) remove dependency checking from Makefile * greeneye: change category 'Games' to 'Game' in order to comply with freedesktop.org XDG menu-spec. Thanks @jkinney23 for providing this fix. * filter.c: support case-insensitive non-ASCII search (issue #91) Thanks to @Vladimir-csp * xfce4-panel: remove gtk+-3.0 dependency jgmenu-4.5.0/docs/relnotes/4.1.0.txt000066400000000000000000000020121472613136300167720ustar00rootroot00000000000000jgmenu v4.1.0 release notes =========================== Updates since v4.0.2 -------------------- * Add i18n support for {pre,ap}pend.csv file in jgmenu-apps(1) * Add man page jgmenu-i18n(1) * Add options --no-append and --no-prepend to jgmenu-apps(1) module. Thanks @capn-damo for this suggestions. * Whitespace-trim all comma separated fields when using the argv-buf library, which is used for parsing menu data and widgets. This allows CSV data to be indented or aligned without affecting the content. Again, thanks to @capn-damo * Resolve tilde in --csv-file value (issue #113). Suggested-by: @capn-damo * Add config option `csv_no_duplicates` to prevent applications from showing in multiple directories. Only supported by jgmenu-apps(1) module. Suggested-by: @johnraff * Respect that % can be escaped using %%, when removing field codes (e.g. %U and %f) from .desktop file Exec= strings (issue #68). Supported by jgmenu-apps(1) and jgmenu-lx(1). Reported-by: @Vladimir-csp jgmenu-4.5.0/docs/relnotes/4.2.0.txt000066400000000000000000000017251472613136300170050ustar00rootroot00000000000000jgmenu v4.2.0 release notes =========================== Updates since v4.1.0 -------------------- * Add config options icon_norm_alpha and icon_sel_alpha. Written-by: @wsdfhjxc * Support hooks. See jgmenu(1) for full details. * Support startup script. Run ~/.config/jgmenu/startup on initial launch. This feature enables optional syncing with others settings such as GTK3. * gtktheme: save last theme name in ~/.cache/jgmenu/.last-gtktheme This supports scripts for syncing gtktheme on startup. * obtheme: set menu_border=0 by default to avoid inheriting unwanted menu border thickness if openbox theme does not contain an entry for it. Suggested-by: @johnraff * configure: support --libexecdir= and --libdir= (issue #109) Thanks @tieugene * configure: use the correct xfce4panel library. Suggested-by: @Misko-2083 * xfce4-panel: remove dpkg-architecture and hardcoded debian paths from Makefile (issue #110). Thanks @tieugene jgmenu-4.5.0/docs/relnotes/4.2.1.txt000066400000000000000000000002341472613136300170000ustar00rootroot00000000000000jgmenu v4.2.1 release notes =========================== Updates since v4.2.0 -------------------- * Fix apps module bug (issue #119) Helped-by: @geolaw jgmenu-4.5.0/docs/relnotes/4.3.0.txt000066400000000000000000000021271472613136300170030ustar00rootroot00000000000000jgmenu v4.3.0 release notes =========================== Updates since v4.2.1 -------------------- * Add gradient support for menu window background. Use config options menu_gradient_pos and color_menu_bg_to. Written-by: @Artideusz * Survive locales which are not supported by X11, for example en_HK.UTF-8 * Safely handle main event loop signals when X11 struggles to keep up under extreme load or on very old machines * obtheme: set color_title_border correctly (issue #142) Reported-by: @johnraff * obtheme: parse menu.overlap.x (issue #136). Reported-by: @johnraff * gtktheme: set title colours to match main menu. Written-by: @johnraff * Add persistent mode config options and --persistent command line option. When enabled, the menu does not exit or hide when it normally would, for example on selecting an item or pressing escape. Written-by: @phedders * Add ^quit() markup. This simply exits and is designed to work with the persistent mode. Written-by: @phedders * Add contib/ file jgmenu-unicode-icons.sh (PR #124) Written-by: @wsdfhjxc jgmenu-4.5.0/docs/relnotes/4.4.0.txt000066400000000000000000000017561472613136300170130ustar00rootroot00000000000000jgmenu v4.4.0 release notes =========================== Updates since v4.3.0 -------------------- * Make --simple force short-lived mode (the way it was always intended to be an is described in documentation). Fixes issue #153. * jgmenu-apps: - Respect TryExec in .desktop files including the handling of absolute paths. Fixes issues #146 and #151. Suggested-by: @johnraff. - Parse .desktop file 'Path' field and support working directory Written-by: @BitterlyIronic. - Make exec[] field bigger to allow long strings (as seen in for example wine applications). - Include .desktop files in $XDG_DATA_DIRS/applications/ sub-directories For example, ~/.local/share/applications/wine/Programs/Games/ * jgmenu-lx: escape C:\ in order to cope with libmenu-cache escaping the backslash in 'C:\' in wine applications' .desktop file Exec= field * gtktheme: call `jgmenu_run config` synchronously to avoid config file write errors jgmenu-4.5.0/docs/relnotes/4.4.1.txt000066400000000000000000000022041472613136300170010ustar00rootroot00000000000000jgmenu v4.4.1 release notes =========================== Updates since v4.4.0 -------------------- * Chase librsvg2 API changes - Use rsvg_handle_render_document() to render icons instead of deprecated rsvg_handle_get_dimensions() and rsvg_handle_render_cairo() This requres librsvg2 >= 2.46 - jgmenu.svg: specify width and height to enable some applications using imlib2 >= v1.8 (such as feh and tint2) to render the jgmenu.svg icon correctly. This is an indirect result of the librsvg2 API deprecation of rsvg_handle_get_dimensions() and rsvg_handle_render_cairo() * jgmenu-apps: correctly sort desktop entries in languages other than English. Issue #166 * Handle symlinked icon directories in order to support Papirus-Dark. Issue #122. With thanks to @rafern @VectorKappa @M4he * Use cache directory ${XDG_CACHE_HOME:-$HOME/.cache} rather than just defaulting to ~/.cache. Issue #175. Written-by: @tupo2 * Fix widgets cursor-motion bug caused by background @rect and @text widgets blocking action widgets which should handle mouse-over. Issue #167 jgmenu-4.5.0/docs/relnotes/4.5.0.txt000066400000000000000000000023461472613136300170100ustar00rootroot00000000000000jgmenu v4.5.0 release notes =========================== Updates since v4.4.1 -------------------- * Add config option `search_empty_string` so that the default '' can be overridden. (#232) * Ignore entries with empty commands when de-duplicating search results. This makes a search for "aa" with the csv data below render two results rather than one. (#227) a, aa, aaa, b, bb, bbb, * jgmenu-apps: add config options `--prepend-file` and `--append-file` (#215) * Do not focus any item on launch/awake to increase consistency with most other menus (#209) * Make `librsvg` dependency optional. Also support both `2.40.x` and newer. * Escape special characters (`<`, `>` and `&`) in @search widget to render correctly with pango markup. (#194) * contrib/xfce4-panel: * Fix xfce4-panel registration. Thanks-to: @fweimer-rh * Add `X-XFCE-API=2.0` to .desktop file to make the plugin work with the latest xfce4-panel * jgmenu-apps: handle name and generic-name containing commas (#192) * Fix widgets button-release bug by not executing widget action on button release if pointer has moved outside widget area since pressed (#189) jgmenu-4.5.0/examples/000077500000000000000000000000001472613136300146315ustar00rootroot00000000000000jgmenu-4.5.0/examples/Makefile000066400000000000000000000002111472613136300162630ustar00rootroot00000000000000export ASAN_OPTIONS=detect_leaks=0 all: @./ex01.sh @./ex02.sh @./ex03.sh @./ex04.sh @./ex05.sh @./ex06.sh @./ex07.sh @./ex08.sh jgmenu-4.5.0/examples/README000066400000000000000000000012531472613136300155120ustar00rootroot00000000000000EXAMPLE FILES ============= Most example scripts need to be run from the examples/ directory. ex0* are for testing purposes. - They are intended to be used by invoking `make && make ex` from the top level directory whilst coding - They use ../jgmenu, so do not require a `make install`. - They are not designed to look pretty, but to test specific features or properties. - They may change over time depending on what the devs need. Specific files -------------- ex01 Menu based on simple CSV file. Tests right-aligned items. ex02 Tests separators, scroll, pgup/pgdown, etc. ex03 Tests long text, at-pointer ex04 Tests icon positioning and icon theme inheritance jgmenu-4.5.0/examples/ex01.sh000077500000000000000000000001121472613136300157370ustar00rootroot00000000000000#!/bin/sh ../jgmenu --simple --config-file=ex01/jgmenurc < ex01/menu.csv jgmenu-4.5.0/examples/ex01/000077500000000000000000000000001472613136300154065ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex01/jgmenurc000066400000000000000000000026451472613136300171520ustar00rootroot00000000000000 #stay_alive = 1 #hide_on_startup = 0 #csv_cmd = pmenu #tint2_look = 1 #at_pointer = 0 #terminal_exec = x-terminal-emulator #terminal_args = -e #monitor = 0 #hover_delay = 100 #hide_back_items = 1 #menu_margin_x = 0 #menu_margin_y = 0 #menu_width = 200 menu_padding_top = 90 #menu_padding_right = 5 #menu_padding_bottom = 5 #menu_padding_left = 5 #menu_radius = 1 #menu_border = 0 #menu_halign = left menu_valign = top #sub_spacing = 1 #sub_padding_top = auto #sub_padding_right = auto #sub_padding_bottom = auto #sub_padding_left = auto #sub_hover_action = 1 #item_margin_x = 3 #item_margin_y = 3 #item_height = 25 #item_padding_x = 4 #item_radius = 1 #item_border = 0 #item_halign = left #sep_height = 5 #font = #font_fallback = xtg #icon_size = 22 #icon_text_spacing = 10 #icon_theme = #icon_theme_fallback = xtg #arrow_string = > #arrow_width = 15 color_menu_bg = #eeeeee 100 #color_menu_border = #eeeeee 8 color_norm_bg = #000000 0 color_norm_fg = #111111 100 color_sel_bg = #2222dd 60 color_sel_fg = #eeeeee 100 #color_sel_border = #eeeeee 8 #color_sep_fg = #ffffff 20 #csv_name_format = %n (%g) #csv_single_window = 0 jgmenu-4.5.0/examples/ex01/menu.csv000066400000000000000000000053171472613136300170750ustar00rootroot00000000000000# # ex01 # # Menu with widgets # @rect,,10,10,180,25,3,left,top,#666666 15,#000000 0,content @search,,10,10,180,25,3,left,top,#666666 90,#222222 3,Type to search... @icon,^root(submenu),10,50,24,24,3,left,top,#2222dd 50,#eeeeee 20,/usr/share/icons/Adwaita/24x24/emblems/emblem-favorite-symbolic.symbolic.png @icon,^root(submenu),44,50,24,24,3,left,top,#2222dd 50,#eeeeee 20,/usr/share/icons/Adwaita/24x24/emblems/emblem-system-symbolic.symbolic.png @icon,^root(submenu),78,50,24,24,3,left,top,#2222dd 50,#eeeeee 20,/usr/share/icons/Adwaita/24x24/emblems/emblem-photos-symbolic.symbolic.png jgmenu demo,^tag(root) directory,^checkout(submenu),folder-documents browser,firefox,web-browser file manager,pcmanfm,system-file-manager terminal,xterm,utilities-terminal leafpad,leafpad,leafpad gparted,gparted,gparted submenu,^tag(submenu) Image Viewer,gpicview ,gpicview Widget Factory,gtk3-widget-factory,gtk3-widget-factory TigerVNC Viewer,/usr/bin/vncviewer,tigervnc Icon Browser,gtk3-icon-browser,gtk3-icon-browser New private window,firefox -private-window,firefox MPlayer Media Player,mplayer ,mplayer Print Preview,evince-previewer ,document-print-preview View file,/usr/bin/gcr-viewer,document-print-preview GNU Image Manipulation Program,gimp-2.8 ,gimp PulseAudio Volume Control,pavucontrol,multimedia-volume-control urxvt,urxvt,utilities-terminal Document Viewer,evince ,evince CMake,cmake-gui ,CMakeSetup Privilege granting,gksu-properties,gksu.png Access Prompt,/usr/lib/gcr/gcr-prompter,security-medium Access Prompt,/usr/lib/gcr/gcr-prompter,security-medium File Manager PCManFM,pcmanfm ,system-file-manager Tint2,tint2,tint2 Shortcut Editor,lxshortcut -i ,applications-other mtPaint,mtpaint ,mtpaint Avahi Zeroconf Browser,/usr/bin/avahi-discover,network-wired KeePassX,keepassx ,keepassx urxvt (client),urxvtc,utilities-terminal Avahi SSH Server Browser,/usr/bin/bssh,network-wired Avahi SSH Server Browser,/usr/bin/bssh,network-wired NetSurf Web Browser,netsurf ,netsurf.png Desktop Preferences,pcmanfm --desktop-pref,user-desktop urxvt (tabbed),urxvt-tabbed,utilities-terminal Root Terminal,gksu -l gnome-terminal,gksu-root-terminal Tint2 Settings,tint2conf,tint2conf GTK+ Demo,gtk3-demo,gtk3-demo Preferred Applications,libfm-pref-apps,preferences-desktop compton,compton --xrender-sync-fence,compton UXTerm,uxterm,xterm-color_48x48 Archive Manager,file-roller ,file-roller Avahi VNC Server Browser,/usr/bin/bvnc,network-wired FLUID,fluid ,fluid Customize Look and Feel,lxappearance,preferences-desktop-theme Dropbox,dropbox,dropbox XTerm,xterm,xterm-color_48x48 Openbox,openbox,openbox Adobe Flash Player,flash-player-properties,flash-player-properties Links,xlinks -g,links_32x32.xpm GParted,/usr/bin/gparted_polkit ,gparted Leafpad,leafpad ,leafpad jgmenu-4.5.0/examples/ex02.sh000077500000000000000000000034021472613136300157450ustar00rootroot00000000000000#!/bin/sh ( printf "%b\n" 'Playing with margins/padding,^tag(root)' printf "%b\n" 'submenu,^checkout(foo)' printf "%b\n" 'terminal,xterm' printf "%b\n" 'browser,firefox' printf "%b\n" 'file manager,pcmanfm' printf "%b\n" 'Try Scrolling/PgUp/PgDn/Home/End,^tag(foo)' printf "%b\n" '^sep()' printf "%b\n" '^sep()' printf "%b\n" '..,^back()' printf "%b\n" 'item1,xterm' printf "%b\n" '^sep(separator with text)' printf "%b\n" 'item2,xterm' printf "%b\n" '^sep()' printf "%b\n" '^sep()' printf "%b\n" '^sep()' printf "%b\n" '^sep()' printf "%b\n" '^sep()' printf "%b\n" '^sep()' printf "%b\n" 'item3,xterm' printf "%b\n" 'item4,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item5,xterm' printf "%b\n" 'item6,xterm' printf "%b\n" '^sep()' printf "%b\n" '^sep(separator with text)' printf "%b\n" 'item7,xterm' printf "%b\n" 'item8,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item9,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item10,xterm' printf "%b\n" 'item11,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item12,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item13,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item14,xterm' printf "%b\n" 'item15,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item16,xterm' printf "%b\n" 'item17,xterm' printf "%b\n" 'item18,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item19,xterm' printf "%b\n" 'item20,xterm' printf "%b\n" 'item21,xterm' printf "%b\n" 'item22,xterm' printf "%b\n" 'item23,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item24,xterm' printf "%b\n" 'item25,xterm' printf "%b\n" 'item26,xterm' printf "%b\n" 'item27,xterm' printf "%b\n" '^sep()' printf "%b\n" 'item28,xterm' printf "%b\n" 'item29,xterm' printf "%b\n" 'item30,xterm' printf "%b\n" 'item31,xterm' printf "%b\n" 'item32 (last),xterm' ) | ../jgmenu --simple --config-file=./ex02/jgmenurc jgmenu-4.5.0/examples/ex02/000077500000000000000000000000001472613136300154075ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex02/jgmenurc000066400000000000000000000006601472613136300171460ustar00rootroot00000000000000# .jgmenurc example menu_margin_x = 10 menu_margin_y = 40 menu_width = 250 menu_radius = 7 menu_border = 1 item_margin_x = 30 item_margin_y = 10 item_height = 30 item_padding_x = 8 item_radius = 10 item_border = 1 sep_height = 5 icon_size = 0 font = Ubuntu 14px color_menu_bg = #335588 100 color_norm_bg = #000000 100 color_norm_fg = #eeeeee 100 color_sel_bg = #ffbb22 60 color_sel_fg = #eeeeee 100 color_sep_fg = #ffffff 20 jgmenu-4.5.0/examples/ex03.sh000077500000000000000000000024051472613136300157500ustar00rootroot00000000000000#!/bin/sh ( printf "%b\n" 'root,^tag(root)' printf "%b\n" 'a,^checkout(a)' printf "%b\n" 'b,^checkout(b)' printf "%b\n" 'c (width check),^checkout(c)' printf "%b\n" 'a,^tag(a)' printf "%b\n" 'aa,^checkout(aa)' printf "%b\n" 'ab,^checkout(ab)' printf "%b\n" 'a1' printf "%b\n" 'a2' printf "%b\n" 'a3' printf "%b\n" 'aa,^tag(aa)' printf "%b\n" 'aa1' printf "%b\n" 'aa1' printf "%b\n" 'ab,^tag(ab)' printf "%b\n" 'ab1' printf "%b\n" 'ab1' printf "%b\n" 'b,^tag(b)' printf "%b\n" 'b1' printf "%b\n" 'b2' printf "%b\n" 'c,^tag(c)' printf "%b\n" 'c1 - e abcde,^checkout(cc)' printf "%b\n" 'cc,^tag(cc)' printf "%b\n" 'cc1 - t abcdefghijklmnopqrst,^checkout(ccc)' printf "%b\n" 'ccc,^tag(ccc)' printf "%b\n" 'ccc1 - n abcdefghijklmnopqrstuvwxyzabcdefghijklmn,^checkout(cccc)' printf "%b\n" 'cccc,^tag(cccc)' printf "%b\n" 'cccc1 - s abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs,^checkout(ccccc)' printf "%b\n" 'ccccc,^tag(ccccc)' printf "%b\n" 'ccccc1 - abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs,^checkout(cccccc)' printf "%b\n" 'cccccc,^tag(cccccc)' printf "%b\n" 'cccccc1 - abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz,^checkout(cccccc)' ) | ../jgmenu --simple --config-file=./ex03/jgmenurc jgmenu-4.5.0/examples/ex03/000077500000000000000000000000001472613136300154105ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex03/jgmenurc000066400000000000000000000007071472613136300171510ustar00rootroot00000000000000# .jgmenurc example at_pointer = 1 menu_margin_x = 10 menu_margin_y = 40 menu_width = 24 menu_radius = 7 menu_border = 1 item_margin_x = 0 item_margin_y = 10 item_height = 30 item_padding_x = 1 item_radius = 10 item_border = 1 sep_height = 5 icon_size = 0 font = Ubuntu 14px color_menu_bg = #335588 100 color_norm_bg = #000000 100 color_norm_fg = #eeeeee 100 color_sel_bg = #ffbb22 60 color_sel_fg = #eeeeee 100 color_sep_fg = #ffffff 20 jgmenu-4.5.0/examples/ex04.sh000077500000000000000000000007411472613136300157520ustar00rootroot00000000000000#!/bin/sh ( printf "%b\n" 'theme1 i1.svg,:,i1' printf "%b\n" 'theme2 i2.svg,:,i2' printf "%b\n" '^sep(icon alignment)' printf "%b\n" 'icon22x22 (png),:,icon22x22png' printf "%b\n" 'icon22x22 (xpm),:,icon22x22xpm' printf "%b\n" 'icon22x11 (png),:,icon22x11png' printf "%b\n" 'icon22x11 (xpm),:,icon22x11xpm' printf "%b\n" 'icon64x32 (svg),:,icon64x32svg' printf "%b\n" 'icon32x64 (svg),:,icon32x64svg' ) | XDG_DATA_HOME=$(pwd)/ex04 ../jgmenu --simple --config-file=./ex04/jgmenurc jgmenu-4.5.0/examples/ex04/000077500000000000000000000000001472613136300154115ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex04/icons/000077500000000000000000000000001472613136300165245ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex04/icons/theme1/000077500000000000000000000000001472613136300177075ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex04/icons/theme1/22/000077500000000000000000000000001472613136300201325ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex04/icons/theme1/22/icon22x11png.png000066400000000000000000000015321472613136300227740ustar00rootroot00000000000000PNG  IHDR L"LPLTE۶mmmIII$$$mI$mI$mmII$$mI$۶mmII$$mmII$$۶mmmIII$$ےmmIIm$$mmII$$mmII$$II$$$$۶۶mmImI$I$ےmmII$m$mmII$$mmII$$II$$$$ےmmIIm$$ImmII$$mmmII$$mmII$$II$$$$۶mmmIII$ےmImm$mI$mI$I$$۶۶mmImI$Iے۶mIm$mm۶I$mI۶$I$$ےmImm$IImI$mmmI$mI$I$$۶۶mmImI$I$ےmmII$m$ےmImm$II$mIm$Im$۶ےmmII$m$ImmII$$mmIm$Im$ImIm$I$mے۶mIm$mII$mےIm$Im$ےmmIIm$$ImmII$$mےmImImI*IDATc` X!,np`IENDB`jgmenu-4.5.0/examples/ex04/icons/theme1/22/icon22x11xpm.xpm000066400000000000000000000111141472613136300230310ustar00rootroot00000000000000/* XPM */ static char *icon22x16_xpm[] = { "22 11 256 2", "AA c #000000", "BA c #FF0000", "CA c #00FF00", "DA c #FFFF00", "EA c #0000FF", "FA c #FF00FF", "GA c #00FFFF", "HA c #FFFFFF", "IA c #DBDBDB", "JA c #B6B6B6", "KA c #929292", "LA c #6D6D6D", "MA c #494949", "NA c #242424", "OA c #DB0000", "PA c #B60000", "QA c #920000", "RA c #6D0000", "SA c #490000", "TA c #240000", "UA c #00DB00", "VA c #00B600", "WA c #009200", "XA c #006D00", "YA c #004900", "ZA c #002400", "aA c #DBDB00", "bA c #B6B600", "cA c #929200", "dA c #6D6D00", "eA c #494900", "fA c #242400", "gA c #0000DB", "hA c #0000B6", "iA c #000092", "jA c #00006D", "kA c #000049", "lA c #000024", "mA c #DB00DB", "nA c #B600B6", "oA c #920092", "pA c #6D006D", "qA c #490049", "rA c #240024", "sA c #00DBDB", "tA c #00B6B6", "uA c #009292", "vA c #006D6D", "wA c #004949", "xA c #002424", "yA c #FFDBDB", "zA c #DBB6B6", "0A c #B69292", "1A c #926D6D", "2A c #6D4949", "3A c #492424", "4A c #FFB6B6", "5A c #DB9292", "6A c #B66D6D", "7A c #924949", "8A c #6D2424", "9A c #FF9292", "+A c #DB6D6D", "/A c #B64949", "AB c #922424", "BB c #FF6D6D", "CB c #DB4949", "DB c #B62424", "EB c #FF4949", "FB c #DB2424", "GB c #FF2424", "HB c #DBFFDB", "IB c #B6DBB6", "JB c #92B692", "KB c #6D926D", "LB c #496D49", "MB c #244924", "NB c #B6FFB6", "OB c #92DB92", "PB c #6DB66D", "QB c #499249", "RB c #246D24", "SB c #92FF92", "TB c #6DDB6D", "UB c #49B649", "VB c #249224", "WB c #6DFF6D", "XB c #49DB49", "YB c #24B624", "ZB c #49FF49", "aB c #24DB24", "bB c #24FF24", "cB c #DBDBFF", "dB c #B6B6DB", "eB c #9292B6", "fB c #6D6D92", "gB c #49496D", "hB c #242449", "iB c #B6B6FF", "jB c #9292DB", "kB c #6D6DB6", "lB c #494992", "mB c #24246D", "nB c #9292FF", "oB c #6D6DDB", "pB c #4949B6", "qB c #242492", "rB c #6D6DFF", "sB c #4949DB", "tB c #2424B6", "uB c #4949FF", "vB c #2424DB", "wB c #2424FF", "xB c #FFFFDB", "yB c #DBDBB6", "zB c #B6B692", "0B c #92926D", "1B c #6D6D49", "2B c #494924", "3B c #FFFFB6", "4B c #DBDB92", "5B c #B6B66D", "6B c #929249", "7B c #6D6D24", "8B c #FFFF92", "9B c #DBDB6D", "+B c #B6B649", "/B c #929224", "AC c #FFFF6D", "BC c #DBDB49", "CC c #B6B624", "DC c #FFFF49", "EC c #DBDB24", "FC c #FFFF24", "GC c #FFDBFF", "HC c #DBB6DB", "IC c #B692B6", "JC c #926D92", "KC c #6D496D", "LC c #492449", "MC c #FFB6FF", "NC c #DB92DB", "OC c #B66DB6", "PC c #924992", "QC c #6D246D", "RC c #FF92FF", "SC c #DB6DDB", "TC c #B649B6", "UC c #922492", "VC c #FF6DFF", "WC c #DB49DB", "XC c #B624B6", "YC c #FF49FF", "ZC c #DB24DB", "aC c #FF24FF", "bC c #DBFFFF", "cC c #B6DBDB", "dC c #92B6B6", "eC c #6D9292", "fC c #496D6D", "gC c #244949", "hC c #B6FFFF", "iC c #92DBDB", "jC c #6DB6B6", "kC c #499292", "lC c #246D6D", "mC c #92FFFF", "nC c #6DDBDB", "oC c #49B6B6", "pC c #249292", "qC c #6DFFFF", "rC c #49DBDB", "sC c #24B6B6", "tC c #49FFFF", "uC c #24DBDB", "vC c #24FFFF", "wC c #FFDBB6", "xC c #DBB692", "yC c #B6926D", "zC c #926D49", "0C c #6D4924", "1C c #492400", "2C c #FFB692", "3C c #DB926D", "4C c #B66D49", "5C c #924924", "6C c #6D2400", "7C c #FFB6DB", "8C c #DB92B6", "9C c #B66D92", "+C c #92496D", "/C c #6D2449", "AD c #490024", "BD c #FF92B6", "CD c #DB6D92", "DD c #B6496D", "ED c #922449", "FD c #6D0024", "GD c #DBB6FF", "HD c #B692DB", "ID c #926DB6", "JD c #6D4992", "KD c #49246D", "LD c #240049", "MD c #B692FF", "ND c #926DDB", "OD c #6D49B6", "PD c #492492", "QD c #24006D", "RD c #B6DBFF", "SD c #92B6DB", "TD c #6D92B6", "UD c #496D92", "VD c #24496D", "WD c #002449", "XD c #92B6FF", "YD c #6D92DB", "ZD c #496DB6", "aD c #244992", "bD c #00246D", "cD c #B6FFDB", "dD c #92DBB6", "eD c #6DB692", "fD c #49926D", "gD c #246D49", "hD c #004924", "iD c #92FFB6", "jD c #6DDB92", "kD c #49B66D", "lD c #249249", "mD c #006D24", "nD c #DBFFB6", "oD c #B6DB92", "pD c #92B66D", "qD c #6D9249", "rD c #496D24", "sD c #244900", "tD c #B6FF92", "uD c #92DB6D", "vD c #6DB649", "wD c #499224", "xD c #246D00", "yD c #FFB600", "zD c #DB9200", "0D c #B66D00", "1D c #924900", "2D c #FF00B6", "3D c #DB0092", "4D c #B6006D", "5D c #920049", "6D c #00B6FF", "7D c #0092DB", "8D c #006DB6", "9D c #004992", "+D c #000000", "/D c #000000", "EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA" }; jgmenu-4.5.0/examples/ex04/icons/theme1/22/icon22x22png.png000066400000000000000000000015341472613136300230000ustar00rootroot00000000000000PNG  IHDRj PLTE۶mmmIII$$$mI$mI$mmII$$mI$۶mmII$$mmII$$۶mmmIII$$ےmmIIm$$mmII$$mmII$$II$$$$۶۶mmImI$I$ےmmII$m$mmII$$mmII$$II$$$$ےmmIIm$$ImmII$$mmmII$$mmII$$II$$$$۶mmmIII$ےmImm$mI$mI$I$$۶۶mmImI$Iے۶mIm$mm۶I$mI۶$I$$ےmImm$IImI$mmmI$mI$I$$۶۶mmImI$I$ےmmII$m$ےmImm$II$mIm$Im$۶ےmmII$m$ImmII$$mmIm$Im$ImIm$I$mے۶mIm$mII$mےIm$Im$ےmmIIm$$ImmII$$mےmImImI*IDATc` XQ)E6aTIENDB`jgmenu-4.5.0/examples/ex04/icons/theme1/22/icon22x22xpm.xpm000066400000000000000000000121341472613136300230360ustar00rootroot00000000000000/* XPM */ static char *icon22x22_xpm[] = { "22 22 256 2", "AA c #000000", "BA c #FF0000", "CA c #00FF00", "DA c #FFFF00", "EA c #0000FF", "FA c #FF00FF", "GA c #00FFFF", "HA c #FFFFFF", "IA c #DBDBDB", "JA c #B6B6B6", "KA c #929292", "LA c #6D6D6D", "MA c #494949", "NA c #242424", "OA c #DB0000", "PA c #B60000", "QA c #920000", "RA c #6D0000", "SA c #490000", "TA c #240000", "UA c #00DB00", "VA c #00B600", "WA c #009200", "XA c #006D00", "YA c #004900", "ZA c #002400", "aA c #DBDB00", "bA c #B6B600", "cA c #929200", "dA c #6D6D00", "eA c #494900", "fA c #242400", "gA c #0000DB", "hA c #0000B6", "iA c #000092", "jA c #00006D", "kA c #000049", "lA c #000024", "mA c #DB00DB", "nA c #B600B6", "oA c #920092", "pA c #6D006D", "qA c #490049", "rA c #240024", "sA c #00DBDB", "tA c #00B6B6", "uA c #009292", "vA c #006D6D", "wA c #004949", "xA c #002424", "yA c #FFDBDB", "zA c #DBB6B6", "0A c #B69292", "1A c #926D6D", "2A c #6D4949", "3A c #492424", "4A c #FFB6B6", "5A c #DB9292", "6A c #B66D6D", "7A c #924949", "8A c #6D2424", "9A c #FF9292", "+A c #DB6D6D", "/A c #B64949", "AB c #922424", "BB c #FF6D6D", "CB c #DB4949", "DB c #B62424", "EB c #FF4949", "FB c #DB2424", "GB c #FF2424", "HB c #DBFFDB", "IB c #B6DBB6", "JB c #92B692", "KB c #6D926D", "LB c #496D49", "MB c #244924", "NB c #B6FFB6", "OB c #92DB92", "PB c #6DB66D", "QB c #499249", "RB c #246D24", "SB c #92FF92", "TB c #6DDB6D", "UB c #49B649", "VB c #249224", "WB c #6DFF6D", "XB c #49DB49", "YB c #24B624", "ZB c #49FF49", "aB c #24DB24", "bB c #24FF24", "cB c #DBDBFF", "dB c #B6B6DB", "eB c #9292B6", "fB c #6D6D92", "gB c #49496D", "hB c #242449", "iB c #B6B6FF", "jB c #9292DB", "kB c #6D6DB6", "lB c #494992", "mB c #24246D", "nB c #9292FF", "oB c #6D6DDB", "pB c #4949B6", "qB c #242492", "rB c #6D6DFF", "sB c #4949DB", "tB c #2424B6", "uB c #4949FF", "vB c #2424DB", "wB c #2424FF", "xB c #FFFFDB", "yB c #DBDBB6", "zB c #B6B692", "0B c #92926D", "1B c #6D6D49", "2B c #494924", "3B c #FFFFB6", "4B c #DBDB92", "5B c #B6B66D", "6B c #929249", "7B c #6D6D24", "8B c #FFFF92", "9B c #DBDB6D", "+B c #B6B649", "/B c #929224", "AC c #FFFF6D", "BC c #DBDB49", "CC c #B6B624", "DC c #FFFF49", "EC c #DBDB24", "FC c #FFFF24", "GC c #FFDBFF", "HC c #DBB6DB", "IC c #B692B6", "JC c #926D92", "KC c #6D496D", "LC c #492449", "MC c #FFB6FF", "NC c #DB92DB", "OC c #B66DB6", "PC c #924992", "QC c #6D246D", "RC c #FF92FF", "SC c #DB6DDB", "TC c #B649B6", "UC c #922492", "VC c #FF6DFF", "WC c #DB49DB", "XC c #B624B6", "YC c #FF49FF", "ZC c #DB24DB", "aC c #FF24FF", "bC c #DBFFFF", "cC c #B6DBDB", "dC c #92B6B6", "eC c #6D9292", "fC c #496D6D", "gC c #244949", "hC c #B6FFFF", "iC c #92DBDB", "jC c #6DB6B6", "kC c #499292", "lC c #246D6D", "mC c #92FFFF", "nC c #6DDBDB", "oC c #49B6B6", "pC c #249292", "qC c #6DFFFF", "rC c #49DBDB", "sC c #24B6B6", "tC c #49FFFF", "uC c #24DBDB", "vC c #24FFFF", "wC c #FFDBB6", "xC c #DBB692", "yC c #B6926D", "zC c #926D49", "0C c #6D4924", "1C c #492400", "2C c #FFB692", "3C c #DB926D", "4C c #B66D49", "5C c #924924", "6C c #6D2400", "7C c #FFB6DB", "8C c #DB92B6", "9C c #B66D92", "+C c #92496D", "/C c #6D2449", "AD c #490024", "BD c #FF92B6", "CD c #DB6D92", "DD c #B6496D", "ED c #922449", "FD c #6D0024", "GD c #DBB6FF", "HD c #B692DB", "ID c #926DB6", "JD c #6D4992", "KD c #49246D", "LD c #240049", "MD c #B692FF", "ND c #926DDB", "OD c #6D49B6", "PD c #492492", "QD c #24006D", "RD c #B6DBFF", "SD c #92B6DB", "TD c #6D92B6", "UD c #496D92", "VD c #24496D", "WD c #002449", "XD c #92B6FF", "YD c #6D92DB", "ZD c #496DB6", "aD c #244992", "bD c #00246D", "cD c #B6FFDB", "dD c #92DBB6", "eD c #6DB692", "fD c #49926D", "gD c #246D49", "hD c #004924", "iD c #92FFB6", "jD c #6DDB92", "kD c #49B66D", "lD c #249249", "mD c #006D24", "nD c #DBFFB6", "oD c #B6DB92", "pD c #92B66D", "qD c #6D9249", "rD c #496D24", "sD c #244900", "tD c #B6FF92", "uD c #92DB6D", "vD c #6DB649", "wD c #499224", "xD c #246D00", "yD c #FFB600", "zD c #DB9200", "0D c #B66D00", "1D c #924900", "2D c #FF00B6", "3D c #DB0092", "4D c #B6006D", "5D c #920049", "6D c #00B6FF", "7D c #0092DB", "8D c #006DB6", "9D c #004992", "+D c #000000", "/D c #000000", "EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EADADADADADADADADADADADADADADADADADADADADAEA", "EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA" }; jgmenu-4.5.0/examples/ex04/icons/theme1/48/000077500000000000000000000000001472613136300201425ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex04/icons/theme1/48/i1.svg000066400000000000000000000004001472613136300211660ustar00rootroot00000000000000 jgmenu-4.5.0/examples/ex04/icons/theme1/index.theme000066400000000000000000000000531472613136300220400ustar00rootroot00000000000000Inherits=theme2,theme-which-does-not-exist jgmenu-4.5.0/examples/ex04/icons/theme1/scalable/000077500000000000000000000000001472613136300214555ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex04/icons/theme1/scalable/icon32x64svg.svg000066400000000000000000000006341472613136300243600ustar00rootroot00000000000000 jgmenu-4.5.0/examples/ex04/icons/theme1/scalable/icon64x32svg.svg000066400000000000000000000006341472613136300243600ustar00rootroot00000000000000 jgmenu-4.5.0/examples/ex04/icons/theme2/000077500000000000000000000000001472613136300177105ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex04/icons/theme2/48/000077500000000000000000000000001472613136300201435ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex04/icons/theme2/48/i2.svg000066400000000000000000000002701472613136300211750ustar00rootroot00000000000000 = jgmenu-4.5.0/examples/ex04/jgmenurc000066400000000000000000000010311472613136300171410ustar00rootroot00000000000000menu_margin_x = 0 menu_margin_y = 31 menu_width = 600 menu_radius = 2 menu_border = 0 item_margin_x = 4 item_margin_y = 4 item_height = 24 item_padding_x = 3 item_radius = 0 item_border = 0 sep_height = 10 sep_markup = underline="single" sep_halign = center font = Ubuntu 14 icon_size = 22 icon_theme = theme1 color_menu_bg = #76c7d7 80 color_norm_bg = #76c7d7 0 color_norm_fg = #faf7f3 100 color_sel_bg = #a5ecfa 50 color_sel_fg = #47848f 100 color_sep_fg = #faf7f3 100 jgmenu-4.5.0/examples/ex05.sh000077500000000000000000000000671472613136300157540ustar00rootroot00000000000000#!/bin/sh ../jgmenu --simple --csv-file=ex05/root.csv jgmenu-4.5.0/examples/ex05/000077500000000000000000000000001472613136300154125ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex05/pipe1.csv000066400000000000000000000000631472613136300171440ustar00rootroot00000000000000this is pipe1 goto pipe2,^pipe(cat ex05/pipe2.csv) jgmenu-4.5.0/examples/ex05/pipe2.csv000066400000000000000000000004221472613136300171440ustar00rootroot00000000000000this is pipe2 list files in current directory,^pipe(ls -1) """list pixmaps using triple quote""","""^pipe(find /usr/share/pixmaps -type f -printf '%f,display %p,%p\n')""" checkout foo,^checkout(foo) checkout bar,^checkout(bar) ^tag(foo) one two three ^tag(bar) alpha beta jgmenu-4.5.0/examples/ex05/root.csv000066400000000000000000000000731472613136300171120ustar00rootroot00000000000000item1,:,folder goto pipe1,^pipe(cat ex05/pipe1.csv),folder jgmenu-4.5.0/examples/ex06.sh000077500000000000000000000003451472613136300157540ustar00rootroot00000000000000#!/bin/sh ( echo "one,one" echo "two,^checkout(foo)" echo "foo,^tag(foo)" for i in $(seq 100) do echo "item ${i},\"\"\"^pipe(for j in \$(seq 100); do echo "item \$j"; done) \"\"\" " done ) | ../jgmenu --vsimple --at-pointer jgmenu-4.5.0/examples/ex07.sh000077500000000000000000000010111472613136300157440ustar00rootroot00000000000000#!/bin/sh ( printf "%b\n" 'item a' printf "%b\n" 'item b' printf "%b\n" 'sub1,^root(sub1)' printf "%b\n" 'sub2,^root(sub2)' printf "%b\n" '' printf "%b\n" '^tag(sub1)' printf "%b\n" 'back,^back()' printf "%b\n" 'item 1.a' printf "%b\n" 'item 1.b' printf "%b\n" 'places-pipe,^pipe(jgmenu_run places)"' printf "%b\n" '' printf "%b\n" '^tag(sub2)' printf "%b\n" 'back,^back()' printf "%b\n" 'item 2.a' printf "%b\n" 'item 2.b' printf "%b\n" '' ) | XDG_DATA_HOME=$(pwd)/ex07 ../jgmenu --simple --config-file=./ex07/jgmenurc jgmenu-4.5.0/examples/ex07/000077500000000000000000000000001472613136300154145ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex07/jgmenurc000066400000000000000000000027411472613136300171550ustar00rootroot00000000000000# jgmenu config file (jgmenurc) # # See the man page jgmenu(1) for further details. #stay_alive = 1 #hide_on_startup = 0 #csv_cmd = pmenu tint2_look = 0 #at_pointer = 0 #terminal_exec = x-terminal-emulator #terminal_args = -e #monitor = 0 #hover_delay = 100 #menu_margin_x = 0 #menu_margin_y = 0 #menu_width = 200 #menu_padding_top = 5 #menu_padding_right = 5 #menu_padding_bottom = 5 #menu_padding_left = 5 #menu_radius = 1 menu_border = 1 #menu_halign = left #menu_valign = bottom #sub_spacing = 1 #sub_padding_top = auto #sub_padding_right = auto #sub_padding_bottom = auto #sub_padding_left = auto #sub_hover_action = 1 #item_margin_x = 3 #item_margin_y = 3 #item_height = 18 #item_padding_x = 4 #item_radius = 1 item_border = 1 #item_halign = left #sep_height = 5 font = Sans 9 #font_fallback = xtg #icon_size = 22 #icon_text_spacing = 10 #icon_theme = #icon_theme_fallback = xtg #arrow_string = ▸ #arrow_width = 15 color_menu_bg = #000000 100 color_menu_border = #eeeeee 30 #color_norm_bg = #000000 00 #color_norm_fg = #eeeeee 100 #color_sel_bg = #ffffff 20 #color_sel_fg = #eeeeee 100 #color_sel_border = #eeeeee 8 #color_sep_fg = #ffffff 20 #csv_name_format = %n (%g) jgmenu-4.5.0/examples/ex08.sh000077500000000000000000000000621472613136300157520ustar00rootroot00000000000000#!/bin/sh jgmenu --vsimple --csv-file=ex08/root jgmenu-4.5.0/examples/ex08/000077500000000000000000000000001472613136300154155ustar00rootroot00000000000000jgmenu-4.5.0/examples/ex08/only-one-item000077500000000000000000000000401472613136300200310ustar00rootroot00000000000000#!/bin/sh echo "only one item" jgmenu-4.5.0/examples/ex08/pipemenu-clashing-root-tag000077500000000000000000000000731472613136300225050ustar00rootroot00000000000000#!/bin/sh echo "^tag(clash1)" echo "bbbb.1" echo "bbbb.1" jgmenu-4.5.0/examples/ex08/pipemenu-clashing-submenu-tag000077500000000000000000000002001472613136300231700ustar00rootroot00000000000000#!/bin/sh echo "cccc.1" echo "cccc.2" echo "^checkout(clash2)" echo "^tag(clash2)" echo "cccc.clash2.1" echo "cccc.clash2.2" jgmenu-4.5.0/examples/ex08/root000066400000000000000000000006211472613136300163220ustar00rootroot00000000000000^tag(clash1) 1 2 pipe pipemenu-clashing-root-tag,^pipe(./ex08/pipemenu-clashing-root-tag) pipe pipemenu-clashing-submenu-tag,^pipe(./ex08/pipemenu-clashing-submenu-tag) pipe only-one-item,^pipe(./ex08/only-one-item) pipe tag-but-no-items,^pipe(./ex08/tag-but-no-items) pipe command which does not exist,^pipe(this-command-does-not-exist) 3 4 ^checkout(clash2) ^tag(clash2) clash2.1 clash2.2 clash2.3 jgmenu-4.5.0/examples/ex08/tag-but-no-items000077500000000000000000000000441472613136300204350ustar00rootroot00000000000000#!/bin/sh echo "^tag(not_a_clash)" jgmenu-4.5.0/examples/ex09.sh000077500000000000000000000010141472613136300157510ustar00rootroot00000000000000#!/bin/sh menu_file= ask_user_for_input () { tmp_file=$(mktemp) cd ../tests/t0006/menus for i in ./* do echo "${i#./},${i#./}" >> ${tmp_file} done menu_file=$(cat ${tmp_file} | jgmenu --no-spawn --config-file= --simple 2>/dev/null) cd ../.. rm -f ${tmp_file} } ask_user_for_input export XDG_MENU_PREFIX="${menu_file%applications\.menu}" printf "XDG_MENU_PREFIX=%b\n" "${XDG_MENU_PREFIX}" export XDG_CONFIG_DIRS="a:b:c:::d:$PWD/../tests/t0006:e:f" ../jgmenu --csv-cmd="$PWD/../jgmenu-lx" --simple --config-file= jgmenu-4.5.0/ppa/000077500000000000000000000000001472613136300135735ustar00rootroot00000000000000jgmenu-4.5.0/ppa/make_ubuntu.sh000077500000000000000000000025331472613136300164540ustar00rootroot00000000000000#!/bin/bash # Requirements: devscripts PKG=jgmenu set -x rm -rf ${PKG}* 2>/dev/null || true if [ ! -z "$1" ] then MINOR="$1" else MINOR="1" fi # Get version (and check that the repository is clean) VERSION="$(git show -s --pretty=format:%cI.%ct.%h | tr -d ':' | tr -d '-' | tr '.' '-' | sed 's/T[0-9\+]*//g').$MINOR" REPO="tint2-git" set -e # Export repository contents to source directory DIR=$PKG-$VERSION echo "Making release $DIR" pushd . cd .. git checkout-index --prefix=ppa/$DIR/ -a popd # Copy the debian files into the source directory cp -r ../debian $DIR/debian for DISTRO in trusty xenial zesty artful do # Cleanup from previous builds rm -rf ${PKG}_$VERSION-* # Update debian package changelog if necessary echo -e "$PKG ($VERSION-$DISTRO-1) $DISTRO; urgency=medium\n\n$(git log --pretty=format:' * %h %an (%ci) %s %d')\n -- o9000 $(date -R)\n" > $DIR/debian/changelog # Create source tarball ARCHIVE=${PKG}_$VERSION-$DISTRO.orig.tar.gz rm -rf $ARCHIVE tar -czf $ARCHIVE $DIR # Build package KEY=$(gpg --list-secret-keys | awk '/^sec/ { print $2 }' | cut -d / -f 2) pushd . cd $DIR debuild -S -k$KEY popd # Upload package dput ppa:o9000/$REPO ${PKG}_$VERSION-$DISTRO-1_source.changes done # Cleanup rm -rf $DIR $ARCHIVE rm -rf ${PKG}_$VERSION-* jgmenu-4.5.0/scripts/000077500000000000000000000000001472613136300145025ustar00rootroot00000000000000jgmenu-4.5.0/scripts/README000066400000000000000000000010751472613136300153650ustar00rootroot00000000000000These scripts are generally intended to be run from the project top-level directory, like this: ./scripts/foo.sh Check C code ------------ checkpatch.pl is copied from the linux kernel tree: https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl Use checkpatch-wrapper.sh to check files, for example: ./scripts/checkpatch-wrapper.sh *.c Check shell scripts ------------------- checkbashisms.pl is copied from: http://ftp.debian.org/debian/pool/main/d/devscripts/ Example usage: find . -name "*.sh" | xargs ./scripts/checkbashisms.pl --force jgmenu-4.5.0/scripts/asan000066400000000000000000000002421472613136300153450ustar00rootroot00000000000000# This file is designed to be sourced before running jgmenu with ASAN export ASAN_OPTIONS=detect_leaks=1 export LSAN_OPTIONS=suppressions=$PWD/scripts/lsan.supp jgmenu-4.5.0/scripts/check000077500000000000000000000040331472613136300155050ustar00rootroot00000000000000#!/usr/bin/env bash g_analyse_all=f g_cppcheck=t g_clangformat=f g_shellcheck=t g_resume_mode=f logfile=.tmp-check-script die () { printf '\033[31mfatal:\033[m %b\n' "$@" >&2 exit 1 } warn () { printf '\033[31mwarn:\033[m %b\n' "$@" >&2 } say () { printf '\033[32m%s\033[m' "$@" } isinstalled () { type "$1" >/dev/null 2>&1 } usage () { printf "%s\n" \ "Usage: check [] [...] Options: -a, --all run check on all .c .h and .sh files in src/ -h, --help show help -i, --in-situ pass -i to clang-format --resume same as --all, but carry on with last aborted" exit 0 } analyse () { [[ -e $1 ]] || die "file ($1) does not exist" say " CHECK $1" if [[ $(file $1) == *shell\ script* ]]; then say " [checkbashisms]" perl ./scripts/checkbashisms.pl --force "$1" [[ $g_shellcheck = f ]] && return say " [shellcheck]" shellcheck "$1" fi if [[ $(file $1) == *C\ source* ]]; then if [[ $g_cppcheck = t ]]; then say " [cppcheck]" ./scripts/cppcheck-wrapper.sh "$1" fi say " [checkpatch.pl]" if [[ $g_clangformat = t ]]; then say " [clang-format]" ./scripts/clang-format-wrapper.sh "$1" fi ./scripts/checkpatch-wrapper.sh "$1" fi printf "\n" } analyse_all () { [[ $g_resume_mode = f ]] && rm -f "${logfile}" for f in src/*.sh src/*.c src/*.h; do grep "${f}" "${logfile}" >/dev/null 2>&1 && continue analyse "$f" printf '%b\n' "${f}" >> "${logfile}" done } main () { [[ -e src/jgmenu.c ]] || die "must be run from top-level directory" [[ $# = 0 ]] && usage isinstalled cppcheck || { warn "cppcheck not installed"; g_cppcheck=f; } isinstalled clang-format || { warn "clang-format not installed"; g_clangformat=f; } isinstalled shellcheck || { warn "shellcheck not installed"; g_shellcheck=f; } for arg do opt=${arg%%=*} var=${arg#*=} case "$opt" in -a|-all) g_analyse_all=t ;; -i) g_insitu=t ;; -h|--help) usage ;; --resume) g_analyse_all=t g_resume_mode=t ;; *) analyse "$var" esac done [[ $g_analyse_all = t ]] && analyse_all } main "$@" jgmenu-4.5.0/scripts/checkbashisms-wrapper.sh000077500000000000000000000005661472613136300213350ustar00rootroot00000000000000#!/bin/sh printf "%s\n" "Checking shell scripts for bashisms..." find src/ -name "*.sh" | xargs perl ./scripts/checkbashisms.pl --force 2>&1 \ | grep -v "^could not find" printf "%s\n" "Searching for files staring with '#!/bin/bash'..." for f in $(find . -name "*.sh" | xargs) do if cat ${f} | grep '^#!/bin/bash' >/dev/null 2>&1 then printf "%b\n" "${f}" fi done jgmenu-4.5.0/scripts/checkbashisms.1000066400000000000000000000046041472613136300173770ustar00rootroot00000000000000.TH CHECKBASHISMS 1 "Debian Utilities" "DEBIAN" \" -*- nroff -*- .SH NAME checkbashisms \- check for bashisms in /bin/sh scripts .SH SYNOPSIS \fBcheckbashisms\fR \fIscript\fR ... .br \fBcheckbashisms \-\-help\fR|\fB\-\-version\fR .SH DESCRIPTION \fBcheckbashisms\fR, based on one of the checks from the \fBlintian\fR system, performs basic checks on \fI/bin/sh\fR shell scripts for the possible presence of bashisms. It takes the names of the shell scripts on the command line, and outputs warnings if possible bashisms are detected. .PP Note that the definition of a bashism in this context roughly equates to "a shell feature that is not required to be supported by POSIX"; this means that some issues flagged may be permitted under optional sections of POSIX, such as XSI or User Portability. .PP In cases where POSIX and Debian Policy disagree, \fBcheckbashisms\fR by default allows extensions permitted by Policy but may also provide options for stricter checking. .SH OPTIONS .TP .BR \-\-help ", " \-h Show a summary of options. .TP .BR \-\-newline ", " \-n Check for "\fBecho \-n\fR" usage (non POSIX but required by Debian Policy 10.4.) .TP .BR \-\-posix ", " \-p Check for issues which are non POSIX but required to be supported by Debian Policy 10.4 (implies \fB\-n\fR). .TP .BR \-\-force ", " \-f Force each script to be checked, even if it would normally not be (for instance, it has a bash or non POSIX shell shebang or appears to be a shell wrapper). .TP .BR \-\-extra ", " \-x Highlight lines which, whilst they do not contain bashisms, may be useful in determining whether a particular issue is a false positive which may be ignored. For example, the use of "\fB$BASH_ENV\fR" may be preceded by checking whether "\fB$BASH\fR" is set. .TP .BR \-\-version ", " \-v Show version and copyright information. .SH "EXIT VALUES" The exit value will be 0 if no possible bashisms or other problems were detected. Otherwise it will be the sum of the following error values: .TP 1 A possible bashism was detected. .TP 2 A file was skipped for some reason, for example, because it was unreadable or not found. The warning message will give details. .TP 4 No bashisms were detected in a bash script. .SH "SEE ALSO" .BR lintian (1) .SH AUTHOR \fBcheckbashisms\fR was originally written as a shell script by Yann Dirson <\fIdirson@debian.org\fR> and rewritten in Perl with many more features by Julian Gilbey <\fIjdg@debian.org\fR>. jgmenu-4.5.0/scripts/checkbashisms.pl000066400000000000000000000630451472613136300176560ustar00rootroot00000000000000#!/usr/bin/perl # This script is essentially copied from /usr/share/lintian/checks/scripts, # which is: # Copyright (C) 1998 Richard Braakman # Copyright (C) 2002 Josip Rodin # This version is # Copyright (C) 2003 Julian Gilbey # # 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 2 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 . use strict; use warnings; use Getopt::Long qw(:config bundling permute no_getopt_compat); use File::Temp qw/tempfile/; sub init_hashes; (my $progname = $0) =~ s|.*/||; my $usage = <<"EOF"; Usage: $progname [-n] [-f] [-x] script ... or: $progname --help or: $progname --version This script performs basic checks for the presence of bashisms in /bin/sh scripts and the lack of bashisms in /bin/bash ones. EOF my $version = <<"EOF"; This is $progname, from the Debian devscripts package, version ###VERSION### This code is copyright 2003 by Julian Gilbey , based on original code which is copyright 1998 by Richard Braakman and copyright 2002 by Josip Rodin. This program comes with ABSOLUTELY NO WARRANTY. You are free to redistribute this code under the terms of the GNU General Public License, version 2, or (at your option) any later version. EOF my ($opt_echo, $opt_force, $opt_extra, $opt_posix); my ($opt_help, $opt_version); my @filenames; # Detect if STDIN is a pipe if (scalar(@ARGV) == 0 && (-p STDIN or -f STDIN)) { push(@ARGV, '-'); } ## ## handle command-line options ## $opt_help = 1 if int(@ARGV) == 0; GetOptions("help|h" => \$opt_help, "version|v" => \$opt_version, "newline|n" => \$opt_echo, "force|f" => \$opt_force, "extra|x" => \$opt_extra, "posix|p" => \$opt_posix, ) or die "Usage: $progname [options] filelist\nRun $progname --help for more details\n"; if ($opt_help) { print $usage; exit 0; } if ($opt_version) { print $version; exit 0; } $opt_echo = 1 if $opt_posix; my $mode = 0; my $issues = 0; my $status = 0; my $makefile = 0; my (%bashisms, %string_bashisms, %singlequote_bashisms); my $LEADIN = qr'(?:(?:^|[`&;(|{])\s*|(?:(?:if|elif|while)(?:\s+!)?|then|do|shell)\s+)'; init_hashes; my @bashisms_keys = sort keys %bashisms; my @string_bashisms_keys = sort keys %string_bashisms; my @singlequote_bashisms_keys = sort keys %singlequote_bashisms; foreach my $filename (@ARGV) { my $check_lines_count = -1; my $display_filename = $filename; if ($filename eq '-') { my $tmp_fh; ($tmp_fh, $filename) = tempfile("chkbashisms_tmp.XXXX", TMPDIR => 1, UNLINK => 1); while (my $line = ) { print $tmp_fh $line; } close($tmp_fh); $display_filename = "(stdin)"; } if (!$opt_force) { $check_lines_count = script_is_evil_and_wrong($filename); } if ($check_lines_count == 0 or $check_lines_count == 1) { warn "script $display_filename does not appear to be a /bin/sh script; skipping\n"; next; } if ($check_lines_count != -1) { warn "script $display_filename appears to be a shell wrapper; only checking the first " . "$check_lines_count lines\n"; } unless (open C, '<', $filename) { warn "cannot open script $display_filename for reading: $!\n"; $status |= 2; next; } $issues = 0; $mode = 0; my $cat_string = ""; my $cat_indented = 0; my $quote_string = ""; my $last_continued = 0; my $continued = 0; my $found_rules = 0; my $buffered_orig_line = ""; my $buffered_line = ""; my %start_lines; while () { next unless ($check_lines_count == -1 or $. <= $check_lines_count); if ($. == 1) { # This should be an interpreter line if (m,^\#!\s*(?:\S+/env\s+)?(\S+),) { my $interpreter = $1; if ($interpreter =~ m,(?:^|/)make$,) { init_hashes if !$makefile++; $makefile = 1; } else { init_hashes if $makefile--; $makefile = 0; } next if $opt_force; if ($interpreter =~ m,(?:^|/)bash$,) { $mode = 1; } elsif ($interpreter !~ m,(?:^|/)(sh|dash|posh)$,) { ### ksh/zsh? warn "script $display_filename does not appear to be a /bin/sh script; skipping\n"; $status |= 2; last; } } else { warn "script $display_filename does not appear to have a \#! interpreter line;\nyou may get strange results\n"; } } chomp; my $orig_line = $_; # We want to remove end-of-line comments, so need to skip # comments that appear inside balanced pairs # of single or double quotes # Remove comments in the "quoted" part of a line that starts # in a quoted block? The problem is that we have no idea # whether the program interpreting the block treats the # quote character as part of the comment or as a quote # terminator. We err on the side of caution and assume it # will be treated as part of the comment. # s/^(?:.*?[^\\])?$quote_string(.*)$/$1/ if $quote_string ne ""; # skip comment lines if (m,^\s*\#, && $quote_string eq '' && $buffered_line eq '' && $cat_string eq '') { next; } # Remove quoted strings so we can more easily ignore comments # inside them s/(^|[^\\](?:\\\\)*)\'(?:\\.|[^\\\'])+\'/$1''/g; s/(^|[^\\](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1""/g; # If inside a quoted string, remove everything before the quote s/^.+?\'// if ($quote_string eq "'"); s/^.+?[^\\]\"// if ($quote_string eq '"'); # If the remaining string contains what looks like a comment, # eat it. In either case, swap the unmodified script line # back in for processing. if (m/(?:^|[^[\\])[\s\&;\(\)](\#.*$)/) { $_ = $orig_line; s/\Q$1\E//; # eat comments } else { $_ = $orig_line; } # Handle line continuation if (!$makefile && $cat_string eq '' && m/\\$/) { chop; $buffered_line .= $_; $buffered_orig_line .= $orig_line . "\n"; next; } if ($buffered_line ne '') { $_ = $buffered_line . $_; $orig_line = $buffered_orig_line . $orig_line; $buffered_line =''; $buffered_orig_line =''; } if ($makefile) { $last_continued = $continued; if (/[^\\]\\$/) { $continued = 1; } else { $continued = 0; } # Don't match lines that look like a rule if we're in a # continuation line before the start of the rules if (/^[\w%-]+:+\s.*?;?(.*)$/ and !($last_continued and !$found_rules)) { $found_rules = 1; $_ = $1 if $1; } last if m%^\s*(override\s|export\s)?\s*SHELL\s*:?=\s*(/bin/)?bash\s*%; # Remove "simple" target names s/^[\w%.-]+(?:\s+[\w%.-]+)*::?//; s/^\t//; s/(?|<|;|\Z)/o and m/$LEADIN(\.\s+[^\s;\`:]+\s+([^\s;]+))/o) { if ($2 =~ /^(\&|\||\d?>|<)/) { # everything is ok ; } else { $found = 1; $match = $1; $explanation = "sourced script with arguments"; output_explanation($display_filename, $orig_line, $explanation); } } # Remove "quoted quotes". They're likely to be inside # another pair of quotes; we're not interested in # them for their own sake and removing them makes finding # the limits of the outer pair far easier. $line =~ s/(^|[^\\\'\"])\"\'\"/$1/g; $line =~ s/(^|[^\\\'\"])\'\"\'/$1/g; foreach my $re (@singlequote_bashisms_keys) { my $expl = $singlequote_bashisms{$re}; if ($line =~ m/($re)/) { $found = 1; $match = $1; $explanation = $expl; output_explanation($display_filename, $orig_line, $explanation); } } my $re='(?); } } # $cat_line contains the version of the line we'll check # for heredoc delimiters later. Initially, remove any # spaces between << and the delimiter to make the following # updates to $cat_line easier. However, don't remove the # spaces if the delimiter starts with a -, as that changes # how the delimiter is searched. my $cat_line = $line; $cat_line =~ s/(<\<-?)\s+(?!-)/$1/g; # Ignore anything inside single quotes; it could be an # argument to grep or the like. $line =~ s/(^|[^\\\"](?:\\\\)*)\'(?:\\.|[^\\\'])+\'/$1''/g; # As above, with the exception that we don't remove the string # if the quote is immediately preceded by a < or a -, so we # can match "foo <<-?'xyz'" as a heredoc later # The check is a little more greedy than we'd like, but the # heredoc test itself will weed out any false positives $cat_line =~ s/(^|[^<\\\"-](?:\\\\)*)\'(?:\\.|[^\\\'])+\'/$1''/g; $re='(?); } } foreach my $re (@string_bashisms_keys) { my $expl = $string_bashisms{$re}; if ($line =~ m/($re)/) { $found = 1; $match = $1; $explanation = $expl; output_explanation($display_filename, $orig_line, $explanation); } } # We've checked for all the things we still want to notice in # double-quoted strings, so now remove those strings as well. $line =~ s/(^|[^\\\'](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1""/g; $cat_line =~ s/(^|[^<\\\'-](?:\\\\)*)\"(?:\\.|[^\\\"])+\"/$1""/g; foreach my $re (@bashisms_keys) { my $expl = $bashisms{$re}; if ($line =~ m/($re)/) { $found = 1; $match = $1; $explanation = $expl; output_explanation($display_filename, $orig_line, $explanation); } } # This check requires the value to be compared, which could # be done in the regex itself but requires "use re 'eval'". # So it's better done in its own if ($line =~ m/$LEADIN((?:exit|return)\s+(\d{3,}))/o && $2 > 255) { $explanation = 'exit|return status code greater than 255'; output_explanation($display_filename, $orig_line, $explanation); } # Only look for the beginning of a heredoc here, after we've # stripped out quoted material, to avoid false positives. if ($cat_line =~ m/(?:^|[^<])\<\<(\-?)\s*(?:(?!<|'|")((?:[^\s;>|]+(?:(?<=\\)[\s;>|])?)+)|[\'\"](.*?)[\'\"])/) { $cat_indented = ($1 && $1 eq '-')? 1 : 0; my $quoted = defined($3); $cat_string = $quoted? $3 : $2; unless ($quoted) { # Now strip backslashes. Keep the position of the # last match in a variable, as s/// resets it back # to undef, but we don't want that. my $pos = 0; pos($cat_string) = $pos; while ($cat_string =~ s/\G(.*?)\\/$1/) { # postition += length of match + the character # that followed the backslash: $pos += length($1)+1; pos($cat_string) = $pos; } } $start_lines{'cat_string'} = $.; } } } warn "error: $display_filename: Unterminated heredoc found, EOF reached. Wanted: <$cat_string>, opened in line $start_lines{'cat_string'}\n" if ($cat_string ne ''); warn "error: $display_filename: Unterminated quoted string found, EOF reached. Wanted: <$quote_string>, opened in line $start_lines{'quote_string'}\n" if ($quote_string ne ''); warn "error: $display_filename: EOF reached while on line continuation.\n" if ($buffered_line ne ''); close C; if ($mode && !$issues) { warn "could not find any possible bashisms in bash script $filename\n"; $status |= 4; } } exit $status; sub output_explanation { my ($filename, $line, $explanation) = @_; if ($mode) { # When examining a bash script, just flag that there are indeed # bashisms present $issues = 1; } else { warn "possible bashism in $filename line $. ($explanation):\n$line\n"; $status |= 1; } } # Returns non-zero if the given file is not actually a shell script, # just looks like one. sub script_is_evil_and_wrong { my ($filename) = @_; my $ret = -1; # lintian's version of this function aborts if the file # can't be opened, but we simply return as the next # test in the calling code handles reporting the error # itself open (IN, '<', $filename) or return $ret; my $i = 0; my $var = "0"; my $backgrounded = 0; local $_; while () { chomp; next if /^#/o; next if /^$/o; last if (++$i > 55); if (m~ # the exec should either be "eval"ed or a new statement (^\s*|\beval\s*[\'\"]|(;|&&|\b(then|else))\s*) # eat anything between the exec and $0 exec\s*.+\s* # optionally quoted executable name (via $0) .?\$$var.?\s* # optional "end of options" indicator (--\s*)? # Match expressions of the form '${1+$@}', '${1:+"$@"', # '"${1+$@', "$@", etc where the quotes (before the dollar # sign(s)) are optional and the second (or only if the $1 # clause is omitted) parameter may be $@ or $*. # # Finally the whole subexpression may be omitted for scripts # which do not pass on their parameters (i.e. after re-execing # they take their parameters (and potentially data) from stdin .?(\$\{1:?\+.?)?(\$(\@|\*))?~x) { $ret = $. - 1; last; } elsif (/^\s*(\w+)=\$0;/) { $var = $1; } elsif (m~ # Match scripts which use "foo $0 $@ &\nexec true\n" # Program name \S+\s+ # As above .?\$$var.?\s* (--\s*)? .?(\$\{1:?\+.?)?(\$(\@|\*))?.?\s*\&~x) { $backgrounded = 1; } elsif ($backgrounded and m~ # the exec should either be "eval"ed or a new statement (^\s*|\beval\s*[\'\"]|(;|&&|\b(then|else))\s*) exec\s+true(\s|\Z)~x) { $ret = $. - 1; last; } elsif (m~\@DPATCH\@~) { $ret = $. - 1; last; } } close IN; return $ret; } sub init_hashes { %bashisms = ( qr'(?:^|\s+)function [^<>\(\)\[\]\{\};|\s]+(\s|\(|\Z)' => q<'function' is useless>, $LEADIN . qr'select\s+\w+' => q<'select' is not POSIX>, qr'(test|-o|-a)\s*[^\s]+\s+==\s' => q, qr'\[\s+[^\]]+\s+==\s' => q, qr'\s\|\&' => q, qr'[^\\\$]\{([^\s\\\}]*?,)+[^\\\}\s]*\}' => q, qr'\{\d+\.\.\d+(?:\.\.\d+)?\}' => q, qr'(?i)\{[a-z]\.\.[a-z](?:\.\.\d+)?\}' => q, qr'(?:^|\s+)\w+\[\d+\]=' => q, $LEADIN . qr'read\s+(?:-[a-qs-zA-Z\d-]+)' => q, $LEADIN . qr'read\s*(?:-\w+\s*)*(?:\".*?\"|[\'].*?[\'])?\s*(?:;|$)' => q, $LEADIN . qr'echo\s+(-n\s+)?-n?en?\s' => q, $LEADIN . qr'exec\s+-[acl]' => q, $LEADIN . qr'let\s' => q, qr'(? q<'((' should be '$(('>, qr'(?:^|\s+)(\[|test)\s+-a' => q, qr'\&>' => qword 2\>&1>, qr'(<\&|>\&)\s*((-|\d+)[^\s;|)}`&\\\\]|[^-\d\s]+(? qword 2\>&1>, qr'\[\[(?!:)' => q, qr'/dev/(tcp|udp)' => q, $LEADIN . qr'builtin\s' => q, $LEADIN . qr'caller\s' => q, $LEADIN . qr'compgen\s' => q, $LEADIN . qr'complete\s' => q, $LEADIN . qr'declare\s' => q, $LEADIN . qr'dirs(\s|\Z)' => q, $LEADIN . qr'disown\s' => q, $LEADIN . qr'enable\s' => q, $LEADIN . qr'mapfile\s' => q, $LEADIN . qr'readarray\s' => q, $LEADIN . qr'shopt(\s|\Z)' => q, $LEADIN . qr'suspend\s' => q, $LEADIN . qr'time\s' => q