Openbox - 共通事項 - メニュー - openbox-xdg-menu - 概要

 クラウディア
1. 概要
2. 調査
3. openbox-xdg-menu は何者?
4. ソース

1. 概要

 「Fedora 33 Openbox」のものは、これまでのものとまた、異なっています。

2. 調査


$ ls ~/.config/openbox/
lxqt-rc.xml
 ここには、「menu.xml」は存在しないようです。

$ ls /etc/xdg/openbox/
autostart  environment  lxqt-rc.xml  menu.xml  rc.xml  terminals.menu
 ここのものを使用しているようです。  でまぁ、

/etc/xdg/openbox/menu.xml
 の中身を見て

<?xml version="1.0" encoding="UTF-8"?>

<openbox_menu xmlns="http://openbox.org/3.4/menu">

<menu id="applications-menu" label="Applications" execute="/usr/libexec/openbox-xdg-menu applications"/>
<menu id="preferences-menu" label="Preferences" execute="/usr/libexec/openbox-xdg-menu preferences"/>
<menu id="administration-menu" label="Administration" execute="/usr/libexec/openbox-xdg-menu system-settings"/>
<menu id="terminals-menu" label="Terminals" execute="/usr/libexec/openbox-xdg-menu /etc/xdg/openbox/terminals"/>

<menu id="root-menu" label="Openbox 3">
  <separator label="Openbox"/>
  <menu id="applications-menu"/>
  <menu id="preferences-menu"/>
  <menu id="administration-menu"/>
  <separator/>
  <menu id="terminals-menu"/>
  <separator/>
  <item label="Reconfigure">
    <action name="Reconfigure" />
  </item>
  <item label="Exit">
    <action name="Exit">
      <prompt>yes</prompt>
    </action>
  </item>
  <separator/>
  <item label="Log Out">
    <action name="SessionLogout">
      <prompt>yes</prompt>
    </action>
  </item>
</menu>

</openbox_menu>
 おお

/usr/libexec/openbox-xdg-menu
 てのが、動的にメニューを表示しているのだな・・・と理解するのであります。

3. openbox-xdg-menu は何者?

 では、「openbox-xdg-menu」かと見てみると

$ file /usr/libexec/openbox-xdg-menu
/usr/libexec/openbox-xdg-menu: Python script, ASCII text executable
 なるほど、「Pyrhon」で書かれているのね、ということがわかるのでありました。  「Pyrhon」のバージョンを調べてみます。

$ python --version
Python 3.9.0
 なかなか、新しいようであります(2020年11月30日現在)。

4. ソース


/usr/libexec/openbox-xdg-menu
 本体は、そこまで長いソースではありませんでした。  全行でも 108行です。  こんなの
#!/usr/bin/python3
#
# Copyright (C) 2008  Red Hat, Inc.
#
# 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 <http://www.gnu.org/licenses/>.
#
# Author(s): Luke Macken <lmacken@redhat.com>
#            Miroslav Lichvar <mlichvar@redhat.com>
#            Edward Sheldrake <ejsheldrake@gmail.com>


import xdg.Menu, xdg.DesktopEntry, xdg.Config
import re, sys, os
from xml.sax.saxutils import escape

icons = True
try:
	import gi
	gi.require_version('Gtk', '3.0')
	from gi.repository import Gtk
except ImportError:
	icons = False

def icon_attr(entry):
	if icons is False:
		return ''

	name = entry.getIcon()

	if os.path.exists(name):
		return ' icon="' + name + '"'

	# work around broken .desktop files
	# unless the icon is a full path it should not have an extension
	name = re.sub('\..{3,4}$', '', name)

	# imlib2 cannot load svg
	iconinfo = theme.lookup_icon(name, 22, Gtk.IconLookupFlags.NO_SVG)
	if iconinfo:
		iconfile = iconinfo.get_filename()
		if hasattr(iconinfo, 'free'):
			iconinfo.free()
		if iconfile:
			return ' icon="' + iconfile + '"'
	return ''

def escape_utf8(s):
	if sys.version_info[0] < 3 and isinstance(s, unicode):
		s = s.encode('utf-8', 'xmlcharrefreplace')
	return escape(s)

def entry_name(entry):
	return escape_utf8(entry.getName())

def walk_menu(entry):
	if isinstance(entry, xdg.Menu.Menu) and entry.Show is True:
		print('<menu id="%s" label="%s"%s>' \
			% (entry_name(entry),
			entry_name(entry),
			escape_utf8(icon_attr(entry))))
		list(map(walk_menu, entry.getEntries()))
		print('</menu>')
	elif isinstance(entry, xdg.Menu.MenuEntry) and entry.Show is True:
		name = entry_name(entry.DesktopEntry)
		print('	<item label="%s"%s>' % (name.replace('"', ''),
			escape_utf8(icon_attr(entry.DesktopEntry))))
		command = re.sub(' -caption "%c"| -caption %c',
			' -caption "%s"' % name,
			escape_utf8(entry.DesktopEntry.getExec()))
		command = re.sub(' [^ ]*%[fFuUdDnNickvm]', '', command)
		if entry.DesktopEntry.getTerminal():
			command = 'xterm -title "%s" -e %s' % (name, command)
		print('		<action name="Execute">' + \
			'<command>%s</command></action>' % command)
		print('	</item>')

if len(sys.argv) > 1:
	menufile = sys.argv[1] + '.menu'
else:
	menufile = 'applications.menu'

lang = os.environ.get('LANG')
if lang:
	xdg.Config.setLocale(lang)

# lie to get the same menu as in GNOME
xdg.Config.setWindowManager('GNOME')

if icons:
  theme = Gtk.IconTheme.get_default()

menu = xdg.Menu.parse(menufile)

print('<?xml version="1.0" encoding="UTF-8"?>')
print('<openbox_pipe_menu>')
list(map(walk_menu, menu.getEntries()))
print('</openbox_pipe_menu>')

損保との違いU-NEXTマイニングベース
 
 
カウンタバックグラウンド