diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index a4ef5a985e9e..2daa0854fa4e 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -77,6 +77,7 @@
./programs/man.nix
./programs/mosh.nix
./programs/nano.nix
+ ./programs/oblogout.nix
./programs/screen.nix
./programs/shadow.nix
./programs/shell.nix
diff --git a/nixos/modules/programs/oblogout.nix b/nixos/modules/programs/oblogout.nix
new file mode 100644
index 000000000000..79a8ddb7ce37
--- /dev/null
+++ b/nixos/modules/programs/oblogout.nix
@@ -0,0 +1,160 @@
+# Global configuration for oblogout.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.programs.oblogout;
+
+in
+{
+ ###### interface
+
+ options = {
+
+ programs.oblogout = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to install OBLogout and create /etc/oblogout.conf.
+ See ${pkgs.oblogout}/share/doc/README.
+ '';
+ };
+
+ opacity = mkOption {
+ type = types.int;
+ default = 70;
+ description = ''
+ '';
+ };
+
+ bgcolor = mkOption {
+ type = types.str;
+ default = "black";
+ description = ''
+ '';
+ };
+
+ buttontheme = mkOption {
+ type = types.str;
+ default = "simplistic";
+ description = ''
+ '';
+ };
+
+ buttons = mkOption {
+ type = types.str;
+ default = "cancel, logout, restart, shutdown, suspend, hibernate";
+ description = ''
+ '';
+ };
+
+ cancel = mkOption {
+ type = types.str;
+ default = "Escape";
+ description = ''
+ '';
+ };
+
+ shutdown = mkOption {
+ type = types.str;
+ default = "S";
+ description = ''
+ '';
+ };
+
+ restart = mkOption {
+ type = types.str;
+ default = "R";
+ description = ''
+ '';
+ };
+
+ suspend = mkOption {
+ type = types.str;
+ default = "U";
+ description = ''
+ '';
+ };
+
+ logout = mkOption {
+ type = types.str;
+ default = "L";
+ description = ''
+ '';
+ };
+
+ lock = mkOption {
+ type = types.str;
+ default = "K";
+ description = ''
+ '';
+ };
+
+ hibernate = mkOption {
+ type = types.str;
+ default = "H";
+ description = ''
+ '';
+ };
+
+ clogout = mkOption {
+ type = types.str;
+ default = "openbox --exit";
+ description = ''
+ '';
+ };
+
+ clock = mkOption {
+ type = types.str;
+ default = "";
+ description = ''
+ '';
+ };
+
+ cswitchuser = mkOption {
+ type = types.str;
+ default = "";
+ description = ''
+ '';
+ };
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.oblogout ];
+
+ environment.etc."oblogout.conf".text = ''
+ [settings]
+ usehal = false
+
+ [looks]
+ opacity = ${toString cfg.opacity}
+ bgcolor = ${cfg.bgcolor}
+ buttontheme = ${cfg.buttontheme}
+ buttons = ${cfg.buttons}
+
+ [shortcuts]
+ cancel = ${cfg.cancel}
+ shutdown = ${cfg.shutdown}
+ restart = ${cfg.restart}
+ suspend = ${cfg.suspend}
+ logout = ${cfg.logout}
+ lock = ${cfg.lock}
+ hibernate = ${cfg.hibernate}
+
+ [commands]
+ shutdown = systemctl poweroff
+ restart = systemctl reboot
+ suspend = systemctl suspend
+ hibernate = systemctl hibernate
+ logout = ${cfg.clogout}
+ lock = ${cfg.clock}
+ switchuser = ${cfg.cswitchuser}
+ '';
+ };
+}
diff --git a/pkgs/tools/X11/oblogout/default.nix b/pkgs/tools/X11/oblogout/default.nix
new file mode 100644
index 000000000000..26bb32b17b0c
--- /dev/null
+++ b/pkgs/tools/X11/oblogout/default.nix
@@ -0,0 +1,36 @@
+{ stdenv, fetchFromGitHub, intltool, file, pythonPackages, cairo }:
+
+pythonPackages.buildPythonApplication rec {
+ name = "oblogout-unstable-${version}";
+ version = "2009-11-18";
+
+ src = fetchFromGitHub {
+ owner = "nikdoof";
+ repo = "oblogout";
+ rev = "ee023158c03dee720a1af9b1307b14ed5a95f5a0";
+ sha256 = "0nj87q94idb5ki4wnb2xipfgc6k6clr3rmm4xxh46b58z4zhhbmj";
+ };
+
+ nativeBuildInputs = [ intltool file pythonPackages.distutils_extra ];
+
+ buildInputs = [ cairo ];
+
+ propagatedBuildInputs = [ pythonPackages.pygtk pythonPackages.pillow pythonPackages.dbus-python ];
+
+ patches = [ ./oblogout-0.3-fixes.patch ];
+
+ postPatch = ''
+ substituteInPlace data/oblogout --replace sys.prefix \"$out/${pythonPackages.python.sitePackages}\"
+ substituteInPlace oblogout/__init__.py --replace sys.prefix \"$out\"
+ mkdir -p $out/share/doc
+ cp -a README $out/share/doc
+ '';
+
+ meta = {
+ description = "Openbox logout script";
+ homepage = "https://launchpad.net/oblogout";
+ license = stdenv.lib.licenses.gpl2;
+ platforms = stdenv.lib.platforms.linux;
+ maintainers = [ stdenv.lib.maintainers.romildo ];
+ };
+}
diff --git a/pkgs/tools/X11/oblogout/oblogout-0.3-fixes.patch b/pkgs/tools/X11/oblogout/oblogout-0.3-fixes.patch
new file mode 100644
index 000000000000..c58103c6d407
--- /dev/null
+++ b/pkgs/tools/X11/oblogout/oblogout-0.3-fixes.patch
@@ -0,0 +1,66 @@
+diff --git a/data/oblogout b/data/oblogout
+index 8058c4a..dfe5285 100755
+--- a/data/oblogout
++++ b/data/oblogout
+@@ -77,8 +77,10 @@ def main(argv = None):
+ config = 'data/oblogout.conf'
+ elif os.path.isfile('%s/.config/oblogout.conf' % os.getenv("HOME")):
+ config = '%s/.config/oblogout.conf' % os.getenv("HOME")
+- else:
++ elif os.path.isfile('/etc/oblogout.conf'):
+ config = '/etc/oblogout.conf'
++ else:
++ config = sys.prefix + '/etc/oblogout.conf'
+
+ # Check config in local path, if it exists pass it on
+ if not os.path.isfile(config):
+diff --git a/data/oblogout.conf b/data/oblogout.conf
+index 810872c..b1c1009 100644
+--- a/data/oblogout.conf
++++ b/data/oblogout.conf
+@@ -1,11 +1,11 @@
+ [settings]
+-usehal = true
++usehal = false
+
+ [looks]
+ opacity = 70
+ bgcolor = black
+ buttontheme = simplistic
+-buttons = cancel, logout, restart, shutdown, suspend, lock
++buttons = cancel, logout, restart, shutdown, suspend
+
+ [shortcuts]
+ cancel = Escape
+@@ -17,11 +17,11 @@ lock = K
+ hibernate = H
+
+ [commands]
+-shutdown = shutdown -h now
+-restart = reboot
+-suspend = pmi action suspend
+-hibernate = pmi action hibernate
+-safesuspend = safesuspend
+-lock = gnome-screensaver-command -l
+-switchuser = gdm-control --switch-user
++shutdown = systemctl poweroff
++restart = systemctl reboot
++suspend = systemctl suspend
++hibernate = systemctl hibernate
++# safesuspend = safesuspend
++# lock = gnome-screensaver-command -l
++# switchuser = gdm-control --switch-user
+ logout = openbox --exit
+diff --git a/oblogout/__init__.py b/oblogout/__init__.py
+index b9e4e01..12f521f 100644
+--- a/oblogout/__init__.py
++++ b/oblogout/__init__.py
+@@ -138,7 +138,7 @@ class OpenboxLogout():
+ self.logger.debug("Rendering Fade")
+ # Convert Pixbuf to PIL Image
+ wh = (pb.get_width(),pb.get_height())
+- pilimg = Image.fromstring("RGB", wh, pb.get_pixels())
++ pilimg = Image.frombytes("RGB", wh, pb.get_pixels())
+
+ pilimg = pilimg.point(lambda p: (p * self.opacity) / 255 )
+
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 6257f7a4c182..2744973948a0 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -13940,6 +13940,8 @@ in
inherit (gnome2) libglade;
};
+ oblogout = callPackage ../tools/X11/oblogout { };
+
obs-studio = qt5.callPackage ../applications/video/obs-studio {
alsaSupport = stdenv.isLinux;
pulseaudioSupport = config.pulseaudio or true;