diff --git a/menu.xml b/menu.xml
new file mode 100644
index 0000000..238cf52
--- /dev/null
+++ b/menu.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openbox-3.6.1.tar.xz b/openbox-3.6.1.tar.xz
new file mode 100644
index 0000000..fb3d479
Binary files /dev/null and b/openbox-3.6.1.tar.xz differ
diff --git a/openbox-python3.patch b/openbox-python3.patch
new file mode 100644
index 0000000..f17bef3
--- /dev/null
+++ b/openbox-python3.patch
@@ -0,0 +1,113 @@
+diff -up openbox-3.6.1/data/autostart/openbox-xdg-autostart.python3 openbox-3.6.1/data/autostart/openbox-xdg-autostart
+--- openbox-3.6.1/data/autostart/openbox-xdg-autostart.python3 2013-04-17 14:27:27.000000000 +0200
++++ openbox-3.6.1/data/autostart/openbox-xdg-autostart 2018-04-17 15:52:23.849765020 +0200
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python
++#!/usr/bin/python3
+
+ # openbox-xdg-autostart runs things based on the XDG autostart specification
+ # Copyright (C) 2008 Dana Jansens
+@@ -28,9 +28,9 @@ try:
+ from xdg.DesktopEntry import DesktopEntry
+ from xdg.Exceptions import ParsingError
+ except ImportError:
+- print
+- print >>sys.stderr, "ERROR:", ME, "requires PyXDG to be installed"
+- print
++ print()
++ print("ERROR:", ME, "requires PyXDG to be installed", file=sys.stderr)
++ print()
+ sys.exit(1)
+
+ def main(argv=sys.argv):
+@@ -51,7 +51,7 @@ def main(argv=sys.argv):
+ try:
+ autofile = AutostartFile(path)
+ except ParsingError:
+- print "Invalid .desktop file: " + path
++ print("Invalid .desktop file: " + path)
+ else:
+ if not autofile in files:
+ files.append(autofile)
+@@ -99,9 +99,9 @@ class AutostartFile:
+
+ def _alert(self, str, info=False):
+ if info:
+- print "\t ", str
++ print("\t ", str)
+ else:
+- print "\t*", str
++ print("\t*", str)
+
+ def _showInEnvironment(self, envs, verbose=False):
+ default = not self.de.getOnlyShowIn()
+@@ -146,9 +146,9 @@ class AutostartFile:
+
+ def display(self, envs):
+ if self._shouldRun(envs):
+- print "[*] " + self.de.getName()
++ print("[*] " + self.de.getName())
+ else:
+- print "[ ] " + self.de.getName()
++ print("[ ] " + self.de.getName())
+ self._alert("File: " + self.path, info=True)
+ if self.de.getExec():
+ self._alert("Executes: " + self.de.getExec(), info=True)
+@@ -165,33 +165,33 @@ class AutostartFile:
+ os.chdir(here)
+
+ def show_help():
+- print "Usage:", ME, "[OPTION]... [ENVIRONMENT]..."
+- print
+- print "This tool will run xdg autostart .desktop files"
+- print
+- print "OPTIONS"
+- print " --list Show a list of the files which would be run"
+- print " Files which would be run are marked with an asterix"
+- print " symbol [*]. For files which would not be run,"
+- print " information is given for why they are excluded"
+- print " --help Show this help and exit"
+- print " --version Show version and copyright information"
+- print
+- print "ENVIRONMENT specifies a list of environments for which to run autostart"
+- print "applications. If none are specified, only applications which do not "
+- print "limit themselves to certain environments will be run."
+- print
+- print "ENVIRONMENT can be one or more of:"
+- print " GNOME Gnome Desktop"
+- print " KDE KDE Desktop"
+- print " ROX ROX Desktop"
+- print " XFCE XFCE Desktop"
+- print " Old Legacy systems"
++ print("Usage:", ME, "[OPTION]... [ENVIRONMENT]...")
++ print()
++ print("This tool will run xdg autostart .desktop files")
++ print()
++ print("OPTIONS")
++ print(" --list Show a list of the files which would be run")
++ print(" Files which would be run are marked with an asterix")
++ print(" symbol [*]. For files which would not be run,")
++ print(" information is given for why they are excluded")
++ print(" --help Show this help and exit")
++ print(" --version Show version and copyright information")
++ print()
++ print("ENVIRONMENT specifies a list of environments for which to run autostart")
++ print("applications. If none are specified, only applications which do not ")
++ print("limit themselves to certain environments will be run.")
++ print
++ print("ENVIRONMENT can be one or more of:")
++ print(" GNOME Gnome Desktop")
++ print(" KDE KDE Desktop")
++ print(" ROX ROX Desktop")
++ print(" XFCE XFCE Desktop")
++ print(" Old Legacy systems")
+ print
+
+ def show_version():
+- print ME, VERSION
+- print "Copyright (c) 2008 Dana Jansens"
++ print(ME, VERSION)
++ print("Copyright (c) 2008 Dana Jansens")
+ print
+
+ if __name__ == "__main__":
diff --git a/openbox.spec b/openbox.spec
new file mode 100644
index 0000000..b2b7507
--- /dev/null
+++ b/openbox.spec
@@ -0,0 +1,120 @@
+Name: openbox
+Version: 3.6.1
+Release: 11
+Summary: Windowmanager based on the original blackbox-code
+License: GPLv2+
+URL: http://openbox.org
+Source0: http://openbox.org/dist/%{name}/%{name}-%{version}.tar.xz
+Source1: http://icculus.org/openbox/tools/setlayout.c
+Source2: xdg-menu
+Source3: menu.xml
+Source4: terminals.menu
+Patch1: openbox-python3.patch
+
+Suggests: python3-gobject
+BuildRequires: gettext desktop-file-utils pango-devel startup-notification-devel libxml2-devel
+BuildRequires: libXcursor-devel libXt-devel libXrandr-devel libXinerama-devel imlib2-devel libpng-devel
+Requires: python3-pyxdg redhat-menus
+Provides: firstboot(windowmanager)
+Obsoletes: gdm-control < 3.5.2-5 gnome-panel-control < 3.5.2-5 %{name}-gnome < 3.5.2-5
+Provides: %{name}-libs = %{version}-%{release}
+Obsoletes: %{name}-libs < %{version}-%{release}
+
+%description
+Openbox is a window manager for the X11 windowing system.
+It currently runs on a large list of platforms. It was originally
+based on blackbox and currently remains very similar, even using
+blackbox styles (with available extensions) for its themeing.
+
+Openbox is the spawn of a number of previous blackbox users/hackers.
+Being overall pleased with the window manager, but feeling left unable
+to contribute, this project was born.The Openbox project is developed,
+maintained, and contributed to by these individuals.
+
+%package devel
+Summary: Development files for openbox
+Requires: %{name} = %{version}-%{release} pkgconfig pango-devel libxml2-devel glib2-devel
+
+%description devel
+This package contains libraries and header files for developing applications that
+use openbox.
+
+%package kde
+Summary: Openbox KDE integration
+Requires: %{name} = %{version}-%{release} plasma-workspace
+BuildArch: noarch
+
+%description kde
+This package provides openbox KDE integration and tools.
+
+%package help
+Summary: Help documentation for %{name}
+
+%description help
+Man pages and other related help documents for %{name}.
+
+%prep
+%autosetup -n %{name}-%{version} -p1
+
+%build
+%configure --disable-static
+sed -ie 's|^hardcode_libdir_flag_spec=.*$|hardcode_libdir_flag_spec=""|g' libtool
+sed -ie 's|^runpath_var=LD_RUN_PATH$|runpath_var=DIE_RPATH_DIE|g' libtool
+%make_build
+
+gcc $RPM_OPT_FLAGS $RPM_LD_FLAGS -o setlayout %{SOURCE1} -lX11
+
+%install
+%make_install
+install setlayout %{buildroot}%{_bindir}
+install -p %{SOURCE2} %{buildroot}%{_libexecdir}/openbox-xdg-menu
+sed 's|_LIBEXECDIR_|%{_libexecdir}|g' < %{SOURCE3} > %{buildroot}%{_sysconfdir}/xdg/%{name}/menu.xml
+
+install -m644 -p %{SOURCE4} %{buildroot}%{_sysconfdir}/xdg/%{name}/terminals.menu
+
+install -m644 -D data/gnome-session/openbox-gnome.session \
+ %{buildroot}%{_datadir}/gnome-session/sessions/openbox-gnome.session
+install -m644 -D data/gnome-session/openbox-gnome-fallback.session \
+ %{buildroot}%{_datadir}/gnome-session/sessions/openbox-gnome-fallback.session
+
+%find_lang %{name}
+%delete_la
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+%files -f %{name}.lang
+%doc AUTHORS CHANGELOG COMPLIANCE COPYING README
+%dir %{_sysconfdir}/xdg/%{name}/
+%config(noreplace) %{_sysconfdir}/xdg/%{name}/*
+%{_bindir}/{%{name},%{name}-session,obxprop,setlayout}
+%{_datadir}/pixmaps/%{name}.png
+%{_datadir}/xsessions/%{name}.desktop
+%{_datadir}/themes/*/
+%{_libexecdir}/openbox-*
+%{_datadir}/applications/*%{name}.desktop
+%doc COPYING
+%{_libdir}/{libobrender.so.*,libobt.so.*}
+
+%files devel
+%{_includedir}/%{name}/
+%{_libdir}/{libobrender.so,libobt.so}
+%{_libdir}/pkgconfig/*.pc
+%exclude %{_datadir}/doc/%{name}
+%exclude %{_datadir}/gnome-session/sessions/openbox-gnome*.session
+%exclude %{_datadir}/gnome/wm-properties/openbox.desktop
+%exclude %{_mandir}/man1/%{name}-gnome-session*.1*
+%exclude %{_bindir}/{gdm-control,gnome-panel-control,%{name}-gnome-session}
+%exclude %{_datadir}/xsessions/%{name}-gnome.desktop
+
+%files kde
+%{_bindir}/%{name}-kde-session
+%{_datadir}/xsessions/%{name}-kde.desktop
+
+%files help
+%doc data/*.xsd data/menu.xml doc/rc-mouse-focus.xml
+%{_mandir}/man1/*
+
+%changelog
+* Fri Dec 20 2019 wangzhishun - 3.6.1-11
+- Package init
diff --git a/setlayout.c b/setlayout.c
new file mode 100644
index 0000000..1ad0f9b
--- /dev/null
+++ b/setlayout.c
@@ -0,0 +1,52 @@
+/* To compile this program, run
+ * gcc -o setlayout setlayout.c -lX11
+ */
+#include
+#include
+#include
+#include
+#include
+
+/* orientation of pager */
+#define _NET_WM_ORIENTATION_HORZ 0
+#define _NET_WM_ORIENTATION_VERT 1
+
+/* starting corner for counting spaces */
+#define _NET_WM_TOPLEFT 0
+#define _NET_WM_TOPRIGHT 1
+#define _NET_WM_BOTTOMRIGHT 2
+#define _NET_WM_BOTTOMLEFT 3
+
+int main(int argc, char *argv[]) {
+ unsigned long data[4];
+ Display *display;
+ int screen;
+ Window root;
+
+ if (argc < 4) {
+ printf("pls, you need to give 4 numbers to me.\n"
+ "The first is layout, 0 is horizontal and 1 is vertical.\n"
+ "Second and third is number of desks horizontally and vertically.\n"
+ "The last is starting corner, 0 = topleft, 1 = topright,\n"
+ " 2 = bottomright, 3 = bottomleft.\n");
+ return 1;
+ }
+
+ data[0] = atoi(argv[1]); //_NET_WM_ORIENTATION_HORZ;
+ data[1] = atoi(argv[2]);
+ data[2] = atoi(argv[3]);
+ data[3] = atoi(argv[4]); //_NET_WM_TOPLEFT;
+
+ display = XOpenDisplay(NULL);
+ screen = DefaultScreen(display);
+ root = RootWindow(display, screen);
+
+ XChangeProperty(display, root,
+ XInternAtom(display, "_NET_DESKTOP_LAYOUT", False),
+ XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&data, 4);
+
+ XFlush(display);
+ XCloseDisplay(display);
+
+ return 0;
+}
diff --git a/terminals.menu b/terminals.menu
new file mode 100644
index 0000000..450543e
--- /dev/null
+++ b/terminals.menu
@@ -0,0 +1,16 @@
+
+
+
diff --git a/xdg-menu b/xdg-menu
new file mode 100644
index 0000000..ccd0efd
--- /dev/null
+++ b/xdg-menu
@@ -0,0 +1,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 .
+#
+# Author(s): Luke Macken
+# Miroslav Lichvar
+# Edward Sheldrake
+
+
+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('')
+ elif isinstance(entry, xdg.Menu.MenuEntry) and entry.Show is True:
+ name = entry_name(entry.DesktopEntry)
+ print(' - ' % (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(' ' + \
+ '%s' % command)
+ print('
')
+
+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('')
+print('')
+list(map(walk_menu, menu.getEntries()))
+print('')