about summary refs log tree commit diff
path: root/overlays
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-07-13 22:00:09 +0000
committerAlyssa Ross <hi@alyssa.is>2020-07-13 23:10:03 +0000
commitadd8759f14c9ebb65bca21a95e317e4316d3f6be (patch)
tree3a67356df4b197a7add4034478499bc91d2258dc /overlays
parent424dfb57297d0d1af4467571b8d739b08b02fca8 (diff)
downloadnixlib-add8759f14c9ebb65bca21a95e317e4316d3f6be.tar
nixlib-add8759f14c9ebb65bca21a95e317e4316d3f6be.tar.gz
nixlib-add8759f14c9ebb65bca21a95e317e4316d3f6be.tar.bz2
nixlib-add8759f14c9ebb65bca21a95e317e4316d3f6be.tar.lz
nixlib-add8759f14c9ebb65bca21a95e317e4316d3f6be.tar.xz
nixlib-add8759f14c9ebb65bca21a95e317e4316d3f6be.tar.zst
nixlib-add8759f14c9ebb65bca21a95e317e4316d3f6be.zip
overlays: don't apply to all nixpkgs trees
Since the nixlib root is the NIX_PATH root, overlays were in the
NIX_PATH as "nixpkgs-overlays".  Nixpkgs imports that by default to
look for overlays.  This meant that an arbitrary Nixpkgs tree would
end up trying to use the Nixlib overlays, which wouldn't always work.
It would also mean that derivations built from those trees wouldn't
match the ones other people would try to build, which is undesirable
for working on nixpkgs.  I think this is unfortunate behaviour for
anybody working on nixpkgs, and nixpkgs probably shouldn't load
overlays from impurely at all by default, but it is what it is.

Since I can't really change what upstream nixpkgs does here, the best
I can do is change the nixpkgs in nixlib.  It will now load overlays
from a sibling "overlays" directory.  Renaming the "nixpkgs-overlays"
directory at the nixlib root to "overlays" means that it will be
loaded by default _only_ by the nixpkgs it is colocated with.  It also
means that it is still accessible in the NIX_PATH as <overlays>, which
is fine and convenient as long as nothing starts looking at that by
default.
Diffstat (limited to 'overlays')
-rw-r--r--overlays/patches/cgit/default.nix5
-rw-r--r--overlays/patches/cgit/ui-commit-use-Git-raw-note-format.patch195
-rw-r--r--overlays/patches/default.nix17
-rw-r--r--overlays/patches/dino/0001-add-an-option-to-enable-omemo-by-default-in-new-conv.patch115
-rw-r--r--overlays/patches/dino/default.nix16
-rw-r--r--overlays/patches/firefox/beta/D6695.diff281
-rw-r--r--overlays/patches/firefox/nightly/D6695.diff159
-rw-r--r--overlays/patches/firefox/packages.nix27
-rw-r--r--overlays/patches/firefox/profiles.ini8
-rw-r--r--overlays/patches/firefox/release/D6695.diff282
-rw-r--r--overlays/patches/firefox/user.js1
-rw-r--r--overlays/patches/public-inbox/0003-view-don-t-show-page-if-no-links-follow-it.patch27
-rw-r--r--overlays/patches/public-inbox/0004-view-don-t-500-if-no-mail-received-yet.patch25
-rw-r--r--overlays/patches/public-inbox/0005-wwwstream-make-source-info-configurable.patch112
-rw-r--r--overlays/patches/public-inbox/default.nix9
-rw-r--r--overlays/patches/python/default.nix11
-rw-r--r--overlays/patches/python/packages/hyperkitty/0001-Improve-look-of-fixed-width-messages.patch29
-rw-r--r--overlays/patches/python/packages/hyperkitty/default.nix7
-rw-r--r--overlays/patches/tmux/default.nix7
-rw-r--r--overlays/scripts/choose/choose.in20
-rw-r--r--overlays/scripts/choose/choosebin.in17
-rw-r--r--overlays/scripts/choose/default.nix8
-rw-r--r--overlays/scripts/default.nix3
23 files changed, 1381 insertions, 0 deletions
diff --git a/overlays/patches/cgit/default.nix b/overlays/patches/cgit/default.nix
new file mode 100644
index 000000000000..fa63bf5f14ed
--- /dev/null
+++ b/overlays/patches/cgit/default.nix
@@ -0,0 +1,5 @@
+{ cgit }:
+
+cgit.overrideAttrs ({ patches ? [], ... }: {
+  patches = patches ++ [ ./ui-commit-use-Git-raw-note-format.patch ];
+})
diff --git a/overlays/patches/cgit/ui-commit-use-Git-raw-note-format.patch b/overlays/patches/cgit/ui-commit-use-Git-raw-note-format.patch
new file mode 100644
index 000000000000..ce1a5aa559cc
--- /dev/null
+++ b/overlays/patches/cgit/ui-commit-use-Git-raw-note-format.patch
@@ -0,0 +1,195 @@
+Return-Path: <cgit-bounces@lists.zx2c4.com>
+Received: from compute4.internal (compute4.nyi.internal [10.202.2.44])
+	 by sloti36d2t04 (Cyrus 3.1.6-553-gc304556-fmstable-20190524v1) with LMTPA;
+	 Sun, 26 May 2019 12:57:16 -0400
+X-Cyrus-Session-Id: sloti36d2t04-1558889836-2458433-2-14112916921354509248
+X-Sieve: CMU Sieve 3.0
+X-Spam-known-sender: no
+X-Spam-score: 0.0
+X-Spam-hits: BAYES_00 -1.9, FORGED_GMAIL_RCVD 1, FREEMAIL_FORGED_FROMDOMAIN 0.001,
+  FREEMAIL_FROM 0.001, HEADER_FROM_DIFFERENT_DOMAINS 0.001,
+  MAILING_LIST_MULTI -1, ME_ZS_CLEAN -0.001, RCVD_IN_DNSWL_NONE -0.0001,
+  SPF_HELO_NONE 0.001, SPF_PASS -0.001, LANGUAGES enfr, BAYES_USED user,
+  SA_VERSION 3.4.2
+X-Spam-source: IP='192.95.5.69', Host='krantz.zx2c4.com', Country='US', FromHeader='com',
+  MailFrom='com'
+X-Spam-charsets: plain='us-ascii'
+X-Resolved-to: alyssa@fastmail.com
+X-Delivered-to: hi@alyssa.is
+X-Mail-from: cgit-bounces@lists.zx2c4.com
+Received: from mx6 ([10.202.2.205])
+  by compute4.internal (LMTPProxy); Sun, 26 May 2019 12:57:16 -0400
+Received: from mx6.messagingengine.com (localhost [127.0.0.1])
+	by mailmx.nyi.internal (Postfix) with ESMTP id C0158A2008C
+	for <hi@alyssa.is>; Sun, 26 May 2019 12:57:15 -0400 (EDT)
+Received: from mx6.messagingengine.com (localhost [127.0.0.1])
+    by mx6.messagingengine.com (Authentication Milter) with ESMTP
+    id D6950A237B8;
+    Sun, 26 May 2019 12:57:15 -0400
+ARC-Seal: i=1; a=rsa-sha256; cv=none; d=messagingengine.com; s=fm2; t=
+    1558889835; b=B7I3OXdhlHrdrasWp1rFG7Jjk+h0sxqdku2fN7+USIl8d3vp12
+    muXmMQxDMOOsEoeVd4hI8tipG7pGUmZSW8zetR+jYztp8rQATypbIbixctfVxwls
+    s0Ef0IPTEpyFn9YFOOQKLat5Ul7Qr5z5XGBjVi8LYocsnJBTSk5yHHeRrJBWWl5V
+    RGqLWse1Ldf8qEOy/b/th18XGbRpJFCVPxV9jZkoaSiF585wGKkEeoI4dfNJ3SRh
+    vktPXDJqVoU72cDyIa71fhxlWR/hOaf2Ca9n27URIPFxBuBz3b6s6faf2pEsFY2E
+    5dM2DH1WwTTf1Mooe5t2RrZWOKshkEL3Tojw==
+ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=
+    messagingengine.com; h=from:to:subject:date:message-id
+    :mime-version:list-id:list-unsubscribe:list-archive:list-post
+    :list-help:list-subscribe:content-type:content-transfer-encoding
+    :sender; s=fm2; t=1558889835; bh=VlVjl7sSy403Efad4r51sLCJz3cq/zu
+    Le82anVQc3Yk=; b=TkUYZjyqgEFkmEI5GSiRJq1ELkPP0WKcVMOuI/01v2lkWeu
+    wU/i8o4QxKYxpDTwvk8Y+OmaqTW3MJ9YoRAcIgbaaMz7NgD54BuZi7zb8QJTUQtH
+    WGycNVev/OZEoN8//53TZMTVzPtA41l32/cIQ6cZW6IhMSQ1HgTBX8hhyOjlUY6c
+    rzq2e/e0Jvuv2Z5xIOjGNOBRbmsJ4liQOJmW7oDLX83EKP+87DzlB6chPIqwhZ9E
+    XOaX0uCRdj2GaOJAF4/RD8hzG4Ya8fI3zpK28qonZN6XDentjWtIRb+kBSCsGYm6
+    iD7X9tYrNk192KU1jGasGCQpDhkt0EMk18Axd6Q==
+ARC-Authentication-Results: i=1; mx6.messagingengine.com; arc=none (no signatures found);
+    dkim=none (no signatures found);
+    dmarc=fail policy.published-domain-policy=none
+    policy.published-subdomain-policy=quarantine
+    policy.applied-disposition=none policy.evaluated-disposition=none
+    policy.override-reason=mailing_list policy.arc-aware-result=fail
+    (p=none,sp=quarantine,has-list-id=yes,d=none,d.eval=none,override=mailing_list,arc_aware_result=fail)
+    policy.policy-from=p header.from=gmail.com;
+    iprev=pass smtp.remote-ip=192.95.5.69 (krantz.zx2c4.com);
+    spf=pass smtp.mailfrom=cgit-bounces@lists.zx2c4.com
+    smtp.helo=krantz.zx2c4.com;
+    x-aligned-from=fail;
+    x-ptr=pass smtp.helo=krantz.zx2c4.com policy.ptr=krantz.zx2c4.com;
+    x-return-mx=pass header.domain=gmail.com policy.is_org=yes
+    (MX Record found);
+    x-return-mx=pass smtp.domain=lists.zx2c4.com policy.org_domain=zx2c4.com
+    policy.is_org=no (MX Record found);
+    x-tls=pass smtp.version=TLSv1.2 smtp.cipher=ECDHE-RSA-AES128-GCM-SHA256
+    smtp.bits=128/128;
+    x-vs=clean score=0 state=0;
+    x-zs=clean
+Authentication-Results: mx6.messagingengine.com;
+    arc=none (no signatures found);
+    dkim=none (no signatures found);
+    dmarc=fail policy.published-domain-policy=none
+      policy.published-subdomain-policy=quarantine
+      policy.applied-disposition=none policy.evaluated-disposition=none
+      policy.override-reason=mailing_list policy.arc-aware-result=fail
+      (p=none,sp=quarantine,has-list-id=yes,d=none,d.eval=none,override=mailing_list,arc_aware_result=fail)
+      policy.policy-from=p header.from=gmail.com;
+    iprev=pass smtp.remote-ip=192.95.5.69 (krantz.zx2c4.com);
+    spf=pass smtp.mailfrom=cgit-bounces@lists.zx2c4.com
+      smtp.helo=krantz.zx2c4.com;
+    x-aligned-from=fail;
+    x-ptr=pass smtp.helo=krantz.zx2c4.com policy.ptr=krantz.zx2c4.com;
+    x-return-mx=pass header.domain=gmail.com policy.is_org=yes
+      (MX Record found);
+    x-return-mx=pass smtp.domain=lists.zx2c4.com policy.org_domain=zx2c4.com
+      policy.is_org=no (MX Record found);
+    x-tls=pass smtp.version=TLSv1.2 smtp.cipher=ECDHE-RSA-AES128-GCM-SHA256
+      smtp.bits=128/128;
+    x-vs=clean score=0 state=0;
+    x-zs=clean
+X-ME-VSSU: VW5zdWI9bWFpbHRvOmNnaXQtcmVxdWVzdEBsaXN0cy56eDJjNC5jb20_c3ViamVjdD11bn
+    N1YnNjcmliZQ
+X-ME-VSSU: VW5zdWI9aHR0cHM6Ly9saXN0cy56eDJjNC5jb20vbWFpbG1hbi9vcHRpb25zL2NnaXQ
+X-ME-VSCause: gggruggvucftvghtrhhoucdtuddrgeduuddruddvtddguddtkecutefuodetggdotefrod
+    ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp
+    uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecunecujfgurhephffvuf
+    ffkffogghpjefjgedufedttgfgvghssehtjeertdertddvnecuhfhrohhmpeevhhhrihhs
+    ucforgihohcuoegrkhhlhhhfvgigsehgmhgrihhlrdgtohhmqeenucffohhmrghinhepii
+    igvdgtgedrtghomhenucfkphepudelvddrleehrdehrdeiledpvddtledrleefrddufeej
+    rddvtdelnecurfgrrhgrmhepihhnvghtpeduledvrdelhedrhedrieelpdhhvghlohepkh
+    hrrghnthiirdiigidvtgegrdgtohhmpdhmrghilhhfrhhomhepoegtghhithdqsghouhhn
+    tggvsheslhhishhtshdriiigvdgtgedrtghomheqnecuvehluhhsthgvrhfuihiivgeptd
+X-ME-VSScore: 0
+X-ME-VSCategory: clean
+X-ME-ZSResult: clean
+Received-SPF: pass
+    (lists.zx2c4.com: 192.95.5.69 is authorized to use 'cgit-bounces@lists.zx2c4.com' in 'mfrom' identity (mechanism 'mx' matched))
+    receiver=mx6.messagingengine.com;
+    identity=mailfrom;
+    envelope-from="cgit-bounces@lists.zx2c4.com";
+    helo=krantz.zx2c4.com;
+    client-ip=192.95.5.69
+Received: from krantz.zx2c4.com (krantz.zx2c4.com [192.95.5.69])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
+	(No client certificate requested)
+	by mx6.messagingengine.com (Postfix) with ESMTPS
+	for <hi@alyssa.is>; Sun, 26 May 2019 12:57:13 -0400 (EDT)
+Received: from krantz.zx2c4.com (localhost [IPv6:::1])
+	by krantz.zx2c4.com (ZX2C4 Mail Server) with ESMTP id 6360ad08;
+	Sun, 26 May 2019 16:57:12 +0000 (UTC)
+X-Remote-Delivered-To: cgit@lists.zx2c4.com
+Received: from krantz.zx2c4.com (localhost [127.0.0.1])
+ by krantz.zx2c4.com (ZX2C4 Mail Server) with ESMTP id 94ab4c5e
+ for <cgit@lists.zx2c4.com>; Sun, 26 May 2019 16:57:10 +0000 (UTC)
+Received: from avasout02.plus.net (avasout02.plus.net [212.159.14.17])
+ by krantz.zx2c4.com (ZX2C4 Mail Server) with ESMTP id 151b7cee
+ for <cgit@lists.zx2c4.com>; Sun, 26 May 2019 16:57:10 +0000 (UTC)
+Received: from mailserver ([209.93.137.209]) by smtp with ESMTP
+ id UwSFhu7pnpYZWUwSGhosYl; Sun, 26 May 2019 17:57:06 +0100
+X-CM-Score: 0.00
+X-CNFS-Analysis: v=2.3 cv=cd2sUULM c=1 sm=1 tr=0
+ a=u68OYVRc/Z2sxEGkPHj3Dw==:117 a=u68OYVRc/Z2sxEGkPHj3Dw==:17
+ a=x7bEGLp0ZPQA:10 a=YbTMELGUhT8A:10 a=pGLkceISAAAA:8 a=HzQmFnjoOBWeq84yEp4A:9
+From: Chris Mayo <aklhfex@gmail.com>
+To: cgit@lists.zx2c4.com
+Subject: [PATCH] ui-commit: use Git raw note format
+Date: Sun, 26 May 2019 17:57:01 +0100
+Message-Id: <20190526165701.28904-1-aklhfex@gmail.com>
+X-Mailer: git-send-email 2.21.0
+MIME-Version: 1.0
+X-CMAE-Envelope: MS4wfP0CKvHqBVrlItMYLboOh+RL0e032hTB6uaiaMMwhAjdzE++e0bjO/pa6p0htCiM3UnX4Z2U0JMo1hqMzjz6Fvn9UDKX/K3SZq+SO3in/Ef8asqzdu/i
+ +D4sjBdxh3JSqvmeqsDZQIthJNuQTPajW0uaVQrKRHhx3qXMtgNqpj1J
+X-BeenThere: cgit@lists.zx2c4.com
+X-Mailman-Version: 2.1.15
+Precedence: list
+List-Id: List for cgit developers and users <cgit.lists.zx2c4.com>
+List-Unsubscribe: <https://lists.zx2c4.com/mailman/options/cgit>,
+ <mailto:cgit-request@lists.zx2c4.com?subject=unsubscribe>
+List-Archive: <http://lists.zx2c4.com/pipermail/cgit/>
+List-Post: <mailto:cgit@lists.zx2c4.com>
+List-Help: <mailto:cgit-request@lists.zx2c4.com?subject=help>
+List-Subscribe: <https://lists.zx2c4.com/mailman/listinfo/cgit>,
+ <mailto:cgit-request@lists.zx2c4.com?subject=subscribe>
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+Errors-To: cgit-bounces@lists.zx2c4.com
+Sender: "CGit" <cgit-bounces@lists.zx2c4.com>
+X-TUID: seh0e1Lgy6q2
+
+Currently a commit note is shown as:
+
+Notes
+
+  Notes:
+      <note text>
+
+Change to:
+
+Notes
+  <note text>
+
+Signed-off-by: Chris Mayo <aklhfex@gmail.com>
+---
+ ui-commit.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ui-commit.c b/ui-commit.c
+index 9a47b54..52b4c2a 100644
+--- a/ui-commit.c
++++ b/ui-commit.c
+@@ -39,7 +39,7 @@ void cgit_print_commit(char *hex, const char *prefix)
+ 	}
+ 	info = cgit_parse_commit(commit);
+ 
+-	format_display_notes(&oid, &notes, PAGE_ENCODING, 0);
++	format_display_notes(&oid, &notes, PAGE_ENCODING, 1);
+ 
+ 	load_ref_decorations(NULL, DECORATE_FULL_REFS);
+ 
+-- 
+2.21.0
+
+_______________________________________________
+CGit mailing list
+CGit@lists.zx2c4.com
+https://lists.zx2c4.com/mailman/listinfo/cgit
diff --git a/overlays/patches/default.nix b/overlays/patches/default.nix
new file mode 100644
index 000000000000..4c664ba3ab11
--- /dev/null
+++ b/overlays/patches/default.nix
@@ -0,0 +1,17 @@
+self: super: {
+  cgit = self.callPackage ./cgit { inherit (super) cgit; };
+
+  dino = self.callPackage ./dino { inherit (super) dino; };
+
+  firefoxPackages = self.callPackage ./firefox/packages.nix {
+    inherit (super) firefoxPackages;
+  };
+
+  public-inbox = self.callPackage ./public-inbox {
+    inherit (super) public-inbox;
+  };
+
+  python3 = self.callPackage ./python { python = super.python3; };
+
+  tmux = self.callPackage ./tmux { inherit (super) tmux; };
+}
diff --git a/overlays/patches/dino/0001-add-an-option-to-enable-omemo-by-default-in-new-conv.patch b/overlays/patches/dino/0001-add-an-option-to-enable-omemo-by-default-in-new-conv.patch
new file mode 100644
index 000000000000..030c165d87b8
--- /dev/null
+++ b/overlays/patches/dino/0001-add-an-option-to-enable-omemo-by-default-in-new-conv.patch
@@ -0,0 +1,115 @@
+From cee5e27b157081a3ce55869bd5f649560a6127ea Mon Sep 17 00:00:00 2001
+From: lumi <lumi@pew.im>
+Date: Thu, 17 Oct 2019 16:43:40 +0200
+Subject: [PATCH] add an option to enable omemo by default in new conversations
+
+---
+ libdino/src/entity/settings.vala              | 10 ++++++++++
+ libdino/src/service/conversation_manager.vala |  5 +++++
+ main/data/settings_dialog.ui                  | 12 ++++++++++++
+ main/src/ui/settings_dialog.vala              |  3 +++
+ 4 files changed, 30 insertions(+)
+
+diff --git a/libdino/src/entity/settings.vala b/libdino/src/entity/settings.vala
+index bf1ebed..f9cd734 100644
+--- a/libdino/src/entity/settings.vala
++++ b/libdino/src/entity/settings.vala
+@@ -11,6 +11,7 @@ public class Settings : Object {
+         send_marker_ = col_to_bool_or_default("send_marker", true);
+         notifications_ = col_to_bool_or_default("notifications", true);
+         convert_utf8_smileys_ = col_to_bool_or_default("convert_utf8_smileys", true);
++        omemo_default_ = col_to_bool_or_default("omemo_default", false);
+     }
+ 
+     private bool col_to_bool_or_default(string key, bool def) {
+@@ -53,6 +54,15 @@ public class Settings : Object {
+             convert_utf8_smileys_ = value;
+         }
+     }
++
++    private bool omemo_default_;
++    public bool omemo_default {
++        get { return omemo_default_; }
++        set {
++            db.settings.insert().or("REPLACE").value(db.settings.key, "omemo_default").value(db.settings.value, value.to_string()).perform();
++            omemo_default_ = value;
++        }
++    }
+ }
+ 
+ }
+diff --git a/libdino/src/service/conversation_manager.vala b/libdino/src/service/conversation_manager.vala
+index c473ea7..e980e08 100644
+--- a/libdino/src/service/conversation_manager.vala
++++ b/libdino/src/service/conversation_manager.vala
+@@ -8,6 +8,8 @@ public class ConversationManager : StreamInteractionModule, Object {
+     public static ModuleIdentity<ConversationManager> IDENTITY = new ModuleIdentity<ConversationManager>("conversation_manager");
+     public string id { get { return IDENTITY.id; } }
+ 
++    private Dino.Entities.Settings settings = Dino.Application.get_default().settings;
++
+     public signal void conversation_activated(Conversation conversation);
+     public signal void conversation_deactivated(Conversation conversation);
+ 
+@@ -46,6 +48,9 @@ public class ConversationManager : StreamInteractionModule, Object {
+ 
+         // Create a new converation
+         Conversation conversation = new Conversation(jid, account, type);
++        if (settings.omemo_default) {
++            conversation.encryption = Encryption.OMEMO;
++        }
+         add_conversation(conversation);
+         conversation.persist(db);
+         return conversation;
+diff --git a/main/data/settings_dialog.ui b/main/data/settings_dialog.ui
+index c76f347..23ee7b8 100644
+--- a/main/data/settings_dialog.ui
++++ b/main/data/settings_dialog.ui
+@@ -65,6 +65,18 @@
+                                 <property name="height">1</property>
+                             </packing>
+                         </child>
++                        <child>
++                          <object class="GtkCheckButton" id="omemo_default_checkbutton">
++                            <property name="label" translatable="yes">Enable OMEMO by default</property>
++                            <property name="visible">True</property>
++                          </object>
++                          <packing>
++                              <property name="left_attach">0</property>
++                              <property name="top_attach">4</property>
++                              <property name="width">1</property>
++                              <property name="height">1</property>
++                          </packing>
++                        </child>
+                     </object>
+                 </child>
+             </object>
+diff --git a/main/src/ui/settings_dialog.vala b/main/src/ui/settings_dialog.vala
+index 68c711d..6401a2d 100644
+--- a/main/src/ui/settings_dialog.vala
++++ b/main/src/ui/settings_dialog.vala
+@@ -9,6 +9,7 @@ class SettingsDialog : Dialog {
+     [GtkChild] private CheckButton marker_checkbutton;
+     [GtkChild] private CheckButton notification_checkbutton;
+     [GtkChild] private CheckButton emoji_checkbutton;
++    [GtkChild] private CheckButton omemo_default_checkbutton;
+ 
+     Dino.Entities.Settings settings = Dino.Application.get_default().settings;
+ 
+@@ -19,11 +20,13 @@ class SettingsDialog : Dialog {
+         marker_checkbutton.active = settings.send_marker;
+         notification_checkbutton.active = settings.notifications;
+         emoji_checkbutton.active = settings.convert_utf8_smileys;
++        omemo_default_checkbutton.active = settings.omemo_default;
+ 
+         typing_checkbutton.toggled.connect(() => { settings.send_typing = typing_checkbutton.active; } );
+         marker_checkbutton.toggled.connect(() => { settings.send_marker = marker_checkbutton.active; } );
+         notification_checkbutton.toggled.connect(() => { settings.notifications = notification_checkbutton.active; } );
+         emoji_checkbutton.toggled.connect(() => { settings.convert_utf8_smileys = emoji_checkbutton.active; });
++        omemo_default_checkbutton.toggled.connect(() => { settings.omemo_default = omemo_default_checkbutton.active; });
+     }
+ }
+ 
+-- 
+2.23.0
+
diff --git a/overlays/patches/dino/default.nix b/overlays/patches/dino/default.nix
new file mode 100644
index 000000000000..2a23ee5e0cc9
--- /dev/null
+++ b/overlays/patches/dino/default.nix
@@ -0,0 +1,16 @@
+{ dino, fetchpatch }:
+
+dino.overrideAttrs ({ patches ? [], ... }: {
+  patches = patches ++ [
+    ./0001-add-an-option-to-enable-omemo-by-default-in-new-conv.patch
+    (fetchpatch {
+      url = "https://github.com/dino/dino/commit/f85bf7af3d355794a2a5208aea21efeb5b6e529d.patch";
+      sha256 = "0y8dldydvj75i2n53brki9czvzw1qwlk5646k3xrx5pnl31c7p5b";
+    })
+  ];
+
+  postInstall = ''
+    mkdir -p $out/share/man/man1
+    mv ../doc/dino.1 $out/share/man/man1
+  '';
+})
diff --git a/overlays/patches/firefox/beta/D6695.diff b/overlays/patches/firefox/beta/D6695.diff
new file mode 100644
index 000000000000..f8a8deeb8581
--- /dev/null
+++ b/overlays/patches/firefox/beta/D6695.diff
@@ -0,0 +1,281 @@
+diff --git a/toolkit/moz.build b/toolkit/moz.build
+index 109fb2c..0b871d9 100644
+--- a/toolkit/moz.build
++++ b/toolkit/moz.build
+@@ -72,3 +72,5 @@ with Files('mozapps/preferences/**'):
+ with Files('pluginproblem/**'):
+     BUG_COMPONENT = ('Core', 'Plug-ins')
+ 
++if CONFIG['ENABLE_TESTS']:
++    DIRS += ['tests/gtest']
+diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
+index aafe82e..2d850fe 100644
+--- a/toolkit/xre/nsXREDirProvider.cpp
++++ b/toolkit/xre/nsXREDirProvider.cpp
+@@ -390,13 +390,6 @@ nsXREDirProvider::GetFile(const char* aProperty, bool* aPersistent,
+     nsCOMPtr<nsIFile> localDir;
+     rv = GetUserDataDirectoryHome(getter_AddRefs(localDir), false);
+     if (NS_SUCCEEDED(rv)) {
+-#if defined(XP_MACOSX)
+-      rv = localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla"));
+-#else
+-      rv = localDir->AppendNative(NS_LITERAL_CSTRING(".mozilla"));
+-#endif
+-    }
+-    if (NS_SUCCEEDED(rv)) {
+       localDir.swap(file);
+     }
+   }
+@@ -1238,7 +1231,8 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
+             nsDependentCString(hasVendor ? GetAppVendor() : GetAppName())))) {
+       return NS_ERROR_FAILURE;
+     }
+-  } else if (NS_FAILED(localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla")))) {
++  }
++  else if (NS_FAILED(localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla")))) {
+     return NS_ERROR_FAILURE;
+   }
+ 
+@@ -1367,6 +1361,9 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   localDir = dirFileMac;
++
++  rv = localDir->AppendRelativeNativePath(nsDependentCString("Mozilla"));
++  NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_IOS)
+   nsAutoCString userDir;
+   if (GetUIKitDirectory(aLocal, userDir)) {
+@@ -1390,6 +1387,9 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   rv = NS_NewLocalFile(path, true, getter_AddRefs(localDir));
++  NS_ENSURE_SUCCESS(rv, rv);
++  rv = localDir->AppendRelativeNativePath(nsDependentCString("Mozilla"));
++  NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_UNIX)
+   const char* homeDir = getenv("HOME");
+   if (!homeDir || !*homeDir) return NS_ERROR_FAILURE;
+@@ -1411,8 +1411,51 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+         rv = localDir->AppendNative(NS_LITERAL_CSTRING(".cache"));
+     }
+   } else {
++    bool exists;
++    // check old config ~/.mozilla
+     rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
+                                getter_AddRefs(localDir));
++    NS_ENSURE_SUCCESS(rv, rv);
++    rv = localDir->AppendRelativeNativePath(nsDependentCString(".mozilla"));
++    NS_ENSURE_SUCCESS(rv, rv);
++    rv = localDir->Exists(&exists);
++    NS_ENSURE_SUCCESS(rv, rv);
++    // otherwise, use new config
++    if (!exists) {
++      const char* xdghomedir = getenv("XDG_DATA_HOME");
++      if (!xdghomedir || !*xdghomedir) {
++        rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
++                                   getter_AddRefs(localDir));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->AppendRelativeNativePath(nsDependentCString(".local"));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->Exists(&exists);
++        if (NS_SUCCEEDED(rv) && !exists) {
++          rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++          NS_ENSURE_SUCCESS(rv, rv);
++        }
++        rv = localDir->AppendRelativeNativePath(nsDependentCString("share"));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->Exists(&exists);
++        if (NS_SUCCEEDED(rv) && !exists) {
++          rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++        }
++      }
++      else {
++        rv = NS_NewNativeLocalFile(nsDependentCString(xdghomedir), true,
++                               getter_AddRefs(localDir));
++      }
++      NS_ENSURE_SUCCESS(rv, rv);
++
++      rv = localDir->AppendRelativeNativePath(nsDependentCString("mozilla"));
++      NS_ENSURE_SUCCESS(rv, rv);
++      rv = localDir->Exists(&exists);
++      NS_ENSURE_SUCCESS(rv, rv);
++      if (NS_SUCCEEDED(rv) && !exists) {
++        rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
++        NS_ENSURE_SUCCESS(rv, rv);
++      }
++    }
+   }
+ #else
+ #error "Don't know how to get product dir on your platform"
+@@ -1523,20 +1566,12 @@ nsresult nsXREDirProvider::AppendSysUserExtensionPath(nsIFile* aFile) {
+ 
+ #if defined(XP_MACOSX) || defined(XP_WIN)
+ 
+-  static const char* const sXR = "Mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "Extensions";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+ #elif defined(XP_UNIX)
+ 
+-  static const char* const sXR = ".mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "extensions";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+@@ -1554,20 +1589,12 @@ nsresult nsXREDirProvider::AppendSysUserExtensionsDevPath(nsIFile* aFile) {
+ 
+ #if defined(XP_MACOSX) || defined(XP_WIN)
+ 
+-  static const char* const sXR = "Mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "SystemExtensionsDev";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+ #elif defined(XP_UNIX)
+ 
+-  static const char* const sXR = ".mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "systemextensionsdev";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+@@ -1625,9 +1652,6 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
+   NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_UNIX)
+   nsAutoCString folder;
+-  // Make it hidden (by starting with "."), except when local (the
+-  // profile is already under ~/.cache or XDG_CACHE_HOME).
+-  if (!aLocal) folder.Assign('.');
+ 
+   if (!profile.IsEmpty()) {
+     // Skip any leading path characters
+@@ -1647,8 +1671,12 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
+       folder.Append(vendor);
+       ToLowerCase(folder);
+ 
+-      rv = aFile->AppendNative(folder);
+-      NS_ENSURE_SUCCESS(rv, rv);
++      // Keep the 'mozilla' path for cache:
++      // Use ${XDG_DATA_HOME:-$HOME/.cache}/mozilla/firefox
++      if (aLocal) {
++        rv = aFile->AppendNative(folder);
++        NS_ENSURE_SUCCESS(rv, rv);
++      }
+ 
+       folder.Truncate();
+     }
+diff --git a/xpcom/io/nsAppFileLocationProvider.cpp b/xpcom/io/nsAppFileLocationProvider.cpp
+index 90e4ec9..8b838ec 100644
+--- a/xpcom/io/nsAppFileLocationProvider.cpp
++++ b/xpcom/io/nsAppFileLocationProvider.cpp
+@@ -247,7 +247,7 @@ nsresult nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile) {
+ // GetProductDirectory - Gets the directory which contains the application data
+ // folder
+ //
+-// UNIX   : ~/.mozilla/
++// UNIX   : ~/.mozilla/ or ${XDG_DATA_HOME:-~/.local/share}/mozilla
+ // WIN    : <Application Data folder on user's machine>\Mozilla
+ // Mac    : :Documents:Mozilla:
+ //----------------------------------------------------------------------------------------
+@@ -291,19 +291,80 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
+     return rv;
+   }
+ #elif defined(XP_UNIX)
+-  rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), true,
++  const char* homeDir = PR_GetEnv("HOME");
++  /* check old config ~/.mozilla */
++  rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
+                              getter_AddRefs(localDir));
+   if (NS_FAILED(rv)) {
+     return rv;
+   }
++  rv = localDir->AppendRelativeNativePath(nsDependentCString(".mozilla"));
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
++  rv = localDir->Exists(&exists);
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
++  /* otherwise, use new config */
++  if (!exists) {
++    const char* xdghomedir = PR_GetEnv("XDG_DATA_HOME");
++    if (!xdghomedir || !*xdghomedir) {
++      /* XDG_DATA_HOME=$HOME/.local/share */
++      rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
++                                 getter_AddRefs(localDir));
++      if (NS_FAILED(rv)) {
++        return rv;
++      }
++      rv = localDir->AppendRelativeNativePath(nsDependentCString(".local"));
++      if (NS_FAILED(rv)) {
++        return rv;
++      }
++      rv = localDir->Exists(&exists);
++      if (NS_SUCCEEDED(rv) && !exists) {
++        rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++        if (NS_FAILED(rv)) {
++          return rv;
++        }
++      }
++      rv = localDir->AppendRelativeNativePath(nsDependentCString("share"));
++      if (NS_FAILED(rv)) {
++        return rv;
++      }
++      rv = localDir->Exists(&exists);
++      if (NS_SUCCEEDED(rv) && !exists) {
++        rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++      }
++    }
++    else {
++      rv = NS_NewNativeLocalFile(nsDependentCString(xdghomedir), true,
++                                 getter_AddRefs(localDir));
++    }
++    if (NS_FAILED(rv)) {
++      return rv;
++    }
++    rv = localDir->AppendRelativeNativePath(nsDependentCString("mozilla"));
++    if (NS_FAILED(rv)) {
++      return rv;
++    }
++  }
+ #else
+ #error dont_know_how_to_get_product_dir_on_your_platform
+ #endif
+ 
++#if !defined(XP_UNIX) || defined(XP_MACOSX)
++  // Since we have to check for legacy configuration, we have
++  // the complete path for Linux already, so this is not
++  // needed. If we stop checking for legacy at some point,
++  // then we can change this to not be protected by
++  // this clause.
+   rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
++
+   if (NS_FAILED(rv)) {
+     return rv;
+   }
++#endif
++
+   rv = localDir->Exists(&exists);
+ 
+   if (NS_SUCCEEDED(rv) && !exists) {
+@@ -323,7 +384,7 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
+ // GetDefaultUserProfileRoot - Gets the directory which contains each user
+ // profile dir
+ //
+-// UNIX   : ~/.mozilla/
++// UNIX   : ~/.mozilla/ or ${XDG_DATA_HOME:-~/.local/share}/mozilla
+ // WIN    : <Application Data folder on user's machine>\Mozilla\Profiles
+ // Mac    : :Documents:Mozilla:Profiles:
+ //----------------------------------------------------------------------------------------
diff --git a/overlays/patches/firefox/nightly/D6695.diff b/overlays/patches/firefox/nightly/D6695.diff
new file mode 100644
index 000000000000..31a08471a8cc
--- /dev/null
+++ b/overlays/patches/firefox/nightly/D6695.diff
@@ -0,0 +1,159 @@
+--- a/toolkit/xre/nsXREDirProvider.cpp
++++ b/toolkit/xre/nsXREDirProvider.cpp
+@@ -390,13 +390,6 @@ nsXREDirProvider::GetFile(const char* aProperty, bool* aPersistent,
+     nsCOMPtr<nsIFile> localDir;
+     rv = GetUserDataDirectoryHome(getter_AddRefs(localDir), false);
+     if (NS_SUCCEEDED(rv)) {
+-#if defined(XP_MACOSX)
+-      rv = localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla"));
+-#else
+-      rv = localDir->AppendNative(NS_LITERAL_CSTRING(".mozilla"));
+-#endif
+-    }
+-    if (NS_SUCCEEDED(rv)) {
+       localDir.swap(file);
+     }
+   }
+@@ -1249,8 +1242,6 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
+             nsDependentCString(hasVendor ? GetAppVendor() : GetAppName())))) {
+       return NS_ERROR_FAILURE;
+     }
+-  } else if (NS_FAILED(localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla")))) {
+-    return NS_ERROR_FAILURE;
+   }
+
+   if (NS_FAILED(localDir->Append(NS_LITERAL_STRING("updates"))) ||
+@@ -1378,6 +1369,9 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+   NS_ENSURE_SUCCESS(rv, rv);
+
+   localDir = dirFileMac;
++
++  rv = localDir->AppendRelativeNativePath(nsDependentCString("Mozilla"));
++  NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_IOS)
+   nsAutoCString userDir;
+   if (GetUIKitDirectory(aLocal, userDir)) {
+@@ -1401,6 +1395,9 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+   NS_ENSURE_SUCCESS(rv, rv);
+
+   rv = NS_NewLocalFile(path, true, getter_AddRefs(localDir));
++  NS_ENSURE_SUCCESS(rv, rv);
++  rv = localDir->AppendRelativeNativePath(nsDependentCString("Mozilla"));
++  NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_UNIX)
+   const char* homeDir = getenv("HOME");
+   if (!homeDir || !*homeDir) return NS_ERROR_FAILURE;
+@@ -1422,8 +1419,51 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+         rv = localDir->AppendNative(NS_LITERAL_CSTRING(".cache"));
+     }
+   } else {
++    bool exists;
++    /* check old config ~/.mozilla */
+     rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
+                                getter_AddRefs(localDir));
++    NS_ENSURE_SUCCESS(rv, rv);
++    rv = localDir->AppendRelativeNativePath(nsDependentCString(".mozilla"));
++    NS_ENSURE_SUCCESS(rv, rv);
++    rv = localDir->Exists(&exists);
++    NS_ENSURE_SUCCESS(rv, rv);
++    /* otherwise, use new config */
++    if (!exists) {
++      const char* xdghomedir = getenv("XDG_DATA_HOME");
++      if (!xdghomedir || !*xdghomedir) {
++        rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
++                                   getter_AddRefs(localDir));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->AppendRelativeNativePath(nsDependentCString(".local"));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->Exists(&exists);
++        if (NS_SUCCEEDED(rv) && !exists) {
++          rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++          NS_ENSURE_SUCCESS(rv, rv);
++        }
++        rv = localDir->AppendRelativeNativePath(nsDependentCString("share"));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->Exists(&exists);
++        if (NS_SUCCEEDED(rv) && !exists) {
++          rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++        }
++      }
++      else {
++        rv = NS_NewNativeLocalFile(nsDependentCString(xdghomedir), true,
++                               getter_AddRefs(localDir));
++      }
++      NS_ENSURE_SUCCESS(rv, rv);
++
++      rv = localDir->AppendRelativeNativePath(nsDependentCString("mozilla"));
++      NS_ENSURE_SUCCESS(rv, rv);
++      rv = localDir->Exists(&exists);
++      NS_ENSURE_SUCCESS(rv, rv);
++      if (NS_SUCCEEDED(rv) && !exists) {
++        rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
++        NS_ENSURE_SUCCESS(rv, rv);
++      }
++    }
+   }
+ #else
+ #error "Don't know how to get product dir on your platform"
+@@ -1534,20 +1574,12 @@ nsresult nsXREDirProvider::AppendSysUserExtensionPath(nsIFile* aFile) {
+
+ #if defined(XP_MACOSX) || defined(XP_WIN)
+
+-  static const char* const sXR = "Mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "Extensions";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+
+ #elif defined(XP_UNIX)
+
+-  static const char* const sXR = ".mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "extensions";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+@@ -1565,20 +1597,12 @@ nsresult nsXREDirProvider::AppendSysUserExtensionsDevPath(nsIFile* aFile) {
+
+ #if defined(XP_MACOSX) || defined(XP_WIN)
+
+-  static const char* const sXR = "Mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "SystemExtensionsDev";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+
+ #elif defined(XP_UNIX)
+
+-  static const char* const sXR = ".mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "systemextensionsdev";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+@@ -1636,9 +1660,6 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
+   NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_UNIX)
+   nsAutoCString folder;
+-  // Make it hidden (by starting with "."), except when local (the
+-  // profile is already under ~/.cache or XDG_CACHE_HOME).
+-  if (!aLocal) folder.Assign('.');
+
+   if (!profile.IsEmpty()) {
+     // Skip any leading path characters
+@@ -1658,9 +1679,6 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
+       folder.Append(vendor);
+       ToLowerCase(folder);
+
+-      rv = aFile->AppendNative(folder);
+-      NS_ENSURE_SUCCESS(rv, rv);
+-
+       folder.Truncate();
+     }
+
diff --git a/overlays/patches/firefox/packages.nix b/overlays/patches/firefox/packages.nix
new file mode 100644
index 000000000000..ec4fdcc5336e
--- /dev/null
+++ b/overlays/patches/firefox/packages.nix
@@ -0,0 +1,27 @@
+{ firefoxPackages, clangStdenv }:
+
+with firefoxPackages;
+
+firefoxPackages // {
+  # Use clangStdenv to work around
+  # <https://github.com/NixOS/nixpkgs/issues/84283>
+  # (Firefox fails to build with GCC on AMD EPYC 7401P.)
+
+  firefox = (firefox.override {
+    stdenv = clangStdenv;
+  }).overrideAttrs ({ patches ? [], ... }: {
+    patches = patches ++ [ release/D6695.diff ];
+  });
+
+  firefox-beta = (firefox-beta.override {
+    stdenv = clangStdenv;
+  }).overrideAttrs ({ patches ? [], ... }: {
+    patches = patches ++ [ beta/D6695.diff ];
+  });
+
+  firefox-nightly = (firefox-nightly.override {
+    stdenv = clangStdenv;
+  }).overrideAttrs ({ patches ? [], ... }: {
+    patches = patches ++ [ nightly/D6695.diff ];
+  });
+}
diff --git a/overlays/patches/firefox/profiles.ini b/overlays/patches/firefox/profiles.ini
new file mode 100644
index 000000000000..becf53354e76
--- /dev/null
+++ b/overlays/patches/firefox/profiles.ini
@@ -0,0 +1,8 @@
+[General]
+StartWithLastProfile=1
+
+[Profile0]
+Name=default
+IsRelative=1
+Path=default
+Default=1
diff --git a/overlays/patches/firefox/release/D6695.diff b/overlays/patches/firefox/release/D6695.diff
new file mode 100644
index 000000000000..e6425af02ca6
--- /dev/null
+++ b/overlays/patches/firefox/release/D6695.diff
@@ -0,0 +1,282 @@
+diff --git a/toolkit/moz.build b/toolkit/moz.build
+index f01b128b2493a..ae0e19ec9c509 100644
+--- a/toolkit/moz.build
++++ b/toolkit/moz.build
+@@ -84,3 +84,6 @@ with Files('pluginproblem/**'):
+ 
+ with Files('l10n-registry.manifest'):
+     BUG_COMPONENT = ('Core', 'Localization')
++
++if CONFIG['ENABLE_TESTS']:
++    DIRS += ['tests/gtest']
+diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
+index 1d6ffb748e4e4..8708279b964a2 100644
+--- a/toolkit/xre/nsXREDirProvider.cpp
++++ b/toolkit/xre/nsXREDirProvider.cpp
+@@ -390,13 +390,6 @@ nsXREDirProvider::GetFile(const char* aProperty, bool* aPersistent,
+     nsCOMPtr<nsIFile> localDir;
+     rv = GetUserDataDirectoryHome(getter_AddRefs(localDir), false);
+     if (NS_SUCCEEDED(rv)) {
+-#  if defined(XP_MACOSX)
+-      rv = localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla"));
+-#  else
+-      rv = localDir->AppendNative(NS_LITERAL_CSTRING(".mozilla"));
+-#  endif
+-    }
+-    if (NS_SUCCEEDED(rv)) {
+       localDir.swap(file);
+     }
+   }
+@@ -1302,7 +1295,8 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
+             nsDependentCString(hasVendor ? GetAppVendor() : GetAppName())))) {
+       return NS_ERROR_FAILURE;
+     }
+-  } else if (NS_FAILED(localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla")))) {
++  }
++  else if (NS_FAILED(localDir->AppendNative(NS_LITERAL_CSTRING("Mozilla")))) {
+     return NS_ERROR_FAILURE;
+   }
+ 
+@@ -1443,6 +1437,9 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   localDir = dirFileMac;
++
++  rv = localDir->AppendRelativeNativePath(nsDependentCString("Mozilla"));
++  NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_IOS)
+   nsAutoCString userDir;
+   if (GetUIKitDirectory(aLocal, userDir)) {
+@@ -1466,6 +1463,9 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   rv = NS_NewLocalFile(path, true, getter_AddRefs(localDir));
++  NS_ENSURE_SUCCESS(rv, rv);
++  rv = localDir->AppendRelativeNativePath(nsDependentCString("Mozilla"));
++  NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_UNIX)
+   const char* homeDir = getenv("HOME");
+   if (!homeDir || !*homeDir) return NS_ERROR_FAILURE;
+@@ -1487,8 +1487,51 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
+         rv = localDir->AppendNative(NS_LITERAL_CSTRING(".cache"));
+     }
+   } else {
++    bool exists;
++    // check old config ~/.mozilla
+     rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
+                                getter_AddRefs(localDir));
++    NS_ENSURE_SUCCESS(rv, rv);
++    rv = localDir->AppendRelativeNativePath(nsDependentCString(".mozilla"));
++    NS_ENSURE_SUCCESS(rv, rv);
++    rv = localDir->Exists(&exists);
++    NS_ENSURE_SUCCESS(rv, rv);
++    // otherwise, use new config
++    if (!exists) {
++      const char* xdghomedir = getenv("XDG_DATA_HOME");
++      if (!xdghomedir || !*xdghomedir) {
++        rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
++                                   getter_AddRefs(localDir));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->AppendRelativeNativePath(nsDependentCString(".local"));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->Exists(&exists);
++        if (NS_SUCCEEDED(rv) && !exists) {
++          rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++          NS_ENSURE_SUCCESS(rv, rv);
++        }
++        rv = localDir->AppendRelativeNativePath(nsDependentCString("share"));
++        NS_ENSURE_SUCCESS(rv, rv);
++        rv = localDir->Exists(&exists);
++        if (NS_SUCCEEDED(rv) && !exists) {
++          rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++        }
++      }
++      else {
++        rv = NS_NewNativeLocalFile(nsDependentCString(xdghomedir), true,
++                               getter_AddRefs(localDir));
++      }
++      NS_ENSURE_SUCCESS(rv, rv);
++
++      rv = localDir->AppendRelativeNativePath(nsDependentCString("mozilla"));
++      NS_ENSURE_SUCCESS(rv, rv);
++      rv = localDir->Exists(&exists);
++      NS_ENSURE_SUCCESS(rv, rv);
++      if (NS_SUCCEEDED(rv) && !exists) {
++        rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
++        NS_ENSURE_SUCCESS(rv, rv);
++      }
++    }
+   }
+ #else
+ #  error "Don't know how to get product dir on your platform"
+@@ -1609,20 +1652,12 @@ nsresult nsXREDirProvider::AppendSysUserExtensionPath(nsIFile* aFile) {
+ 
+ #if defined(XP_MACOSX) || defined(XP_WIN)
+ 
+-  static const char* const sXR = "Mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "Extensions";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+ #elif defined(XP_UNIX)
+ 
+-  static const char* const sXR = ".mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "extensions";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+@@ -1640,20 +1675,12 @@ nsresult nsXREDirProvider::AppendSysUserExtensionsDevPath(nsIFile* aFile) {
+ 
+ #if defined(XP_MACOSX) || defined(XP_WIN)
+ 
+-  static const char* const sXR = "Mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "SystemExtensionsDev";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+ #elif defined(XP_UNIX)
+ 
+-  static const char* const sXR = ".mozilla";
+-  rv = aFile->AppendNative(nsDependentCString(sXR));
+-  NS_ENSURE_SUCCESS(rv, rv);
+-
+   static const char* const sExtensions = "systemextensionsdev";
+   rv = aFile->AppendNative(nsDependentCString(sExtensions));
+   NS_ENSURE_SUCCESS(rv, rv);
+@@ -1718,9 +1745,6 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
+   NS_ENSURE_SUCCESS(rv, rv);
+ #elif defined(XP_UNIX)
+   nsAutoCString folder;
+-  // Make it hidden (by starting with "."), except when local (the
+-  // profile is already under ~/.cache or XDG_CACHE_HOME).
+-  if (!aLocal) folder.Assign('.');
+ 
+   if (!profile.IsEmpty()) {
+     // Skip any leading path characters
+@@ -1740,8 +1764,12 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
+       folder.Append(vendor);
+       ToLowerCase(folder);
+ 
+-      rv = aFile->AppendNative(folder);
+-      NS_ENSURE_SUCCESS(rv, rv);
++      // Keep the 'mozilla' path for cache:
++      // Use ${XDG_DATA_HOME:-$HOME/.cache}/mozilla/firefox
++      if (aLocal) {
++        rv = aFile->AppendNative(folder);
++        NS_ENSURE_SUCCESS(rv, rv);
++      }
+ 
+       folder.Truncate();
+     }
+diff --git a/xpcom/io/nsAppFileLocationProvider.cpp b/xpcom/io/nsAppFileLocationProvider.cpp
+index e79c8303fe129..53c550db18c05 100644
+--- a/xpcom/io/nsAppFileLocationProvider.cpp
++++ b/xpcom/io/nsAppFileLocationProvider.cpp
+@@ -247,7 +247,7 @@ nsresult nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile) {
+ // GetProductDirectory - Gets the directory which contains the application data
+ // folder
+ //
+-// UNIX   : ~/.mozilla/
++// UNIX   : ~/.mozilla/ or ${XDG_DATA_HOME:-~/.local/share}/mozilla
+ // WIN    : <Application Data folder on user's machine>\Mozilla
+ // Mac    : :Documents:Mozilla:
+ //----------------------------------------------------------------------------------------
+@@ -291,19 +291,80 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
+     return rv;
+   }
+ #elif defined(XP_UNIX)
+-  rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), true,
++  const char* homeDir = PR_GetEnv("HOME");
++  /* check old config ~/.mozilla */
++  rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
+                              getter_AddRefs(localDir));
+   if (NS_FAILED(rv)) {
+     return rv;
+   }
++  rv = localDir->AppendRelativeNativePath(nsDependentCString(".mozilla"));
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
++  rv = localDir->Exists(&exists);
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
++  /* otherwise, use new config */
++  if (!exists) {
++    const char* xdghomedir = PR_GetEnv("XDG_DATA_HOME");
++    if (!xdghomedir || !*xdghomedir) {
++      /* XDG_DATA_HOME=$HOME/.local/share */
++      rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
++                                 getter_AddRefs(localDir));
++      if (NS_FAILED(rv)) {
++        return rv;
++      }
++      rv = localDir->AppendRelativeNativePath(nsDependentCString(".local"));
++      if (NS_FAILED(rv)) {
++        return rv;
++      }
++      rv = localDir->Exists(&exists);
++      if (NS_SUCCEEDED(rv) && !exists) {
++        rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++        if (NS_FAILED(rv)) {
++          return rv;
++        }
++      }
++      rv = localDir->AppendRelativeNativePath(nsDependentCString("share"));
++      if (NS_FAILED(rv)) {
++        return rv;
++      }
++      rv = localDir->Exists(&exists);
++      if (NS_SUCCEEDED(rv) && !exists) {
++        rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0755);
++      }
++    }
++    else {
++      rv = NS_NewNativeLocalFile(nsDependentCString(xdghomedir), true,
++                                 getter_AddRefs(localDir));
++    }
++    if (NS_FAILED(rv)) {
++      return rv;
++    }
++    rv = localDir->AppendRelativeNativePath(nsDependentCString("mozilla"));
++    if (NS_FAILED(rv)) {
++      return rv;
++    }
++  }
+ #else
+ #  error dont_know_how_to_get_product_dir_on_your_platform
+ #endif
+ 
++#if !defined(XP_UNIX) || defined(XP_MACOSX)
++  // Since we have to check for legacy configuration, we have
++  // the complete path for Linux already, so this is not
++  // needed. If we stop checking for legacy at some point,
++  // then we can change this to not be protected by
++  // this clause.
+   rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
++
+   if (NS_FAILED(rv)) {
+     return rv;
+   }
++#endif
++
+   rv = localDir->Exists(&exists);
+ 
+   if (NS_SUCCEEDED(rv) && !exists) {
+@@ -323,7 +384,7 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
+ // GetDefaultUserProfileRoot - Gets the directory which contains each user
+ // profile dir
+ //
+-// UNIX   : ~/.mozilla/
++// UNIX   : ~/.mozilla/ or ${XDG_DATA_HOME:-~/.local/share}/mozilla
+ // WIN    : <Application Data folder on user's machine>\Mozilla\Profiles
+ // Mac    : :Documents:Mozilla:Profiles:
+ //----------------------------------------------------------------------------------------
diff --git a/overlays/patches/firefox/user.js b/overlays/patches/firefox/user.js
new file mode 100644
index 000000000000..8b137891791f
--- /dev/null
+++ b/overlays/patches/firefox/user.js
@@ -0,0 +1 @@
+
diff --git a/overlays/patches/public-inbox/0003-view-don-t-show-page-if-no-links-follow-it.patch b/overlays/patches/public-inbox/0003-view-don-t-show-page-if-no-links-follow-it.patch
new file mode 100644
index 000000000000..811d6149d994
--- /dev/null
+++ b/overlays/patches/public-inbox/0003-view-don-t-show-page-if-no-links-follow-it.patch
@@ -0,0 +1,27 @@
+From 054697a5129725f900a84bbdfee356a4f5373376 Mon Sep 17 00:00:00 2001
+From: Alyssa Ross <hi@alyssa.is>
+Date: Thu, 16 Jan 2020 18:08:33 +0000
+Subject: [PATCH 3/5] view: don't show `page:' if no links follow it
+
+---
+ lib/PublicInbox/View.pm | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
+index 39b04174..aebf7fe9 100644
+--- a/lib/PublicInbox/View.pm
++++ b/lib/PublicInbox/View.pm
+@@ -1157,7 +1157,9 @@ sub pagination_footer ($$) {
+ 		$next = $next ? "$next " : '     ';
+ 		$prev .= qq! <a\nhref='$latest'>latest</a>!;
+ 	}
+-	"<hr><pre>page: $next$prev</pre>";
++	if ($prev || $next) {
++		"<hr><pre>page: $next$prev</pre>";
++	}
+ }
+ 
+ sub index_nav { # callback for WwwStream
+-- 
+2.26.1
+
diff --git a/overlays/patches/public-inbox/0004-view-don-t-500-if-no-mail-received-yet.patch b/overlays/patches/public-inbox/0004-view-don-t-500-if-no-mail-received-yet.patch
new file mode 100644
index 000000000000..eb33468e1992
--- /dev/null
+++ b/overlays/patches/public-inbox/0004-view-don-t-500-if-no-mail-received-yet.patch
@@ -0,0 +1,25 @@
+From 2712913f07d83a6a33bbdc55a1edee0a008e5b2e Mon Sep 17 00:00:00 2001
+From: Alyssa Ross <hi@alyssa.is>
+Date: Thu, 16 Jan 2020 18:09:12 +0000
+Subject: [PATCH 4/5] view: don't 500 if no mail received yet
+
+---
+ lib/PublicInbox/View.pm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
+index aebf7fe9..b40108bc 100644
+--- a/lib/PublicInbox/View.pm
++++ b/lib/PublicInbox/View.pm
+@@ -1083,7 +1083,7 @@ sub acc_topic {
+ sub dump_topics {
+ 	my ($ctx) = @_;
+ 	my $order = delete $ctx->{order}; # [ ds, subj1, subj2, subj3, ... ]
+-	if (!@$order) {
++	if (!defined $order || !@$order) {
+ 		$ctx->{-html_tip} = '<pre>[No topics in range]</pre>';
+ 		return 404;
+ 	}
+-- 
+2.26.1
+
diff --git a/overlays/patches/public-inbox/0005-wwwstream-make-source-info-configurable.patch b/overlays/patches/public-inbox/0005-wwwstream-make-source-info-configurable.patch
new file mode 100644
index 000000000000..605100cd38ae
--- /dev/null
+++ b/overlays/patches/public-inbox/0005-wwwstream-make-source-info-configurable.patch
@@ -0,0 +1,112 @@
+From f119d4315be998de65d5a1b56fa643fb9084410b Mon Sep 17 00:00:00 2001
+From: Alyssa Ross <hi@alyssa.is>
+Date: Fri, 17 Jan 2020 15:21:42 +0000
+Subject: [PATCH 5/5] wwwstream: make source info configurable
+
+---
+ Documentation/public-inbox-config.pod |  6 ++++++
+ lib/PublicInbox/WwwListing.pm         |  9 +++++----
+ lib/PublicInbox/WwwStream.pm          | 28 +++++++++++++++++++++++----
+ 3 files changed, 35 insertions(+), 8 deletions(-)
+
+diff --git a/Documentation/public-inbox-config.pod b/Documentation/public-inbox-config.pod
+index 1c5ba015..5ae23924 100644
+--- a/Documentation/public-inbox-config.pod
++++ b/Documentation/public-inbox-config.pod
+@@ -186,6 +186,12 @@ and the path may be "/dev/null" or any empty file.
+ Multiple files may be specified and will be included in the
+ order specified.
+ 
++=item publicinbox.sourceinfo
++
++Path to a file containing HTML instructions for downloading the
++public-inbox source code.  Useful for AGPL compliance.  If not
++specified, default git clone instructions are used.
++
+ =item publicinboxmda.spamcheck
+ 
+ This may be set to C<none> to disable the use of SpamAssassin
+diff --git a/lib/PublicInbox/WwwListing.pm b/lib/PublicInbox/WwwListing.pm
+index 03534f03..f1a1fd81 100644
+--- a/lib/PublicInbox/WwwListing.pm
++++ b/lib/PublicInbox/WwwListing.pm
+@@ -87,8 +87,8 @@ sub ibx_entry {
+ 	$tmp;
+ }
+ 
+-sub html ($$) {
+-	my ($env, $list) = @_;
++sub html ($$$) {
++	my ($pi_config, $env, $list) = @_;
+ 	my $title = 'public-inbox';
+ 	my $out = '';
+ 	my $code = 404;
+@@ -107,7 +107,8 @@ sub html ($$) {
+ 		$out = '<pre>'.$l->linkify_2(ascii_html($tmp)).'</pre><hr>';
+ 	}
+ 	$out = "<html><head><title>$title</title></head><body>" . $out;
+-	$out .= '<pre>'. PublicInbox::WwwStream::code_footer($env) .
++	$out .= '<pre>' .
++	        PublicInbox::WwwStream::code_footer($pi_config, $env) .
+ 		'</pre></body></html>';
+ 
+ 	my $h = [ 'Content-Type', 'text/html; charset=UTF-8' ];
+@@ -231,7 +232,7 @@ sub call {
+ 		js($env, $list);
+ 	} else { # /
+ 		my $list = $self->{www_cb}->($self, $env, 'www');
+-		html($env, $list);
++		html($self->{pi_config}, $env, $list);
+ 	}
+ }
+ 
+diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm
+index 0f4f55d0..09473c9f 100644
+--- a/lib/PublicInbox/WwwStream.pm
++++ b/lib/PublicInbox/WwwStream.pm
+@@ -76,10 +76,30 @@ sub _html_top ($) {
+ 		"</head><body>". $top . $tip;
+ }
+ 
+-sub code_footer ($) {
+-	my ($env) = @_;
++sub get_user_source_info ($) {
++	my ($pi_config) = @_;
++
++	local $/;
++	my $path = $pi_config->{'publicinbox.sourceinfo'};
++	if (!defined($path)) {
++		return;
++	}
++	open my $fh, '<', $path or do {
++		warn "Failed to open publicinbox.sourceinfo=$path: $!\n";
++		return;
++	};
++	<$fh>;
++}
++
++sub code_footer {
++	my ($pi_config, $env) = @_;
++
+ 	my $u = PublicInbox::Hval::prurl($env, $CODE_URL);
+-	qq(AGPL code for this site: git clone <a\nhref="$u">$u</a>)
++	my $default_info = qq(git clone <a\n href="$u">$u</a>);
++
++	my $info = get_user_source_info($pi_config) || $default_info;
++
++	"AGPL code for this site: $info"
+ }
+ 
+ sub _html_end {
+@@ -153,7 +173,7 @@ EOF
+ 	'<hr><pre>'.join("\n\n",
+ 		$desc,
+ 		$urls,
+-		code_footer($ctx->{env})
++		code_footer($ctx->{www}->{pi_config}, $ctx->{env})
+ 	).'</pre></body></html>';
+ }
+ 
+-- 
+2.26.1
+
diff --git a/overlays/patches/public-inbox/default.nix b/overlays/patches/public-inbox/default.nix
new file mode 100644
index 000000000000..f9f573787c1c
--- /dev/null
+++ b/overlays/patches/public-inbox/default.nix
@@ -0,0 +1,9 @@
+{ public-inbox }:
+
+public-inbox.overrideAttrs ({ patches ? [], ... }: {
+  patches = patches ++ [
+    ./0003-view-don-t-show-page-if-no-links-follow-it.patch
+    ./0004-view-don-t-500-if-no-mail-received-yet.patch
+    ./0005-wwwstream-make-source-info-configurable.patch
+  ];
+})
diff --git a/overlays/patches/python/default.nix b/overlays/patches/python/default.nix
new file mode 100644
index 000000000000..332cebfcb3fc
--- /dev/null
+++ b/overlays/patches/python/default.nix
@@ -0,0 +1,11 @@
+{ python, lib }:
+
+python.override {
+  packageOverrides = lib.composeExtensions python.packageOverrides (
+    final: super: with final; {
+      hyperkitty = callPackage ./packages/hyperkitty {
+        inherit (super) hyperkitty;
+      };
+    }
+  );
+}
diff --git a/overlays/patches/python/packages/hyperkitty/0001-Improve-look-of-fixed-width-messages.patch b/overlays/patches/python/packages/hyperkitty/0001-Improve-look-of-fixed-width-messages.patch
new file mode 100644
index 000000000000..cbf9083ed5e9
--- /dev/null
+++ b/overlays/patches/python/packages/hyperkitty/0001-Improve-look-of-fixed-width-messages.patch
@@ -0,0 +1,29 @@
+From bd62e0ac83b46d763bb6d083e2979032d75c7587 Mon Sep 17 00:00:00 2001
+From: Alyssa Ross <hi@alyssa.is>
+Date: Sat, 4 Apr 2020 11:11:45 +0000
+Subject: [PATCH] Improve look of fixed-width messages
+
+Use the system monospace font, which can be set to whatever the user
+wants, and decrease the font size a bit, because monospace fonts
+usually feel a bit bigger than their variable-width counterparts.
+---
+ hyperkitty/static/hyperkitty/sass/_hyperkitty-message.scss | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/hyperkitty/static/hyperkitty/sass/_hyperkitty-message.scss b/hyperkitty/static/hyperkitty/sass/_hyperkitty-message.scss
+index 25f7f1e..f035d69 100644
+--- a/hyperkitty/static/hyperkitty/sass/_hyperkitty-message.scss
++++ b/hyperkitty/static/hyperkitty/sass/_hyperkitty-message.scss
+@@ -127,7 +127,8 @@ $oddEmailColor: rgb(238, 238, 238);
+     }
+ }
+ .email-body.fixed {
+-    font-family: 'Droid Sans Mono', monospace;
++    font-family: monospace;
++    font-size: 0.9em;
+     white-space: pre;
+ }
+ 
+-- 
+2.24.1
+
diff --git a/overlays/patches/python/packages/hyperkitty/default.nix b/overlays/patches/python/packages/hyperkitty/default.nix
new file mode 100644
index 000000000000..e8a4315e2be4
--- /dev/null
+++ b/overlays/patches/python/packages/hyperkitty/default.nix
@@ -0,0 +1,7 @@
+{ hyperkitty, fetchpatch }:
+
+hyperkitty.overridePythonAttrs ({ patches ? [], ... }: {
+  patches = patches ++ [
+    ./0001-Improve-look-of-fixed-width-messages.patch
+  ];
+})
diff --git a/overlays/patches/tmux/default.nix b/overlays/patches/tmux/default.nix
new file mode 100644
index 000000000000..cc13ac2a86c2
--- /dev/null
+++ b/overlays/patches/tmux/default.nix
@@ -0,0 +1,7 @@
+{ tmux }:
+
+tmux.overrideAttrs ({ CPPFLAGS ? [], ... }: {
+  CPPFLAGS = CPPFLAGS ++ [
+    ''-DTMUX_CONF="\"\$$XDG_CONFIG_HOME/tmux/tmux.conf"\"''
+  ];
+})
diff --git a/overlays/scripts/choose/choose.in b/overlays/scripts/choose/choose.in
new file mode 100644
index 000000000000..7f60b47386a3
--- /dev/null
+++ b/overlays/scripts/choose/choose.in
@@ -0,0 +1,20 @@
+#! @execline@/bin/execlineb -S0
+
+define -s fzf_opts "--reverse"
+
+ifelse { importas -i _ DISPLAY }
+{
+  alacritty --class float -e
+  getpid my_pid
+  importas -i -u my_pid my_pid
+  backtick -i -n term_pid { awk "{print $4}" /proc/${my_pid}/stat }
+  importas -i -u term_pid term_pid
+  redirfd -r 0 /proc/${term_pid}/fd/0
+  redirfd -w 1 /proc/${term_pid}/fd/1
+  @fzf@/bin/fzf $fzf_opts $@
+}
+
+ifelse { importas -i _ TMUX }
+{ @fzf@/bin/fzf-tmux $fzf_opts $@ }
+
+@fzf@/bin/fzf $fzf_opts $@
diff --git a/overlays/scripts/choose/choosebin.in b/overlays/scripts/choose/choosebin.in
new file mode 100644
index 000000000000..7f8ea520c994
--- /dev/null
+++ b/overlays/scripts/choose/choosebin.in
@@ -0,0 +1,17 @@
+#! @execline@/bin/execlineb -S0
+
+backtick -i entry_points {
+  importas PATH PATH
+  heredoc 0 $PATH
+  tr : " "
+}
+importas -s -i -u entry_points entry_points
+
+pipeline {
+  redirfd -w 2 /dev/null
+  find -L $entry_points -mindepth 1 -maxdepth 1 -executable -type f
+}
+
+pipeline { awk -F / "{print $NF}" }
+
+@out@/bin/choose --prompt "$ " $@
diff --git a/overlays/scripts/choose/default.nix b/overlays/scripts/choose/default.nix
new file mode 100644
index 000000000000..d4e845f8b967
--- /dev/null
+++ b/overlays/scripts/choose/default.nix
@@ -0,0 +1,8 @@
+{ runCommand, makeWrapper, execline, fzf }:
+
+runCommand "choose" { inherit execline fzf; } ''
+  install -d $out/bin
+  substituteAll ${./choose.in} $out/bin/choose
+  substituteAll ${./choosebin.in} $out/bin/choosebin
+  chmod +x $out/bin/*
+''
diff --git a/overlays/scripts/default.nix b/overlays/scripts/default.nix
new file mode 100644
index 000000000000..983d32d867a4
--- /dev/null
+++ b/overlays/scripts/default.nix
@@ -0,0 +1,3 @@
+self: super: {
+  choose = self.callPackage ./choose { };
+}